import { CaretLeftIcon, CopyIcon, FolderIcon } from '@phosphor-icons/react';
import { useTranslation } from 'react-i18next';
import {
Command,
CommandInput,
CommandList,
CommandEmpty,
CommandGroup,
CommandItem,
CommandShortcut,
} from './Command';
import type { ActionDefinition, ActionIcon } from '../actions';
import { isSpecialIcon } from '../actions';
import type { ResolvedGroup, ResolvedGroupItem } from '../actions/pages';
import { IdeIcon } from '@/components/ide/IdeIcon';
/**
* Render an action icon, handling special icon types
*/
function ActionItemIcon({ icon }: { icon: ActionIcon }) {
if (isSpecialIcon(icon)) {
if (icon === 'ide-icon') {
return ;
}
if (icon === 'copy-icon') {
return ;
}
}
// Regular phosphor icon
const IconComponent = icon;
return ;
}
// Resolved page structure with pre-processed groups
interface ResolvedCommandBarPage {
id: string;
title?: string;
groups: ResolvedGroup[];
}
interface CommandBarProps {
// Resolved page with groups already processed
page: ResolvedCommandBarPage;
// Whether back navigation is available
canGoBack: boolean;
// Called when user clicks back
onGoBack: () => void;
// Called when user selects an item (action or page)
onSelect: (item: ResolvedGroupItem) => void;
// Get resolved label for an action
getLabel: (action: ActionDefinition) => string;
// Controlled search value
search: string;
// Called when search changes
onSearchChange: (search: string) => void;
}
export function CommandBar({
page,
canGoBack,
onGoBack,
onSelect,
getLabel,
search,
onSearchChange,
}: CommandBarProps) {
const { t } = useTranslation('common');
return (
{
// Always show the back option
if (value === '__back__') return 1;
// Default filtering for other items
if (value.toLowerCase().includes(search.toLowerCase())) return 1;
return 0;
}}
>
{t('commandBar.noResults')}
{canGoBack && !search && (
{t('commandBar.back')}
)}
{/* Render groups directly - order is explicit from page definition */}
{page.groups.map((group) => (
{group.items.map((item) => {
if (item.type === 'page') {
const IconComponent = item.icon;
return (
onSelect(item)}
>
{item.label}
);
} else if (item.type === 'repo') {
return (
onSelect(item)}
>
{item.repo.display_name}
);
} else if (item.type === 'action') {
const label = getLabel(item.action);
return (
onSelect(item)}
className={
item.action.variant === 'destructive'
? 'text-error'
: undefined
}
>
{label}
{item.action.shortcut && (
{item.action.shortcut}
)}
);
}
return null;
})}
))}
);
}