{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "command",
  "type": "registry:ui",
  "dependencies": [
    "@kobalte/core",
    "lucide-solid"
  ],
  "registryDependencies": [
    "@gc-solid/dialog"
  ],
  "files": [
    {
      "path": "ui/command.tsx",
      "content": "import type { Component, ComponentProps, JSX, ParentComponent } from \"solid-js\"\nimport {\n  createContext,\n  createSignal,\n  createUniqueId,\n  mergeProps,\n  Show,\n  splitProps,\n  useContext\n} from \"solid-js\"\n\nimport { Search } from \"lucide-solid\"\n\nimport { cn } from \"@/lib/utils\"\nimport {\n  Dialog,\n  DialogContent,\n  DialogDescription,\n  DialogHeader,\n  DialogTitle\n} from \"@/components/ui/dialog\"\n\ntype CommandContextValue = {\n  search: () => string\n  setSearch: (value: string) => void\n  filter: (value: string, search: string) => number\n}\n\nconst CommandContext = createContext<CommandContextValue>()\n\nconst useCommand = () => {\n  const context = useContext(CommandContext)\n  if (!context) {\n    throw new Error(\"useCommand must be used within a Command component\")\n  }\n  return context\n}\n\nfunction defaultFilter(value: string, search: string): number {\n  const normalizedValue = value.toLowerCase().trim()\n  const normalizedSearch = search.toLowerCase().trim()\n  if (normalizedSearch.length === 0) return 1\n  if (normalizedValue.includes(normalizedSearch)) return 1\n  return 0\n}\n\ntype CommandProps = ComponentProps<\"div\"> & {\n  filter?: (value: string, search: string) => number\n}\n\nconst Command: Component<CommandProps> = (rawProps) => {\n  const props = mergeProps({ filter: defaultFilter }, rawProps)\n  const [local, others] = splitProps(props, [\"class\", \"filter\"])\n  const [search, setSearch] = createSignal(\"\")\n\n  const contextValue: CommandContextValue = {\n    search,\n    setSearch,\n    filter: local.filter\n  }\n\n  return (\n    <CommandContext.Provider value={contextValue}>\n      <div\n        class={cn(\n          \"cn-command flex h-full w-full flex-col overflow-hidden rounded-md bg-popover text-popover-foreground\",\n          local.class\n        )}\n        cmdk-root=\"\"\n        data-slot=\"command\"\n        role=\"application\"\n        {...others}\n      />\n    </CommandContext.Provider>\n  )\n}\n\ntype CommandDialogProps = ComponentProps<typeof Dialog> & {\n  title?: string\n  description?: string\n  class?: string\n  showCloseButton?: boolean\n  children?: JSX.Element\n}\n\nconst CommandDialog: ParentComponent<CommandDialogProps> = (rawProps) => {\n  const props = mergeProps(\n    {\n      title: \"Command Palette\",\n      description: \"Search for a command to run...\",\n      showCloseButton: true\n    },\n    rawProps\n  )\n  const [local, others] = splitProps(props, [\n    \"title\",\n    \"description\",\n    \"class\",\n    \"showCloseButton\",\n    \"children\"\n  ])\n\n  return (\n    <Dialog {...others}>\n      <DialogHeader class=\"sr-only\">\n        <DialogTitle>{local.title}</DialogTitle>\n        <DialogDescription>{local.description}</DialogDescription>\n      </DialogHeader>\n      <DialogContent\n        class={cn(\"overflow-hidden p-0\", local.class)}\n        showCloseButton={local.showCloseButton}\n      >\n        <Command class=\"**:data-[slot=command-input-wrapper]:h-12 [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5\">\n          {local.children}\n        </Command>\n      </DialogContent>\n    </Dialog>\n  )\n}\n\ntype CommandInputProps = ComponentProps<\"input\">\n\nconst CommandInput: Component<CommandInputProps> = (props) => {\n  const [local, others] = splitProps(props, [\"class\", \"value\", \"onInput\"])\n  const command = useCommand()\n  const id = createUniqueId()\n\n  const handleInput = (\n    e: InputEvent & { currentTarget: HTMLInputElement; target: HTMLInputElement }\n  ) => {\n    command.setSearch(e.currentTarget.value)\n    if (typeof local.onInput === \"function\") {\n      local.onInput(e)\n    }\n  }\n\n  return (\n    <div\n      class=\"flex h-9 items-center gap-2 border-b px-3\"\n      cmdk-input-wrapper=\"\"\n      data-slot=\"command-input-wrapper\"\n    >\n      <Search class=\"size-4 shrink-0 opacity-50\" />\n      <input\n        class={cn(\n          \"cn-command-input flex h-10 w-full rounded-md bg-transparent py-3 text-sm outline-hidden placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50\",\n          local.class\n        )}\n        cmdk-input=\"\"\n        data-slot=\"command-input\"\n        id={id}\n        onInput={handleInput}\n        type=\"text\"\n        value={local.value ?? command.search()}\n        {...others}\n      />\n    </div>\n  )\n}\n\ntype CommandListProps = ComponentProps<\"div\">\n\nconst CommandList: ParentComponent<CommandListProps> = (props) => {\n  const [local, others] = splitProps(props, [\"class\"])\n  return (\n    <div\n      class={cn(\n        \"cn-command-list max-h-[300px] scroll-py-1 overflow-y-auto overflow-x-hidden\",\n        local.class\n      )}\n      cmdk-list=\"\"\n      data-slot=\"command-list\"\n      role=\"listbox\"\n      {...others}\n    />\n  )\n}\n\ntype CommandEmptyProps = ComponentProps<\"div\">\n\nconst CommandEmpty: ParentComponent<CommandEmptyProps> = (props) => {\n  const [local, others] = splitProps(props, [\"class\"])\n  const command = useCommand()\n\n  // Show empty state only when search is active but no results\n  const shouldShow = () => command.search().length > 0\n\n  return (\n    <Show when={shouldShow()}>\n      <div\n        class={cn(\"cn-command-empty py-6 text-center text-sm\", local.class)}\n        cmdk-empty=\"\"\n        data-slot=\"command-empty\"\n        role=\"presentation\"\n        {...others}\n      />\n    </Show>\n  )\n}\n\ntype CommandGroupProps = ComponentProps<\"div\"> & {\n  heading?: JSX.Element\n}\n\nconst CommandGroup: ParentComponent<CommandGroupProps> = (props) => {\n  const [local, others] = splitProps(props, [\"class\", \"heading\", \"children\"])\n  const [hasVisibleItems] = createSignal(true)\n\n  // In a real implementation, we would track which items are visible\n  // For now, we'll keep it simple and always show the group\n  const shouldShow = () => hasVisibleItems()\n\n  return (\n    <Show when={shouldShow()}>\n      <div\n        class={cn(\"cn-command-group overflow-hidden p-1\", local.class)}\n        cmdk-group=\"\"\n        data-slot=\"command-group\"\n        role=\"group\"\n        {...others}\n      >\n        <Show when={local.heading}>\n          <div\n            class=\"px-2 py-1.5 font-medium text-muted-foreground text-xs\"\n            cmdk-group-heading=\"\"\n            role=\"presentation\"\n          >\n            {local.heading}\n          </div>\n        </Show>\n        {local.children}\n      </div>\n    </Show>\n  )\n}\n\ntype CommandSeparatorProps = ComponentProps<\"div\">\n\nconst CommandSeparator: Component<CommandSeparatorProps> = (props) => {\n  const [local, others] = splitProps(props, [\"class\"])\n  return (\n    <div\n      class={cn(\"cn-command-separator -mx-1 h-px bg-border\", local.class)}\n      cmdk-separator=\"\"\n      data-slot=\"command-separator\"\n      role=\"separator\"\n      {...others}\n    />\n  )\n}\n\ntype CommandItemProps = ComponentProps<\"div\"> & {\n  value?: string\n  keywords?: string[]\n  onSelect?: (value: string) => void\n  disabled?: boolean\n}\n\nconst CommandItem: ParentComponent<CommandItemProps> = (props) => {\n  const [local, others] = splitProps(props, [\n    \"class\",\n    \"value\",\n    \"keywords\",\n    \"onSelect\",\n    \"disabled\",\n    \"children\"\n  ])\n  const command = useCommand()\n  const [selected] = createSignal(false)\n\n  // Compute search score\n  const score = () => {\n    const searchValue = command.search()\n    if (!local.value) return 1\n\n    // Check main value\n    let mainScore = command.filter(local.value, searchValue)\n\n    // Check keywords\n    if (local.keywords && mainScore === 0) {\n      for (const keyword of local.keywords) {\n        const keywordScore = command.filter(keyword, searchValue)\n        if (keywordScore > 0) {\n          mainScore = keywordScore\n          break\n        }\n      }\n    }\n\n    return mainScore\n  }\n\n  const isVisible = () => score() > 0\n  const isDisabled = () => local.disabled ?? false\n\n  const handleClick = () => {\n    if (isDisabled()) return\n    local.onSelect?.(local.value ?? \"\")\n  }\n\n  const handleKeyDown = (e: KeyboardEvent) => {\n    if (isDisabled()) return\n    if (e.key === \"Enter\" || e.key === \" \") {\n      e.preventDefault()\n      local.onSelect?.(local.value ?? \"\")\n    }\n  }\n\n  return (\n    <Show when={isVisible()}>\n      <div\n        class={cn(\n          \"cn-command-item relative flex cursor-default select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden data-[disabled=true]:pointer-events-none data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-[disabled=true]:opacity-50 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0\",\n          local.class\n        )}\n        cmdk-item=\"\"\n        data-disabled={isDisabled()}\n        data-selected={selected()}\n        data-slot=\"command-item\"\n        onClick={handleClick}\n        onKeyDown={handleKeyDown}\n        role=\"option\"\n        tabIndex={isDisabled() ? undefined : 0}\n        {...others}\n      >\n        {local.children}\n      </div>\n    </Show>\n  )\n}\n\ntype CommandShortcutProps = ComponentProps<\"span\">\n\nconst CommandShortcut: ParentComponent<CommandShortcutProps> = (props) => {\n  const [local, others] = splitProps(props, [\"class\"])\n  return (\n    <span\n      class={cn(\n        \"cn-command-shortcut ml-auto text-muted-foreground text-xs tracking-widest\",\n        local.class\n      )}\n      data-slot=\"command-shortcut\"\n      {...others}\n    />\n  )\n}\n\nexport {\n  Command,\n  CommandDialog,\n  CommandInput,\n  CommandList,\n  CommandEmpty,\n  CommandGroup,\n  CommandItem,\n  CommandShortcut,\n  CommandSeparator\n}\n",
      "type": "registry:ui"
    }
  ]
}