{"name":"shadcd","homepage":"https://pb-ui-five.vercel.app","items":[{"name":"alert-dialog","title":"Alert Dialog","description":"Modal dialog with actions for critical decisions.","type":"registry:ui","docs":"/components/alert-dialog","categories":["overlay","feedback"],"registryDependencies":["https://pb-ui-five.vercel.app/registry/button"],"files":[{"path":"components/ui/alert-dialog.tsx","target":"components/ui/alert-dialog.tsx","type":"registry:ui","content":"\"use client\"\n\nimport * as React from \"react\"\nimport { AlertDialog as AlertDialogPrimitive } from \"@base-ui/react/alert-dialog\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Button } from \"@/components/ui/button\"\n\nfunction AlertDialog({ ...props }: AlertDialogPrimitive.Root.Props) {\n  return <AlertDialogPrimitive.Root data-slot=\"alert-dialog\" {...props} />\n}\n\nfunction AlertDialogTrigger({ ...props }: AlertDialogPrimitive.Trigger.Props) {\n  return (\n    <AlertDialogPrimitive.Trigger data-slot=\"alert-dialog-trigger\" {...props} />\n  )\n}\n\nfunction AlertDialogPortal({ ...props }: AlertDialogPrimitive.Portal.Props) {\n  return (\n    <AlertDialogPrimitive.Portal data-slot=\"alert-dialog-portal\" {...props} />\n  )\n}\n\nfunction AlertDialogOverlay({\n  className,\n  ...props\n}: AlertDialogPrimitive.Backdrop.Props) {\n  return (\n    <AlertDialogPrimitive.Backdrop\n      data-slot=\"alert-dialog-overlay\"\n      className={cn(\n        \"fixed inset-0 isolate z-50 bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction AlertDialogContent({\n  className,\n  size = \"default\",\n  ...props\n}: AlertDialogPrimitive.Popup.Props & {\n  size?: \"default\" | \"sm\"\n}) {\n  return (\n    <AlertDialogPortal>\n      <AlertDialogOverlay />\n      <AlertDialogPrimitive.Popup\n        data-slot=\"alert-dialog-content\"\n        data-size={size}\n        className={cn(\n          \"group/alert-dialog-content fixed top-1/2 left-1/2 z-50 grid w-full -translate-x-1/2 -translate-y-1/2 gap-6 rounded-xl bg-background p-6 ring-1 ring-foreground/10 duration-100 outline-none data-[size=default]:max-w-xs data-[size=sm]:max-w-xs data-[size=default]:sm:max-w-lg data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95\",\n          className\n        )}\n        {...props}\n      />\n    </AlertDialogPortal>\n  )\n}\n\nfunction AlertDialogHeader({\n  className,\n  ...props\n}: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"alert-dialog-header\"\n      className={cn(\n        \"grid grid-rows-[auto_1fr] place-items-center gap-1.5 text-center has-data-[slot=alert-dialog-media]:grid-rows-[auto_auto_1fr] has-data-[slot=alert-dialog-media]:gap-x-6 sm:group-data-[size=default]/alert-dialog-content:place-items-start sm:group-data-[size=default]/alert-dialog-content:text-left sm:group-data-[size=default]/alert-dialog-content:has-data-[slot=alert-dialog-media]:grid-rows-[auto_1fr]\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction AlertDialogFooter({\n  className,\n  ...props\n}: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"alert-dialog-footer\"\n      className={cn(\n        \"flex flex-col-reverse gap-2 group-data-[size=sm]/alert-dialog-content:grid group-data-[size=sm]/alert-dialog-content:grid-cols-2 sm:flex-row sm:justify-end\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction AlertDialogMedia({\n  className,\n  ...props\n}: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"alert-dialog-media\"\n      className={cn(\n        \"mb-2 inline-flex size-16 items-center justify-center rounded-md bg-muted sm:group-data-[size=default]/alert-dialog-content:row-span-2 *:[svg:not([class*='size-'])]:size-8\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction AlertDialogTitle({\n  className,\n  ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Title>) {\n  return (\n    <AlertDialogPrimitive.Title\n      data-slot=\"alert-dialog-title\"\n      className={cn(\n        \"text-lg font-medium sm:group-data-[size=default]/alert-dialog-content:group-has-data-[slot=alert-dialog-media]/alert-dialog-content:col-start-2\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction AlertDialogDescription({\n  className,\n  ...props\n}: React.ComponentProps<typeof AlertDialogPrimitive.Description>) {\n  return (\n    <AlertDialogPrimitive.Description\n      data-slot=\"alert-dialog-description\"\n      className={cn(\n        \"text-sm text-balance text-muted-foreground md:text-pretty *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction AlertDialogAction({\n  className,\n  ...props\n}: React.ComponentProps<typeof Button>) {\n  return (\n    <Button\n      data-slot=\"alert-dialog-action\"\n      className={cn(className)}\n      {...props}\n    />\n  )\n}\n\nfunction AlertDialogCancel({\n  className,\n  variant = \"outline\",\n  size = \"default\",\n  ...props\n}: AlertDialogPrimitive.Close.Props &\n  Pick<React.ComponentProps<typeof Button>, \"variant\" | \"size\">) {\n  return (\n    <AlertDialogPrimitive.Close\n      data-slot=\"alert-dialog-cancel\"\n      className={cn(className)}\n      render={<Button variant={variant} size={size} />}\n      {...props}\n    />\n  )\n}\n\nexport {\n  AlertDialog,\n  AlertDialogAction,\n  AlertDialogCancel,\n  AlertDialogContent,\n  AlertDialogDescription,\n  AlertDialogFooter,\n  AlertDialogHeader,\n  AlertDialogMedia,\n  AlertDialogOverlay,\n  AlertDialogPortal,\n  AlertDialogTitle,\n  AlertDialogTrigger,\n}\n"}]},{"name":"badge","title":"Badge","description":"Small status or label indicator.","type":"registry:ui","docs":"/components/badge","categories":["data-display"],"files":[{"path":"components/ui/badge.tsx","target":"components/ui/badge.tsx","type":"registry:ui","content":"import { mergeProps } from \"@base-ui/react/merge-props\"\nimport { useRender } from \"@base-ui/react/use-render\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst badgeVariants = cva(\n  \"group/badge inline-flex h-5 w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-4xl border border-transparent px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-all focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-3!\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-primary text-primary-foreground [a]:hover:bg-primary/80\",\n        secondary:\n          \"bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80\",\n        destructive:\n          \"bg-destructive/10 text-destructive focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:focus-visible:ring-destructive/40 [a]:hover:bg-destructive/20\",\n        outline:\n          \"border-border text-foreground [a]:hover:bg-muted [a]:hover:text-muted-foreground\",\n        ghost:\n          \"hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n    },\n  }\n)\n\nfunction Badge({\n  className,\n  variant = \"default\",\n  render,\n  ...props\n}: useRender.ComponentProps<\"span\"> & VariantProps<typeof badgeVariants>) {\n  return useRender({\n    defaultTagName: \"span\",\n    props: mergeProps<\"span\">(\n      {\n        className: cn(badgeVariants({ variant }), className),\n      },\n      props\n    ),\n    render,\n    state: {\n      slot: \"badge\",\n      variant,\n    },\n  })\n}\n\nexport { Badge, badgeVariants }\n"}]},{"name":"button","title":"Button","description":"Interactive button with variants and sizes.","type":"registry:ui","docs":"/components/button","categories":["forms"],"files":[{"path":"components/ui/button.tsx","target":"components/ui/button.tsx","type":"registry:ui","content":"\"use client\"\n\nimport { Button as ButtonPrimitive } from \"@base-ui/react/button\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst buttonVariants = cva(\n  \"group/button inline-flex shrink-0 items-center justify-center rounded-md border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-primary text-primary-foreground hover:bg-primary/80\",\n        outline:\n          \"border-border bg-background shadow-xs hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50\",\n        secondary:\n          \"bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground\",\n        ghost:\n          \"hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50\",\n        destructive:\n          \"bg-destructive/10 text-destructive hover:bg-destructive/20 focus-visible:border-destructive/40 focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:hover:bg-destructive/30 dark:focus-visible:ring-destructive/40\",\n        link: \"text-primary underline-offset-4 hover:underline\",\n      },\n      size: {\n        default:\n          \"h-9 gap-1.5 px-2.5 in-data-[slot=button-group]:rounded-md has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2\",\n        xs: \"h-6 gap-1 rounded-[min(var(--radius-md),8px)] px-2 text-xs in-data-[slot=button-group]:rounded-md has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3\",\n        sm: \"h-8 gap-1 rounded-[min(var(--radius-md),10px)] px-2.5 in-data-[slot=button-group]:rounded-md has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5\",\n        lg: \"h-10 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-3 has-data-[icon=inline-start]:pl-3\",\n        icon: \"size-9\",\n        \"icon-xs\":\n          \"size-6 rounded-[min(var(--radius-md),8px)] in-data-[slot=button-group]:rounded-md [&_svg:not([class*='size-'])]:size-3\",\n        \"icon-sm\":\n          \"size-8 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-md\",\n        \"icon-lg\": \"size-10\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n      size: \"default\",\n    },\n  }\n)\n\nfunction Button({\n  className,\n  variant = \"default\",\n  size = \"default\",\n  ...props\n}: ButtonPrimitive.Props & VariantProps<typeof buttonVariants>) {\n  return (\n    <ButtonPrimitive\n      data-slot=\"button\"\n      className={cn(buttonVariants({ variant, size, className }))}\n      {...props}\n    />\n  )\n}\n\nexport { Button, buttonVariants }\n"}]},{"name":"card","title":"Card","description":"Container for grouped content and actions.","type":"registry:ui","docs":"/components/card","categories":["layout"],"files":[{"path":"components/ui/card.tsx","target":"components/ui/card.tsx","type":"registry:ui","content":"import * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nfunction Card({\n  className,\n  size = \"default\",\n  ...props\n}: React.ComponentProps<\"div\"> & { size?: \"default\" | \"sm\" }) {\n  return (\n    <div\n      data-slot=\"card\"\n      data-size={size}\n      className={cn(\n        \"group/card flex flex-col gap-6 overflow-hidden rounded-xl bg-card py-6 text-sm text-card-foreground shadow-xs ring-1 ring-foreground/10 has-[>img:first-child]:pt-0 data-[size=sm]:gap-4 data-[size=sm]:py-4 *:[img:first-child]:rounded-t-xl *:[img:last-child]:rounded-b-xl\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction CardHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"card-header\"\n      className={cn(\n        \"group/card-header @container/card-header grid auto-rows-min items-start gap-1 rounded-t-xl px-6 group-data-[size=sm]/card:px-4 has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] [.border-b]:pb-6 group-data-[size=sm]/card:[.border-b]:pb-4\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction CardTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"card-title\"\n      className={cn(\n        \"text-base leading-normal font-medium group-data-[size=sm]/card:text-sm\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction CardDescription({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"card-description\"\n      className={cn(\"text-sm text-muted-foreground\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction CardAction({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"card-action\"\n      className={cn(\n        \"col-start-2 row-span-2 row-start-1 self-start justify-self-end\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction CardContent({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"card-content\"\n      className={cn(\"px-6 group-data-[size=sm]/card:px-4\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction CardFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"card-footer\"\n      className={cn(\n        \"flex items-center rounded-b-xl px-6 group-data-[size=sm]/card:px-4 [.border-t]:pt-6 group-data-[size=sm]/card:[.border-t]:pt-4\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport {\n  Card,\n  CardHeader,\n  CardFooter,\n  CardTitle,\n  CardAction,\n  CardDescription,\n  CardContent,\n}\n"}]},{"name":"combobox","title":"Combobox","description":"Searchable select input with options list.","type":"registry:ui","docs":"/components/combobox","categories":["forms"],"registryDependencies":["https://pb-ui-five.vercel.app/registry/button","https://pb-ui-five.vercel.app/registry/input-group"],"files":[{"path":"components/ui/combobox.tsx","target":"components/ui/combobox.tsx","type":"registry:ui","content":"\"use client\";\n\nimport { Combobox as ComboboxPrimitive } from \"@base-ui/react\";\nimport * as React from \"react\";\n\nimport { Button } from \"@/components/ui/button\";\nimport {\n  InputGroup,\n  InputGroupAddon,\n  InputGroupButton,\n  InputGroupInput,\n} from \"@/components/ui/input-group\";\nimport { cn } from \"@/lib/utils\";\nimport { CheckIcon, ChevronDownIcon, XIcon } from \"lucide-react\";\n\nconst Combobox = ComboboxPrimitive.Root;\n\nfunction ComboboxValue({ ...props }: ComboboxPrimitive.Value.Props) {\n  return <ComboboxPrimitive.Value data-slot=\"combobox-value\" {...props} />;\n}\n\nfunction ComboboxTrigger({\n  className,\n  children,\n  ...props\n}: ComboboxPrimitive.Trigger.Props) {\n  return (\n    <ComboboxPrimitive.Trigger\n      data-slot=\"combobox-trigger\"\n      className={cn(\"[&_svg:not([class*='size-'])]:size-4\", className)}\n      {...props}\n    >\n      {children}\n      <ChevronDownIcon className=\"size-4 text-muted-foreground pointer-events-none\" />\n    </ComboboxPrimitive.Trigger>\n  );\n}\n\nfunction ComboboxClear({ className, ...props }: ComboboxPrimitive.Clear.Props) {\n  return (\n    <ComboboxPrimitive.Clear\n      data-slot=\"combobox-clear\"\n      render={<InputGroupButton variant=\"ghost\" size=\"icon-xs\" />}\n      className={cn(className)}\n      {...props}\n    >\n      <XIcon className=\"pointer-events-none\" />\n    </ComboboxPrimitive.Clear>\n  );\n}\n\nfunction ComboboxInput({\n  className,\n  children,\n  disabled = false,\n  showTrigger = true,\n  showClear = false,\n  ...props\n}: ComboboxPrimitive.Input.Props & {\n  showTrigger?: boolean;\n  showClear?: boolean;\n}) {\n  return (\n    <InputGroup className={cn(\"w-auto\", className)}>\n      <ComboboxPrimitive.Input\n        render={<InputGroupInput disabled={disabled} />}\n        {...props}\n      />\n      <InputGroupAddon align=\"inline-end\">\n        {showTrigger && (\n          <InputGroupButton\n            size=\"icon-xs\"\n            variant=\"ghost\"\n            render={<ComboboxTrigger />}\n            data-slot=\"input-group-button\"\n            className=\"group-has-data-[slot=combobox-clear]/input-group:hidden data-pressed:bg-transparent\"\n            disabled={disabled}\n          />\n        )}\n        {showClear && <ComboboxClear disabled={disabled} />}\n      </InputGroupAddon>\n      {children}\n    </InputGroup>\n  );\n}\n\nfunction ComboboxContent({\n  className,\n  side = \"bottom\",\n  sideOffset = 6,\n  align = \"start\",\n  alignOffset = 0,\n  anchor,\n  ...props\n}: ComboboxPrimitive.Popup.Props &\n  Pick<\n    ComboboxPrimitive.Positioner.Props,\n    \"side\" | \"align\" | \"sideOffset\" | \"alignOffset\" | \"anchor\"\n  >) {\n  return (\n    <ComboboxPrimitive.Portal>\n      <ComboboxPrimitive.Positioner\n        side={side}\n        sideOffset={sideOffset}\n        align={align}\n        alignOffset={alignOffset}\n        anchor={anchor}\n        className=\"z-50 isolate\"\n      >\n        <ComboboxPrimitive.Popup\n          data-slot=\"combobox-content\"\n          data-chips={!!anchor}\n          className={cn(\n            \"group/combobox-content relative max-h-(--available-height) w-(--anchor-width) max-w-(--available-width) min-w-[calc(var(--anchor-width)+--spacing(7))] origin-(--transform-origin) overflow-hidden rounded-md bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[chips=true]:min-w-(--anchor-width) data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 *:data-[slot=input-group]:m-1 *:data-[slot=input-group]:mb-0 *:data-[slot=input-group]:h-8 *:data-[slot=input-group]:border-input/30 *:data-[slot=input-group]:bg-input/30 *:data-[slot=input-group]:shadow-none data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95\",\n            className,\n          )}\n          {...props}\n        />\n      </ComboboxPrimitive.Positioner>\n    </ComboboxPrimitive.Portal>\n  );\n}\n\nfunction ComboboxList({ className, ...props }: ComboboxPrimitive.List.Props) {\n  return (\n    <ComboboxPrimitive.List\n      data-slot=\"combobox-list\"\n      className={cn(\n        \"p-1 data-empty:p-0 max-h-[min(calc(--spacing(72)---spacing(9)),calc(var(--available-height)---spacing(9)))] overflow-y-auto overscroll-contain scroll-py-1 no-scrollbar\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\nfunction ComboboxItem({\n  className,\n  children,\n  ...props\n}: ComboboxPrimitive.Item.Props) {\n  return (\n    <ComboboxPrimitive.Item\n      data-slot=\"combobox-item\"\n      className={cn(\n        \"relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none data-highlighted:bg-accent data-highlighted:text-accent-foreground not-data-[variant=destructive]:data-highlighted:**:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className,\n      )}\n      {...props}\n    >\n      {children}\n      <ComboboxPrimitive.ItemIndicator\n        render={\n          <span className=\"right-2 absolute flex justify-center items-center size-4 pointer-events-none\" />\n        }\n      >\n        <CheckIcon className=\"pointer-events-none\" />\n      </ComboboxPrimitive.ItemIndicator>\n    </ComboboxPrimitive.Item>\n  );\n}\n\nfunction ComboboxGroup({ className, ...props }: ComboboxPrimitive.Group.Props) {\n  return (\n    <ComboboxPrimitive.Group\n      data-slot=\"combobox-group\"\n      className={cn(className)}\n      {...props}\n    />\n  );\n}\n\nfunction ComboboxLabel({\n  className,\n  ...props\n}: ComboboxPrimitive.GroupLabel.Props) {\n  return (\n    <ComboboxPrimitive.GroupLabel\n      data-slot=\"combobox-label\"\n      className={cn(\"px-2 py-1.5 text-muted-foreground text-xs\", className)}\n      {...props}\n    />\n  );\n}\n\nfunction ComboboxCollection({ ...props }: ComboboxPrimitive.Collection.Props) {\n  return (\n    <ComboboxPrimitive.Collection data-slot=\"combobox-collection\" {...props} />\n  );\n}\n\nfunction ComboboxEmpty({ className, ...props }: ComboboxPrimitive.Empty.Props) {\n  return (\n    <ComboboxPrimitive.Empty\n      data-slot=\"combobox-empty\"\n      className={cn(\n        \"hidden group-data-empty/combobox-content:flex justify-center py-2 w-full text-muted-foreground text-sm text-center\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\nfunction ComboboxSeparator({\n  className,\n  ...props\n}: ComboboxPrimitive.Separator.Props) {\n  return (\n    <ComboboxPrimitive.Separator\n      data-slot=\"combobox-separator\"\n      className={cn(\"-mx-1 my-1 bg-border h-px\", className)}\n      {...props}\n    />\n  );\n}\n\nfunction ComboboxChips({\n  className,\n  ...props\n}: React.ComponentPropsWithRef<typeof ComboboxPrimitive.Chips> &\n  ComboboxPrimitive.Chips.Props) {\n  return (\n    <ComboboxPrimitive.Chips\n      data-slot=\"combobox-chips\"\n      className={cn(\n        \"flex flex-wrap items-center gap-1.5 bg-transparent dark:bg-input/30 bg-clip-padding shadow-xs px-2.5 has-data-[slot=combobox-chip]:px-1.5 py-1.5 border border-input has-aria-invalid:border-destructive focus-within:border-ring dark:has-aria-invalid:border-destructive/50 rounded-md has-aria-invalid:ring-3 has-aria-invalid:ring-destructive/20 focus-within:ring-3 focus-within:ring-ring/50 dark:has-aria-invalid:ring-destructive/40 min-h-9 text-sm transition-[color,box-shadow]\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\nfunction ComboboxChip({\n  className,\n  children,\n  showRemove = true,\n  ...props\n}: ComboboxPrimitive.Chip.Props & {\n  showRemove?: boolean;\n}) {\n  return (\n    <ComboboxPrimitive.Chip\n      data-slot=\"combobox-chip\"\n      className={cn(\n        \"flex justify-center items-center gap-1 bg-muted has-disabled:opacity-50 px-1.5 has-data-[slot=combobox-chip-remove]:pr-0 rounded-sm w-fit h-[calc(--spacing(5.5))] font-medium text-foreground text-xs whitespace-nowrap has-disabled:cursor-not-allowed has-disabled:pointer-events-none\",\n        className,\n      )}\n      {...props}\n    >\n      {children}\n      {showRemove && (\n        <ComboboxPrimitive.ChipRemove\n          render={<Button variant=\"ghost\" size=\"icon-xs\" />}\n          className=\"opacity-50 hover:opacity-100 -ml-1\"\n          data-slot=\"combobox-chip-remove\"\n        >\n          <XIcon className=\"pointer-events-none\" />\n        </ComboboxPrimitive.ChipRemove>\n      )}\n    </ComboboxPrimitive.Chip>\n  );\n}\n\nfunction ComboboxChipsInput({\n  className,\n  ...props\n}: ComboboxPrimitive.Input.Props) {\n  return (\n    <ComboboxPrimitive.Input\n      data-slot=\"combobox-chip-input\"\n      className={cn(\"flex-1 outline-none min-w-16\", className)}\n      {...props}\n    />\n  );\n}\n\nfunction useComboboxAnchor() {\n  return React.useRef<HTMLDivElement | null>(null);\n}\n\nexport {\n  Combobox,\n  ComboboxChip,\n  ComboboxChips,\n  ComboboxChipsInput,\n  ComboboxClear,\n  ComboboxCollection,\n  ComboboxContent,\n  ComboboxEmpty,\n  ComboboxGroup,\n  ComboboxInput,\n  ComboboxItem,\n  ComboboxLabel,\n  ComboboxList,\n  ComboboxSeparator,\n  ComboboxTrigger,\n  ComboboxValue,\n  useComboboxAnchor,\n};\n"}]},{"name":"dropdown-menu","title":"Dropdown Menu","description":"Contextual menu with groups and shortcuts.","type":"registry:ui","docs":"/components/dropdown-menu","categories":["overlay"],"files":[{"path":"components/ui/dropdown-menu.tsx","target":"components/ui/dropdown-menu.tsx","type":"registry:ui","content":"\"use client\"\n\nimport * as React from \"react\"\nimport { Menu as MenuPrimitive } from \"@base-ui/react/menu\"\n\nimport { cn } from \"@/lib/utils\"\nimport { ChevronRightIcon, CheckIcon } from \"lucide-react\"\n\nfunction DropdownMenu({ ...props }: MenuPrimitive.Root.Props) {\n  return <MenuPrimitive.Root data-slot=\"dropdown-menu\" {...props} />\n}\n\nfunction DropdownMenuPortal({ ...props }: MenuPrimitive.Portal.Props) {\n  return <MenuPrimitive.Portal data-slot=\"dropdown-menu-portal\" {...props} />\n}\n\nfunction DropdownMenuTrigger({ ...props }: MenuPrimitive.Trigger.Props) {\n  return <MenuPrimitive.Trigger data-slot=\"dropdown-menu-trigger\" {...props} />\n}\n\nfunction DropdownMenuContent({\n  align = \"start\",\n  alignOffset = 0,\n  side = \"bottom\",\n  sideOffset = 4,\n  className,\n  ...props\n}: MenuPrimitive.Popup.Props &\n  Pick<\n    MenuPrimitive.Positioner.Props,\n    \"align\" | \"alignOffset\" | \"side\" | \"sideOffset\"\n  >) {\n  return (\n    <MenuPrimitive.Portal>\n      <MenuPrimitive.Positioner\n        className=\"isolate z-50 outline-none\"\n        align={align}\n        alignOffset={alignOffset}\n        side={side}\n        sideOffset={sideOffset}\n      >\n        <MenuPrimitive.Popup\n          data-slot=\"dropdown-menu-content\"\n          className={cn(\"z-50 max-h-(--available-height) w-(--anchor-width) min-w-32 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-md bg-popover p-1 text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 outline-none data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:overflow-hidden data-closed:fade-out-0 data-closed:zoom-out-95\", className )}\n          {...props}\n        />\n      </MenuPrimitive.Positioner>\n    </MenuPrimitive.Portal>\n  )\n}\n\nfunction DropdownMenuGroup({ ...props }: MenuPrimitive.Group.Props) {\n  return <MenuPrimitive.Group data-slot=\"dropdown-menu-group\" {...props} />\n}\n\nfunction DropdownMenuLabel({\n  className,\n  inset,\n  ...props\n}: MenuPrimitive.GroupLabel.Props & {\n  inset?: boolean\n}) {\n  return (\n    <MenuPrimitive.GroupLabel\n      data-slot=\"dropdown-menu-label\"\n      data-inset={inset}\n      className={cn(\n        \"px-2 py-1.5 text-xs font-medium text-muted-foreground data-inset:pl-8\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuItem({\n  className,\n  inset,\n  variant = \"default\",\n  ...props\n}: MenuPrimitive.Item.Props & {\n  inset?: boolean\n  variant?: \"default\" | \"destructive\"\n}) {\n  return (\n    <MenuPrimitive.Item\n      data-slot=\"dropdown-menu-item\"\n      data-inset={inset}\n      data-variant={variant}\n      className={cn(\n        \"group/dropdown-menu-item relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-8 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 data-[variant=destructive]:*:[svg]:text-destructive\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuSub({ ...props }: MenuPrimitive.SubmenuRoot.Props) {\n  return <MenuPrimitive.SubmenuRoot data-slot=\"dropdown-menu-sub\" {...props} />\n}\n\nfunction DropdownMenuSubTrigger({\n  className,\n  inset,\n  children,\n  ...props\n}: MenuPrimitive.SubmenuTrigger.Props & {\n  inset?: boolean\n}) {\n  return (\n    <MenuPrimitive.SubmenuTrigger\n      data-slot=\"dropdown-menu-sub-trigger\"\n      data-inset={inset}\n      className={cn(\n        \"flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-8 data-popup-open:bg-accent data-popup-open:text-accent-foreground data-open:bg-accent data-open:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      {...props}\n    >\n      {children}\n      <ChevronRightIcon className=\"ml-auto\" />\n    </MenuPrimitive.SubmenuTrigger>\n  )\n}\n\nfunction DropdownMenuSubContent({\n  align = \"start\",\n  alignOffset = -3,\n  side = \"right\",\n  sideOffset = 0,\n  className,\n  ...props\n}: React.ComponentProps<typeof DropdownMenuContent>) {\n  return (\n    <DropdownMenuContent\n      data-slot=\"dropdown-menu-sub-content\"\n      className={cn(\n        \"w-auto min-w-[96px] rounded-md bg-popover p-1 text-popover-foreground shadow-lg ring-1 ring-foreground/10 duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95\",\n        className\n      )}\n      align={align}\n      alignOffset={alignOffset}\n      side={side}\n      sideOffset={sideOffset}\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuCheckboxItem({\n  className,\n  children,\n  checked,\n  inset,\n  ...props\n}: MenuPrimitive.CheckboxItem.Props & {\n  inset?: boolean\n}) {\n  return (\n    <MenuPrimitive.CheckboxItem\n      data-slot=\"dropdown-menu-checkbox-item\"\n      data-inset={inset}\n      className={cn(\n        \"relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-8 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      checked={checked}\n      {...props}\n    >\n      <span\n        className=\"pointer-events-none absolute right-2 flex items-center justify-center\"\n        data-slot=\"dropdown-menu-checkbox-item-indicator\"\n      >\n        <MenuPrimitive.CheckboxItemIndicator>\n          <CheckIcon\n          />\n        </MenuPrimitive.CheckboxItemIndicator>\n      </span>\n      {children}\n    </MenuPrimitive.CheckboxItem>\n  )\n}\n\nfunction DropdownMenuRadioGroup({ ...props }: MenuPrimitive.RadioGroup.Props) {\n  return (\n    <MenuPrimitive.RadioGroup\n      data-slot=\"dropdown-menu-radio-group\"\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuRadioItem({\n  className,\n  children,\n  inset,\n  ...props\n}: MenuPrimitive.RadioItem.Props & {\n  inset?: boolean\n}) {\n  return (\n    <MenuPrimitive.RadioItem\n      data-slot=\"dropdown-menu-radio-item\"\n      data-inset={inset}\n      className={cn(\n        \"relative flex cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-8 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      {...props}\n    >\n      <span\n        className=\"pointer-events-none absolute right-2 flex items-center justify-center\"\n        data-slot=\"dropdown-menu-radio-item-indicator\"\n      >\n        <MenuPrimitive.RadioItemIndicator>\n          <CheckIcon\n          />\n        </MenuPrimitive.RadioItemIndicator>\n      </span>\n      {children}\n    </MenuPrimitive.RadioItem>\n  )\n}\n\nfunction DropdownMenuSeparator({\n  className,\n  ...props\n}: MenuPrimitive.Separator.Props) {\n  return (\n    <MenuPrimitive.Separator\n      data-slot=\"dropdown-menu-separator\"\n      className={cn(\"-mx-1 my-1 h-px bg-border\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction DropdownMenuShortcut({\n  className,\n  ...props\n}: React.ComponentProps<\"span\">) {\n  return (\n    <span\n      data-slot=\"dropdown-menu-shortcut\"\n      className={cn(\n        \"ml-auto text-xs tracking-widest text-muted-foreground group-focus/dropdown-menu-item:text-accent-foreground\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport {\n  DropdownMenu,\n  DropdownMenuPortal,\n  DropdownMenuTrigger,\n  DropdownMenuContent,\n  DropdownMenuGroup,\n  DropdownMenuLabel,\n  DropdownMenuItem,\n  DropdownMenuCheckboxItem,\n  DropdownMenuRadioGroup,\n  DropdownMenuRadioItem,\n  DropdownMenuSeparator,\n  DropdownMenuShortcut,\n  DropdownMenuSub,\n  DropdownMenuSubTrigger,\n  DropdownMenuSubContent,\n}\n"}]},{"name":"field","title":"Field","description":"Form field wrappers and labels.","type":"registry:ui","docs":"/components/field","categories":["forms"],"registryDependencies":["https://pb-ui-five.vercel.app/registry/label","https://pb-ui-five.vercel.app/registry/separator"],"files":[{"path":"components/ui/field.tsx","target":"components/ui/field.tsx","type":"registry:ui","content":"\"use client\"\n\nimport { useMemo } from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Label } from \"@/components/ui/label\"\nimport { Separator } from \"@/components/ui/separator\"\n\nfunction FieldSet({ className, ...props }: React.ComponentProps<\"fieldset\">) {\n  return (\n    <fieldset\n      data-slot=\"field-set\"\n      className={cn(\n        \"flex flex-col gap-6 has-[>[data-slot=checkbox-group]]:gap-3 has-[>[data-slot=radio-group]]:gap-3\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction FieldLegend({\n  className,\n  variant = \"legend\",\n  ...props\n}: React.ComponentProps<\"legend\"> & { variant?: \"legend\" | \"label\" }) {\n  return (\n    <legend\n      data-slot=\"field-legend\"\n      data-variant={variant}\n      className={cn(\n        \"mb-3 font-medium data-[variant=label]:text-sm data-[variant=legend]:text-base\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction FieldGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"field-group\"\n      className={cn(\n        \"group/field-group @container/field-group flex w-full flex-col gap-7 data-[slot=checkbox-group]:gap-3 *:data-[slot=field-group]:gap-4\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nconst fieldVariants = cva(\n  \"group/field flex w-full gap-3 data-[invalid=true]:text-destructive\",\n  {\n    variants: {\n      orientation: {\n        vertical: \"flex-col *:w-full [&>.sr-only]:w-auto\",\n        horizontal:\n          \"flex-row items-center has-[>[data-slot=field-content]]:items-start *:data-[slot=field-label]:flex-auto has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px\",\n        responsive:\n          \"flex-col *:w-full @md/field-group:flex-row @md/field-group:items-center @md/field-group:*:w-auto @md/field-group:has-[>[data-slot=field-content]]:items-start @md/field-group:*:data-[slot=field-label]:flex-auto [&>.sr-only]:w-auto @md/field-group:has-[>[data-slot=field-content]]:[&>[role=checkbox],[role=radio]]:mt-px\",\n      },\n    },\n    defaultVariants: {\n      orientation: \"vertical\",\n    },\n  }\n)\n\nfunction Field({\n  className,\n  orientation = \"vertical\",\n  ...props\n}: React.ComponentProps<\"div\"> & VariantProps<typeof fieldVariants>) {\n  return (\n    <div\n      role=\"group\"\n      data-slot=\"field\"\n      data-orientation={orientation}\n      className={cn(fieldVariants({ orientation }), className)}\n      {...props}\n    />\n  )\n}\n\nfunction FieldContent({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"field-content\"\n      className={cn(\n        \"group/field-content flex flex-1 flex-col gap-1 leading-snug\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction FieldLabel({\n  className,\n  ...props\n}: React.ComponentProps<typeof Label>) {\n  return (\n    <Label\n      data-slot=\"field-label\"\n      className={cn(\n        \"group/field-label peer/field-label flex w-fit gap-2 leading-snug group-data-[disabled=true]/field:opacity-50 has-data-checked:border-primary/30 has-data-checked:bg-primary/5 has-[>[data-slot=field]]:rounded-md has-[>[data-slot=field]]:border *:data-[slot=field]:p-3 dark:has-data-checked:border-primary/20 dark:has-data-checked:bg-primary/10\",\n        \"has-[>[data-slot=field]]:w-full has-[>[data-slot=field]]:flex-col\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction FieldTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"field-label\"\n      className={cn(\n        \"flex w-fit items-center gap-2 text-sm leading-snug font-medium group-data-[disabled=true]/field:opacity-50\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction FieldDescription({ className, ...props }: React.ComponentProps<\"p\">) {\n  return (\n    <p\n      data-slot=\"field-description\"\n      className={cn(\n        \"text-left text-sm leading-normal font-normal text-muted-foreground group-has-data-horizontal/field:text-balance [[data-variant=legend]+&]:-mt-1.5\",\n        \"last:mt-0 nth-last-2:-mt-1\",\n        \"[&>a]:underline [&>a]:underline-offset-4 [&>a:hover]:text-primary\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction FieldSeparator({\n  children,\n  className,\n  ...props\n}: React.ComponentProps<\"div\"> & {\n  children?: React.ReactNode\n}) {\n  return (\n    <div\n      data-slot=\"field-separator\"\n      data-content={!!children}\n      className={cn(\n        \"relative -my-2 h-5 text-sm group-data-[variant=outline]/field-group:-mb-2\",\n        className\n      )}\n      {...props}\n    >\n      <Separator className=\"absolute inset-0 top-1/2\" />\n      {children && (\n        <span\n          className=\"relative mx-auto block w-fit bg-background px-2 text-muted-foreground\"\n          data-slot=\"field-separator-content\"\n        >\n          {children}\n        </span>\n      )}\n    </div>\n  )\n}\n\nfunction FieldError({\n  className,\n  children,\n  errors,\n  ...props\n}: React.ComponentProps<\"div\"> & {\n  errors?: Array<{ message?: string } | undefined>\n}) {\n  const content = useMemo(() => {\n    if (children) {\n      return children\n    }\n\n    if (!errors?.length) {\n      return null\n    }\n\n    const uniqueErrors = [\n      ...new Map(errors.map((error) => [error?.message, error])).values(),\n    ]\n\n    if (uniqueErrors?.length == 1) {\n      return uniqueErrors[0]?.message\n    }\n\n    return (\n      <ul className=\"ml-4 flex list-disc flex-col gap-1\">\n        {uniqueErrors.map(\n          (error, index) =>\n            error?.message && <li key={index}>{error.message}</li>\n        )}\n      </ul>\n    )\n  }, [children, errors])\n\n  if (!content) {\n    return null\n  }\n\n  return (\n    <div\n      role=\"alert\"\n      data-slot=\"field-error\"\n      className={cn(\"text-sm font-normal text-destructive\", className)}\n      {...props}\n    >\n      {content}\n    </div>\n  )\n}\n\nexport {\n  Field,\n  FieldLabel,\n  FieldDescription,\n  FieldError,\n  FieldGroup,\n  FieldLegend,\n  FieldSeparator,\n  FieldSet,\n  FieldContent,\n  FieldTitle,\n}\n"}]},{"name":"input","title":"Input","description":"Text input with consistent styling.","type":"registry:ui","docs":"/components/input","categories":["forms"],"files":[{"path":"components/ui/input.tsx","target":"components/ui/input.tsx","type":"registry:ui","content":"import * as React from \"react\"\nimport { Input as InputPrimitive } from \"@base-ui/react/input\"\n\nimport { cn } from \"@/lib/utils\"\n\nfunction Input({ className, type, ...props }: React.ComponentProps<\"input\">) {\n  return (\n    <InputPrimitive\n      type={type}\n      data-slot=\"input\"\n      className={cn(\n        \"h-9 w-full min-w-0 rounded-md border border-input bg-transparent px-2.5 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { Input }\n"}]},{"name":"input-group","title":"Input Group","description":"Grouped input with add-ons.","type":"registry:ui","docs":"/components/input-group","categories":["forms"],"registryDependencies":["https://pb-ui-five.vercel.app/registry/button","https://pb-ui-five.vercel.app/registry/input","https://pb-ui-five.vercel.app/registry/textarea"],"files":[{"path":"components/ui/input-group.tsx","target":"components/ui/input-group.tsx","type":"registry:ui","content":"\"use client\"\n\nimport * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Button } from \"@/components/ui/button\"\nimport { Input } from \"@/components/ui/input\"\nimport { Textarea } from \"@/components/ui/textarea\"\n\nfunction InputGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"input-group\"\n      role=\"group\"\n      className={cn(\n        \"group/input-group relative flex h-9 w-full min-w-0 items-center rounded-md border border-input shadow-xs transition-[color,box-shadow] outline-none in-data-[slot=combobox-content]:focus-within:border-inherit in-data-[slot=combobox-content]:focus-within:ring-0 has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-3 has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50 has-[[data-slot][aria-invalid=true]]:border-destructive has-[[data-slot][aria-invalid=true]]:ring-3 has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[>[data-align=block-end]]:h-auto has-[>[data-align=block-end]]:flex-col has-[>[data-align=block-start]]:h-auto has-[>[data-align=block-start]]:flex-col has-[>textarea]:h-auto dark:bg-input/30 dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40 has-[>[data-align=block-end]]:[&>input]:pt-3 has-[>[data-align=block-start]]:[&>input]:pb-3 has-[>[data-align=inline-end]]:[&>input]:pr-1.5 has-[>[data-align=inline-start]]:[&>input]:pl-1.5\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nconst inputGroupAddonVariants = cva(\n  \"flex h-auto cursor-text items-center justify-center gap-2 py-1.5 text-sm font-medium text-muted-foreground select-none group-data-[disabled=true]/input-group:opacity-50 [&>kbd]:rounded-[calc(var(--radius)-5px)] [&>svg:not([class*='size-'])]:size-4\",\n  {\n    variants: {\n      align: {\n        \"inline-start\":\n          \"order-first pl-2 has-[>button]:-ml-1 has-[>kbd]:ml-[-0.15rem]\",\n        \"inline-end\":\n          \"order-last pr-2 has-[>button]:-mr-1 has-[>kbd]:mr-[-0.15rem]\",\n        \"block-start\":\n          \"order-first w-full justify-start px-2.5 pt-2 group-has-[>input]/input-group:pt-2 [.border-b]:pb-2\",\n        \"block-end\":\n          \"order-last w-full justify-start px-2.5 pb-2 group-has-[>input]/input-group:pb-2 [.border-t]:pt-2\",\n      },\n    },\n    defaultVariants: {\n      align: \"inline-start\",\n    },\n  }\n)\n\nfunction InputGroupAddon({\n  className,\n  align = \"inline-start\",\n  ...props\n}: React.ComponentProps<\"div\"> & VariantProps<typeof inputGroupAddonVariants>) {\n  return (\n    <div\n      role=\"group\"\n      data-slot=\"input-group-addon\"\n      data-align={align}\n      className={cn(inputGroupAddonVariants({ align }), className)}\n      onClick={(e) => {\n        if ((e.target as HTMLElement).closest(\"button\")) {\n          return\n        }\n        e.currentTarget.parentElement?.querySelector(\"input\")?.focus()\n      }}\n      {...props}\n    />\n  )\n}\n\nconst inputGroupButtonVariants = cva(\n  \"flex items-center gap-2 text-sm shadow-none\",\n  {\n    variants: {\n      size: {\n        xs: \"h-6 gap-1 rounded-[calc(var(--radius)-5px)] px-1.5 [&>svg:not([class*='size-'])]:size-3.5\",\n        sm: \"\",\n        \"icon-xs\":\n          \"size-6 rounded-[calc(var(--radius)-5px)] p-0 has-[>svg]:p-0\",\n        \"icon-sm\": \"size-8 p-0 has-[>svg]:p-0\",\n      },\n    },\n    defaultVariants: {\n      size: \"xs\",\n    },\n  }\n)\n\nfunction InputGroupButton({\n  className,\n  type = \"button\",\n  variant = \"ghost\",\n  size = \"xs\",\n  ...props\n}: Omit<React.ComponentProps<typeof Button>, \"size\" | \"type\"> &\n  VariantProps<typeof inputGroupButtonVariants> & {\n    type?: \"button\" | \"submit\" | \"reset\"\n  }) {\n  return (\n    <Button\n      type={type}\n      data-size={size}\n      variant={variant}\n      className={cn(inputGroupButtonVariants({ size }), className)}\n      {...props}\n    />\n  )\n}\n\nfunction InputGroupText({ className, ...props }: React.ComponentProps<\"span\">) {\n  return (\n    <span\n      className={cn(\n        \"flex items-center gap-2 text-sm text-muted-foreground [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction InputGroupInput({\n  className,\n  ...props\n}: React.ComponentProps<\"input\">) {\n  return (\n    <Input\n      data-slot=\"input-group-control\"\n      className={cn(\n        \"flex-1 rounded-none border-0 bg-transparent shadow-none ring-0 focus-visible:ring-0 aria-invalid:ring-0 dark:bg-transparent\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction InputGroupTextarea({\n  className,\n  ...props\n}: React.ComponentProps<\"textarea\">) {\n  return (\n    <Textarea\n      data-slot=\"input-group-control\"\n      className={cn(\n        \"flex-1 resize-none rounded-none border-0 bg-transparent py-2 shadow-none ring-0 focus-visible:ring-0 aria-invalid:ring-0 dark:bg-transparent\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport {\n  InputGroup,\n  InputGroupAddon,\n  InputGroupButton,\n  InputGroupText,\n  InputGroupInput,\n  InputGroupTextarea,\n}\n"}]},{"name":"label","title":"Label","description":"Accessible label for form controls.","type":"registry:ui","docs":"/components/label","categories":["forms"],"files":[{"path":"components/ui/label.tsx","target":"components/ui/label.tsx","type":"registry:ui","content":"\"use client\"\n\nimport * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nfunction Label({ className, ...props }: React.ComponentProps<\"label\">) {\n  return (\n    <label\n      data-slot=\"label\"\n      className={cn(\n        \"flex items-center gap-2 text-sm leading-none font-medium select-none group-data-[disabled=true]:pointer-events-none group-data-[disabled=true]:opacity-50 peer-disabled:cursor-not-allowed peer-disabled:opacity-50\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { Label }\n"}]},{"name":"select","title":"Select","description":"Custom select with grouped options.","type":"registry:ui","docs":"/components/select","categories":["forms"],"files":[{"path":"components/ui/select.tsx","target":"components/ui/select.tsx","type":"registry:ui","content":"\"use client\"\n\nimport * as React from \"react\"\nimport { Select as SelectPrimitive } from \"@base-ui/react/select\"\n\nimport { cn } from \"@/lib/utils\"\nimport { ChevronDownIcon, CheckIcon, ChevronUpIcon } from \"lucide-react\"\n\nconst Select = SelectPrimitive.Root\n\nfunction SelectGroup({ className, ...props }: SelectPrimitive.Group.Props) {\n  return (\n    <SelectPrimitive.Group\n      data-slot=\"select-group\"\n      className={cn(\"scroll-my-1 p-1\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction SelectValue({ className, ...props }: SelectPrimitive.Value.Props) {\n  return (\n    <SelectPrimitive.Value\n      data-slot=\"select-value\"\n      className={cn(\"flex flex-1 text-left\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction SelectTrigger({\n  className,\n  size = \"default\",\n  children,\n  ...props\n}: SelectPrimitive.Trigger.Props & {\n  size?: \"sm\" | \"default\"\n}) {\n  return (\n    <SelectPrimitive.Trigger\n      data-slot=\"select-trigger\"\n      data-size={size}\n      className={cn(\n        \"flex w-fit items-center justify-between gap-1.5 rounded-md border border-input bg-transparent py-2 pr-2 pl-2.5 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-placeholder:text-muted-foreground data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-1.5 dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      {...props}\n    >\n      {children}\n      <SelectPrimitive.Icon\n        render={\n          <ChevronDownIcon className=\"pointer-events-none size-4 text-muted-foreground\" />\n        }\n      />\n    </SelectPrimitive.Trigger>\n  )\n}\n\nfunction SelectContent({\n  className,\n  children,\n  side = \"bottom\",\n  sideOffset = 4,\n  align = \"center\",\n  alignOffset = 0,\n  alignItemWithTrigger = true,\n  ...props\n}: SelectPrimitive.Popup.Props &\n  Pick<\n    SelectPrimitive.Positioner.Props,\n    \"align\" | \"alignOffset\" | \"side\" | \"sideOffset\" | \"alignItemWithTrigger\"\n  >) {\n  return (\n    <SelectPrimitive.Portal>\n      <SelectPrimitive.Positioner\n        side={side}\n        sideOffset={sideOffset}\n        align={align}\n        alignOffset={alignOffset}\n        alignItemWithTrigger={alignItemWithTrigger}\n        className=\"isolate z-50\"\n      >\n        <SelectPrimitive.Popup\n          data-slot=\"select-content\"\n          data-align-trigger={alignItemWithTrigger}\n          className={cn(\"relative isolate z-50 max-h-(--available-height) w-(--anchor-width) min-w-36 origin-(--transform-origin) overflow-x-hidden overflow-y-auto rounded-md bg-popover text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 data-[align-trigger=true]:animate-none data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95\", className )}\n          {...props}\n        >\n          <SelectScrollUpButton />\n          <SelectPrimitive.List>{children}</SelectPrimitive.List>\n          <SelectScrollDownButton />\n        </SelectPrimitive.Popup>\n      </SelectPrimitive.Positioner>\n    </SelectPrimitive.Portal>\n  )\n}\n\nfunction SelectLabel({\n  className,\n  ...props\n}: SelectPrimitive.GroupLabel.Props) {\n  return (\n    <SelectPrimitive.GroupLabel\n      data-slot=\"select-label\"\n      className={cn(\"px-2 py-1.5 text-xs text-muted-foreground\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction SelectItem({\n  className,\n  children,\n  ...props\n}: SelectPrimitive.Item.Props) {\n  return (\n    <SelectPrimitive.Item\n      data-slot=\"select-item\"\n      className={cn(\n        \"relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2\",\n        className\n      )}\n      {...props}\n    >\n      <SelectPrimitive.ItemText className=\"flex flex-1 shrink-0 gap-2 whitespace-nowrap\">\n        {children}\n      </SelectPrimitive.ItemText>\n      <SelectPrimitive.ItemIndicator\n        render={\n          <span className=\"pointer-events-none absolute right-2 flex size-4 items-center justify-center\" />\n        }\n      >\n        <CheckIcon className=\"pointer-events-none\" />\n      </SelectPrimitive.ItemIndicator>\n    </SelectPrimitive.Item>\n  )\n}\n\nfunction SelectSeparator({\n  className,\n  ...props\n}: SelectPrimitive.Separator.Props) {\n  return (\n    <SelectPrimitive.Separator\n      data-slot=\"select-separator\"\n      className={cn(\"pointer-events-none -mx-1 my-1 h-px bg-border\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction SelectScrollUpButton({\n  className,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollUpArrow>) {\n  return (\n    <SelectPrimitive.ScrollUpArrow\n      data-slot=\"select-scroll-up-button\"\n      className={cn(\n        \"top-0 z-10 flex w-full cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      {...props}\n    >\n      <ChevronUpIcon\n      />\n    </SelectPrimitive.ScrollUpArrow>\n  )\n}\n\nfunction SelectScrollDownButton({\n  className,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollDownArrow>) {\n  return (\n    <SelectPrimitive.ScrollDownArrow\n      data-slot=\"select-scroll-down-button\"\n      className={cn(\n        \"bottom-0 z-10 flex w-full cursor-default items-center justify-center bg-popover py-1 [&_svg:not([class*='size-'])]:size-4\",\n        className\n      )}\n      {...props}\n    >\n      <ChevronDownIcon\n      />\n    </SelectPrimitive.ScrollDownArrow>\n  )\n}\n\nexport {\n  Select,\n  SelectContent,\n  SelectGroup,\n  SelectItem,\n  SelectLabel,\n  SelectScrollDownButton,\n  SelectScrollUpButton,\n  SelectSeparator,\n  SelectTrigger,\n  SelectValue,\n}\n"}]},{"name":"separator","title":"Separator","description":"Horizontal or vertical divider.","type":"registry:ui","docs":"/components/separator","categories":["layout"],"files":[{"path":"components/ui/separator.tsx","target":"components/ui/separator.tsx","type":"registry:ui","content":"\"use client\"\n\nimport { Separator as SeparatorPrimitive } from \"@base-ui/react/separator\"\n\nimport { cn } from \"@/lib/utils\"\n\nfunction Separator({\n  className,\n  orientation = \"horizontal\",\n  ...props\n}: SeparatorPrimitive.Props) {\n  return (\n    <SeparatorPrimitive\n      data-slot=\"separator\"\n      orientation={orientation}\n      className={cn(\n        \"shrink-0 bg-border data-horizontal:h-px data-horizontal:w-full data-vertical:w-px data-vertical:self-stretch\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { Separator }\n"}]},{"name":"textarea","title":"Textarea","description":"Multiline text input.","type":"registry:ui","docs":"/components/textarea","categories":["forms"],"files":[{"path":"components/ui/textarea.tsx","target":"components/ui/textarea.tsx","type":"registry:ui","content":"import * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nfunction Textarea({ className, ...props }: React.ComponentProps<\"textarea\">) {\n  return (\n    <textarea\n      data-slot=\"textarea\"\n      className={cn(\n        \"flex field-sizing-content min-h-16 w-full rounded-md border border-input bg-transparent px-2.5 py-2 text-base shadow-xs transition-[color,box-shadow] outline-none placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 md:text-sm dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { Textarea }\n"}]},{"name":"tag-input","title":"Tag Input","description":"Create tags from typed input and enter press.","type":"registry:ui","docs":"/components/tag-input","categories":["forms","data-entry"],"registryDependencies":["https://pb-ui-five.vercel.app/registry/badge","https://pb-ui-five.vercel.app/registry/button","https://pb-ui-five.vercel.app/registry/input"],"files":[{"path":"components/ui/tag-input.tsx","target":"components/ui/tag-input.tsx","type":"registry:ui","content":"\"use client\";\n\nimport { X } from \"lucide-react\";\nimport * as React from \"react\";\n\nimport { Badge } from \"@/components/ui/badge\";\nimport { Button } from \"@/components/ui/button\";\nimport { Input } from \"@/components/ui/input\";\nimport { cn } from \"@/lib/utils\";\n\nexport type TagInputProps = Omit<React.ComponentProps<\"div\">, \"onChange\"> & {\n  value: string[];\n  onValueChange: (value: string[]) => void;\n  placeholder?: string;\n  maxTags?: number;\n  allowDuplicates?: boolean;\n  disabled?: boolean;\n  showClear?: boolean;\n};\n\nexport function TagInput({\n  value,\n  onValueChange,\n  placeholder = \"Add a tag…\",\n  maxTags,\n  allowDuplicates = false,\n  disabled = false,\n  showClear = false,\n  className,\n  ...props\n}: TagInputProps) {\n  const [inputValue, setInputValue] = React.useState(\"\");\n\n  const addTag = React.useCallback(\n    (raw: string) => {\n      const tagsToAdd = raw\n        .split(/[,,]/)\n        .map((t) => t.trim())\n        .filter((t) => t.length > 0);\n\n      if (tagsToAdd.length === 0) {\n        return;\n      }\n\n      const newValue = [...value];\n      let tagsAdded = false;\n\n      for (const next of tagsToAdd) {\n        if (\n          !allowDuplicates &&\n          newValue.some((t) => t.toLowerCase() === next.toLowerCase())\n        ) {\n          continue;\n        }\n\n        if (typeof maxTags === \"number\" && newValue.length >= maxTags) {\n          break;\n        }\n\n        newValue.push(next);\n        tagsAdded = true;\n      }\n\n      if (tagsAdded) {\n        onValueChange(newValue);\n      }\n      setInputValue(\"\");\n    },\n    [allowDuplicates, maxTags, onValueChange, value],\n  );\n\n  const removeTag = React.useCallback(\n    (tag: string) => {\n      onValueChange(value.filter((item) => item !== tag));\n    },\n    [onValueChange, value],\n  );\n\n  return (\n    <div\n      data-slot=\"tag-input\"\n      className={cn(\n        \"flex flex-wrap items-center gap-2 bg-transparent dark:bg-input/30 px-2.5 py-2 border border-input aria-invalid:border-destructive aria-invalid:focus-within:border-destructive focus-within:border-ring dark:aria-invalid:border-destructive/50 rounded-md aria-invalid:focus-within:ring-destructive/50 focus-within:ring-[3px] focus-within:ring-ring/50 w-full min-h-10 text-foreground\",\n        disabled && \"opacity-50\",\n        className,\n      )}\n      {...props}\n    >\n      {value.map((tag) => (\n        <Badge\n          key={tag}\n          variant=\"secondary\"\n          className=\"group/badge relative ps-2 pe-1 border-none rounded-md h-7 font-medium text-secondary-foreground text-xs transition-colors\"\n        >\n          <span className=\"max-w-56 truncate\">{tag}</span>\n          <Button\n            type=\"button\"\n            variant=\"ghost\"\n            size=\"icon-xs\"\n            className=\"text-muted-foreground hover:text-foreground\"\n            onClick={() => removeTag(tag)}\n            disabled={disabled}\n            aria-label={`Remove ${tag}`}\n          >\n            <X className=\"size-3.5\" />\n          </Button>\n        </Badge>\n      ))}\n      <Input\n        value={inputValue}\n        onChange={(event) => setInputValue(event.target.value)}\n        onKeyDown={(event) => {\n          if (disabled) {\n            return;\n          }\n\n          if (event.key === \"Enter\" || event.key === \",\") {\n            event.preventDefault();\n            addTag(inputValue);\n            return;\n          }\n\n          if (event.key === \"Backspace\" && inputValue.length === 0) {\n            onValueChange(value.slice(0, -1));\n          }\n        }}\n        onBlur={() => {\n          if (disabled) {\n            return;\n          }\n\n          if (inputValue.trim().length > 0) {\n            addTag(inputValue);\n          }\n        }}\n        placeholder={placeholder}\n        disabled={disabled}\n        className=\"flex-1 bg-transparent shadow-none p-0 border-0 focus-visible:ring-0 w-[18ch] min-w-[18ch] h-7\"\n      />\n      {showClear && value.length > 0 && (\n        <Button\n          type=\"button\"\n          variant=\"ghost\"\n          size=\"icon-xs\"\n          className=\"ms-auto text-muted-foreground hover:text-foreground\"\n          onClick={() => onValueChange([])}\n          disabled={disabled}\n          aria-label=\"Clear all tags\"\n        >\n          <X className=\"size-3.5\" />\n        </Button>\n      )}\n    </div>\n  );\n}\n"}]},{"name":"checkbox","title":"Checkbox","description":"Toggle control for boolean values.","type":"registry:ui","docs":"/components/checkbox","categories":["forms"],"files":[{"path":"components/ui/checkbox.tsx","target":"components/ui/checkbox.tsx","type":"registry:ui","content":"\"use client\"\n\nimport { Checkbox as CheckboxPrimitive } from \"@base-ui/react/checkbox\"\n\nimport { cn } from \"@/lib/utils\"\nimport { CheckIcon } from \"lucide-react\"\n\nfunction Checkbox({ className, ...props }: CheckboxPrimitive.Root.Props) {\n  return (\n    <CheckboxPrimitive.Root\n      data-slot=\"checkbox\"\n      className={cn(\n        \"peer relative flex size-4 shrink-0 items-center justify-center rounded-[4px] border border-input shadow-xs transition-shadow outline-none group-has-disabled/field:opacity-50 after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 aria-invalid:aria-checked:border-primary dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:border-primary data-checked:bg-primary data-checked:text-primary-foreground dark:data-checked:bg-primary\",\n        className\n      )}\n      {...props}\n    >\n      <CheckboxPrimitive.Indicator\n        data-slot=\"checkbox-indicator\"\n        className=\"grid place-content-center text-current transition-none [&>svg]:size-3.5\"\n      >\n        <CheckIcon\n        />\n      </CheckboxPrimitive.Indicator>\n    </CheckboxPrimitive.Root>\n  )\n}\n\nexport { Checkbox }\n"}]},{"name":"switch","title":"Switch","description":"Toggle switch for on/off states.","type":"registry:ui","docs":"/components/switch","categories":["forms"],"files":[{"path":"components/ui/switch.tsx","target":"components/ui/switch.tsx","type":"registry:ui","content":"\"use client\"\n\nimport { Switch as SwitchPrimitive } from \"@base-ui/react/switch\"\n\nimport { cn } from \"@/lib/utils\"\n\nfunction Switch({\n  className,\n  size = \"default\",\n  ...props\n}: SwitchPrimitive.Root.Props & {\n  size?: \"sm\" | \"default\"\n}) {\n  return (\n    <SwitchPrimitive.Root\n      data-slot=\"switch\"\n      data-size={size}\n      className={cn(\n        \"peer group/switch relative inline-flex shrink-0 items-center rounded-full border border-transparent shadow-xs transition-all outline-none after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 data-[size=default]:h-[18.4px] data-[size=default]:w-[32px] data-[size=sm]:h-[14px] data-[size=sm]:w-[24px] dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:bg-primary data-unchecked:bg-input dark:data-unchecked:bg-input/80 data-disabled:cursor-not-allowed data-disabled:opacity-50\",\n        className\n      )}\n      {...props}\n    >\n      <SwitchPrimitive.Thumb\n        data-slot=\"switch-thumb\"\n        className=\"pointer-events-none block rounded-full bg-background ring-0 transition-transform group-data-[size=default]/switch:size-4 group-data-[size=sm]/switch:size-3 group-data-[size=default]/switch:data-checked:translate-x-[calc(100%-2px)] group-data-[size=sm]/switch:data-checked:translate-x-[calc(100%-2px)] dark:data-checked:bg-primary-foreground group-data-[size=default]/switch:data-unchecked:translate-x-0 group-data-[size=sm]/switch:data-unchecked:translate-x-0 dark:data-unchecked:bg-foreground\"\n      />\n    </SwitchPrimitive.Root>\n  )\n}\n\nexport { Switch }\n"}]},{"name":"slider","title":"Slider","description":"Range input for selecting numeric values.","type":"registry:ui","docs":"/components/slider","categories":["forms"],"files":[{"path":"components/ui/slider.tsx","target":"components/ui/slider.tsx","type":"registry:ui","content":"\"use client\"\n\nimport * as React from \"react\"\nimport { Slider as SliderPrimitive } from \"@base-ui/react/slider\"\n\nimport { cn } from \"@/lib/utils\"\n\nfunction Slider({\n  className,\n  defaultValue,\n  value,\n  min = 0,\n  max = 100,\n  ...props\n}: SliderPrimitive.Root.Props) {\n  const _values = React.useMemo(\n    () =>\n      Array.isArray(value)\n        ? value\n        : Array.isArray(defaultValue)\n          ? defaultValue\n          : [min, max],\n    [value, defaultValue, min, max]\n  )\n\n  return (\n    <SliderPrimitive.Root\n      className={cn(\"data-horizontal:w-full data-vertical:h-full\", className)}\n      data-slot=\"slider\"\n      defaultValue={defaultValue}\n      value={value}\n      min={min}\n      max={max}\n      thumbAlignment=\"edge\"\n      {...props}\n    >\n      <SliderPrimitive.Control className=\"relative flex w-full touch-none items-center select-none data-disabled:opacity-50 data-vertical:h-full data-vertical:min-h-40 data-vertical:w-auto data-vertical:flex-col\">\n        <SliderPrimitive.Track\n          data-slot=\"slider-track\"\n          className=\"relative grow overflow-hidden rounded-full bg-muted select-none data-horizontal:h-1.5 data-horizontal:w-full data-vertical:h-full data-vertical:w-1.5\"\n        >\n          <SliderPrimitive.Indicator\n            data-slot=\"slider-range\"\n            className=\"bg-primary select-none data-horizontal:h-full data-vertical:w-full\"\n          />\n        </SliderPrimitive.Track>\n        {Array.from({ length: _values.length }, (_, index) => (\n          <SliderPrimitive.Thumb\n            data-slot=\"slider-thumb\"\n            key={index}\n            className=\"block size-4 shrink-0 rounded-full border border-primary bg-white shadow-sm ring-ring/50 transition-[color,box-shadow] select-none hover:ring-4 focus-visible:ring-4 focus-visible:outline-hidden disabled:pointer-events-none disabled:opacity-50\"\n          />\n        ))}\n      </SliderPrimitive.Control>\n    </SliderPrimitive.Root>\n  )\n}\n\nexport { Slider }\n"}]},{"name":"radio-group","title":"Radio Group","description":"Single selection from multiple options.","type":"registry:ui","docs":"/components/radio-group","categories":["forms"],"files":[{"path":"components/ui/radio-group.tsx","target":"components/ui/radio-group.tsx","type":"registry:ui","content":"\"use client\"\n\nimport { Radio as RadioPrimitive } from \"@base-ui/react/radio\"\nimport { RadioGroup as RadioGroupPrimitive } from \"@base-ui/react/radio-group\"\n\nimport { cn } from \"@/lib/utils\"\n\nfunction RadioGroup({ className, ...props }: RadioGroupPrimitive.Props) {\n  return (\n    <RadioGroupPrimitive\n      data-slot=\"radio-group\"\n      className={cn(\"grid w-full gap-3\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction RadioGroupItem({ className, ...props }: RadioPrimitive.Root.Props) {\n  return (\n    <RadioPrimitive.Root\n      data-slot=\"radio-group-item\"\n      className={cn(\n        \"group/radio-group-item peer relative flex aspect-square size-4 shrink-0 rounded-full border border-input outline-none after:absolute after:-inset-x-3 after:-inset-y-2 focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 aria-invalid:aria-checked:border-primary dark:bg-input/30 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 data-checked:border-primary data-checked:bg-primary data-checked:text-primary-foreground dark:data-checked:bg-primary\",\n        className\n      )}\n      {...props}\n    >\n      <RadioPrimitive.Indicator\n        data-slot=\"radio-group-indicator\"\n        className=\"flex size-4 items-center justify-center\"\n      >\n        <span className=\"absolute top-1/2 left-1/2 size-2 -translate-x-1/2 -translate-y-1/2 rounded-full bg-primary-foreground\" />\n      </RadioPrimitive.Indicator>\n    </RadioPrimitive.Root>\n  )\n}\n\nexport { RadioGroup, RadioGroupItem }\n"}]},{"name":"popover","title":"Popover","description":"Floating content panel with positioning.","type":"registry:ui","docs":"/components/popover","categories":["overlay"],"files":[{"path":"components/ui/popover.tsx","target":"components/ui/popover.tsx","type":"registry:ui","content":"\"use client\"\n\nimport * as React from \"react\"\nimport { Popover as PopoverPrimitive } from \"@base-ui/react/popover\"\n\nimport { cn } from \"@/lib/utils\"\n\nfunction Popover({ ...props }: PopoverPrimitive.Root.Props) {\n  return <PopoverPrimitive.Root data-slot=\"popover\" {...props} />\n}\n\nfunction PopoverTrigger({ ...props }: PopoverPrimitive.Trigger.Props) {\n  return <PopoverPrimitive.Trigger data-slot=\"popover-trigger\" {...props} />\n}\n\nfunction PopoverContent({\n  className,\n  align = \"center\",\n  alignOffset = 0,\n  side = \"bottom\",\n  sideOffset = 4,\n  ...props\n}: PopoverPrimitive.Popup.Props &\n  Pick<\n    PopoverPrimitive.Positioner.Props,\n    \"align\" | \"alignOffset\" | \"side\" | \"sideOffset\"\n  >) {\n  return (\n    <PopoverPrimitive.Portal>\n      <PopoverPrimitive.Positioner\n        align={align}\n        alignOffset={alignOffset}\n        side={side}\n        sideOffset={sideOffset}\n        className=\"isolate z-50\"\n      >\n        <PopoverPrimitive.Popup\n          data-slot=\"popover-content\"\n          className={cn(\n            \"z-50 flex w-72 origin-(--transform-origin) flex-col gap-4 rounded-md bg-popover p-4 text-sm text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-hidden duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95\",\n            className\n          )}\n          {...props}\n        />\n      </PopoverPrimitive.Positioner>\n    </PopoverPrimitive.Portal>\n  )\n}\n\nfunction PopoverHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"popover-header\"\n      className={cn(\"flex flex-col gap-1 text-sm\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction PopoverTitle({ className, ...props }: PopoverPrimitive.Title.Props) {\n  return (\n    <PopoverPrimitive.Title\n      data-slot=\"popover-title\"\n      className={cn(\"font-medium\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction PopoverDescription({\n  className,\n  ...props\n}: PopoverPrimitive.Description.Props) {\n  return (\n    <PopoverPrimitive.Description\n      data-slot=\"popover-description\"\n      className={cn(\"text-muted-foreground\", className)}\n      {...props}\n    />\n  )\n}\n\nexport {\n  Popover,\n  PopoverContent,\n  PopoverDescription,\n  PopoverHeader,\n  PopoverTitle,\n  PopoverTrigger,\n}\n"}]},{"name":"calendar","title":"Calendar","description":"Date selection calendar component.","type":"registry:ui","docs":"/components/calendar","categories":["forms","data-entry"],"registryDependencies":["https://pb-ui-five.vercel.app/registry/button"],"dependencies":["react-day-picker"],"files":[{"path":"components/ui/calendar.tsx","target":"components/ui/calendar.tsx","type":"registry:ui","content":"\"use client\"\n\nimport * as React from \"react\"\nimport {\n  DayPicker,\n  getDefaultClassNames,\n  type DayButton,\n  type Locale,\n} from \"react-day-picker\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Button, buttonVariants } from \"@/components/ui/button\"\nimport { ChevronLeftIcon, ChevronRightIcon, ChevronDownIcon } from \"lucide-react\"\n\nfunction Calendar({\n  className,\n  classNames,\n  showOutsideDays = true,\n  captionLayout = \"label\",\n  buttonVariant = \"ghost\",\n  locale,\n  formatters,\n  components,\n  ...props\n}: React.ComponentProps<typeof DayPicker> & {\n  buttonVariant?: React.ComponentProps<typeof Button>[\"variant\"]\n}) {\n  const defaultClassNames = getDefaultClassNames()\n\n  return (\n    <DayPicker\n      showOutsideDays={showOutsideDays}\n      className={cn(\n        \"group/calendar bg-background p-3 [--cell-radius:var(--radius-md)] [--cell-size:--spacing(8)] in-data-[slot=card-content]:bg-transparent in-data-[slot=popover-content]:bg-transparent\",\n        String.raw`rtl:**:[.rdp-button\\_next>svg]:rotate-180`,\n        String.raw`rtl:**:[.rdp-button\\_previous>svg]:rotate-180`,\n        className\n      )}\n      captionLayout={captionLayout}\n      locale={locale}\n      formatters={{\n        formatMonthDropdown: (date) =>\n          date.toLocaleString(locale?.code, { month: \"short\" }),\n        ...formatters,\n      }}\n      classNames={{\n        root: cn(\"w-fit\", defaultClassNames.root),\n        months: cn(\n          \"relative flex flex-col gap-4 md:flex-row\",\n          defaultClassNames.months\n        ),\n        month: cn(\"flex w-full flex-col gap-4\", defaultClassNames.month),\n        nav: cn(\n          \"absolute inset-x-0 top-0 flex w-full items-center justify-between gap-1\",\n          defaultClassNames.nav\n        ),\n        button_previous: cn(\n          buttonVariants({ variant: buttonVariant }),\n          \"size-(--cell-size) p-0 select-none aria-disabled:opacity-50\",\n          defaultClassNames.button_previous\n        ),\n        button_next: cn(\n          buttonVariants({ variant: buttonVariant }),\n          \"size-(--cell-size) p-0 select-none aria-disabled:opacity-50\",\n          defaultClassNames.button_next\n        ),\n        month_caption: cn(\n          \"flex h-(--cell-size) w-full items-center justify-center px-(--cell-size)\",\n          defaultClassNames.month_caption\n        ),\n        dropdowns: cn(\n          \"flex h-(--cell-size) w-full items-center justify-center gap-1.5 text-sm font-medium\",\n          defaultClassNames.dropdowns\n        ),\n        dropdown_root: cn(\n          \"relative rounded-(--cell-radius)\",\n          defaultClassNames.dropdown_root\n        ),\n        dropdown: cn(\n          \"absolute inset-0 bg-popover opacity-0\",\n          defaultClassNames.dropdown\n        ),\n        caption_label: cn(\n          \"font-medium select-none\",\n          captionLayout === \"label\"\n            ? \"text-sm\"\n            : \"flex items-center gap-1 rounded-(--cell-radius) text-sm [&>svg]:size-3.5 [&>svg]:text-muted-foreground\",\n          defaultClassNames.caption_label\n        ),\n        table: \"w-full border-collapse\",\n        weekdays: cn(\"flex\", defaultClassNames.weekdays),\n        weekday: cn(\n          \"flex-1 rounded-(--cell-radius) text-[0.8rem] font-normal text-muted-foreground select-none\",\n          defaultClassNames.weekday\n        ),\n        week: cn(\"mt-2 flex w-full\", defaultClassNames.week),\n        week_number_header: cn(\n          \"w-(--cell-size) select-none\",\n          defaultClassNames.week_number_header\n        ),\n        week_number: cn(\n          \"text-[0.8rem] text-muted-foreground select-none\",\n          defaultClassNames.week_number\n        ),\n        day: cn(\n          \"group/day relative aspect-square h-full w-full rounded-(--cell-radius) p-0 text-center select-none [&:last-child[data-selected=true]_button]:rounded-r-(--cell-radius)\",\n          props.showWeekNumber\n            ? \"[&:nth-child(2)[data-selected=true]_button]:rounded-l-(--cell-radius)\"\n            : \"[&:first-child[data-selected=true]_button]:rounded-l-(--cell-radius)\",\n          defaultClassNames.day\n        ),\n        range_start: cn(\n          \"relative isolate z-0 rounded-l-(--cell-radius) bg-muted after:absolute after:inset-y-0 after:right-0 after:w-4 after:bg-muted\",\n          defaultClassNames.range_start\n        ),\n        range_middle: cn(\"rounded-none\", defaultClassNames.range_middle),\n        range_end: cn(\n          \"relative isolate z-0 rounded-r-(--cell-radius) bg-muted after:absolute after:inset-y-0 after:left-0 after:w-4 after:bg-muted\",\n          defaultClassNames.range_end\n        ),\n        today: cn(\n          \"rounded-(--cell-radius) bg-muted text-foreground data-[selected=true]:rounded-none\",\n          defaultClassNames.today\n        ),\n        outside: cn(\n          \"text-muted-foreground aria-selected:text-muted-foreground\",\n          defaultClassNames.outside\n        ),\n        disabled: cn(\n          \"text-muted-foreground opacity-50\",\n          defaultClassNames.disabled\n        ),\n        hidden: cn(\"invisible\", defaultClassNames.hidden),\n        ...classNames,\n      }}\n      components={{\n        Root: ({ className, rootRef, ...props }) => {\n          return (\n            <div\n              data-slot=\"calendar\"\n              ref={rootRef}\n              className={cn(className)}\n              {...props}\n            />\n          )\n        },\n        Chevron: ({ className, orientation, ...props }) => {\n          if (orientation === \"left\") {\n            return (\n              <ChevronLeftIcon className={cn(\"size-4\", className)} {...props} />\n            )\n          }\n\n          if (orientation === \"right\") {\n            return (\n              <ChevronRightIcon className={cn(\"size-4\", className)} {...props} />\n            )\n          }\n\n          return (\n            <ChevronDownIcon className={cn(\"size-4\", className)} {...props} />\n          )\n        },\n        DayButton: ({ ...props }) => (\n          <CalendarDayButton locale={locale} {...props} />\n        ),\n        WeekNumber: ({ children, ...props }) => {\n          return (\n            <td {...props}>\n              <div className=\"flex size-(--cell-size) items-center justify-center text-center\">\n                {children}\n              </div>\n            </td>\n          )\n        },\n        ...components,\n      }}\n      {...props}\n    />\n  )\n}\n\nfunction CalendarDayButton({\n  className,\n  day,\n  modifiers,\n  locale,\n  ...props\n}: React.ComponentProps<typeof DayButton> & { locale?: Partial<Locale> }) {\n  const defaultClassNames = getDefaultClassNames()\n\n  const ref = React.useRef<HTMLButtonElement>(null)\n  React.useEffect(() => {\n    if (modifiers.focused) ref.current?.focus()\n  }, [modifiers.focused])\n\n  return (\n    <Button\n      variant=\"ghost\"\n      size=\"icon\"\n      data-day={day.date.toLocaleDateString(locale?.code)}\n      data-selected-single={\n        modifiers.selected &&\n        !modifiers.range_start &&\n        !modifiers.range_end &&\n        !modifiers.range_middle\n      }\n      data-range-start={modifiers.range_start}\n      data-range-end={modifiers.range_end}\n      data-range-middle={modifiers.range_middle}\n      className={cn(\n        \"relative isolate z-10 flex aspect-square size-auto w-full min-w-(--cell-size) flex-col gap-1 border-0 leading-none font-normal group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:border-ring group-data-[focused=true]/day:ring-[3px] group-data-[focused=true]/day:ring-ring/50 data-[range-end=true]:rounded-(--cell-radius) data-[range-end=true]:rounded-r-(--cell-radius) data-[range-end=true]:bg-primary data-[range-end=true]:text-primary-foreground data-[range-middle=true]:rounded-none data-[range-middle=true]:bg-muted data-[range-middle=true]:text-foreground data-[range-start=true]:rounded-(--cell-radius) data-[range-start=true]:rounded-l-(--cell-radius) data-[range-start=true]:bg-primary data-[range-start=true]:text-primary-foreground data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground dark:hover:text-foreground [&>span]:text-xs [&>span]:opacity-70\",\n        defaultClassNames.day,\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport { Calendar, CalendarDayButton }\n"}]},{"name":"dialog","title":"Dialog","description":"Modal window for focused interactions.","type":"registry:ui","docs":"/components/dialog","categories":["overlay"],"registryDependencies":["https://pb-ui-five.vercel.app/registry/button"],"files":[{"path":"components/ui/dialog.tsx","target":"components/ui/dialog.tsx","type":"registry:ui","content":"\"use client\"\n\nimport * as React from \"react\"\nimport { Dialog as DialogPrimitive } from \"@base-ui/react/dialog\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Button } from \"@/components/ui/button\"\nimport { XIcon } from \"lucide-react\"\n\nfunction Dialog({ ...props }: DialogPrimitive.Root.Props) {\n  return <DialogPrimitive.Root data-slot=\"dialog\" {...props} />\n}\n\nfunction DialogTrigger({ ...props }: DialogPrimitive.Trigger.Props) {\n  return <DialogPrimitive.Trigger data-slot=\"dialog-trigger\" {...props} />\n}\n\nfunction DialogPortal({ ...props }: DialogPrimitive.Portal.Props) {\n  return <DialogPrimitive.Portal data-slot=\"dialog-portal\" {...props} />\n}\n\nfunction DialogClose({ ...props }: DialogPrimitive.Close.Props) {\n  return <DialogPrimitive.Close data-slot=\"dialog-close\" {...props} />\n}\n\nfunction DialogOverlay({\n  className,\n  ...props\n}: DialogPrimitive.Backdrop.Props) {\n  return (\n    <DialogPrimitive.Backdrop\n      data-slot=\"dialog-overlay\"\n      className={cn(\n        \"fixed inset-0 isolate z-50 bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction DialogContent({\n  className,\n  children,\n  showCloseButton = true,\n  ...props\n}: DialogPrimitive.Popup.Props & {\n  showCloseButton?: boolean\n}) {\n  return (\n    <DialogPortal>\n      <DialogOverlay />\n      <DialogPrimitive.Popup\n        data-slot=\"dialog-content\"\n        className={cn(\n          \"fixed top-1/2 left-1/2 z-50 grid w-full max-w-[calc(100%-2rem)] -translate-x-1/2 -translate-y-1/2 gap-6 rounded-xl bg-background p-6 text-sm ring-1 ring-foreground/10 duration-100 outline-none sm:max-w-md data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95\",\n          className\n        )}\n        {...props}\n      >\n        {children}\n        {showCloseButton && (\n          <DialogPrimitive.Close\n            data-slot=\"dialog-close\"\n            render={\n              <Button\n                variant=\"ghost\"\n                className=\"absolute top-4 right-4\"\n                size=\"icon-sm\"\n              />\n            }\n          >\n            <XIcon\n            />\n            <span className=\"sr-only\">Close</span>\n          </DialogPrimitive.Close>\n        )}\n      </DialogPrimitive.Popup>\n    </DialogPortal>\n  )\n}\n\nfunction DialogHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"dialog-header\"\n      className={cn(\"flex flex-col gap-2\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction DialogFooter({\n  className,\n  showCloseButton = false,\n  children,\n  ...props\n}: React.ComponentProps<\"div\"> & {\n  showCloseButton?: boolean\n}) {\n  return (\n    <div\n      data-slot=\"dialog-footer\"\n      className={cn(\n        \"flex flex-col-reverse gap-2 sm:flex-row sm:justify-end\",\n        className\n      )}\n      {...props}\n    >\n      {children}\n      {showCloseButton && (\n        <DialogPrimitive.Close render={<Button variant=\"outline\" />}>\n          Close\n        </DialogPrimitive.Close>\n      )}\n    </div>\n  )\n}\n\nfunction DialogTitle({ className, ...props }: DialogPrimitive.Title.Props) {\n  return (\n    <DialogPrimitive.Title\n      data-slot=\"dialog-title\"\n      className={cn(\"leading-none font-medium\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction DialogDescription({\n  className,\n  ...props\n}: DialogPrimitive.Description.Props) {\n  return (\n    <DialogPrimitive.Description\n      data-slot=\"dialog-description\"\n      className={cn(\n        \"text-sm text-muted-foreground *:[a]:underline *:[a]:underline-offset-3 *:[a]:hover:text-foreground\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nexport {\n  Dialog,\n  DialogClose,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogOverlay,\n  DialogPortal,\n  DialogTitle,\n  DialogTrigger,\n}\n"}]},{"name":"command","title":"Command","description":"Command palette with search and keyboard navigation.","type":"registry:ui","docs":"/components/command","categories":["overlay","navigation"],"registryDependencies":["https://pb-ui-five.vercel.app/registry/dialog","https://pb-ui-five.vercel.app/registry/input-group"],"dependencies":["cmdk"],"files":[{"path":"components/ui/command.tsx","target":"components/ui/command.tsx","type":"registry:ui","content":"\"use client\"\n\nimport * as React from \"react\"\nimport { Command as CommandPrimitive } from \"cmdk\"\n\nimport { cn } from \"@/lib/utils\"\nimport {\n  Dialog,\n  DialogContent,\n  DialogDescription,\n  DialogHeader,\n  DialogTitle,\n} from \"@/components/ui/dialog\"\nimport {\n  InputGroup,\n  InputGroupAddon,\n} from \"@/components/ui/input-group\"\nimport { SearchIcon, CheckIcon } from \"lucide-react\"\n\nfunction Command({\n  className,\n  ...props\n}: React.ComponentProps<typeof CommandPrimitive>) {\n  return (\n    <CommandPrimitive\n      data-slot=\"command\"\n      className={cn(\n        \"flex size-full flex-col overflow-hidden rounded-xl! bg-popover p-1 text-popover-foreground\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction CommandDialog({\n  title = \"Command Palette\",\n  description = \"Search for a command to run...\",\n  children,\n  className,\n  showCloseButton = false,\n  ...props\n}: Omit<React.ComponentProps<typeof Dialog>, \"children\"> & {\n  title?: string\n  description?: string\n  className?: string\n  showCloseButton?: boolean\n  children: React.ReactNode\n}) {\n  return (\n    <Dialog {...props}>\n      <DialogHeader className=\"sr-only\">\n        <DialogTitle>{title}</DialogTitle>\n        <DialogDescription>{description}</DialogDescription>\n      </DialogHeader>\n      <DialogContent\n        className={cn(\n          \"top-1/3 translate-y-0 overflow-hidden rounded-xl! p-0\",\n          className\n        )}\n        showCloseButton={showCloseButton}\n      >\n        {children}\n      </DialogContent>\n    </Dialog>\n  )\n}\n\nfunction CommandInput({\n  className,\n  ...props\n}: React.ComponentProps<typeof CommandPrimitive.Input>) {\n  return (\n    <div data-slot=\"command-input-wrapper\" className=\"p-1 pb-0\">\n      <InputGroup className=\"h-8! rounded-lg! border-input/30 bg-input/30 shadow-none! *:data-[slot=input-group-addon]:pl-2!\">\n        <CommandPrimitive.Input\n          data-slot=\"command-input\"\n          className={cn(\n            \"w-full text-sm outline-hidden disabled:cursor-not-allowed disabled:opacity-50\",\n            className\n          )}\n          {...props}\n        />\n        <InputGroupAddon>\n          <SearchIcon className=\"size-4 shrink-0 opacity-50\" />\n        </InputGroupAddon>\n      </InputGroup>\n    </div>\n  )\n}\n\nfunction CommandList({\n  className,\n  ...props\n}: React.ComponentProps<typeof CommandPrimitive.List>) {\n  return (\n    <CommandPrimitive.List\n      data-slot=\"command-list\"\n      className={cn(\n        \"no-scrollbar max-h-72 scroll-py-1 overflow-x-hidden overflow-y-auto outline-none\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction CommandEmpty({\n  className,\n  ...props\n}: React.ComponentProps<typeof CommandPrimitive.Empty>) {\n  return (\n    <CommandPrimitive.Empty\n      data-slot=\"command-empty\"\n      className={cn(\"py-6 text-center text-sm\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction CommandGroup({\n  className,\n  ...props\n}: React.ComponentProps<typeof CommandPrimitive.Group>) {\n  return (\n    <CommandPrimitive.Group\n      data-slot=\"command-group\"\n      className={cn(\n        \"overflow-hidden p-1 text-foreground **:[[cmdk-group-heading]]:px-2 **:[[cmdk-group-heading]]:py-1.5 **:[[cmdk-group-heading]]:text-xs **:[[cmdk-group-heading]]:font-medium **:[[cmdk-group-heading]]:text-muted-foreground\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction CommandSeparator({\n  className,\n  ...props\n}: React.ComponentProps<typeof CommandPrimitive.Separator>) {\n  return (\n    <CommandPrimitive.Separator\n      data-slot=\"command-separator\"\n      className={cn(\"-mx-1 h-px w-auto bg-border\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction CommandItem({\n  className,\n  children,\n  ...props\n}: React.ComponentProps<typeof CommandPrimitive.Item>) {\n  return (\n    <CommandPrimitive.Item\n      data-slot=\"command-item\"\n      className={cn(\n        \"group/command-item relative flex cursor-default items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-hidden select-none in-data-[slot=dialog-content]:rounded-lg! data-[disabled=true]:pointer-events-none data-[disabled=true]:opacity-50 data-selected:bg-muted data-selected:text-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 data-selected:**:[svg]:text-foreground\",\n        className\n      )}\n      {...props}\n    >\n      {children}\n      <CheckIcon className=\"ml-auto opacity-0 group-has-data-[slot=command-shortcut]/command-item:hidden group-data-[checked=true]/command-item:opacity-100\" />\n    </CommandPrimitive.Item>\n  )\n}\n\nfunction CommandShortcut({\n  className,\n  ...props\n}: React.ComponentProps<\"span\">) {\n  return (\n    <span\n      data-slot=\"command-shortcut\"\n      className={cn(\n        \"ml-auto text-xs tracking-widest text-muted-foreground group-data-selected/command-item:text-foreground\",\n        className\n      )}\n      {...props}\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"}]},{"name":"datefield-rac","title":"Date Field","description":"Date and time input with segmented fields.","type":"registry:ui","docs":"/components/datefield-rac","categories":["forms","data-entry"],"dependencies":["react-aria-components"],"files":[{"path":"components/ui/datefield-rac.tsx","target":"components/ui/datefield-rac.tsx","type":"registry:ui","content":"\"use client\";\n\nimport {\n  composeRenderProps,\n  type DateFieldProps,\n  DateField as DateFieldRac,\n  type DateInputProps as DateInputPropsRac,\n  DateInput as DateInputRac,\n  type DateSegmentProps,\n  DateSegment as DateSegmentRac,\n  type DateValue as DateValueRac,\n  type TimeFieldProps,\n  TimeField as TimeFieldRac,\n  type TimeValue as TimeValueRac,\n} from \"react-aria-components\";\n\nimport { cn } from \"@/lib/utils\";\n\nfunction DateField<T extends DateValueRac>({\n  className,\n  children,\n  ...props\n}: DateFieldProps<T>) {\n  return (\n    <DateFieldRac\n      className={composeRenderProps(className, (className) => cn(className))}\n      {...props}\n    >\n      {children}\n    </DateFieldRac>\n  );\n}\n\nfunction TimeField<T extends TimeValueRac>({\n  className,\n  children,\n  ...props\n}: TimeFieldProps<T>) {\n  return (\n    <TimeFieldRac\n      className={composeRenderProps(className, (className) => cn(className))}\n      {...props}\n    >\n      {children}\n    </TimeFieldRac>\n  );\n}\n\nfunction DateSegment({ className, ...props }: DateSegmentProps) {\n  return (\n    <DateSegmentRac\n      className={composeRenderProps(className, (className) =>\n        cn(\n          \"inline data-focused:bg-accent data-invalid:data-focused:bg-destructive data-disabled:opacity-50 p-0.5 data-[type=literal]:px-0 rounded outline-hidden text-foreground data-[type=literal]:text-muted-foreground/70 data-focused:data-placeholder:text-foreground data-focused:text-foreground data-invalid:data-focused:data-placeholder:text-primary-foreground data-invalid:data-focused:text-primary-foreground data-invalid:data-placeholder:text-destructive data-invalid:text-destructive data-placeholder:text-muted-foreground/70 caret-transparent data-disabled:cursor-not-allowed\",\n          className,\n        ),\n      )}\n      {...props}\n      data-invalid\n    />\n  );\n}\n\nconst dateInputStyle =\n  \"relative inline-flex h-9 w-full items-center overflow-hidden whitespace-nowrap rounded-md border border-input bg-transparent dark:bg-input/30 px-3 py-2 text-sm shadow-xs transition-[color,box-shadow] outline-none data-focus-within:border-ring data-focus-within:ring-ring/50 data-focus-within:ring-[3px] aria-invalid:border-destructive aria-invalid:data-focus-within:ring-destructive/50 aria-invalid:data-focus-within:border-destructive dark:aria-invalid:border-destructive/50\";\n\ninterface DateInputProps extends DateInputPropsRac {\n  className?: string;\n  unstyled?: boolean;\n}\n\nfunction DateInput({\n  className,\n  unstyled = false,\n  ...props\n}: Omit<DateInputProps, \"children\">) {\n  return (\n    <DateInputRac\n      className={composeRenderProps(className, (className) =>\n        cn(!unstyled && dateInputStyle, className),\n      )}\n      {...props}\n    >\n      {(segment) => <DateSegment segment={segment} />}\n    </DateInputRac>\n  );\n}\n\nexport { DateField, DateInput, dateInputStyle, DateSegment, TimeField };\nexport type { DateInputProps };\n"}]},{"name":"password-input","title":"Password Input","description":"Text input with visibility toggle for passwords.","type":"registry:ui","docs":"/components/password-input","categories":["forms"],"registryDependencies":["https://pb-ui-five.vercel.app/registry/input"],"files":[{"path":"components/ui/password-input.tsx","target":"components/ui/password-input.tsx","type":"registry:ui","content":"\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport { EyeIcon, EyeOffIcon } from \"lucide-react\";\nimport { useId, useState } from \"react\";\n\nimport { Input } from \"@/components/ui/input\";\n\nexport default function PasswordInput({\n  className,\n  ...props\n}: React.ComponentProps<\"input\">) {\n  const id = useId();\n  const [isVisible, setIsVisible] = useState<boolean>(false);\n\n  const toggleVisibility = () => setIsVisible((prevState) => !prevState);\n\n  return (\n    <div className=\"relative\">\n      <Input\n        id={id}\n        className={cn(\"pe-12\", className)}\n        placeholder=\"Password\"\n        type={isVisible ? \"text\" : \"password\"}\n        {...props}\n      />\n      <button\n        className=\"focus:z-10 absolute inset-y-0 flex justify-center items-center hover:bg-accent disabled:opacity-50 focus-visible:border-ring rounded-e-xl outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50 w-12 h-full text-muted-foreground/80 hover:text-foreground transition-colors duration-200 disabled:cursor-not-allowed disabled:pointer-events-none end-0\"\n        type=\"button\"\n        onClick={toggleVisibility}\n        aria-label={isVisible ? \"Hide password\" : \"Show password\"}\n        aria-pressed={isVisible}\n        aria-controls=\"password\"\n      >\n        {isVisible ? (\n          <EyeOffIcon size={16} aria-hidden=\"true\" />\n        ) : (\n          <EyeIcon size={16} aria-hidden=\"true\" />\n        )}\n      </button>\n    </div>\n  );\n}\n"}]},{"name":"file-upload","title":"File Upload","description":"Drag and drop file upload with preview.","type":"registry:ui","docs":"/components/file-upload","categories":["forms","data-entry"],"registryDependencies":["https://pb-ui-five.vercel.app/registry/button","https://pb-ui-five.vercel.app/registry/input","https://pb-ui-five.vercel.app/registry/label"],"files":[{"path":"components/ui/file-upload.tsx","target":"components/ui/file-upload.tsx","type":"registry:ui","content":"\"use client\";\n\nimport { Button } from \"@/components/ui/button\";\nimport { Input } from \"@/components/ui/input\";\nimport { cn } from \"@/lib/utils\";\nimport { FileText, Loader2, Trash2, Upload, X } from \"lucide-react\";\nimport { useCallback, useRef, useState } from \"react\";\nimport { Label } from \"./label\";\n\nexport interface FileUploadProps {\n  /** Current file URL (for edit mode) */\n  currentFileUrl?: string | null;\n  /** Callback when a file is selected */\n  onFileSelect: (file: File | null) => void;\n  /** Callback when user wants to remove existing file */\n  onRemoveExisting?: () => void;\n  /** Whether the upload is in progress */\n  isUploading?: boolean;\n  /** Optional error message */\n  error?: string;\n  /** Label for the field */\n  label?: string;\n  /** Description for the field */\n  description?: string;\n  /** Whether the field is disabled */\n  disabled?: boolean;\n  /** Whether the field is required */\n  required?: boolean;\n  showError?: boolean;\n  className?: string;\n  validateFile?: (file: File) => {\n    valid: boolean;\n    error?: string | undefined;\n  };\n  clickToUploadText?: string;\n  orDragAndDropText?: string;\n  fileTypesText?: string;\n  invalidFileErrorText?: string;\n  uploadingText?: string;\n  viewCurrentFileText?: string;\n  replaceText?: string;\n}\n\nexport function FileUpload({\n  currentFileUrl,\n  onFileSelect,\n  onRemoveExisting,\n  isUploading = false,\n  error,\n  label = \"File Upload\",\n  description = \"Upload your file here.\",\n  disabled = false,\n  required = false,\n  className,\n  validateFile,\n  clickToUploadText = \"Click to upload\",\n  orDragAndDropText = \"or drag and drop\",\n  fileTypesText = \"PDF, DOC, DOCX (max 10MB)\",\n  invalidFileErrorText = \"Invalid file\",\n  uploadingText = \"Uploading...\",\n  viewCurrentFileText = \"View current file\",\n  replaceText = \"Replace\",\n  showError = true,\n}: FileUploadProps) {\n  const [selectedFile, setSelectedFile] = useState<File | null>(null);\n  const [isDragging, setIsDragging] = useState(false);\n  const [validationError, setValidationError] = useState<string | null>(null);\n  const inputRef = useRef<HTMLInputElement>(null);\n\n  const handleFileChange = useCallback(\n    (file: File | null) => {\n      if (validateFile && file) {\n        const validation = validateFile(file);\n        if (!validation.valid) {\n          setValidationError(validation.error || invalidFileErrorText);\n          return;\n        }\n      }\n      setValidationError(null);\n      setSelectedFile(file);\n      onFileSelect(file);\n    },\n    [onFileSelect, validateFile, invalidFileErrorText],\n  );\n\n  const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n    const file = e.target.files?.[0] || null;\n    handleFileChange(file);\n  };\n\n  const handleDrop = useCallback(\n    (e: React.DragEvent) => {\n      e.preventDefault();\n      setIsDragging(false);\n\n      if (disabled || isUploading) return;\n\n      const file = e.dataTransfer.files?.[0] || null;\n      handleFileChange(file);\n    },\n    [disabled, isUploading, handleFileChange],\n  );\n\n  const handleDragOver = (e: React.DragEvent) => {\n    e.preventDefault();\n    if (!disabled && !isUploading) {\n      setIsDragging(true);\n    }\n  };\n\n  const handleDragLeave = (e: React.DragEvent) => {\n    e.preventDefault();\n    setIsDragging(false);\n  };\n\n  const handleRemoveSelected = () => {\n    setSelectedFile(null);\n    setValidationError(null);\n    onFileSelect(null);\n    if (inputRef.current) {\n      inputRef.current.value = \"\";\n    }\n  };\n\n  const handleRemoveExisting = () => {\n    onRemoveExisting?.();\n    handleRemoveSelected();\n  };\n\n  const handleClick = () => {\n    if (!disabled && !isUploading) {\n      inputRef.current?.click();\n    }\n  };\n\n  const displayError = validationError || error;\n  const hasExistingFile = currentFileUrl && !selectedFile;\n  const hasSelectedFile = selectedFile !== null;\n\n  // Extract filename from URL for display\n  const existingFileName = currentFileUrl\n    ? decodeURIComponent(currentFileUrl.split(\"/\").pop() || \"curriculum\")\n    : null;\n\n  return (\n    <div className={cn(\"space-y-4\", className)}>\n      {label && (\n        <Label>\n          {label}\n          {required && (\n            <span aria-hidden className=\"ps-1 text-destructive\">\n              *\n            </span>\n          )}\n        </Label>\n      )}\n      <div\n        className={cn(\n          \"bg-muted/50 shadow-sm border-2 border-transparent border-dashed rounded-lg transition-all\",\n          isDragging && \"border-primary bg-primary/5\",\n          displayError && \"border-destructive\",\n          disabled && \"opacity-50 cursor-not-allowed\",\n          !disabled &&\n            !isUploading &&\n            \"cursor-pointer hover:bg-muted/80 hover:border-ring/30\",\n        )}\n        onDrop={handleDrop}\n        onDragOver={handleDragOver}\n        onDragLeave={handleDragLeave}\n        onClick={handleClick}\n      >\n        <Input\n          ref={inputRef}\n          type=\"file\"\n          accept=\".pdf,.doc,.docx,application/pdf,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document\"\n          onChange={handleInputChange}\n          disabled={disabled || isUploading}\n          className=\"hidden\"\n        />\n\n        {isUploading ? (\n          <div className=\"flex flex-col justify-center items-center py-4\">\n            <Loader2 className=\"mb-2 w-8 h-8 text-primary animate-spin\" />\n            <p className=\"text-muted-foreground text-sm\">{uploadingText}</p>\n          </div>\n        ) : hasSelectedFile ? (\n          <div className=\"flex justify-between items-center\">\n            <div className=\"flex items-center gap-3\">\n              <FileText className=\"w-8 h-8 text-primary\" />\n              <div>\n                <p className=\"font-medium text-sm\">{selectedFile.name}</p>\n                <p className=\"text-muted-foreground text-xs\">\n                  {(selectedFile.size / 1024 / 1024).toFixed(2)} MB\n                </p>\n              </div>\n            </div>\n            <Button\n              type=\"button\"\n              variant=\"ghost\"\n              size=\"sm\"\n              onClick={(e) => {\n                e.stopPropagation();\n                handleRemoveSelected();\n              }}\n              disabled={disabled}\n            >\n              <X className=\"size-4\" />\n            </Button>\n          </div>\n        ) : hasExistingFile ? (\n          <div className=\"flex justify-between items-center\">\n            <div className=\"flex items-center gap-3\">\n              <FileText className=\"w-8 h-8 text-primary\" />\n              <div>\n                <p className=\"font-medium text-sm\">{existingFileName}</p>\n                <a\n                  href={currentFileUrl}\n                  target=\"_blank\"\n                  rel=\"noopener noreferrer\"\n                  className=\"text-primary text-xs hover:underline\"\n                  onClick={(e) => e.stopPropagation()}\n                >\n                  {viewCurrentFileText}\n                </a>\n              </div>\n            </div>\n            <div className=\"flex gap-2\">\n              <Button\n                type=\"button\"\n                variant=\"outline\"\n                size=\"sm\"\n                onClick={(e) => {\n                  e.stopPropagation();\n                  handleClick();\n                }}\n                disabled={disabled}\n              >\n                <Upload className=\"mr-1 size-4\" />\n                {replaceText}\n              </Button>\n              {onRemoveExisting && (\n                <Button\n                  type=\"button\"\n                  variant=\"ghost\"\n                  size=\"sm\"\n                  onClick={(e) => {\n                    e.stopPropagation();\n                    handleRemoveExisting();\n                  }}\n                  disabled={disabled}\n                  className=\"text-destructive hover:text-destructive\"\n                >\n                  <Trash2 className=\"size-4\" />\n                </Button>\n              )}\n            </div>\n          </div>\n        ) : (\n          <div className=\"flex flex-col justify-center items-center py-4\">\n            <Upload className=\"mb-2 w-8 h-8 text-muted-foreground\" />\n            <p className=\"text-muted-foreground text-sm text-center\">\n              <span className=\"font-medium text-primary\">\n                {clickToUploadText}\n              </span>{\" \"}\n              {orDragAndDropText}\n            </p>\n            <p className=\"mt-1 text-muted-foreground text-xs\">\n              {fileTypesText}\n            </p>\n          </div>\n        )}\n      </div>\n\n      {description && !displayError && (\n        <p className=\"text-muted-foreground text-sm\">{description}</p>\n      )}\n\n      {showError && displayError && (\n        <p className=\"text-destructive text-sm\">{displayError}</p>\n      )}\n    </div>\n  );\n}\n"}]},{"name":"multi-select","title":"Multi Select","description":"Select multiple options with grouped support.","type":"registry:ui","docs":"/components/multi-select","categories":["forms"],"registryDependencies":["https://pb-ui-five.vercel.app/registry/combobox"],"files":[{"path":"components/ui/multi-select.tsx","target":"components/ui/multi-select.tsx","type":"registry:ui","content":"\"use client\";\n\nimport {\n  Combobox,\n  ComboboxChip,\n  ComboboxChips,\n  ComboboxChipsInput,\n  ComboboxClear,\n  ComboboxContent,\n  ComboboxEmpty,\n  ComboboxGroup,\n  ComboboxItem,\n  ComboboxLabel,\n  ComboboxList,\n  ComboboxSeparator,\n  ComboboxValue,\n  useComboboxAnchor,\n} from \"@/components/ui/combobox\";\nimport { cn } from \"@/lib/utils\";\nimport * as React from \"react\";\n\nexport type OptionType = {\n  label: string;\n  value: string;\n  category?: string;\n};\n\ninterface MultiSelectProps {\n  options: OptionType[];\n  selected: string[];\n  onChange: (selected: string[]) => void;\n  placeholder?: string;\n  className?: string;\n  grouped?: boolean;\n  invalid?: boolean;\n  disabled?: boolean;\n  showClear?: boolean;\n}\n\nexport function MultiSelect({\n  options,\n  selected,\n  onChange,\n  placeholder = \"Select options...\",\n  className,\n  grouped = false,\n  invalid = false,\n  disabled = false,\n  showClear = false,\n}: MultiSelectProps) {\n  const anchor = useComboboxAnchor();\n\n  const groupedOptions = React.useMemo(() => {\n    if (!grouped) return null;\n\n    return options.reduce<Record<string, OptionType[]>>((acc, option) => {\n      const category = option.category || \"Other\";\n      if (!acc[category]) {\n        acc[category] = [];\n      }\n      acc[category].push(option);\n      return acc;\n    }, {});\n  }, [options, grouped]);\n\n  const categories = groupedOptions ? Object.keys(groupedOptions) : [];\n\n  // Convert string[] selected to OptionType[] for Combobox\n  const selectedOptions = React.useMemo(\n    () => options.filter((o) => selected.includes(o.value)),\n    [options, selected],\n  );\n\n  // Handle value change from Combobox (converts OptionType[] back to string[])\n  const handleValueChange = React.useCallback(\n    (newValue: OptionType[]) => {\n      onChange(newValue.map((item) => item.value));\n    },\n    [onChange],\n  );\n\n  return (\n    <Combobox\n      items={options}\n      itemToStringValue={(item) => item.label}\n      multiple\n      value={selectedOptions}\n      onValueChange={handleValueChange}\n      disabled={disabled}\n    >\n      <ComboboxChips\n        ref={anchor}\n        aria-invalid={invalid}\n        className={cn(\"w-full\", className)}\n      >\n        <ComboboxValue>\n          {selectedOptions.map((option) => (\n            <ComboboxChip key={option.value}>{option.label}</ComboboxChip>\n          ))}\n        </ComboboxValue>\n        <ComboboxChipsInput placeholder={placeholder} />\n        {showClear && selected.length > 0 && (\n          <ComboboxClear disabled={disabled} className=\"ms-auto\" />\n        )}\n      </ComboboxChips>\n      <ComboboxContent anchor={anchor}>\n        <ComboboxEmpty>No results found.</ComboboxEmpty>\n        <ComboboxList>\n          {grouped && groupedOptions\n            ? categories.map((category, index) => (\n                <React.Fragment key={category}>\n                  <ComboboxGroup>\n                    <ComboboxLabel>{category}</ComboboxLabel>\n                    {groupedOptions[category].map((option) => (\n                      <ComboboxItem key={option.value} value={option}>\n                        {option.label}\n                      </ComboboxItem>\n                    ))}\n                  </ComboboxGroup>\n                  {index < categories.length - 1 && <ComboboxSeparator />}\n                </React.Fragment>\n              ))\n            : (item) => (\n                <ComboboxItem key={item.value} value={item}>\n                  {item.label}\n                </ComboboxItem>\n              )}\n        </ComboboxList>\n      </ComboboxContent>\n    </Combobox>\n  );\n}\n"}]},{"name":"tabs","title":"Tabs","description":"Tabbed interface for organized content.","type":"registry:ui","docs":"/components/tabs","categories":["navigation","layout"],"files":[{"path":"components/ui/tabs.tsx","target":"components/ui/tabs.tsx","type":"registry:ui","content":"\"use client\"\n\nimport { Tabs as TabsPrimitive } from \"@base-ui/react/tabs\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\n\nfunction Tabs({\n  className,\n  orientation = \"horizontal\",\n  ...props\n}: TabsPrimitive.Root.Props) {\n  return (\n    <TabsPrimitive.Root\n      data-slot=\"tabs\"\n      data-orientation={orientation}\n      className={cn(\n        \"group/tabs flex gap-2 data-horizontal:flex-col\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nconst tabsListVariants = cva(\n  \"group/tabs-list inline-flex w-fit items-center justify-center rounded-lg p-[3px] text-muted-foreground group-data-horizontal/tabs:h-9 group-data-vertical/tabs:h-fit group-data-vertical/tabs:flex-col data-[variant=line]:rounded-none\",\n  {\n    variants: {\n      variant: {\n        default: \"bg-muted\",\n        line: \"gap-1 bg-transparent\",\n      },\n    },\n    defaultVariants: {\n      variant: \"default\",\n    },\n  }\n)\n\nfunction TabsList({\n  className,\n  variant = \"default\",\n  ...props\n}: TabsPrimitive.List.Props & VariantProps<typeof tabsListVariants>) {\n  return (\n    <TabsPrimitive.List\n      data-slot=\"tabs-list\"\n      data-variant={variant}\n      className={cn(tabsListVariants({ variant }), className)}\n      {...props}\n    />\n  )\n}\n\nfunction TabsTrigger({ className, ...props }: TabsPrimitive.Tab.Props) {\n  return (\n    <TabsPrimitive.Tab\n      data-slot=\"tabs-trigger\"\n      className={cn(\n        \"relative inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 rounded-md border border-transparent px-2 py-1 text-sm font-medium whitespace-nowrap text-foreground/60 transition-all group-data-vertical/tabs:w-full group-data-vertical/tabs:justify-start hover:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:outline-1 focus-visible:outline-ring disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 dark:text-muted-foreground dark:hover:text-foreground group-data-[variant=default]/tabs-list:data-active:shadow-sm group-data-[variant=line]/tabs-list:data-active:shadow-none [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        \"group-data-[variant=line]/tabs-list:bg-transparent group-data-[variant=line]/tabs-list:data-active:bg-transparent dark:group-data-[variant=line]/tabs-list:data-active:border-transparent dark:group-data-[variant=line]/tabs-list:data-active:bg-transparent\",\n        \"data-active:bg-background data-active:text-foreground dark:data-active:border-input dark:data-active:bg-input/30 dark:data-active:text-foreground\",\n        \"after:absolute after:bg-foreground after:opacity-0 after:transition-opacity group-data-horizontal/tabs:after:inset-x-0 group-data-horizontal/tabs:after:bottom-[-5px] group-data-horizontal/tabs:after:h-0.5 group-data-vertical/tabs:after:inset-y-0 group-data-vertical/tabs:after:-right-1 group-data-vertical/tabs:after:w-0.5 group-data-[variant=line]/tabs-list:data-active:after:opacity-100\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction TabsContent({ className, ...props }: TabsPrimitive.Panel.Props) {\n  return (\n    <TabsPrimitive.Panel\n      data-slot=\"tabs-content\"\n      className={cn(\"flex-1 text-sm outline-none\", className)}\n      {...props}\n    />\n  )\n}\n\nexport { Tabs, TabsList, TabsTrigger, TabsContent, tabsListVariants }\n"}]},{"name":"rhf-base-controller","title":"RHF Base Controller","description":"Base controller wrapper for React Hook Form fields.","type":"registry:ui","docs":"/components/rhf-base-controller","categories":["forms"],"registryDependencies":["https://pb-ui-five.vercel.app/registry/field"],"dependencies":["react-hook-form"],"files":[{"path":"components/ui/rhf-inputs/base-controller.tsx","target":"components/ui/rhf-inputs/base-controller.tsx","type":"registry:ui","content":"\"use client\";\n\nimport { ReactNode } from \"react\";\nimport {\n  Control,\n  Controller,\n  ControllerFieldState,\n  ControllerRenderProps,\n  FieldPath,\n  FieldValues,\n  UseFormStateReturn,\n} from \"react-hook-form\";\nimport {\n  Field,\n  FieldContent,\n  FieldDescription,\n  FieldError,\n  FieldLabel,\n} from \"../field\";\n\ntype ControllerRenderParams<T extends FieldValues> = {\n  field: ControllerRenderProps<T, FieldPath<T>>;\n  fieldState: ControllerFieldState;\n  formState: UseFormStateReturn<T>;\n  ariaDescribedBy: string | undefined;\n};\n\nexport type BaseControllerProps<T extends FieldValues> = {\n  control: Control<T>;\n  name: FieldPath<T>;\n  label?: string;\n  description?: string | ReactNode;\n  disableFieldError?: boolean;\n  required?: boolean;\n  orientation?: \"vertical\" | \"horizontal\";\n  layout?: \"standard\" | \"inline\";\n  containerClassName?: string;\n  children: (params: ControllerRenderParams<T>) => ReactNode;\n};\n\nexport function BaseController<T extends FieldValues>({\n  control,\n  name,\n  label,\n  description,\n  disableFieldError = false,\n  required = false,\n  orientation = \"vertical\",\n  layout = \"standard\",\n  containerClassName,\n  children,\n}: BaseControllerProps<T>) {\n  const isInline = layout === \"inline\";\n\n  return (\n    <Controller\n      name={name}\n      control={control}\n      rules={{ required }}\n      render={({ field, fieldState, formState }) => {\n        const ariaDescribedBy =\n          [\n            description ? `${field.name}-description` : undefined,\n            fieldState.error ? `${field.name}-error` : undefined,\n          ]\n            .filter(Boolean)\n            .join(\" \") || undefined;\n\n        const labelContent = label && (\n          <FieldLabel\n            htmlFor={field.name}\n            className={isInline ? undefined : \"font-bold\"}\n          >\n            {label}\n            {required && (\n              <span aria-hidden className=\"ps-1 text-destructive\">\n                *\n              </span>\n            )}\n          </FieldLabel>\n        );\n\n        const descriptionContent = description && (\n          <FieldDescription id={`${field.name}-description`}>\n            {description}\n          </FieldDescription>\n        );\n\n        const errorContent = !disableFieldError && fieldState.invalid && (\n          <FieldError id={`${field.name}-error`} errors={[fieldState.error]} />\n        );\n\n        return (\n          <Field\n            data-invalid={fieldState.invalid}\n            orientation={orientation}\n            className={containerClassName}\n          >\n            {isInline ? (\n              <FieldContent className=\"gap-1\">\n                <div className=\"flex items-center gap-3\">\n                  {children({ field, fieldState, formState, ariaDescribedBy })}\n                  <div className=\"space-y-1 leading-none\">\n                    {labelContent}\n                    {descriptionContent}\n                  </div>\n                </div>\n                {errorContent}\n              </FieldContent>\n            ) : (\n              <>\n                {labelContent}\n                <FieldContent className=\"gap-1\">\n                  {children({ field, fieldState, formState, ariaDescribedBy })}\n                  {descriptionContent}\n                  {errorContent}\n                </FieldContent>\n              </>\n            )}\n          </Field>\n        );\n      }}\n    />\n  );\n}\n"}]},{"name":"rhf-input-field","title":"RHF Input Field","description":"Text input field with React Hook Form integration.","type":"registry:ui","docs":"/components/rhf-input-field","categories":["forms"],"registryDependencies":["https://pb-ui-five.vercel.app/registry/rhf-base-controller","https://pb-ui-five.vercel.app/registry/input"],"dependencies":["react-hook-form"],"files":[{"path":"components/ui/rhf-inputs/input-field.tsx","target":"components/ui/rhf-inputs/input-field.tsx","type":"registry:ui","content":"\"use client\";\n\nimport { InputHTMLAttributes } from \"react\";\nimport { FieldValues } from \"react-hook-form\";\nimport { Input } from \"../input\";\nimport { BaseController, BaseControllerProps } from \"./base-controller\";\n\ntype FieldInputProps<T extends FieldValues> = Omit<\n  InputHTMLAttributes<HTMLInputElement>,\n  \"name\" | \"id\"\n> & {\n  maxLength?: number;\n} & Omit<BaseControllerProps<T>, \"children\">;\n\nexport function InputField<T extends FieldValues>({\n  control,\n  name,\n  label,\n  description,\n  maxLength,\n  disableFieldError = false,\n  required,\n  ...inputProps\n}: FieldInputProps<T>) {\n  return (\n    <BaseController\n      control={control}\n      name={name}\n      label={label}\n      required={required}\n      description={description}\n      disableFieldError={disableFieldError}\n    >\n      {({ field, fieldState, ariaDescribedBy }) => (\n        <div className=\"relative\">\n          <Input\n            id={field.name}\n            aria-invalid={!!fieldState.error}\n            aria-required={required}\n            aria-describedby={ariaDescribedBy}\n            {...field}\n            value={field.value ?? \"\"}\n            {...inputProps}\n            className={`${maxLength ? \"pr-16\" : \"\"} ${\n              inputProps.className || \"\"\n            }`}\n          />\n          {maxLength && (\n            <div className=\"top-1/2 right-3 absolute text-muted-foreground text-xs -translate-y-1/2 pointer-events-none\">\n              {(field.value || \"\").length}/{maxLength}\n            </div>\n          )}\n        </div>\n      )}\n    </BaseController>\n  );\n}\n"}]},{"name":"rhf-checkbox-field","title":"RHF Checkbox Field","description":"Checkbox field with React Hook Form integration.","type":"registry:ui","docs":"/components/rhf-checkbox-field","categories":["forms"],"registryDependencies":["https://pb-ui-five.vercel.app/registry/rhf-base-controller","https://pb-ui-five.vercel.app/registry/checkbox"],"dependencies":["react-hook-form"],"files":[{"path":"components/ui/rhf-inputs/checkbox-field.tsx","target":"components/ui/rhf-inputs/checkbox-field.tsx","type":"registry:ui","content":"\"use client\";\n\nimport { FieldValues } from \"react-hook-form\";\nimport { Checkbox } from \"../checkbox\";\nimport { BaseController, BaseControllerProps } from \"./base-controller\";\n\ntype FieldCheckboxProps<T extends FieldValues> = Omit<\n  React.ComponentProps<typeof Checkbox>,\n  \"checked\" | \"onCheckedChange\" | \"id\"\n> &\n  Omit<BaseControllerProps<T>, \"children\" | \"layout\"> & {\n    orientation?: \"vertical\" | \"horizontal\";\n  };\n\nexport function CheckboxField<T extends FieldValues>({\n  control,\n  name,\n  label,\n  description,\n  disableFieldError = false,\n  orientation = \"horizontal\",\n  required,\n  ...checkboxProps\n}: FieldCheckboxProps<T>) {\n  return (\n    <BaseController\n      control={control}\n      name={name}\n      label={label}\n      description={description}\n      disableFieldError={disableFieldError}\n      required={required}\n      layout=\"inline\"\n      orientation={orientation}\n    >\n      {({ field, ariaDescribedBy }) => (\n        <Checkbox\n          id={field.name}\n          checked={field.value}\n          onCheckedChange={field.onChange}\n          aria-describedby={ariaDescribedBy}\n          {...checkboxProps}\n        />\n      )}\n    </BaseController>\n  );\n}\n"}]},{"name":"rhf-select-field","title":"RHF Select Field","description":"Select field with React Hook Form integration.","type":"registry:ui","docs":"/components/rhf-select-field","categories":["forms"],"registryDependencies":["https://pb-ui-five.vercel.app/registry/rhf-base-controller","https://pb-ui-five.vercel.app/registry/select"],"dependencies":["react-hook-form"],"files":[{"path":"components/ui/rhf-inputs/select-field.tsx","target":"components/ui/rhf-inputs/select-field.tsx","type":"registry:ui","content":"import { ReactNode, RefAttributes } from \"react\";\nimport { FieldValues } from \"react-hook-form\";\nimport {\n  Select,\n  SelectContent,\n  SelectItem,\n  SelectTrigger,\n  SelectValue,\n} from \"../select\";\nimport { BaseController, BaseControllerProps } from \"./base-controller\";\n\nconst EMPTY_SELECT_VALUE = \"\";\n\ntype SelectOption = {\n  value: string;\n  label: string;\n  leading?: ReactNode;\n};\n\ntype FieldSelectProps<T extends FieldValues> = {\n  placeholder?: string;\n  onValueChange?: (value: string | null) => void;\n  selectProps?: React.ComponentProps<typeof Select>;\n  triggerProps?: React.ComponentProps<typeof SelectTrigger> &\n    RefAttributes<HTMLButtonElement> & {\n      size?: \"sm\" | \"default\";\n    };\n} & Omit<BaseControllerProps<T>, \"children\"> &\n  (\n    | {\n        options: SelectOption[];\n        children?: never;\n      }\n    | {\n        options?: never;\n        children: ReactNode;\n      }\n  );\n\nexport function SelectField<T extends FieldValues>({\n  control,\n  name,\n  label,\n  description,\n  disableFieldError = false,\n  options,\n  placeholder,\n  onValueChange,\n  triggerProps,\n  children,\n  required,\n  ...selectProps\n}: FieldSelectProps<T>) {\n  return (\n    <BaseController\n      control={control}\n      name={name}\n      label={label}\n      required={required}\n      description={description}\n      disableFieldError={disableFieldError}\n    >\n      {({ field, fieldState, ariaDescribedBy }) => {\n        return (\n          <Select\n            value={field.value ?? EMPTY_SELECT_VALUE}\n            onValueChange={(value) => {\n              field.onChange(value);\n              onValueChange?.(value);\n            }}\n            {...selectProps}\n          >\n            <SelectTrigger\n              id={field.name}\n              aria-required={required}\n              aria-invalid={!!fieldState.error}\n              aria-describedby={ariaDescribedBy}\n              data-invalid={!!fieldState.error}\n              {...triggerProps}\n            >\n              {placeholder &&\n              (field.value === EMPTY_SELECT_VALUE ||\n                field.value === undefined ||\n                field.value === null) ? (\n                <SelectValue>{placeholder}</SelectValue>\n              ) : (\n                <SelectValue />\n              )}\n            </SelectTrigger>\n            <SelectContent>\n              {placeholder && (\n                <SelectItem value={null} key=\"placeholder\">\n                  {placeholder}\n                </SelectItem>\n              )}\n              {options\n                ? options.map((option) => {\n                    return (\n                      <SelectItem key={option.value} value={option.value}>\n                        {option.leading ? (\n                          <span className=\"flex items-center gap-2\">\n                            {option.leading}\n                            <span>{option.label}</span>\n                          </span>\n                        ) : (\n                          option.label\n                        )}\n                      </SelectItem>\n                    );\n                  })\n                : children}\n            </SelectContent>\n          </Select>\n        );\n      }}\n    </BaseController>\n  );\n}\n"}]},{"name":"rhf-textarea-field","title":"RHF Textarea Field","description":"Textarea field with React Hook Form integration.","type":"registry:ui","docs":"/components/rhf-textarea-field","categories":["forms"],"registryDependencies":["https://pb-ui-five.vercel.app/registry/rhf-base-controller","https://pb-ui-five.vercel.app/registry/textarea"],"dependencies":["react-hook-form"],"files":[{"path":"components/ui/rhf-inputs/textarea-field.tsx","target":"components/ui/rhf-inputs/textarea-field.tsx","type":"registry:ui","content":"import { FieldValues } from \"react-hook-form\";\nimport { Textarea } from \"../textarea\";\nimport { BaseController, BaseControllerProps } from \"./base-controller\";\n\ntype FieldTextareaProps<T extends FieldValues> = Omit<\n  React.TextareaHTMLAttributes<HTMLTextAreaElement>,\n  \"name\" | \"id\"\n> & {\n  maxLength?: number;\n} & Omit<BaseControllerProps<T>, \"children\">;\n\nexport function TextareaField<T extends FieldValues>({\n  control,\n  name,\n  label,\n  description,\n  maxLength,\n  disableFieldError = false,\n  required,\n  ...textareaProps\n}: FieldTextareaProps<T> & { required?: boolean }) {\n  return (\n    <BaseController\n      control={control}\n      name={name}\n      label={label}\n      required={required}\n      description={description}\n      disableFieldError={disableFieldError}\n    >\n      {({ field, fieldState, ariaDescribedBy }) => (\n        <div className=\"relative\">\n          <Textarea\n            id={field.name}\n            aria-required={required}\n            {...field}\n            {...textareaProps}\n            aria-invalid={!!fieldState.error}\n            aria-describedby={ariaDescribedBy}\n            className={`${maxLength ? \"pr-16\" : \"\"} ${\n              textareaProps.className || \"\"\n            }`}\n          />\n          {maxLength && (\n            <div className=\"top-3 right-3 absolute bg-background/80 px-1 rounded text-muted-foreground text-xs pointer-events-none\">\n              {(field.value || \"\").length}/{maxLength}\n            </div>\n          )}\n        </div>\n      )}\n    </BaseController>\n  );\n}\n"}]},{"name":"rhf-radio-group-field","title":"RHF Radio Group Field","description":"Radio group field with React Hook Form integration.","type":"registry:ui","docs":"/components/rhf-radio-group-field","categories":["forms"],"registryDependencies":["https://pb-ui-five.vercel.app/registry/rhf-base-controller","https://pb-ui-five.vercel.app/registry/radio-group","https://pb-ui-five.vercel.app/registry/label"],"dependencies":["react-hook-form"],"files":[{"path":"components/ui/rhf-inputs/radio-group-field.tsx","target":"components/ui/rhf-inputs/radio-group-field.tsx","type":"registry:ui","content":"import { FieldValues } from \"react-hook-form\";\nimport { Label } from \"../label\";\nimport { RadioGroup, RadioGroupItem } from \"../radio-group\";\nimport { BaseController, BaseControllerProps } from \"./base-controller\";\n\ntype RadioOption = {\n  value: string;\n  label: string;\n  disabled?: boolean;\n};\n\ntype FieldRadioGroupProps<T extends FieldValues> = Omit<\n  React.ComponentProps<typeof RadioGroup>,\n  \"value\" | \"onValueChange\"\n> &\n  Omit<BaseControllerProps<T>, \"children\"> & {\n    options: RadioOption[];\n  };\n\nexport function RadioGroupField<T extends FieldValues>({\n  control,\n  name,\n  label,\n  description,\n  disableFieldError = false,\n  options,\n  required,\n  ...radioGroupProps\n}: FieldRadioGroupProps<T>) {\n  return (\n    <BaseController\n      control={control}\n      name={name}\n      label={label}\n      required={required}\n      description={description}\n      disableFieldError={disableFieldError}\n    >\n      {({ field, fieldState, ariaDescribedBy }) => (\n        <RadioGroup\n          id={field.name}\n          value={field.value}\n          onValueChange={field.onChange}\n          aria-invalid={!!fieldState.error}\n          aria-describedby={ariaDescribedBy}\n          {...radioGroupProps}\n        >\n          {options.map((option) => (\n            <div key={option.value} className=\"flex items-center space-x-2\">\n              <RadioGroupItem\n                value={option.value}\n                id={`${field.name}-${option.value}`}\n                disabled={option.disabled}\n              />\n              <Label\n                htmlFor={`${field.name}-${option.value}`}\n                className=\"cursor-pointer\"\n              >\n                {option.label}\n              </Label>\n            </div>\n          ))}\n        </RadioGroup>\n      )}\n    </BaseController>\n  );\n}\n"}]},{"name":"rhf-slider-field","title":"RHF Slider Field","description":"Slider field with React Hook Form integration.","type":"registry:ui","docs":"/components/rhf-slider-field","categories":["forms"],"registryDependencies":["https://pb-ui-five.vercel.app/registry/rhf-base-controller","https://pb-ui-five.vercel.app/registry/slider"],"dependencies":["react-hook-form"],"files":[{"path":"components/ui/rhf-inputs/slider-field.tsx","target":"components/ui/rhf-inputs/slider-field.tsx","type":"registry:ui","content":"import { FieldValues } from \"react-hook-form\";\nimport { Slider } from \"../slider\";\nimport { BaseController, BaseControllerProps } from \"./base-controller\";\n\ntype FieldSliderProps<T extends FieldValues> = Omit<\n  React.ComponentProps<typeof Slider>,\n  \"value\" | \"onValueChange\"\n> &\n  Omit<BaseControllerProps<T>, \"children\"> & {\n    showValue?: boolean;\n    valueFormatter?: (value: number) => string;\n  };\n\nexport function SliderField<T extends FieldValues>({\n  control,\n  name,\n  label,\n  description,\n  disableFieldError = false,\n  showValue = false,\n  valueFormatter,\n  required,\n  ...sliderProps\n}: FieldSliderProps<T>) {\n  return (\n    <BaseController\n      control={control}\n      name={name}\n      label={label}\n      required={required}\n      description={description}\n      disableFieldError={disableFieldError}\n    >\n      {({ field, fieldState, ariaDescribedBy }) => {\n        // Base UI Slider requires a valid number array.\n        // Fallback to min (or 0) when field value is undefined.\n        const min = sliderProps.min ?? 0;\n        const sliderValue = field.value ?? min;\n\n        return (\n          <div className=\"space-y-2\">\n            <Slider\n              id={field.name}\n              {...sliderProps}\n              value={[sliderValue]}\n              onValueChange={(newValue) => {\n                // Base UI can return number or number[] depending on how it's set\n                const actualValue = Array.isArray(newValue)\n                  ? newValue[0]\n                  : newValue;\n                field.onChange(actualValue);\n              }}\n              aria-invalid={!!fieldState.error}\n              aria-describedby={ariaDescribedBy}\n            />\n            {showValue && (\n              <div className=\"text-muted-foreground text-sm text-center\">\n                {valueFormatter ? valueFormatter(sliderValue) : sliderValue}\n              </div>\n            )}\n          </div>\n        );\n      }}\n    </BaseController>\n  );\n}\n"}]},{"name":"rhf-switch-field","title":"RHF Switch Field","description":"Switch field with React Hook Form integration.","type":"registry:ui","docs":"/components/rhf-switch-field","categories":["forms"],"registryDependencies":["https://pb-ui-five.vercel.app/registry/field","https://pb-ui-five.vercel.app/registry/switch"],"dependencies":["react-hook-form"],"files":[{"path":"components/ui/rhf-inputs/switch-field.tsx","target":"components/ui/rhf-inputs/switch-field.tsx","type":"registry:ui","content":"\"use client\";\n\nimport { Control, Controller, FieldPath, FieldValues } from \"react-hook-form\";\nimport {\n  Field,\n  FieldContent,\n  FieldDescription,\n  FieldError,\n  FieldLabel,\n} from \"../field\";\nimport { Switch } from \"../switch\";\n\ntype FieldSwitchProps<T extends FieldValues> = Omit<\n  React.ComponentProps<typeof Switch>,\n  \"checked\" | \"onCheckedChange\"\n> & {\n  control: Control<T>;\n  name: FieldPath<T>;\n  label?: string;\n  description?: string;\n  disableFieldError?: boolean;\n  required?: boolean;\n};\n\nexport function SwitchField<T extends FieldValues>({\n  control,\n  name,\n  label,\n  description,\n  disableFieldError = false,\n  required,\n  ...switchProps\n}: FieldSwitchProps<T>) {\n  return (\n    <Controller\n      control={control}\n      name={name}\n      render={({ field, fieldState }) => (\n        <Field\n          className=\"flex flex-row justify-between items-center p-3 border rounded-lg\"\n          orientation=\"horizontal\"\n        >\n          <div className=\"space-y-0.5\">\n            {label && (\n              <FieldLabel className=\"text-base\">\n                {label}\n                {required && (\n                  <span aria-hidden className=\"ps-1 text-destructive\">\n                    *\n                  </span>\n                )}\n              </FieldLabel>\n            )}\n            {description && <FieldDescription id={`${field.name}-description`}>{description}</FieldDescription>}\n          </div>\n          <FieldContent className=\"flex justify-end items-end\">\n            <Switch\n              checked={field.value}\n              onCheckedChange={field.onChange}\n              {...switchProps}\n            />\n          </FieldContent>\n          {!disableFieldError && fieldState.invalid && (\n            <FieldError id={`${field.name}-error`} errors={[fieldState.error]} />\n          )}\n        </Field>\n      )}\n    />\n  );\n}\n"}]},{"name":"rhf-password-field","title":"RHF Password Field","description":"Password input field with React Hook Form integration.","type":"registry:ui","docs":"/components/rhf-password-field","categories":["forms"],"registryDependencies":["https://pb-ui-five.vercel.app/registry/rhf-base-controller","https://pb-ui-five.vercel.app/registry/password-input"],"dependencies":["react-hook-form"],"files":[{"path":"components/ui/rhf-inputs/password-field.tsx","target":"components/ui/rhf-inputs/password-field.tsx","type":"registry:ui","content":"\"use client\";\n\nimport { InputHTMLAttributes } from \"react\";\nimport { FieldValues } from \"react-hook-form\";\nimport PasswordInput from \"../password-input\";\nimport { BaseController, BaseControllerProps } from \"./base-controller\";\n\ntype FieldInputProps<T extends FieldValues> = Omit<\n  InputHTMLAttributes<HTMLInputElement>,\n  \"name\" | \"id\"\n> &\n  Omit<BaseControllerProps<T>, \"children\">;\n\nexport function PasswordField<T extends FieldValues>({\n  control,\n  name,\n  label,\n  description,\n  disableFieldError = false,\n  required,\n  ...inputProps\n}: FieldInputProps<T>) {\n  return (\n    <BaseController\n      control={control}\n      name={name}\n      label={label}\n      required={required}\n      description={description}\n      disableFieldError={disableFieldError}\n    >\n      {({ field, fieldState, ariaDescribedBy }) => (\n        <PasswordInput\n          id={field.name}\n          aria-invalid={!!fieldState.error}\n          aria-required={required}\n          aria-describedby={ariaDescribedBy}\n          {...field}\n          {...inputProps}\n          className={`${inputProps.className || \"\"}`}\n        />\n      )}\n    </BaseController>\n  );\n}\n"}]},{"name":"rhf-input-with-tag-field","title":"RHF Input with Tag Field","description":"Tag input field with React Hook Form integration.","type":"registry:ui","docs":"/components/rhf-input-with-tag-field","categories":["forms"],"registryDependencies":["https://pb-ui-five.vercel.app/registry/rhf-base-controller","https://pb-ui-five.vercel.app/registry/tag-input"],"dependencies":["react-hook-form"],"files":[{"path":"components/ui/rhf-inputs/input-with-tag-field.tsx","target":"components/ui/rhf-inputs/input-with-tag-field.tsx","type":"registry:ui","content":"import { FieldValues } from \"react-hook-form\";\nimport { TagInput } from \"../tag-input\";\nimport { BaseController, BaseControllerProps } from \"./base-controller\";\n\ntype Props<T extends FieldValues> = {\n  placeholder?: string;\n  showClear?: boolean;\n} & Omit<BaseControllerProps<T>, \"children\">;\n\nexport function InputWithTagField<T extends FieldValues>({\n  control,\n  name,\n  label,\n  description,\n  disableFieldError = false,\n  placeholder,\n  required,\n  showClear,\n}: Props<T>) {\n  return (\n    <BaseController\n      control={control}\n      name={name}\n      label={label}\n      required={required}\n      description={description}\n      disableFieldError={disableFieldError}\n    >\n      {({ field, fieldState, ariaDescribedBy }) => (\n        <TagInput\n          id={field.name}\n          // The TagInput component expects an array of tags\n          // Ensure we always pass an array, defaulting to empty if undefined\n          placeholder={placeholder}\n          value={(field.value as string[] | undefined) || []}\n          onValueChange={(newTags: string[]) => field.onChange(newTags)}\n          showClear={showClear}\n          aria-invalid={!!fieldState.error}\n          aria-describedby={ariaDescribedBy}\n        />\n      )}\n    </BaseController>\n  );\n}\n"}]},{"name":"rhf-multi-select-field","title":"RHF Multi Select Field","description":"Multi select field with React Hook Form integration.","type":"registry:ui","docs":"/components/rhf-multi-select-field","categories":["forms"],"registryDependencies":["https://pb-ui-five.vercel.app/registry/rhf-base-controller","https://pb-ui-five.vercel.app/registry/multi-select"],"dependencies":["react-hook-form"],"files":[{"path":"components/ui/rhf-inputs/multi-select-field.tsx","target":"components/ui/rhf-inputs/multi-select-field.tsx","type":"registry:ui","content":"import { FieldValues } from \"react-hook-form\";\nimport { MultiSelect, OptionType } from \"../multi-select\";\nimport { BaseController, BaseControllerProps } from \"./base-controller\";\n\ntype FieldSelectProps<T extends FieldValues> = {\n  placeholder?: string;\n  options: OptionType[];\n  grouped?: boolean;\n  disabled?: boolean;\n  showClear?: boolean;\n  onChange?: (values: string[]) => void;\n} & Omit<BaseControllerProps<T>, \"children\">;\n\nexport function MultiSelectField<T extends FieldValues>({\n  control,\n  name,\n  label,\n  description,\n  disableFieldError = false,\n  required,\n  options,\n  grouped,\n  placeholder,\n  disabled,\n  showClear,\n  onChange,\n}: FieldSelectProps<T>) {\n  return (\n    <BaseController\n      control={control}\n      name={name}\n      label={label}\n      description={description}\n      disableFieldError={disableFieldError}\n      required={required}\n    >\n      {({ field, fieldState, ariaDescribedBy }) => (\n        <MultiSelect\n          options={options}\n          selected={field.value || []}\n          onChange={(values) => {\n            field.onChange(values);\n            onChange?.(values);\n          }}\n          placeholder={placeholder}\n          invalid={!!fieldState.error}\n          grouped={grouped}\n          disabled={disabled}\n          showClear={showClear}\n          aria-describedby={ariaDescribedBy}\n        />\n      )}\n    </BaseController>\n  );\n}\n"}]},{"name":"rhf-input-date-field","title":"RHF Input Date Field","description":"Date input field with React Hook Form integration.","type":"registry:ui","docs":"/components/rhf-input-date-field","categories":["forms"],"registryDependencies":["https://pb-ui-five.vercel.app/registry/rhf-base-controller","https://pb-ui-five.vercel.app/registry/datefield-rac"],"dependencies":["react-hook-form"],"files":[{"path":"components/ui/rhf-inputs/input-date-field.tsx","target":"components/ui/rhf-inputs/input-date-field.tsx","type":"registry:ui","content":"import {\n  getLocalTimeZone,\n  parseDate,\n  parseDateTime,\n} from \"@internationalized/date\";\nimport { format } from \"date-fns\";\nimport { DateFieldProps, DateValue } from \"react-aria-components\";\nimport { FieldValues } from \"react-hook-form\";\nimport { DateField, DateInput, DateInputProps } from \"../datefield-rac\";\nimport { BaseController, BaseControllerProps } from \"./base-controller\";\n\ntype FieldInputProps<T extends FieldValues> = Omit<\n  BaseControllerProps<T>,\n  \"children\"\n> &\n  Omit<DateFieldProps<DateValue>, \"value\" | \"onChange\" | \"children\"> & {\n    defaultValue?: Date | string;\n  } & Pick<DateInputProps, \"className\" | \"unstyled\">;\n\ntype DateLike = Date | string | null | undefined;\n\nfunction toDateValue(value: DateLike): DateValue | undefined {\n  if (!value) return undefined;\n  if (value instanceof Date) {\n    const dateString = format(value, \"yyyy-MM-dd\");\n    return parseDate(dateString);\n  }\n  if (typeof value === \"string\") {\n    try {\n      return parseDate(value);\n    } catch {\n      try {\n        return parseDateTime(value);\n      } catch {\n        return undefined;\n      }\n    }\n  }\n  return undefined;\n}\n\nexport function InputDateField<T extends FieldValues>({\n  control,\n  name,\n  label,\n  description,\n  disableFieldError = false,\n  className,\n  required,\n  ...inputProps\n}: FieldInputProps<T>) {\n  const { defaultValue, ...restInputProps } = inputProps;\n\n  return (\n    <BaseController\n      control={control}\n      name={name}\n      label={label}\n      required={required}\n      description={description}\n      disableFieldError={disableFieldError}\n    >\n      {({ field, fieldState, ariaDescribedBy }) => {\n        const resolvedValue = toDateValue(field.value as DateLike);\n        const resolvedDefaultValue = toDateValue(defaultValue);\n\n        return (\n          <DateField\n            className=\"*:not-first:mt-2\"\n            value={resolvedValue}\n            defaultValue={resolvedDefaultValue}\n            onChange={(nextValue) => {\n              if (!nextValue) {\n                field.onChange(undefined);\n                return;\n              }\n\n              const timeZone = getLocalTimeZone();\n              field.onChange(nextValue.toDate(timeZone));\n            }}\n            {...restInputProps}\n          >\n            <DateInput\n              className={className}\n              aria-invalid={!!fieldState.error}\n              aria-required={required}\n              aria-describedby={ariaDescribedBy}\n            />\n          </DateField>\n        );\n      }}\n    </BaseController>\n  );\n}\n"}]},{"name":"rhf-date-picker-field","title":"RHF Date Picker Field","description":"Date picker field with React Hook Form integration.","type":"registry:ui","docs":"/components/rhf-date-picker-field","categories":["forms"],"registryDependencies":["https://pb-ui-five.vercel.app/registry/rhf-base-controller","https://pb-ui-five.vercel.app/registry/calendar","https://pb-ui-five.vercel.app/registry/popover","https://pb-ui-five.vercel.app/registry/button"],"dependencies":["react-hook-form","date-fns"],"files":[{"path":"components/ui/rhf-inputs/date-picker-field.tsx","target":"components/ui/rhf-inputs/date-picker-field.tsx","type":"registry:ui","content":"import { format } from \"date-fns\";\nimport { CalendarIcon } from \"lucide-react\";\nimport * as React from \"react\";\nimport { FieldValues } from \"react-hook-form\";\n\nimport { cn } from \"@/lib/utils\";\nimport { Button } from \"../button\";\nimport { Calendar } from \"../calendar\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"../popover\";\nimport { BaseController, BaseControllerProps } from \"./base-controller\";\n\ntype DatePickerFieldProps<T extends FieldValues> = Omit<\n  BaseControllerProps<T>,\n  \"children\"\n> & {\n  placeholder?: string;\n  formatString?: string;\n  calendarProps?: React.ComponentProps<typeof Calendar>;\n  buttonProps?: React.ComponentProps<typeof Button>;\n};\n\nexport function DatePickerField<T extends FieldValues>({\n  control,\n  name,\n  label,\n  description,\n  disableFieldError = false,\n  required,\n  placeholder = \"Pick a date\",\n  formatString,\n  calendarProps,\n  buttonProps,\n}: DatePickerFieldProps<T>) {\n  const formatter = React.useMemo(\n    () =>\n      new Intl.DateTimeFormat(\"it-IT\", {\n        day: \"2-digit\",\n        month: \"2-digit\",\n        year: \"numeric\",\n      }),\n    [],\n  );\n  const {\n    className: buttonClassName,\n    variant,\n    ...restButtonProps\n  } = buttonProps ?? {};\n\n  return (\n    <BaseController\n      control={control}\n      name={name}\n      label={label}\n      required={required}\n      description={description}\n      disableFieldError={disableFieldError}\n    >\n      {({ field, fieldState, ariaDescribedBy }) => (\n        <Popover>\n          <PopoverTrigger\n            render={\n              <Button\n                variant={variant ?? \"outline\"}\n                data-empty={!field.value}\n                aria-invalid={!!fieldState.error}\n                aria-describedby={ariaDescribedBy}\n                className={cn(\n                  \"justify-start font-normal data-[empty=true]:text-muted-foreground text-left\",\n                  buttonClassName,\n                  fieldState.error &&\n                    \"border-destructive focus-visible:border-destructive focus-visible:ring-destructive/50 focus-visible:ring-[3px] aria-invalid:ring-0\",\n                )}\n                {...restButtonProps}\n              />\n            }\n          >\n            <CalendarIcon className=\"me-2 size-4\" />\n            {field.value ? (\n              formatString ? (\n                format(field.value as Date, formatString)\n              ) : (\n                formatter.format(field.value as Date)\n              )\n            ) : (\n              <span>{placeholder}</span>\n            )}\n          </PopoverTrigger>\n          <PopoverContent className=\"p-0 w-auto\">\n            <Calendar\n              autoFocus\n              {...calendarProps}\n              mode=\"single\"\n              selected={field.value as Date | undefined}\n              onSelect={(date) => field.onChange(date ?? undefined)}\n            />\n          </PopoverContent>\n        </Popover>\n      )}\n    </BaseController>\n  );\n}\n"}]},{"name":"rhf-date-time-picker-field","title":"RHF Date Time Picker Field","description":"Date and time picker field with React Hook Form integration.","type":"registry:ui","docs":"/components/rhf-date-time-picker-field","categories":["forms"],"registryDependencies":["https://pb-ui-five.vercel.app/registry/rhf-base-controller","https://pb-ui-five.vercel.app/registry/calendar","https://pb-ui-five.vercel.app/registry/popover","https://pb-ui-five.vercel.app/registry/button","https://pb-ui-five.vercel.app/registry/input"],"dependencies":["react-hook-form","date-fns"],"files":[{"path":"components/ui/rhf-inputs/date-time-picker-field.tsx","target":"components/ui/rhf-inputs/date-time-picker-field.tsx","type":"registry:ui","content":"import { format } from \"date-fns\";\nimport { CalendarIcon } from \"lucide-react\";\nimport * as React from \"react\";\nimport { FieldValues } from \"react-hook-form\";\n\nimport { cn } from \"@/lib/utils\";\nimport { Button } from \"../button\";\nimport { Calendar } from \"../calendar\";\nimport { Input } from \"../input\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"../popover\";\nimport { BaseController, BaseControllerProps } from \"./base-controller\";\n\ntype DateTimePickerFieldProps<T extends FieldValues> = Omit<\n  BaseControllerProps<T>,\n  \"children\"\n> & {\n  placeholder?: string;\n  formatString?: string;\n  calendarProps?: React.ComponentProps<typeof Calendar>;\n  buttonProps?: React.ComponentProps<typeof Button>;\n  timeInputProps?: Omit<\n    React.ComponentProps<typeof Input>,\n    \"id\" | \"name\" | \"type\" | \"value\" | \"onChange\" | \"onBlur\" | \"disabled\"\n  >;\n  showSeconds?: boolean;\n};\n\nfunction normalizeTimeValue(value: string, showSeconds: boolean) {\n  if (!value) return value;\n  if (!showSeconds) return value;\n  if (/^\\d{2}:\\d{2}$/.test(value)) return `${value}:00`;\n  return value;\n}\n\nfunction applyTimeToDate(baseDate: Date, timeValue: string) {\n  const [hours = \"0\", minutes = \"0\", seconds = \"0\"] = timeValue.split(\":\");\n  const nextDate = new Date(baseDate);\n  nextDate.setHours(Number(hours), Number(minutes), Number(seconds), 0);\n  return nextDate;\n}\n\nexport function DateTimePickerField<T extends FieldValues>({\n  control,\n  name,\n  label,\n  description,\n  disableFieldError = false,\n  required,\n  placeholder = \"Pick a date & time\",\n  formatString,\n  calendarProps,\n  buttonProps,\n  timeInputProps,\n  showSeconds = false,\n}: DateTimePickerFieldProps<T>) {\n  const formatter = new Intl.DateTimeFormat(\"it-IT\", {\n    day: \"2-digit\",\n    month: \"2-digit\",\n    year: \"numeric\",\n  });\n  const {\n    className: buttonClassName,\n    variant,\n    ...restButtonProps\n  } = buttonProps ?? {};\n  const {\n    className: timeInputClassName,\n    step,\n    ...restTimeInputProps\n  } = timeInputProps ?? {};\n  const timeFormat = showSeconds ? \"HH:mm:ss\" : \"HH:mm\";\n  const resolvedStep =\n    typeof step === \"number\" ? step : showSeconds ? 1 : undefined;\n\n  return (\n    <BaseController\n      control={control}\n      name={name}\n      label={label}\n      required={required}\n      description={description}\n      disableFieldError={disableFieldError}\n    >\n      {({ field, fieldState, ariaDescribedBy }) => {\n        const dateValue = field.value as Date | undefined;\n        const hasValue = Boolean(dateValue);\n        const timeValue = dateValue ? format(dateValue, timeFormat) : \"\";\n        const displayValue = dateValue\n          ? formatString\n            ? format(dateValue, formatString)\n            : `${formatter.format(dateValue)} ${format(dateValue, timeFormat)}`\n          : null;\n\n        return (\n          <Popover>\n            <PopoverTrigger\n              render={\n                <Button\n                  variant={variant ?? \"outline\"}\n                  data-empty={!hasValue}\n                  aria-invalid={!!fieldState.error}\n                  aria-describedby={ariaDescribedBy}\n                  className={cn(\n                    \"justify-start font-normal data-[empty=true]:text-muted-foreground text-left\",\n                    buttonClassName,\n                    fieldState.error &&\n                      \"border-destructive focus-visible:border-destructive focus-visible:ring-destructive/50 focus-visible:ring-[3px] aria-invalid:ring-0\",\n                  )}\n                  {...restButtonProps}\n                />\n              }\n            >\n              <CalendarIcon className=\"me-2 size-4\" />\n              {displayValue ? (\n                <span>{displayValue}</span>\n              ) : (\n                <span>{placeholder}</span>\n              )}\n            </PopoverTrigger>\n            <PopoverContent className=\"p-0 w-auto\">\n              <div className=\"flex flex-col\">\n                <Calendar\n                  autoFocus\n                  {...calendarProps}\n                  mode=\"single\"\n                  selected={dateValue}\n                  onSelect={(selectedDate) => {\n                    if (!selectedDate) {\n                      field.onChange(undefined);\n                      return;\n                    }\n\n                    const nextDate = applyTimeToDate(\n                      selectedDate,\n                      timeValue || \"00:00:00\",\n                    );\n                    field.onChange(nextDate);\n                  }}\n                />\n                <div className=\"p-3 border-t\">\n                  <span className=\"block mb-2 text-muted-foreground text-xs\">\n                    Time\n                  </span>\n                  <Input\n                    id={`${field.name}-time`}\n                    name={`${field.name}-time`}\n                    type=\"time\"\n                    aria-invalid={!!fieldState.error}\n                    aria-required={required}\n                    aria-describedby={ariaDescribedBy}\n                    disabled={!dateValue}\n                    value={timeValue}\n                    onBlur={() => {\n                      field.onBlur();\n\n                      const normalizedValue = normalizeTimeValue(\n                        timeValue,\n                        showSeconds,\n                      );\n                      if (!normalizedValue) {\n                        field.onChange(undefined);\n                        return;\n                      }\n\n                      if (dateValue) {\n                        field.onChange(\n                          applyTimeToDate(dateValue, normalizedValue),\n                        );\n                      }\n                    }}\n                    onChange={(event) => {\n                      const nextInputValue = event.target.value;\n                      if (!nextInputValue) {\n                        field.onChange(undefined);\n                        return;\n                      }\n\n                      if (!dateValue) return;\n\n                      field.onChange(\n                        applyTimeToDate(dateValue, nextInputValue),\n                      );\n                    }}\n                    step={resolvedStep}\n                    className={timeInputClassName}\n                    {...restTimeInputProps}\n                  />\n                </div>\n              </div>\n            </PopoverContent>\n          </Popover>\n        );\n      }}\n    </BaseController>\n  );\n}\n"}]},{"name":"rhf-range-date-picker-field","title":"RHF Range Date Picker Field","description":"Range date picker field with React Hook Form integration.","type":"registry:ui","docs":"/components/rhf-range-date-picker-field","categories":["forms"],"registryDependencies":["https://pb-ui-five.vercel.app/registry/rhf-base-controller","https://pb-ui-five.vercel.app/registry/calendar","https://pb-ui-five.vercel.app/registry/popover","https://pb-ui-five.vercel.app/registry/button"],"dependencies":["react-hook-form","date-fns"],"files":[{"path":"components/ui/rhf-inputs/range-date-picker-field.tsx","target":"components/ui/rhf-inputs/range-date-picker-field.tsx","type":"registry:ui","content":"import { format } from \"date-fns\";\nimport { CalendarIcon } from \"lucide-react\";\nimport * as React from \"react\";\nimport { DateRange } from \"react-day-picker\";\nimport { FieldValues } from \"react-hook-form\";\n\nimport { cn } from \"@/lib/utils\";\nimport { Button } from \"../button\";\nimport { Calendar } from \"../calendar\";\nimport { Popover, PopoverContent, PopoverTrigger } from \"../popover\";\nimport { BaseController, BaseControllerProps } from \"./base-controller\";\n\ntype RangeDatePickerFieldProps<T extends FieldValues> = Omit<\n  BaseControllerProps<T>,\n  \"children\"\n> & {\n  placeholder?: string;\n  formatString?: string;\n  calendarProps?: React.ComponentProps<typeof Calendar>;\n  buttonProps?: React.ComponentProps<typeof Button>;\n};\n\nexport function RangeDatePickerField<T extends FieldValues>({\n  control,\n  name,\n  label,\n  description,\n  disableFieldError = false,\n  required,\n  placeholder = \"Pick a date range\",\n  formatString,\n  calendarProps,\n  buttonProps,\n}: RangeDatePickerFieldProps<T>) {\n  const formatter = React.useMemo(\n    () =>\n      new Intl.DateTimeFormat(\"it-IT\", {\n        day: \"2-digit\",\n        month: \"2-digit\",\n        year: \"numeric\",\n      }),\n    [],\n  );\n  const {\n    className: buttonClassName,\n    variant,\n    ...restButtonProps\n  } = buttonProps ?? {};\n\n  return (\n    <BaseController\n      control={control}\n      name={name}\n      label={label}\n      required={required}\n      description={description}\n      disableFieldError={disableFieldError}\n    >\n      {({ field, fieldState, ariaDescribedBy }) => {\n        const range = field.value as DateRange | undefined;\n        const hasValue = Boolean(range?.from);\n        const display = range?.from\n          ? range.to\n            ? formatString\n              ? `${format(range.from, formatString)} - ${format(range.to, formatString)}`\n              : `${formatter.format(range.from)} - ${formatter.format(range.to)}`\n            : formatString\n              ? format(range.from, formatString)\n              : formatter.format(range.from)\n          : null;\n\n        return (\n          <Popover>\n            <PopoverTrigger\n              render={\n                <Button\n                  variant={variant ?? \"outline\"}\n                  data-empty={!hasValue}\n                  aria-invalid={!!fieldState.error}\n                  aria-describedby={ariaDescribedBy}\n                  className={cn(\n                    \"justify-start font-normal data-[empty=true]:text-muted-foreground text-left\",\n                    buttonClassName,\n                    fieldState.error &&\n                      \"border-destructive focus-visible:border-destructive focus-visible:ring-destructive/50 focus-visible:ring-[3px] aria-invalid:ring-0\",\n                  )}\n                  {...restButtonProps}\n                />\n              }\n            >\n              <CalendarIcon className=\"me-2 size-4\" />\n              {display ? <span>{display}</span> : <span>{placeholder}</span>}\n            </PopoverTrigger>\n            <PopoverContent className=\"p-0 w-auto\">\n              <Calendar\n                autoFocus\n                {...calendarProps}\n                mode=\"range\"\n                selected={range}\n                onSelect={(nextRange) => field.onChange(nextRange ?? undefined)}\n              />\n            </PopoverContent>\n          </Popover>\n        );\n      }}\n    </BaseController>\n  );\n}\n"}]},{"name":"rhf-time-picker-field","title":"RHF Time Picker Field","description":"Time picker field with React Hook Form integration.","type":"registry:ui","docs":"/components/rhf-time-picker-field","categories":["forms"],"registryDependencies":["https://pb-ui-five.vercel.app/registry/rhf-base-controller","https://pb-ui-five.vercel.app/registry/input"],"dependencies":["react-hook-form","date-fns"],"files":[{"path":"components/ui/rhf-inputs/time-picker-field.tsx","target":"components/ui/rhf-inputs/time-picker-field.tsx","type":"registry:ui","content":"\"use client\";\nimport { InputHTMLAttributes } from \"react\";\nimport { ControllerFieldState, FieldValues } from \"react-hook-form\";\n\nimport { Input } from \"../input\";\nimport { BaseController, BaseControllerProps } from \"./base-controller\";\n\ntype TimePickerFieldProps<T extends FieldValues> = Omit<\n  BaseControllerProps<T>,\n  \"children\"\n> &\n  Omit<InputHTMLAttributes<HTMLInputElement>, \"name\" | \"id\" | \"type\"> & {\n    showSeconds?: boolean;\n  };\n\nfunction normalizeTimeValue(value: string, showSeconds: boolean) {\n  if (!value) return value;\n  if (!showSeconds) return value;\n  if (/^\\d{2}:\\d{2}$/.test(value)) return `${value}:00`;\n  return value;\n}\n\nexport function TimePickerField<T extends FieldValues>({\n  control,\n  name,\n  label,\n  description,\n  disableFieldError = false,\n  required,\n  showSeconds = false,\n  ...inputProps\n}: TimePickerFieldProps<T>) {\n  const { step, ...restInputProps } = inputProps;\n  const resolvedStep =\n    typeof step === \"number\" ? step : showSeconds ? 1 : undefined;\n\n  return (\n    <BaseController\n      control={control}\n      name={name}\n      label={label}\n      required={required}\n      description={description}\n      disableFieldError={disableFieldError}\n    >\n      {({ field, fieldState, ariaDescribedBy }) => (\n        <TimePickerInput\n          name={field.name}\n          value={field.value}\n          onBlur={field.onBlur}\n          onChange={field.onChange}\n          fieldState={fieldState}\n          required={required}\n          showSeconds={showSeconds}\n          step={resolvedStep}\n          inputProps={restInputProps}\n          ariaDescribedBy={ariaDescribedBy}\n        />\n      )}\n    </BaseController>\n  );\n}\n\ntype TimePickerInputProps<T extends FieldValues> = {\n  name: string;\n  value: T[keyof T] | undefined;\n  onBlur: () => void;\n  onChange: (value: string | undefined) => void;\n  fieldState: ControllerFieldState;\n  required?: boolean;\n  showSeconds: boolean;\n  step?: number;\n  inputProps: Omit<\n    InputHTMLAttributes<HTMLInputElement>,\n    \"name\" | \"id\" | \"type\"\n  >;\n  ariaDescribedBy?: string;\n};\n\nfunction TimePickerInput<T extends FieldValues>({\n  name,\n  value: fieldValue,\n  onBlur,\n  onChange,\n  fieldState,\n  required,\n  showSeconds,\n  step,\n  inputProps,\n  ariaDescribedBy,\n}: TimePickerInputProps<T>) {\n  const rawValue = fieldValue as unknown;\n  const value = typeof rawValue === \"string\" ? rawValue : \"\";\n  const inputValue = value;\n\n  return (\n    <Input\n      id={name}\n      name={name}\n      type=\"time\"\n      aria-invalid={!!fieldState.error}\n      aria-required={required}\n      aria-describedby={ariaDescribedBy}\n      value={inputValue}\n      onBlur={() => {\n        onBlur();\n\n        const normalizedValue = normalizeTimeValue(inputValue, showSeconds);\n        if (!normalizedValue) {\n          onChange(undefined);\n          return;\n        }\n\n        onChange(normalizedValue);\n      }}\n      onChange={(event) => {\n        const nextInputValue = event.target.value;\n        if (!nextInputValue) {\n          onChange(undefined);\n          return;\n        }\n\n        onChange(nextInputValue);\n      }}\n      step={step}\n      {...inputProps}\n    />\n  );\n}\n"}]},{"name":"rhf-file-upload-field","title":"RHF File Upload Field","description":"File upload field with React Hook Form integration.","type":"registry:ui","docs":"/components/rhf-file-upload-field","categories":["forms"],"registryDependencies":["https://pb-ui-five.vercel.app/registry/rhf-base-controller","https://pb-ui-five.vercel.app/registry/file-upload"],"dependencies":["react-hook-form"],"files":[{"path":"components/ui/rhf-inputs/file-upload-field.tsx","target":"components/ui/rhf-inputs/file-upload-field.tsx","type":"registry:ui","content":"\"use client\";\n\nimport { FieldValues } from \"react-hook-form\";\nimport { FileUpload, FileUploadProps } from \"../file-upload\";\nimport { BaseController, BaseControllerProps } from \"./base-controller\";\n\ntype FileUploadFieldProps<T extends FieldValues> = Omit<\n  FileUploadProps,\n  \"onFileSelect\" | \"error\" | \"label\" | \"description\" | \"required\"\n> &\n  Omit<BaseControllerProps<T>, \"children\">;\n\nexport function FileUploadField<T extends FieldValues>({\n  control,\n  name,\n  label,\n  description,\n  disableFieldError = false,\n  required,\n  ...fileUploadProps\n}: FileUploadFieldProps<T>) {\n  return (\n    <BaseController\n      control={control}\n      name={name}\n      label={label}\n      required={required}\n      description={description}\n      disableFieldError={disableFieldError}\n    >\n      {({ field, fieldState, ariaDescribedBy }) => (\n        <FileUpload\n          {...fileUploadProps}\n          label=\"\"\n          description=\"\"\n          required={required}\n          showError={false}\n          error={fieldState.error?.message}\n          aria-describedby={ariaDescribedBy}\n          onFileSelect={(file) => {\n            field.onChange(file);\n          }}\n        />\n      )}\n    </BaseController>\n  );\n}\n"}]},{"name":"number-input","title":"Number Input","description":"Numeric input with increment/decrement controls.","type":"registry:ui","docs":"/components/number-input","categories":["forms"],"registryDependencies":["https://pb-ui-five.vercel.app/registry/button","https://pb-ui-five.vercel.app/registry/input"],"files":[{"path":"components/ui/number-input.tsx","target":"components/ui/number-input.tsx","type":"registry:ui","content":"\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport { MinusIcon, PlusIcon } from \"lucide-react\";\nimport * as React from \"react\";\nimport { Button } from \"./button\";\nimport { Input } from \"./input\";\n\nexport type NumberInputProps = Omit<\n  React.InputHTMLAttributes<HTMLInputElement>,\n  \"type\" | \"value\" | \"onChange\"\n> & {\n  value?: number | null;\n  onChange?: (value: number | null) => void;\n  min?: number;\n  max?: number;\n  step?: number;\n  showControls?: boolean;\n  /** Allow decimal numbers. When false, only integers are allowed. */\n  allowDecimals?: boolean;\n  /** Maximum number of decimal places. Only applies when allowDecimals is true. */\n  decimalPlaces?: number;\n  /** Locale for decimal separator detection. Defaults to browser locale. */\n  locale?: string;\n};\n\nfunction NumberInput({\n  value,\n  onChange,\n  min,\n  max,\n  step = 1,\n  showControls = true,\n  allowDecimals = false,\n  decimalPlaces,\n  locale,\n  disabled,\n  className,\n  ...props\n}: NumberInputProps) {\n  // Get the decimal separator for the locale (defaults to browser locale)\n  const decimalSeparator = React.useMemo(() => {\n    const parts = new Intl.NumberFormat(locale).formatToParts(1.1);\n    return parts.find((part) => part.type === \"decimal\")?.value ?? \".\";\n  }, [locale]);\n\n  // Format a number for display\n  const formatValue = React.useCallback(\n    (val: number) => {\n      let formatted: string;\n      if (allowDecimals && decimalPlaces !== undefined) {\n        formatted = val.toFixed(decimalPlaces);\n      } else {\n        // Use enough precision to represent the number accurately\n        formatted = String(val);\n      }\n      // Replace standard decimal separator with locale-specific one\n      if (decimalSeparator !== \".\") {\n        formatted = formatted.replace(\".\", decimalSeparator);\n      }\n      return formatted;\n    },\n    [allowDecimals, decimalPlaces, decimalSeparator],\n  );\n\n  // Parse input string to number, handling locale decimal separator\n  const parseInput = React.useCallback(\n    (input: string): number | null => {\n      if (input === \"\" || input === \"-\") return null;\n      // Normalize: replace locale decimal separator with standard dot\n      let normalized = input;\n      if (decimalSeparator !== \".\") {\n        normalized = normalized.replace(decimalSeparator, \".\");\n      }\n      // Also accept dot as input even if locale uses comma\n      normalized = normalized.replace(\",\", \".\");\n      const parsed = parseFloat(normalized);\n      return isNaN(parsed) ? null : parsed;\n    },\n    [decimalSeparator],\n  );\n\n  // Clamp and round value according to constraints\n  const clampValue = React.useCallback(\n    (val: number): number => {\n      let result = val;\n      if (min != null && result < min) result = min;\n      if (max != null && result > max) result = max;\n      if (!allowDecimals) {\n        result = Math.round(result);\n      } else if (decimalPlaces !== undefined) {\n        const factor = Math.pow(10, decimalPlaces);\n        result = Math.round(result * factor) / factor;\n      }\n      return result;\n    },\n    [min, max, allowDecimals, decimalPlaces],\n  );\n\n  const [inputValue, setInputValue] = React.useState<string>(\n    value != null ? formatValue(value) : \"\",\n  );\n\n  // Track focus state to prevent reformatting while typing\n  const isFocusedRef = React.useRef(false);\n  const prevValueRef = React.useRef(value);\n\n  React.useEffect(() => {\n    // Only update from external value when NOT focused\n    // This prevents reformatting while the user is typing\n    if (!isFocusedRef.current && value !== prevValueRef.current) {\n      setInputValue(value != null ? formatValue(value) : \"\");\n      prevValueRef.current = value;\n    }\n  }, [value, formatValue]);\n\n  const handleFocus = () => {\n    isFocusedRef.current = true;\n  };\n\n  const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n    const raw = e.target.value;\n\n    // Allow free typing - only filter obvious garbage\n    // Allow: digits, minus sign, dot, comma (for locale flexibility)\n    const isValidChar = /^-?[\\d.,]*$/.test(raw);\n    if (!isValidChar && raw !== \"\") return;\n\n    // If decimals not allowed, prevent typing decimal separators\n    if (!allowDecimals && (raw.includes(\".\") || raw.includes(\",\"))) {\n      return;\n    }\n\n    setInputValue(raw);\n\n    // Parse and notify parent (without clamping during typing)\n    const parsed = parseInput(raw);\n    if (parsed !== null) {\n      onChange?.(parsed);\n    } else if (raw === \"\" || raw === \"-\") {\n      onChange?.(null);\n    }\n  };\n\n  const handleBlur = () => {\n    isFocusedRef.current = false;\n\n    if (value != null) {\n      // Clamp and format on blur\n      const clamped = clampValue(value);\n      setInputValue(formatValue(clamped));\n      prevValueRef.current = clamped;\n      if (clamped !== value) {\n        onChange?.(clamped);\n      }\n    } else {\n      setInputValue(\"\");\n    }\n  };\n\n  const increment = () => {\n    const current = value ?? 0;\n    const newValue = clampValue(current + step);\n    onChange?.(newValue);\n    setInputValue(formatValue(newValue));\n    prevValueRef.current = newValue;\n  };\n\n  const decrement = () => {\n    const current = value ?? 0;\n    const newValue = clampValue(current - step);\n    onChange?.(newValue);\n    setInputValue(formatValue(newValue));\n    prevValueRef.current = newValue;\n  };\n\n  const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {\n    if (e.key === \"ArrowUp\") {\n      e.preventDefault();\n      if (canIncrement) increment();\n    } else if (e.key === \"ArrowDown\") {\n      e.preventDefault();\n      if (canDecrement) decrement();\n    }\n  };\n\n  const canIncrement = max == null || (value ?? 0) < max;\n  const canDecrement = min == null || (value ?? 0) > min;\n\n  return (\n    <div className={cn(\"flex items-center\", className)}>\n      {showControls && (\n        <Button\n          type=\"button\"\n          variant=\"outline\"\n          size=\"icon\"\n          onClick={decrement}\n          disabled={disabled || !canDecrement}\n          className=\"border-r-0 rounded-r-none\"\n          aria-label=\"Decrease value\"\n        >\n          <MinusIcon className=\"size-4\" />\n        </Button>\n      )}\n      <Input\n        type=\"text\"\n        inputMode={allowDecimals ? \"decimal\" : \"numeric\"}\n        value={inputValue}\n        onChange={handleInputChange}\n        onFocus={handleFocus}\n        onBlur={handleBlur}\n        onKeyDown={handleKeyDown}\n        disabled={disabled}\n        className={cn(\"text-center\", showControls && \"rounded-none border-x-0\")}\n        {...props}\n      />\n      {showControls && (\n        <Button\n          type=\"button\"\n          variant=\"outline\"\n          size=\"icon\"\n          onClick={increment}\n          disabled={disabled || !canIncrement}\n          className=\"border-l-0 rounded-l-none\"\n          aria-label=\"Increase value\"\n        >\n          <PlusIcon className=\"size-4\" />\n        </Button>\n      )}\n    </div>\n  );\n}\n\nexport { NumberInput };\n"}]},{"name":"input-otp","title":"Input OTP","description":"One-time password input with segmented fields.","type":"registry:ui","docs":"/components/input-otp","categories":["forms"],"dependencies":["input-otp"],"files":[{"path":"components/ui/input-otp.tsx","target":"components/ui/input-otp.tsx","type":"registry:ui","content":"\"use client\"\n\nimport * as React from \"react\"\nimport { OTPInput, OTPInputContext } from \"input-otp\"\n\nimport { cn } from \"@/lib/utils\"\nimport { MinusIcon } from \"lucide-react\"\n\nfunction InputOTP({\n  className,\n  containerClassName,\n  ...props\n}: React.ComponentProps<typeof OTPInput> & {\n  containerClassName?: string\n}) {\n  return (\n    <OTPInput\n      data-slot=\"input-otp\"\n      containerClassName={cn(\n        \"cn-input-otp flex items-center has-disabled:opacity-50\",\n        containerClassName\n      )}\n      spellCheck={false}\n      className={cn(\"disabled:cursor-not-allowed\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction InputOTPGroup({ className, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"input-otp-group\"\n      className={cn(\n        \"flex items-center rounded-md has-aria-invalid:border-destructive has-aria-invalid:ring-3 has-aria-invalid:ring-destructive/20 dark:has-aria-invalid:ring-destructive/40\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\nfunction InputOTPSlot({\n  index,\n  className,\n  ...props\n}: React.ComponentProps<\"div\"> & {\n  index: number\n}) {\n  const inputOTPContext = React.useContext(OTPInputContext)\n  const { char, hasFakeCaret, isActive } = inputOTPContext?.slots[index] ?? {}\n\n  return (\n    <div\n      data-slot=\"input-otp-slot\"\n      data-active={isActive}\n      className={cn(\n        \"relative flex size-9 items-center justify-center border-y border-r border-input text-sm shadow-xs transition-all outline-none first:rounded-l-md first:border-l last:rounded-r-md aria-invalid:border-destructive data-[active=true]:z-10 data-[active=true]:border-ring data-[active=true]:ring-3 data-[active=true]:ring-ring/50 data-[active=true]:aria-invalid:border-destructive data-[active=true]:aria-invalid:ring-destructive/20 dark:bg-input/30 dark:data-[active=true]:aria-invalid:ring-destructive/40\",\n        className\n      )}\n      {...props}\n    >\n      {char}\n      {hasFakeCaret && (\n        <div className=\"pointer-events-none absolute inset-0 flex items-center justify-center\">\n          <div className=\"h-4 w-px animate-caret-blink bg-foreground duration-1000\" />\n        </div>\n      )}\n    </div>\n  )\n}\n\nfunction InputOTPSeparator({ ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div\n      data-slot=\"input-otp-separator\"\n      className=\"flex items-center [&_svg:not([class*='size-'])]:size-4\"\n      role=\"separator\"\n      {...props}\n    >\n      <MinusIcon\n      />\n    </div>\n  )\n}\n\nexport { InputOTP, InputOTPGroup, InputOTPSlot, InputOTPSeparator }\n"}]},{"name":"color-picker","title":"Color Picker","description":"Color selection with visual swatch and hex input.","type":"registry:ui","docs":"/components/color-picker","categories":["forms"],"registryDependencies":["https://pb-ui-five.vercel.app/registry/input"],"files":[{"path":"components/ui/color-picker.tsx","target":"components/ui/color-picker.tsx","type":"registry:ui","content":"\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport * as React from \"react\";\nimport { Input } from \"./input\";\n\nexport type ColorPickerProps = Omit<\n  React.InputHTMLAttributes<HTMLInputElement>,\n  \"type\" | \"value\" | \"onChange\"\n> & {\n  value?: string;\n  onChange?: (value: string) => void;\n  showInput?: boolean;\n};\n\nfunction ColorPicker({\n  value = \"#000000\",\n  onChange,\n  showInput = true,\n  disabled,\n  className,\n  ...props\n}: ColorPickerProps) {\n  const [inputValue, setInputValue] = React.useState(value);\n\n  React.useEffect(() => {\n    setInputValue(value);\n  }, [value]);\n\n  const handleColorChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n    const newValue = e.target.value;\n    setInputValue(newValue);\n    onChange?.(newValue);\n  };\n\n  const handleTextChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n    const newValue = e.target.value;\n    setInputValue(newValue);\n\n    // Only trigger onChange if it's a valid hex color\n    if (/^#[0-9A-Fa-f]{6}$/.test(newValue)) {\n      onChange?.(newValue);\n    }\n  };\n\n  const handleBlur = () => {\n    // Normalize to valid hex on blur\n    if (!/^#[0-9A-Fa-f]{6}$/.test(inputValue)) {\n      setInputValue(value);\n    }\n  };\n\n  return (\n    <div className={cn(\"flex items-center gap-2\", className)}>\n      <div className=\"relative\">\n        <input\n          type=\"color\"\n          value={value}\n          onChange={handleColorChange}\n          disabled={disabled}\n          className={cn(\n            \"bg-transparent shadow-xs p-1 border border-input rounded-md size-10 transition-shadow cursor-pointer\",\n            \"focus-visible:outline-none focus-visible:ring-[3px] focus-visible:ring-ring/50 focus-visible:border-ring\",\n            disabled && \"cursor-not-allowed opacity-50\",\n          )}\n          {...props}\n        />\n      </div>\n      {showInput && (\n        <Input\n          type=\"text\"\n          value={inputValue}\n          onChange={handleTextChange}\n          onBlur={handleBlur}\n          disabled={disabled}\n          placeholder=\"#000000\"\n          className=\"w-28 font-mono uppercase\"\n          maxLength={7}\n        />\n      )}\n    </div>\n  );\n}\n\nexport { ColorPicker };\n"}]},{"name":"rating","title":"Rating","description":"Star rating component with hover preview.","type":"registry:ui","docs":"/components/rating","categories":["forms","data-entry"],"files":[{"path":"components/ui/rating.tsx","target":"components/ui/rating.tsx","type":"registry:ui","content":"\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport * as React from \"react\";\n\nconst sizeClasses = {\n  sm: \"size-4\",\n  default: \"size-5\",\n  lg: \"size-6\",\n};\n\nexport type RatingProps = {\n  value?: number;\n  onChange?: (value: number) => void;\n  max?: number;\n  disabled?: boolean;\n  readOnly?: boolean;\n  size?: \"sm\" | \"default\" | \"lg\";\n  allowHalf?: boolean;\n  className?: string;\n  \"aria-label\"?: string;\n  \"aria-invalid\"?: boolean;\n};\n\nconst StarIcon = ({\n  isFilled,\n  isHalfFilled,\n  size,\n  className,\n}: {\n  isFilled: boolean;\n  isHalfFilled: boolean;\n  size: string;\n  className?: string;\n}) => {\n  return (\n    <div className={cn(\"inline-block relative\", size, className)}>\n      {/* Empty star background */}\n      <svg\n        xmlns=\"http://www.w3.org/2000/svg\"\n        viewBox=\"0 0 24 24\"\n        fill=\"none\"\n        stroke=\"currentColor\"\n        strokeWidth=\"2\"\n        strokeLinecap=\"round\"\n        strokeLinejoin=\"round\"\n        className={cn(\"absolute inset-0 text-muted-foreground\")}\n      >\n        <polygon points=\"12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2\" />\n      </svg>\n      {/* Filled/Half-filled star overlay */}\n      <svg\n        xmlns=\"http://www.w3.org/2000/svg\"\n        viewBox=\"0 0 24 24\"\n        fill=\"currentColor\"\n        stroke=\"currentColor\"\n        strokeWidth=\"2\"\n        strokeLinecap=\"round\"\n        strokeLinejoin=\"round\"\n        className={cn(\n          \"absolute inset-0 transition-opacity\",\n          isFilled || isHalfFilled\n            ? \"text-yellow-400 fill-yellow-400\"\n            : \"opacity-0\",\n        )}\n        style={{\n          clipPath: isHalfFilled\n            ? \"polygon(0 0, 50% 0, 50% 100%, 0 100%)\"\n            : undefined,\n        }}\n      >\n        <polygon points=\"12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2\" />\n      </svg>\n    </div>\n  );\n};\n\nfunction Rating({\n  value = 0,\n  onChange,\n  max = 5,\n  disabled = false,\n  readOnly = false,\n  allowHalf = false,\n  size = \"default\",\n  className,\n  \"aria-label\": ariaLabel = \"Rating\",\n  \"aria-invalid\": ariaInvalid,\n  ...props\n}: RatingProps) {\n  const [hoverValue, setHoverValue] = React.useState<number | null>(null);\n  const displayValue = hoverValue ?? value;\n\n  const handleMouseMove = (\n    e: React.MouseEvent<HTMLButtonElement>,\n    index: number,\n  ) => {\n    if (disabled || readOnly) return;\n\n    if (allowHalf) {\n      const { left, width } = e.currentTarget.getBoundingClientRect();\n      const percent = (e.clientX - left) / width;\n      const newValue = index + (percent > 0.5 ? 1 : 0.5);\n      setHoverValue(newValue);\n    } else {\n      setHoverValue(index + 1);\n    }\n  };\n\n  const handleClick = (rating: number) => {\n    if (disabled || readOnly) return;\n    onChange?.(rating);\n  };\n\n  const handleMouseLeave = () => {\n    setHoverValue(null);\n  };\n\n  const handleKeyDown = (e: React.KeyboardEvent, rating: number) => {\n    if (disabled || readOnly) return;\n    if (e.key === \"Enter\" || e.key === \" \") {\n      e.preventDefault();\n      onChange?.(rating);\n    }\n  };\n\n  // Clean up rating logic for rendering\n  const renderStars = () => {\n    return Array.from({ length: max }, (_, index) => {\n      const starValue = index + 1;\n      const isFilled = displayValue >= starValue;\n      const isHalfFilled =\n        allowHalf && !isFilled && displayValue >= starValue - 0.5;\n\n      return (\n        <button\n          key={index}\n          type=\"button\"\n          role=\"radio\"\n          aria-checked={\n            value === starValue || (allowHalf && value === starValue - 0.5)\n          }\n          aria-label={`${starValue} star${starValue !== 1 ? \"s\" : \"\"}`}\n          disabled={disabled}\n          tabIndex={readOnly ? -1 : 0}\n          onClick={() => handleClick(hoverValue ?? starValue)}\n          onMouseMove={(e) => handleMouseMove(e, index)}\n          onKeyDown={(e) => handleKeyDown(e, starValue)}\n          className={cn(\n            \"p-0.5 rounded-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 transition-transform\",\n            !disabled && !readOnly && \"cursor-pointer hover:scale-110\",\n            disabled && \"cursor-not-allowed opacity-50\",\n          )}\n        >\n          <StarIcon\n            isFilled={isFilled}\n            isHalfFilled={isHalfFilled}\n            size={sizeClasses[size]}\n            className={cn(\"transition-colors\")}\n          />\n        </button>\n      );\n    });\n  };\n\n  return (\n    <div\n      role=\"radiogroup\"\n      aria-label={ariaLabel}\n      aria-invalid={ariaInvalid}\n      className={cn(\"inline-flex items-center gap-0.5\", className)}\n      onMouseLeave={handleMouseLeave}\n      {...props}\n    >\n      {renderStars()}\n    </div>\n  );\n}\n\nexport { Rating };\n"}]},{"name":"rhf-combobox-field","title":"RHF Combobox Field","description":"Searchable combobox field with React Hook Form integration.","type":"registry:ui","docs":"/components/rhf-combobox-field","categories":["forms"],"registryDependencies":["https://pb-ui-five.vercel.app/registry/rhf-base-controller","https://pb-ui-five.vercel.app/registry/combobox"],"dependencies":["react-hook-form"],"files":[{"path":"components/ui/rhf-inputs/combobox-field.tsx","target":"components/ui/rhf-inputs/combobox-field.tsx","type":"registry:ui","content":"\"use client\";\n\nimport { FieldValues } from \"react-hook-form\";\nimport {\n  Combobox,\n  ComboboxContent,\n  ComboboxEmpty,\n  ComboboxGroup,\n  ComboboxInput,\n  ComboboxItem,\n  ComboboxLabel,\n  ComboboxList,\n} from \"../combobox\";\nimport { BaseController, BaseControllerProps } from \"./base-controller\";\n\nexport type ComboboxOption = {\n  value: string;\n  label: string;\n  disabled?: boolean;\n};\n\nexport type ComboboxOptionGroup = {\n  label: string;\n  options: ComboboxOption[];\n};\n\ntype ComboboxFieldProps<T extends FieldValues> = Omit<\n  BaseControllerProps<T>,\n  \"children\"\n> & {\n  options: (ComboboxOption | ComboboxOptionGroup)[];\n  placeholder?: string;\n  emptyMessage?: string;\n  disabled?: boolean;\n  showClear?: boolean;\n  className?: string;\n};\n\nfunction isOptionGroup(\n  option: ComboboxOption | ComboboxOptionGroup,\n): option is ComboboxOptionGroup {\n  return \"options\" in option;\n}\n\nexport function ComboboxField<T extends FieldValues>({\n  control,\n  name,\n  label,\n  description,\n  required,\n  disableFieldError = false,\n  options,\n  placeholder = \"Search...\",\n  emptyMessage = \"No options found.\",\n  disabled = false,\n  showClear = true,\n  className,\n}: ComboboxFieldProps<T>) {\n  return (\n    <BaseController\n      control={control}\n      name={name}\n      label={label}\n      required={required}\n      description={description}\n      disableFieldError={disableFieldError}\n    >\n      {({ field, fieldState, ariaDescribedBy }) => (\n        <Combobox\n          value={field.value ?? \"\"}\n          onValueChange={(value) => field.onChange(value)}\n          disabled={disabled}\n        >\n          <ComboboxInput\n            id={field.name}\n            placeholder={placeholder}\n            showClear={showClear}\n            aria-invalid={!!fieldState.error}\n            aria-describedby={ariaDescribedBy}\n            className={className}\n          />\n          <ComboboxContent>\n            <ComboboxList>\n              <ComboboxEmpty>{emptyMessage}</ComboboxEmpty>\n              {options.map((option, index) =>\n                isOptionGroup(option) ? (\n                  <ComboboxGroup key={`group-${index}`}>\n                    <ComboboxLabel>{option.label}</ComboboxLabel>\n                    {option.options.map((opt) => (\n                      <ComboboxItem\n                        key={opt.value}\n                        value={opt.value}\n                        disabled={opt.disabled}\n                      >\n                        {opt.label}\n                      </ComboboxItem>\n                    ))}\n                  </ComboboxGroup>\n                ) : (\n                  <ComboboxItem\n                    key={option.value}\n                    value={option.value}\n                    disabled={option.disabled}\n                  >\n                    {option.label}\n                  </ComboboxItem>\n                ),\n              )}\n            </ComboboxList>\n          </ComboboxContent>\n        </Combobox>\n      )}\n    </BaseController>\n  );\n}\n"}]},{"name":"rhf-number-field","title":"RHF Number Field","description":"Numeric input field with React Hook Form integration.","type":"registry:ui","docs":"/components/rhf-number-field","categories":["forms"],"registryDependencies":["https://pb-ui-five.vercel.app/registry/rhf-base-controller","https://pb-ui-five.vercel.app/registry/number-input"],"dependencies":["react-hook-form"],"files":[{"path":"components/ui/rhf-inputs/number-field.tsx","target":"components/ui/rhf-inputs/number-field.tsx","type":"registry:ui","content":"\"use client\";\n\nimport { FieldValues } from \"react-hook-form\";\nimport { NumberInput, NumberInputProps } from \"../number-input\";\nimport { BaseController, BaseControllerProps } from \"./base-controller\";\n\ntype NumberFieldProps<T extends FieldValues> = Omit<\n  BaseControllerProps<T>,\n  \"children\"\n> &\n  Omit<NumberInputProps, \"value\" | \"onChange\" | \"name\" | \"id\">;\n\nexport function NumberField<T extends FieldValues>({\n  control,\n  name,\n  label,\n  description,\n  required,\n  disableFieldError = false,\n  min,\n  max,\n  step,\n  showControls,\n  allowDecimals,\n  decimalPlaces,\n  locale,\n  disabled,\n  className,\n  ...inputProps\n}: NumberFieldProps<T>) {\n  return (\n    <BaseController\n      control={control}\n      name={name}\n      label={label}\n      required={required}\n      description={description}\n      disableFieldError={disableFieldError}\n    >\n      {({ field, fieldState, ariaDescribedBy }) => (\n        <NumberInput\n          id={field.name}\n          value={field.value ?? null}\n          onChange={(value) => field.onChange(value)}\n          min={min}\n          max={max}\n          step={step}\n          showControls={showControls}\n          allowDecimals={allowDecimals}\n          decimalPlaces={decimalPlaces}\n          locale={locale}\n          disabled={disabled}\n          aria-invalid={!!fieldState.error}\n          aria-required={required}\n          aria-describedby={ariaDescribedBy}\n          className={className}\n          {...inputProps}\n        />\n      )}\n    </BaseController>\n  );\n}\n"}]},{"name":"rhf-otp-field","title":"RHF OTP Field","description":"OTP/PIN input field with React Hook Form integration.","type":"registry:ui","docs":"/components/rhf-otp-field","categories":["forms"],"registryDependencies":["https://pb-ui-five.vercel.app/registry/rhf-base-controller","https://pb-ui-five.vercel.app/registry/input-otp"],"dependencies":["react-hook-form"],"files":[{"path":"components/ui/rhf-inputs/otp-field.tsx","target":"components/ui/rhf-inputs/otp-field.tsx","type":"registry:ui","content":"\"use client\";\n\nimport { FieldValues } from \"react-hook-form\";\nimport { InputOTP, InputOTPGroup, InputOTPSlot } from \"../input-otp\";\nimport { BaseController, BaseControllerProps } from \"./base-controller\";\n\ntype OTPFieldProps<T extends FieldValues> = Omit<\n  BaseControllerProps<T>,\n  \"children\"\n> & {\n  /** Number of OTP digits */\n  length?: number;\n  /** Pattern for input validation (e.g., /^[0-9]*$/) */\n  pattern?: RegExp;\n  disabled?: boolean;\n  className?: string;\n};\n\nexport function OTPField<T extends FieldValues>({\n  control,\n  name,\n  label,\n  description,\n  required,\n  disableFieldError = false,\n  length = 6,\n  pattern,\n  disabled = false,\n  className,\n}: OTPFieldProps<T>) {\n  return (\n    <BaseController\n      control={control}\n      name={name}\n      label={label}\n      required={required}\n      description={description}\n      disableFieldError={disableFieldError}\n    >\n      {({ field, fieldState, ariaDescribedBy }) => (\n        <InputOTP\n          id={field.name}\n          maxLength={length}\n          value={field.value ?? \"\"}\n          onChange={(value) => field.onChange(value)}\n          disabled={disabled}\n          pattern={pattern?.source}\n          aria-invalid={!!fieldState.error}\n          aria-describedby={ariaDescribedBy}\n          className={className}\n        >\n          <InputOTPGroup>\n            {Array.from({ length }, (_, index) => (\n              <InputOTPSlot\n                key={index}\n                index={index}\n                aria-invalid={!!fieldState.error}\n              />\n            ))}\n          </InputOTPGroup>\n        </InputOTP>\n      )}\n    </BaseController>\n  );\n}\n"}]},{"name":"rhf-checkbox-group-field","title":"RHF Checkbox Group Field","description":"Multiple checkboxes as array with React Hook Form integration.","type":"registry:ui","docs":"/components/rhf-checkbox-group-field","categories":["forms"],"registryDependencies":["https://pb-ui-five.vercel.app/registry/rhf-base-controller","https://pb-ui-five.vercel.app/registry/checkbox","https://pb-ui-five.vercel.app/registry/label"],"dependencies":["react-hook-form"],"files":[{"path":"components/ui/rhf-inputs/checkbox-group-field.tsx","target":"components/ui/rhf-inputs/checkbox-group-field.tsx","type":"registry:ui","content":"\"use client\";\n\nimport { FieldValues } from \"react-hook-form\";\nimport { Checkbox } from \"../checkbox\";\nimport { Label } from \"../label\";\nimport { BaseController, BaseControllerProps } from \"./base-controller\";\n\nexport type CheckboxGroupOption = {\n  value: string;\n  label: string;\n  disabled?: boolean;\n};\n\ntype CheckboxGroupFieldProps<T extends FieldValues> = Omit<\n  BaseControllerProps<T>,\n  \"children\"\n> & {\n  options: CheckboxGroupOption[];\n  orientation?: \"horizontal\" | \"vertical\";\n  disabled?: boolean;\n  className?: string;\n};\n\nexport function CheckboxGroupField<T extends FieldValues>({\n  control,\n  name,\n  label,\n  description,\n  required,\n  disableFieldError = false,\n  options,\n  orientation = \"vertical\",\n  disabled = false,\n  className,\n}: CheckboxGroupFieldProps<T>) {\n  return (\n    <BaseController\n      control={control}\n      name={name}\n      label={label}\n      required={required}\n      description={description}\n      disableFieldError={disableFieldError}\n    >\n      {({ field, fieldState, ariaDescribedBy }) => {\n        const values: string[] = Array.isArray(field.value) ? field.value : [];\n\n        const handleChange = (optionValue: string, checked: boolean) => {\n          if (checked) {\n            field.onChange([...values, optionValue]);\n          } else {\n            field.onChange(values.filter((v) => v !== optionValue));\n          }\n        };\n\n        return (\n          <div\n            role=\"group\"\n            aria-describedby={ariaDescribedBy}\n            className={`flex ${\n              orientation === \"horizontal\"\n                ? \"flex-row flex-wrap gap-4\"\n                : \"flex-col gap-2\"\n            } ${className ?? \"\"}`}\n          >\n            {options.map((option) => (\n              <div key={option.value} className=\"flex items-center gap-2\">\n                <Checkbox\n                  id={`${field.name}-${option.value}`}\n                  checked={values.includes(option.value)}\n                  onCheckedChange={(checked) =>\n                    handleChange(option.value, !!checked)\n                  }\n                  disabled={disabled || option.disabled}\n                  aria-invalid={!!fieldState.error}\n                />\n                <Label\n                  htmlFor={`${field.name}-${option.value}`}\n                  className=\"font-normal cursor-pointer\"\n                >\n                  {option.label}\n                </Label>\n              </div>\n            ))}\n          </div>\n        );\n      }}\n    </BaseController>\n  );\n}\n"}]},{"name":"rhf-phone-field","title":"RHF Phone Field","description":"Phone input with country code and React Hook Form integration.","type":"registry:ui","docs":"/components/rhf-phone-field","categories":["forms"],"registryDependencies":["https://pb-ui-five.vercel.app/registry/rhf-base-controller","https://pb-ui-five.vercel.app/registry/input","https://pb-ui-five.vercel.app/registry/select"],"dependencies":["react-hook-form"],"files":[{"path":"components/ui/rhf-inputs/phone-field.tsx","target":"components/ui/rhf-inputs/phone-field.tsx","type":"registry:ui","content":"\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport * as React from \"react\";\nimport { FieldValues } from \"react-hook-form\";\nimport { Input } from \"../input\";\nimport {\n  Select,\n  SelectContent,\n  SelectItem,\n  SelectTrigger,\n  SelectValue,\n} from \"../select\";\nimport { BaseController, BaseControllerProps } from \"./base-controller\";\n\n// Common country codes with their dial codes\nconst DEFAULT_COUNTRIES = [\n  { code: \"US\", dialCode: \"+1\", name: \"United States\" },\n  { code: \"GB\", dialCode: \"+44\", name: \"United Kingdom\" },\n  { code: \"DE\", dialCode: \"+49\", name: \"Germany\" },\n  { code: \"FR\", dialCode: \"+33\", name: \"France\" },\n  { code: \"IT\", dialCode: \"+39\", name: \"Italy\" },\n  { code: \"ES\", dialCode: \"+34\", name: \"Spain\" },\n  { code: \"NL\", dialCode: \"+31\", name: \"Netherlands\" },\n  { code: \"BE\", dialCode: \"+32\", name: \"Belgium\" },\n  { code: \"CH\", dialCode: \"+41\", name: \"Switzerland\" },\n  { code: \"AT\", dialCode: \"+43\", name: \"Austria\" },\n  { code: \"AU\", dialCode: \"+61\", name: \"Australia\" },\n  { code: \"CA\", dialCode: \"+1\", name: \"Canada\" },\n  { code: \"JP\", dialCode: \"+81\", name: \"Japan\" },\n  { code: \"CN\", dialCode: \"+86\", name: \"China\" },\n  { code: \"IN\", dialCode: \"+91\", name: \"India\" },\n  { code: \"BR\", dialCode: \"+55\", name: \"Brazil\" },\n  { code: \"MX\", dialCode: \"+52\", name: \"Mexico\" },\n  { code: \"KR\", dialCode: \"+82\", name: \"South Korea\" },\n  { code: \"RU\", dialCode: \"+7\", name: \"Russia\" },\n  { code: \"ZA\", dialCode: \"+27\", name: \"South Africa\" },\n];\n\nexport type Country = {\n  code: string;\n  dialCode: string;\n  name: string;\n};\n\ntype PhoneFieldProps<T extends FieldValues> = Omit<\n  BaseControllerProps<T>,\n  \"children\"\n> & {\n  countries?: Country[];\n  defaultCountry?: string;\n  placeholder?: string;\n  disabled?: boolean;\n  className?: string;\n};\n\nexport function PhoneField<T extends FieldValues>({\n  control,\n  name,\n  label,\n  description,\n  required,\n  disableFieldError = false,\n  countries = DEFAULT_COUNTRIES,\n  defaultCountry = \"US\",\n  placeholder = \"Phone number\",\n  disabled = false,\n  className,\n}: PhoneFieldProps<T>) {\n  const [selectedCountry, setSelectedCountry] = React.useState(\n    () => countries.find((c) => c.code === defaultCountry) ?? countries[0],\n  );\n\n  return (\n    <BaseController\n      control={control}\n      name={name}\n      label={label}\n      required={required}\n      description={description}\n      disableFieldError={disableFieldError}\n    >\n      {({ field, fieldState, ariaDescribedBy }) => {\n        // Parse the current value to extract country and number\n        const parsePhoneValue = (value: string | undefined) => {\n          if (!value) return { dialCode: selectedCountry.dialCode, number: \"\" };\n\n          // Find matching country code\n          for (const country of countries) {\n            if (value.startsWith(country.dialCode)) {\n              return {\n                dialCode: country.dialCode,\n                number: value.slice(country.dialCode.length).trim(),\n              };\n            }\n          }\n          return { dialCode: selectedCountry.dialCode, number: value };\n        };\n\n        const { number } = parsePhoneValue(field.value);\n\n        const handleCountryChange = (countryCode: string | null) => {\n          if (!countryCode) return;\n          const country = countries.find((c) => c.code === countryCode);\n          if (country) {\n            setSelectedCountry(country);\n            // Update the full phone number with new dial code\n            if (number) {\n              field.onChange(`${country.dialCode}${number}`);\n            }\n          }\n        };\n\n        const handleNumberChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n          const raw = e.target.value.replace(/[^0-9]/g, \"\");\n          if (raw) {\n            field.onChange(`${selectedCountry.dialCode}${raw}`);\n          } else {\n            field.onChange(\"\");\n          }\n        };\n\n        return (\n          <div className={cn(\"flex gap-2\", className)}>\n            <Select\n              value={selectedCountry.code}\n              onValueChange={handleCountryChange}\n              disabled={disabled}\n            >\n              <SelectTrigger className=\"w-24 shrink-0\">\n                <SelectValue>\n                  <span className=\"text-sm\">{selectedCountry.dialCode}</span>\n                </SelectValue>\n              </SelectTrigger>\n              <SelectContent>\n                {countries.map((country) => (\n                  <SelectItem key={country.code} value={country.code}>\n                    <span className=\"flex items-center gap-2\">\n                      <span className=\"text-muted-foreground\">\n                        {country.dialCode}\n                      </span>\n                      <span>{country.name}</span>\n                    </span>\n                  </SelectItem>\n                ))}\n              </SelectContent>\n            </Select>\n            <Input\n              id={field.name}\n              type=\"tel\"\n              inputMode=\"tel\"\n              value={number}\n              onChange={handleNumberChange}\n              placeholder={placeholder}\n              disabled={disabled}\n              aria-invalid={!!fieldState.error}\n              aria-required={required}\n              aria-describedby={ariaDescribedBy}\n              className=\"flex-1\"\n            />\n          </div>\n        );\n      }}\n    </BaseController>\n  );\n}\n"}]},{"name":"rhf-currency-field","title":"RHF Currency Field","description":"Currency input with symbol and React Hook Form integration.","type":"registry:ui","docs":"/components/rhf-currency-field","categories":["forms"],"registryDependencies":["https://pb-ui-five.vercel.app/registry/rhf-base-controller","https://pb-ui-five.vercel.app/registry/input"],"dependencies":["react-hook-form"],"files":[{"path":"components/ui/rhf-inputs/currency-field.tsx","target":"components/ui/rhf-inputs/currency-field.tsx","type":"registry:ui","content":"\"use client\";\n\nimport { cn } from \"@/lib/utils\";\nimport * as React from \"react\";\nimport { FieldValues } from \"react-hook-form\";\nimport { Input } from \"../input\";\nimport { BaseController, BaseControllerProps } from \"./base-controller\";\n\ntype CurrencyFieldProps<T extends FieldValues> = Omit<\n  BaseControllerProps<T>,\n  \"children\"\n> & {\n  currency?: string;\n  locale?: string;\n  min?: number;\n  max?: number;\n  placeholder?: string;\n  disabled?: boolean;\n  className?: string;\n  allowCents?: boolean;\n};\n\nfunction CurrencyInput({\n  value,\n  onChange,\n  onBlur,\n  min,\n  max,\n  currencySymbol,\n  decimalSeparator,\n  placeholder,\n  disabled,\n  id,\n  error,\n  required,\n  allowCents = false,\n  formatValue,\n  ariaDescribedBy,\n}: {\n  value: number | null | undefined;\n  onChange: (value: number | null) => void;\n  onBlur: () => void;\n  min?: number;\n  max?: number;\n  currencySymbol: string;\n  decimalSeparator: string;\n  placeholder?: string;\n  disabled?: boolean;\n  id: string;\n  error?: boolean;\n  required?: boolean;\n  allowCents?: boolean;\n  formatValue: (value: number) => string;\n  ariaDescribedBy?: string;\n}) {\n  const [inputValue, setInputValue] = React.useState<string>(\n    value != null ? formatValue(value) : \"\",\n  );\n  const [isFocused, setIsFocused] = React.useState(false);\n\n  React.useEffect(() => {\n    if (!isFocused) {\n      setInputValue(value != null ? formatValue(value) : \"\");\n    }\n  }, [value, formatValue, isFocused]);\n\n  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n    const input = e.target.value;\n\n    // Allow digits, minus, and the locale-specific decimal separator\n    const escapedSep = decimalSeparator.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n    const pattern = allowCents\n      ? new RegExp(`[^0-9${escapedSep}-]`, \"g\")\n      : /[^0-9-]/g;\n\n    const raw = input.replace(pattern, \"\");\n\n    // Normalize decimal separator to period for parsing\n    const normalized = raw.replace(decimalSeparator, \".\");\n\n    setInputValue(raw);\n\n    if (normalized === \"\" || normalized === \"-\") {\n      onChange(null);\n      return;\n    }\n\n    const parsed = allowCents\n      ? parseFloat(normalized)\n      : parseInt(normalized, 10);\n    if (!isNaN(parsed)) {\n      let clamped = parsed;\n      if (min != null) clamped = Math.max(min, clamped);\n      if (max != null) clamped = Math.min(max, clamped);\n      onChange(clamped);\n    }\n  };\n\n  const handleFocus = () => {\n    setIsFocused(true);\n    // Show raw number when focused for easier editing\n    if (value != null) {\n      const rawValue = allowCents\n        ? String(value).replace(\".\", decimalSeparator)\n        : String(value);\n      setInputValue(rawValue);\n    }\n  };\n\n  const handleBlurInput = () => {\n    setIsFocused(false);\n    // Format value on blur\n    if (value != null) {\n      setInputValue(formatValue(value));\n    } else {\n      setInputValue(\"\");\n    }\n    onBlur();\n  };\n\n  return (\n    <div className=\"relative\">\n      <span className=\"top-1/2 left-3 absolute text-muted-foreground text-sm -translate-y-1/2 pointer-events-none\">\n        {currencySymbol}\n      </span>\n      <Input\n        id={id}\n        type=\"text\"\n        inputMode=\"decimal\"\n        value={inputValue}\n        onChange={handleChange}\n        onFocus={handleFocus}\n        onBlur={handleBlurInput}\n        placeholder={placeholder}\n        disabled={disabled}\n        aria-invalid={error}\n        aria-required={required}\n        aria-describedby={ariaDescribedBy}\n        className=\"pl-7\"\n      />\n    </div>\n  );\n}\n\nexport function CurrencyField<T extends FieldValues>({\n  control,\n  name,\n  label,\n  description,\n  required,\n  disableFieldError = false,\n  currency = \"USD\",\n  locale = \"en-US\",\n  min,\n  max,\n  placeholder,\n  disabled = false,\n  className,\n  allowCents = false,\n}: CurrencyFieldProps<T>) {\n  const currencySymbol = React.useMemo(() => {\n    return (\n      new Intl.NumberFormat(locale, {\n        style: \"currency\",\n        currency,\n        minimumFractionDigits: 0,\n        maximumFractionDigits: 0,\n      })\n        .formatToParts(0)\n        .find((part) => part.type === \"currency\")?.value ?? \"$\"\n    );\n  }, [locale, currency]);\n\n  const decimalSeparator = React.useMemo(() => {\n    return (\n      new Intl.NumberFormat(locale)\n        .formatToParts(1.1)\n        .find((part) => part.type === \"decimal\")?.value ?? \".\"\n    );\n  }, [locale]);\n\n  const formatValue = React.useCallback(\n    (value: number) => {\n      return new Intl.NumberFormat(locale, {\n        minimumFractionDigits: allowCents ? 2 : 0,\n        maximumFractionDigits: allowCents ? 2 : 0,\n      }).format(value);\n    },\n    [locale, allowCents],\n  );\n\n  return (\n    <BaseController\n      control={control}\n      name={name}\n      label={label}\n      required={required}\n      description={description}\n      disableFieldError={disableFieldError}\n    >\n      {({ field, fieldState, ariaDescribedBy }) => (\n        <div className={cn(className)}>\n          <CurrencyInput\n            value={field.value}\n            onChange={(value) => field.onChange(value)}\n            onBlur={field.onBlur}\n            min={min}\n            max={max}\n            currencySymbol={currencySymbol}\n            decimalSeparator={decimalSeparator}\n            placeholder={placeholder}\n            disabled={disabled}\n            id={field.name}\n            error={!!fieldState.error}\n            required={required}\n            allowCents={allowCents}\n            formatValue={formatValue}\n            ariaDescribedBy={ariaDescribedBy}\n          />\n        </div>\n      )}\n    </BaseController>\n  );\n}\n"}]},{"name":"rhf-color-picker-field","title":"RHF Color Picker Field","description":"Color picker field with React Hook Form integration.","type":"registry:ui","docs":"/components/rhf-color-picker-field","categories":["forms"],"registryDependencies":["https://pb-ui-five.vercel.app/registry/rhf-base-controller","https://pb-ui-five.vercel.app/registry/color-picker"],"dependencies":["react-hook-form"],"files":[{"path":"components/ui/rhf-inputs/color-picker-field.tsx","target":"components/ui/rhf-inputs/color-picker-field.tsx","type":"registry:ui","content":"\"use client\";\n\nimport { FieldValues } from \"react-hook-form\";\nimport { ColorPicker, ColorPickerProps } from \"../color-picker\";\nimport { BaseController, BaseControllerProps } from \"./base-controller\";\n\ntype ColorPickerFieldProps<T extends FieldValues> = Omit<\n  BaseControllerProps<T>,\n  \"children\"\n> &\n  Omit<ColorPickerProps, \"value\" | \"onChange\">;\n\nexport function ColorPickerField<T extends FieldValues>({\n  control,\n  name,\n  label,\n  description,\n  required,\n  disableFieldError = false,\n  showInput,\n  disabled,\n  className,\n}: ColorPickerFieldProps<T>) {\n  return (\n    <BaseController\n      control={control}\n      name={name}\n      label={label}\n      required={required}\n      description={description}\n      disableFieldError={disableFieldError}\n    >\n      {({ field, fieldState, ariaDescribedBy }) => (\n        <ColorPicker\n          id={field.name}\n          value={field.value ?? \"#000000\"}\n          onChange={(value) => field.onChange(value)}\n          showInput={showInput}\n          disabled={disabled}\n          aria-invalid={!!fieldState.error}\n          aria-describedby={ariaDescribedBy}\n          className={className}\n        />\n      )}\n    </BaseController>\n  );\n}\n"}]},{"name":"rhf-rating-field","title":"RHF Rating Field","description":"Star rating field with React Hook Form integration.","type":"registry:ui","docs":"/components/rhf-rating-field","categories":["forms"],"registryDependencies":["https://pb-ui-five.vercel.app/registry/rhf-base-controller","https://pb-ui-five.vercel.app/registry/rating"],"dependencies":["react-hook-form"],"files":[{"path":"components/ui/rhf-inputs/rating-field.tsx","target":"components/ui/rhf-inputs/rating-field.tsx","type":"registry:ui","content":"\"use client\";\n\nimport { FieldValues } from \"react-hook-form\";\nimport { Rating, RatingProps } from \"../rating\";\nimport { BaseController, BaseControllerProps } from \"./base-controller\";\n\ntype RatingFieldProps<T extends FieldValues> = Omit<\n  BaseControllerProps<T>,\n  \"children\"\n> &\n  Omit<RatingProps, \"value\" | \"onChange\">;\n\nexport function RatingField<T extends FieldValues>({\n  control,\n  name,\n  label,\n  description,\n  required,\n  disableFieldError = false,\n  max,\n  disabled,\n  readOnly,\n  allowHalf,\n  size,\n  className,\n}: RatingFieldProps<T>) {\n  return (\n    <BaseController\n      control={control}\n      name={name}\n      label={label}\n      required={required}\n      description={description}\n      disableFieldError={disableFieldError}\n    >\n      {({ field, fieldState, ariaDescribedBy }) => (\n        <Rating\n          value={field.value ?? 0}\n          onChange={(value) => field.onChange(value)}\n          max={max}\n          disabled={disabled}\n          readOnly={readOnly}\n          allowHalf={allowHalf}\n          size={size}\n          aria-invalid={!!fieldState.error}\n          aria-describedby={ariaDescribedBy}\n          className={className}\n        />\n      )}\n    </BaseController>\n  );\n}\n"}]},{"name":"rhf-inputs","title":"React Hook Form Inputs (All)","description":"Complete collection of form field components with React Hook Form integration.","type":"registry:ui","docs":"/components/rhf-inputs","categories":["forms","data-entry"],"registryDependencies":["https://pb-ui-five.vercel.app/registry/rhf-base-controller","https://pb-ui-five.vercel.app/registry/rhf-input-field","https://pb-ui-five.vercel.app/registry/rhf-checkbox-field","https://pb-ui-five.vercel.app/registry/rhf-checkbox-group-field","https://pb-ui-five.vercel.app/registry/rhf-select-field","https://pb-ui-five.vercel.app/registry/rhf-combobox-field","https://pb-ui-five.vercel.app/registry/rhf-textarea-field","https://pb-ui-five.vercel.app/registry/rhf-radio-group-field","https://pb-ui-five.vercel.app/registry/rhf-slider-field","https://pb-ui-five.vercel.app/registry/rhf-switch-field","https://pb-ui-five.vercel.app/registry/rhf-password-field","https://pb-ui-five.vercel.app/registry/rhf-input-with-tag-field","https://pb-ui-five.vercel.app/registry/rhf-multi-select-field","https://pb-ui-five.vercel.app/registry/rhf-number-field","https://pb-ui-five.vercel.app/registry/rhf-otp-field","https://pb-ui-five.vercel.app/registry/rhf-input-date-field","https://pb-ui-five.vercel.app/registry/rhf-date-picker-field","https://pb-ui-five.vercel.app/registry/rhf-date-time-picker-field","https://pb-ui-five.vercel.app/registry/rhf-range-date-picker-field","https://pb-ui-five.vercel.app/registry/rhf-time-picker-field","https://pb-ui-five.vercel.app/registry/rhf-file-upload-field","https://pb-ui-five.vercel.app/registry/rhf-phone-field","https://pb-ui-five.vercel.app/registry/rhf-currency-field","https://pb-ui-five.vercel.app/registry/rhf-color-picker-field","https://pb-ui-five.vercel.app/registry/rhf-rating-field"],"dependencies":["react-hook-form"],"files":[{"path":"components/ui/rhf-inputs/index.ts","target":"components/ui/rhf-inputs/index.ts","type":"registry:ui","content":"export { BaseController, type BaseControllerProps } from \"./base-controller\";\nexport { CheckboxField } from \"./checkbox-field\";\nexport { CheckboxGroupField, type CheckboxGroupOption } from \"./checkbox-group-field\";\nexport { ColorPickerField } from \"./color-picker-field\";\nexport { ComboboxField, type ComboboxOption, type ComboboxOptionGroup } from \"./combobox-field\";\nexport { CurrencyField } from \"./currency-field\";\nexport { DatePickerField } from \"./date-picker-field\";\nexport { DateTimePickerField } from \"./date-time-picker-field\";\nexport { FileUploadField } from \"./file-upload-field\";\nexport { InputDateField } from \"./input-date-field\";\nexport { InputField } from \"./input-field\";\nexport { InputWithTagField } from \"./input-with-tag-field\";\nexport { MultiSelectField } from \"./multi-select-field\";\nexport { NumberField } from \"./number-field\";\nexport { OTPField } from \"./otp-field\";\nexport { PasswordField } from \"./password-field\";\nexport { PhoneField, type Country } from \"./phone-field\";\nexport { RadioGroupField } from \"./radio-group-field\";\nexport { RangeDatePickerField } from \"./range-date-picker-field\";\nexport { RatingField } from \"./rating-field\";\nexport { SelectField } from \"./select-field\";\nexport { SliderField } from \"./slider-field\";\nexport { SwitchField } from \"./switch-field\";\nexport { TextareaField } from \"./textarea-field\";\nexport { TimePickerField } from \"./time-picker-field\";\n"}]}]}