{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "input-group",
  "description": "Add addons, buttons, and helper content to inputs.",
  "dependencies": [
    "class-variance-authority"
  ],
  "registryDependencies": [
    "@ondo-ui/button",
    "@ondo-ui/input",
    "@ondo-ui/textarea",
    "@ondo-ui/utils"
  ],
  "files": [
    {
      "path": "components/ui/input-group.tsx",
      "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\ntype InputGroupSize = \"xs\" | \"sm\" | \"default\" | \"lg\" | \"xl\" | \"2xl\"\n\nconst InputGroupSizeContext = React.createContext<InputGroupSize>(\"default\")\n\nfunction InputGroup({\n  className,\n  size = \"default\",\n  ...props\n}: React.ComponentProps<\"div\"> & { size?: InputGroupSize }) {\n  return (\n    <InputGroupSizeContext.Provider value={size}>\n      <div\n        data-slot=\"input-group\"\n        data-size={size}\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 data-[size=lg]:h-10 data-[size=sm]:h-8 data-[size=xs]:h-6 data-[size=xl]:h-11 data-[size=xl]:rounded-lg data-[size=2xl]:h-13 data-[size=2xl]:rounded-xl 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    </InputGroupSizeContext.Provider>\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 group-data-[size=xs]/input-group:gap-1 group-data-[size=xs]/input-group:py-0.5 group-data-[size=xs]/input-group:text-xs group-data-[size=xl]/input-group:text-base group-data-[size=2xl]/input-group:gap-2.5 group-data-[size=2xl]/input-group:text-lg [&>kbd]:rounded-[calc(var(--radius)-5px)] [&>svg:not([class*='size-'])]:size-4 group-data-[size=xs]/input-group:[&>svg:not([class*='size-'])]:size-3 group-data-[size=xl]/input-group:[&>svg:not([class*='size-'])]:size-5 group-data-[size=2xl]/input-group:[&>svg:not([class*='size-'])]:size-6\",\n  {\n    variants: {\n      align: {\n        \"inline-start\":\n          \"order-first pl-2 group-data-[size=xl]/input-group:pl-3 group-data-[size=2xl]/input-group:pl-4 has-[>button]:-ml-1 group-data-[size=xl]/input-group:has-[>button]:-ml-1.5 group-data-[size=2xl]/input-group:has-[>button]:-ml-2 has-[>kbd]:ml-[-0.15rem]\",\n        \"inline-end\":\n          \"order-last pr-2 group-data-[size=xl]/input-group:pr-3 group-data-[size=2xl]/input-group:pr-4 has-[>button]:-mr-1 group-data-[size=xl]/input-group:has-[>button]:-mr-1.5 group-data-[size=2xl]/input-group:has-[>button]:-mr-2 has-[>kbd]:mr-[-0.15rem]\",\n        \"block-start\":\n          \"order-first w-full justify-start px-2.5 pt-2 group-data-[size=xs]/input-group:px-2 group-data-[size=xl]/input-group:px-3 group-data-[size=2xl]/input-group:px-4 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-data-[size=xs]/input-group:px-2 group-data-[size=xl]/input-group:px-3 group-data-[size=2xl]/input-group:px-4 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\n// Matches upstream shadcn exactly: the same four sizes, the same classes, and\n// the size is NOT forwarded to Button. Diverging here would make a demo copied\n// from the shadcn docs render differently -- upstream's `icon-xs` inherits\n// Button's default 16px icon, and forwarding the size would shrink it to 12px.\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\n// Used when `size` is omitted. In a `default` group this renders exactly like\n// upstream's `xs`; the group-scaled steps only exist for the sizes upstream's\n// InputGroup does not have. The addon contributes vertical padding, so a fitted\n// button is that much shorter than the group. Height only -- an icon-only button\n// needs an explicit `icon-*` size, because CSS cannot tell an icon-only button\n// from one with text: `:only-child` ignores text nodes, so `svg:only-child`\n// matches `<button>label <svg/></button>` too.\nconst inputGroupButtonAutoSize =\n  \"h-6 gap-1 rounded-[calc(var(--radius)-5px)] px-1.5 [&>svg:not([class*='size-'])]:size-3.5 \" +\n  \"group-data-[size=xs]/input-group:h-5 group-data-[size=xs]/input-group:gap-0.5 group-data-[size=xs]/input-group:px-1 group-data-[size=xs]/input-group:text-xs group-data-[size=xs]/input-group:[&>svg:not([class*='size-'])]:size-3 \" +\n  \"group-data-[size=sm]/input-group:h-5 \" +\n  \"group-data-[size=lg]/input-group:h-7 \" +\n  \"group-data-[size=xl]/input-group:h-8 group-data-[size=xl]/input-group:rounded-md group-data-[size=xl]/input-group:px-2 group-data-[size=xl]/input-group:[&>svg:not([class*='size-'])]:size-4 \" +\n  \"group-data-[size=2xl]/input-group:h-10 group-data-[size=2xl]/input-group:gap-1.5 group-data-[size=2xl]/input-group:rounded-md group-data-[size=2xl]/input-group:px-2.5 group-data-[size=2xl]/input-group:text-base group-data-[size=2xl]/input-group:[&>svg:not([class*='size-'])]:size-4\"\n\nfunction InputGroupButton({\n  className,\n  type = \"button\",\n  variant = \"ghost\",\n  size,\n  ...props\n}: Omit<React.ComponentProps<typeof Button>, \"size\" | \"type\"> &\n  VariantProps<typeof inputGroupButtonVariants> & {\n    type?: \"button\" | \"submit\" | \"reset\"\n  }) {\n  if (size == null) {\n    return (\n      <Button\n        type={type}\n        data-size=\"auto\"\n        variant={variant}\n        className={cn(inputGroupButtonAutoSize, className)}\n        {...props}\n      />\n    )\n  }\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}: Omit<React.ComponentProps<typeof Input>, \"size\">) {\n  const size = React.useContext(InputGroupSizeContext)\n\n  return (\n    <Input\n      data-slot=\"input-group-control\"\n      size={size}\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}: Omit<React.ComponentProps<\"textarea\">, \"size\">) {\n  const size = React.useContext(InputGroupSizeContext)\n\n  return (\n    <Textarea\n      data-slot=\"input-group-control\"\n      size={size}\n      className={cn(\n        \"flex-1 resize-none 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\nexport {\n  InputGroup,\n  InputGroupAddon,\n  InputGroupButton,\n  InputGroupText,\n  InputGroupInput,\n  InputGroupTextarea,\n}\n",
      "type": "registry:ui"
    }
  ],
  "type": "registry:ui"
}