{
  "name": "command",
  "type": "registry:ui",
  "title": "Command",
  "description": "Command combines a dialog and autocomplete list for fast keyboard-driven navigation, search, and actions.",
  "registryDependencies": [
    "@siteplane/base",
    "@siteplane/autocomplete"
  ],
  "dependencies": [
    "@base-ui/react@1.5.0",
    "lucide-react@1.18.0"
  ],
  "files": [
    {
      "path": "src/components/ui/command.tsx",
      "type": "registry:ui",
      "content": "\"use client\";\n\nimport { Dialog as CommandDialogPrimitive } from \"@base-ui/react/dialog\";\nimport { SearchIcon } from \"lucide-react\";\nimport type * as React from \"react\";\nimport { cn } from \"@/lib/utils\";\nimport { SiteplaneUIPortalScope } from \"@/components/ui/siteplane-provider\";\nimport { overlayBackdropClassName } from \"@/components/ui/overlay-shared\";\nimport { shortcutClassName } from \"@/components/ui/typography\";\nimport {\n  Autocomplete,\n  AutocompleteCollection,\n  AutocompleteEmpty,\n  AutocompleteGroup,\n  AutocompleteGroupLabel,\n  AutocompleteInput,\n  AutocompleteItem,\n  AutocompleteList,\n  AutocompleteSeparator,\n} from \"@/components/ui/autocomplete\";\n\nexport const CommandDialog: typeof CommandDialogPrimitive.Root =\n  CommandDialogPrimitive.Root;\n\nexport const CommandDialogPortal: typeof CommandDialogPrimitive.Portal =\n  CommandDialogPrimitive.Portal;\n\nexport const CommandCreateHandle: typeof CommandDialogPrimitive.createHandle =\n  CommandDialogPrimitive.createHandle;\n\nexport function CommandDialogTrigger(\n  props: CommandDialogPrimitive.Trigger.Props,\n): React.ReactElement {\n  return (\n    <CommandDialogPrimitive.Trigger\n      data-slot=\"command-dialog-trigger\"\n      {...props}\n    />\n  );\n}\n\nexport function CommandDialogBackdrop({\n  className,\n  ...props\n}: CommandDialogPrimitive.Backdrop.Props): React.ReactElement {\n  return (\n    <CommandDialogPrimitive.Backdrop\n      className={cn(overlayBackdropClassName, className)}\n      data-slot=\"command-dialog-backdrop\"\n      {...props}\n    />\n  );\n}\n\nexport function CommandDialogViewport({\n  className,\n  ...props\n}: CommandDialogPrimitive.Viewport.Props): React.ReactElement {\n  return (\n    <CommandDialogPrimitive.Viewport\n      className={cn(\n        \"fixed inset-0 z-50 flex flex-col items-center px-4 py-[max(--spacing(4),4vh)] sm:py-[10vh]\",\n        className,\n      )}\n      data-slot=\"command-dialog-viewport\"\n      {...props}\n    />\n  );\n}\n\nexport function CommandDialogPopup({\n  className,\n  children,\n  portalProps,\n  ...props\n}: CommandDialogPrimitive.Popup.Props & {\n  portalProps?: CommandDialogPrimitive.Portal.Props;\n}): React.ReactElement {\n  return (\n    <CommandDialogPortal {...portalProps}>\n      <SiteplaneUIPortalScope>\n        <CommandDialogBackdrop />\n        <CommandDialogViewport>\n          <CommandDialogPrimitive.Popup\n            className={cn(\n              \"relative row-start-2 flex max-h-105 min-h-0 w-full min-w-0 max-w-xl -translate-y-[calc(1.25rem*var(--nested-dialogs))] scale-[calc(1-0.1*var(--nested-dialogs))] flex-col rounded-2xl border bg-popover not-dark:bg-clip-padding text-popover-foreground opacity-[calc(1-0.1*var(--nested-dialogs))] shadow-lg/5 outline-none siteplane-dialog-motion will-change-transform before:pointer-events-none before:absolute before:inset-0 before:rounded-[inherit] before:bg-muted/72 before:shadow-[0_1px_--theme(--color-black/4%)] data-nested:data-ending-style:translate-y-8 data-nested:data-starting-style:translate-y-8 data-nested-dialog-open:origin-top data-ending-style:scale-98 data-starting-style:scale-98 data-ending-style:opacity-0 data-starting-style:opacity-0 **:data-[slot=scroll-area-viewport]:data-has-overflow-y:pe-1 dark:before:shadow-[0_-1px_--theme(--color-white/6%)]\",\n              className,\n            )}\n            data-slot=\"command-dialog-popup\"\n            {...props}\n          >\n            {children}\n          </CommandDialogPrimitive.Popup>\n        </CommandDialogViewport>\n      </SiteplaneUIPortalScope>\n    </CommandDialogPortal>\n  );\n}\n\nexport function Command({\n  autoHighlight = \"always\",\n  keepHighlight = true,\n  ...props\n}: React.ComponentProps<typeof Autocomplete>): React.ReactElement {\n  return (\n    <Autocomplete\n      autoHighlight={autoHighlight}\n      inline\n      keepHighlight={keepHighlight}\n      open\n      {...props}\n    />\n  );\n}\n\nexport function CommandInput({\n  className,\n  placeholder = undefined,\n  ...props\n}: React.ComponentProps<typeof AutocompleteInput>): React.ReactElement {\n  return (\n    <div className=\"px-2.5 py-1.5\">\n      <AutocompleteInput\n        autoFocus\n        className={cn(\n          \"border-transparent! bg-transparent! shadow-none before:hidden has-focus-visible:ring-0\",\n          className,\n        )}\n        placeholder={placeholder}\n        size=\"lg\"\n        startAddon={<SearchIcon />}\n        {...props}\n      />\n    </div>\n  );\n}\n\nexport function CommandList({\n  className,\n  ...props\n}: React.ComponentProps<typeof AutocompleteList>): React.ReactElement {\n  return (\n    <AutocompleteList\n      className={cn(\"not-empty:scroll-py-2 not-empty:p-2\", className)}\n      data-slot=\"command-list\"\n      {...props}\n    />\n  );\n}\n\nexport function CommandEmpty({\n  className,\n  ...props\n}: React.ComponentProps<typeof AutocompleteEmpty>): React.ReactElement {\n  return (\n    <AutocompleteEmpty\n      className={cn(\"not-empty:py-6\", className)}\n      data-slot=\"command-empty\"\n      {...props}\n    />\n  );\n}\n\nexport function CommandPanel({\n  className,\n  ...props\n}: React.ComponentProps<\"div\">): React.ReactElement {\n  return (\n    <div\n      className={cn(\n        \"relative -mx-px not-has-[+[data-slot=command-footer]]:-mb-px min-h-0 not-has-[+[data-slot=command-footer]]:rounded-b-2xl border border-b-0 bg-popover bg-clip-padding shadow-xs/5 [clip-path:inset(0_1px)] not-has-[+[data-slot=command-footer]]:[clip-path:inset(0_1px_1px_1px_round_0_0_calc(var(--radius-2xl)-1px)_calc(var(--radius-2xl)-1px))] before:pointer-events-none before:absolute before:inset-0 **:data-[slot=scroll-area-scrollbar]:mt-2\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\nexport function CommandGroup({\n  className,\n  ...props\n}: React.ComponentProps<typeof AutocompleteGroup>): React.ReactElement {\n  return (\n    <AutocompleteGroup\n      className={className}\n      data-slot=\"command-group\"\n      {...props}\n    />\n  );\n}\n\nexport function CommandGroupLabel({\n  className,\n  ...props\n}: React.ComponentProps<typeof AutocompleteGroupLabel>): React.ReactElement {\n  return (\n    <AutocompleteGroupLabel\n      className={className}\n      data-slot=\"command-group-label\"\n      {...props}\n    />\n  );\n}\n\nexport function CommandCollection({\n  ...props\n}: React.ComponentProps<typeof AutocompleteCollection>): React.ReactElement {\n  return <AutocompleteCollection data-slot=\"command-collection\" {...props} />;\n}\n\nexport function CommandItem({\n  className,\n  ...props\n}: React.ComponentProps<typeof AutocompleteItem>): React.ReactElement {\n  return (\n    <AutocompleteItem\n      className={cn(\"py-1.5\", className)}\n      data-slot=\"command-item\"\n      {...props}\n    />\n  );\n}\n\nexport function CommandSeparator({\n  className,\n  ...props\n}: React.ComponentProps<typeof AutocompleteSeparator>): React.ReactElement {\n  return (\n    <AutocompleteSeparator\n      className={cn(\"my-2\", className)}\n      data-slot=\"command-separator\"\n      {...props}\n    />\n  );\n}\n\nexport function CommandShortcut({\n  className,\n  ...props\n}: React.ComponentProps<\"kbd\">): React.ReactElement {\n  return (\n    <kbd\n      className={cn(shortcutClassName, className)}\n      data-slot=\"command-shortcut\"\n      {...props}\n    />\n  );\n}\n\nexport function CommandFooter({\n  className,\n  ...props\n}: React.ComponentProps<\"div\">): React.ReactElement {\n  return (\n    <div\n      className={cn(\n        \"flex items-center justify-between gap-2 rounded-b-[calc(var(--radius-2xl)-1px)] border-t px-5 py-3 text-muted-foreground text-xs\",\n        className,\n      )}\n      data-slot=\"command-footer\"\n      {...props}\n    />\n  );\n}\n\nexport { CommandDialogPrimitive };\n"
    },
    {
      "path": "src/components/ui/overlay-shared.ts",
      "type": "registry:ui",
      "content": "// Geteilte Shell-Klassen der zentrierten Overlays. Dialog, AlertDialog und\n// Command (CommandDialog) re-implementierten zuvor identische Backdrop-/Viewport-/\n// Popup-Strings. Jetzt liegt jede Klasse genau einmal hier, sodass eine Aenderung\n// alle Overlays gleichzeitig erreicht. Literale Strings -> Tailwind-Scan-sicher.\n\nimport { cn } from \"@/lib/utils\";\nimport { surfaceClassNames } from \"@/components/ui/surface\";\n\nexport const overlayBackdropClassName =\n  \"fixed inset-0 z-50 bg-black/32 backdrop-blur-sm transition-all duration-(--motion-duration-overlay) ease-(--motion-ease-apple-out) data-ending-style:opacity-0 data-starting-style:opacity-0\";\n\nexport const overlayViewportClassName =\n  \"fixed inset-0 z-50 grid grid-rows-[1fr_auto_3fr] justify-items-center p-4\";\n\nexport const overlayViewportMobileStickClassName =\n  \"max-sm:grid-rows-[1fr_auto] max-sm:p-0 max-sm:pt-12\";\n\n// Gemeinsame Popup-Chrome von Dialog + AlertDialog. Dialog ergaenzt `outline-none`\n// (es traegt den schliessbaren Close-Button), AlertDialog nicht.\nexport const overlayDialogPopupClassName = cn(\n  surfaceClassNames.overlay,\n  \"row-start-2 flex max-h-full min-h-0 w-full min-w-0 max-w-lg origin-center flex-col rounded-2xl opacity-[calc(1-var(--nested-dialogs))] siteplane-dialog-motion will-change-transform before:rounded-[inherit] data-ending-style:opacity-0 data-starting-style:opacity-0 sm:scale-[calc(1-0.1*var(--nested-dialogs))] sm:data-ending-style:scale-98 sm:data-starting-style:scale-98\",\n);\n\nexport const overlayDialogPopupMobileStickClassName =\n  \"max-sm:max-w-none max-sm:origin-bottom max-sm:rounded-none max-sm:border-x-0 max-sm:border-t max-sm:border-b-0 max-sm:data-ending-style:translate-y-4 max-sm:data-starting-style:translate-y-4 max-sm:before:hidden max-sm:before:rounded-none\";\n"
    },
    {
      "path": "src/components/ui/typography.ts",
      "type": "registry:ui",
      "content": "export const codeInlineClassName =\n  \"rounded-(--code-inline-radius) border border-border bg-muted px-1.5 py-0.5 font-mono [font-size:var(--code-inline-font-size)] text-foreground\";\n\nexport const codeBlockBaseClassName =\n  \"relative w-full overflow-x-auto rounded-lg border border-border bg-muted/50 font-mono text-foreground leading-relaxed\";\n\nexport const codeBlockSizeClassNames = {\n  default: \"px-3.5 py-3 text-xs\",\n  sm: \"px-3 py-2 [font-size:var(--code-block-sm-font-size)]\",\n} as const;\n\nexport const kbdClassName =\n  \"pointer-events-none inline-flex h-5 min-w-5 shrink-0 select-none items-center justify-center gap-1 whitespace-nowrap rounded-(--kbd-radius) bg-muted px-1 font-medium font-sans text-muted-foreground text-xs [&_svg:not([class*='size-'])]:size-3\";\n\nexport const shortcutClassName =\n  \"ms-auto font-medium font-sans text-muted-foreground/72 text-xs tracking-normal\";\n"
    }
  ],
  "categories": [
    "overlays"
  ],
  "docs": "# Command\n\n> Siteplane UI release `0.1.1`.\n\n## Public Purpose\n\nCommand combines a dialog and autocomplete list for keyboard-driven navigation,\nsearch, and actions. It may also render as a standalone embedded command list.\n\n## Import\n\n`import { Command, CommandCollection, CommandCreateHandle, CommandDialog, CommandDialogPopup, CommandDialogTrigger, CommandEmpty, CommandFooter, CommandGroup, CommandGroupLabel, CommandInput, CommandItem, CommandList, CommandPanel, CommandSeparator, CommandShortcut } from \"@/components/ui/command\";`\n\n## Public API\n\n- `CommandDialog` provides modal focus management; use the standalone\n  `Command` composition only when the list belongs in the page.\n- `CommandCreateHandle` opens or closes the dialog from detached triggers or\n  imperative application flows.\n- `autoHighlight` accepts `false`, `true`, or `\"always\"` and defaults to\n  `\"always\"`, so the first result is ready for Enter.\n- Use `CommandGroup`, `CommandSeparator`, and `CommandShortcut` to make\n  results scannable.\n- `CommandEmpty` reports no matches; `CommandFooter` may explain keyboard\n  controls.\n\n## Public Motion\n\n- Modal Command uses native Dialog backdrop and popup motion.\n- Filtering and highlighting come from Autocomplete; do not wrap either layer in\n  a second transition.\n- Active items use a pointer cursor while CommandInput keeps a text cursor.\n\n## Public Accessibility\n\n- CommandInput receives focus and must have a visible or accessible name.\n- Keep keyboard navigation, Enter selection, Escape dismissal, outside click,\n  focus trapping, and focus restoration native.\n- Every CommandItem needs a clear label. Shortcuts are supporting context, not\n  the only action name.\n- Dialog triggers need visible text or an accessible label.\n\n## Public Agent Guidance\n\n- Use Command for search-driven navigation and actions, not as a generic menu or\n  select.\n- Choose modal or standalone composition deliberately.\n- Preserve native Dialog and Autocomplete focus, filtering, cursor, and motion\n  behavior.\n\n## Public Links\n\n- [Documentation and preview](https://ui.siteplane.io/docs/components/overlays/command)\n\n- [Registry source](https://ui.siteplane.io/r/command.json)\n",
  "meta": {
    "siteplane:agentContractVersion": 1,
    "siteplane:docs": "https://ui.siteplane.io/docs/components/overlays/command",
    "siteplane:releaseVersion": "0.1.1",
    "siteplane:sourceOwned": true
  },
  "devDependencies": []
}
