{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "search-input",
  "title": "Search input",
  "description": "A customizable search input component with composable left and right elements.",
  "dependencies": [
    "@mdi/js"
  ],
  "registryDependencies": [
    "https://blok.sitecore.com/r/theme.json",
    "https://blok.sitecore.com/r/input.json",
    "https://blok.sitecore.com/r/button.json",
    "https://blok.sitecore.com/r/tooltip.json"
  ],
  "files": [
    {
      "path": "src/components/ui/search-input.tsx",
      "content": "\"use client\";\n\nimport { mdiClose } from \"@mdi/js\";\nimport * as React from \"react\";\n\nimport { Button } from \"@/components/ui/button\";\nimport { Input } from \"@/components/ui/input\";\nimport {\n  Tooltip,\n  TooltipContent,\n  TooltipTrigger,\n} from \"@/components/ui/tooltip\";\nimport { Icon } from \"@/lib/icon\";\nimport { cn } from \"@/lib/utils\";\n\n// SearchInput wrapper (similar to InputGroup)\nfunction SearchInput({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"search-input\"\n      role=\"group\"\n      className={cn(\n        \"relative flex w-full items-center rounded-md border border-input transition-[color,box-shadow] outline-none\",\n        \"h-10 min-w-0\",\n        \"bg-white dark:bg-input/30\",\n        // Focus state (border-2 primary, no ring)\n        \"has-[[data-slot=search-input-control]:focus-visible]:border-2 has-[[data-slot=search-input-control]:focus-visible]:border-primary\",\n        // Error state\n        \"has-[[data-slot=search-input-control][aria-invalid=true]]:ring-destructive/20 has-[[data-slot=search-input-control][aria-invalid=true]]:border-destructive dark:has-[[data-slot=search-input-control][aria-invalid=true]]:ring-destructive/40\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\n// SearchInputLeftElement (for icons, similar to InputLeftElement)\nfunction SearchInputLeftElement({\n  className,\n  children,\n  ...props\n}: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"search-input-left-element\"\n      className={cn(\n        \"text-muted-foreground flex h-auto cursor-text items-center justify-center pl-3 pointer-events-none\",\n        \"[&>svg:not([class*='size-'])]:size-5\",\n        className,\n      )}\n      {...props}\n    >\n      {children}\n    </div>\n  );\n}\n\n// SearchInputRightElement (for clear button, similar to InputRightElement)\nfunction SearchInputRightElement({\n  className,\n  children,\n  ...props\n}: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"search-input-right-element\"\n      className={cn(\"flex h-auto items-center justify-center pr-1\", className)}\n      {...props}\n    >\n      {children}\n    </div>\n  );\n}\n\n// SearchInputField (the actual input field, identical to Input but without ring)\nconst SearchInputField = React.forwardRef<\n  HTMLInputElement,\n  React.ComponentProps<\"input\">\n>(({ className, type = \"text\", ...props }, ref) => {\n  return (\n    <Input\n      ref={ref}\n      type={type}\n      data-slot=\"search-input-control\"\n      className={cn(\n        \"flex-1 rounded-none border-0 bg-transparent shadow-none dark:bg-transparent\",\n        \"focus-visible:ring-0 focus:ring-0 focus:border-0 focus-visible:border-0\",\n        \"pl-2 pr-2\",\n        className,\n      )}\n      {...props}\n    />\n  );\n});\nSearchInputField.displayName = \"SearchInputField\";\n\n// Helper component for clear button with tooltip\ninterface SearchInputClearButtonProps\n  extends Omit<React.ComponentProps<typeof Button>, \"children\"> {\n  onClear?: () => void;\n  tooltipLabel?: string;\n}\n\nfunction SearchInputClearButton({\n  onClear,\n  tooltipLabel = \"Clear search\",\n  className,\n  ...props\n}: SearchInputClearButtonProps) {\n  return (\n    <Tooltip>\n      <TooltipTrigger asChild>\n        <Button\n          type=\"button\"\n          variant=\"ghost\"\n          size=\"icon-xs\"\n          colorScheme=\"neutral\"\n          aria-label={tooltipLabel}\n          onClick={onClear}\n          className={cn(\n            \"text-subtle-text hover:text-body-text hover:bg-neutral-bg-active focus:outline-none\",\n            className,\n          )}\n          {...props}\n        >\n          <Icon path={mdiClose} size={0.75} />\n        </Button>\n      </TooltipTrigger>\n      <TooltipContent>{tooltipLabel}</TooltipContent>\n    </Tooltip>\n  );\n}\n\nexport {\n  SearchInput,\n  SearchInputLeftElement,\n  SearchInputRightElement,\n  SearchInputField,\n  SearchInputClearButton,\n};\n",
      "type": "registry:ui"
    },
    {
      "path": "src/lib/icon.tsx",
      "content": "import type { SVGProps } from \"react\";\n\ntype IconProps = SVGProps<SVGSVGElement> & {\n  path: string;\n  title?: string;\n  size?: number | string;\n  className?: string;\n  fill?: string;\n};\n\nexport function Icon({\n  path,\n  title,\n  size = 1,\n  className,\n  fill = \"currentColor\",\n  ...rest\n}: IconProps) {\n  return (\n    <svg\n      transform={`scale(${size})`}\n      viewBox=\"0 0 24 24\"\n      aria-label={title}\n      className={className}\n      {...rest}\n    >\n      {title ? <title>{title}</title> : null}\n      <path d={path} fill={fill} />\n    </svg>\n  );\n}\n",
      "type": "registry:lib"
    }
  ],
  "type": "registry:ui"
}