{
  "name": "input-group",
  "type": "registry:ui",
  "title": "Input Group",
  "description": "Input Group combines an input or textarea with tightly related icons, units, text, shortcuts, or inline actions.",
  "registryDependencies": [
    "@siteplane/base",
    "@siteplane/input",
    "@siteplane/textarea"
  ],
  "dependencies": [
    "class-variance-authority@0.7.1"
  ],
  "files": [
    {
      "path": "src/components/ui/input-group.tsx",
      "type": "registry:ui",
      "content": "\"use client\";\n\nimport { cva, type VariantProps } from \"class-variance-authority\";\nimport type * as React from \"react\";\nimport { cn } from \"@/lib/utils\";\nimport { Input, type InputProps } from \"@/components/ui/input\";\nimport { surfaceClassNames } from \"@/components/ui/surface\";\nimport { Textarea, type TextareaProps } from \"@/components/ui/textarea\";\n\nconst inputGroupAddonVariants = cva(\n  \"flex h-auto cursor-text select-none items-center justify-center gap-2 leading-none [&>kbd]:rounded-[calc(var(--radius)-5px)] in-[[data-slot=input-group]:has([data-slot=input-control],[data-slot=textarea-control])]:[&_svg:not([class*='size-'])]:size-4.5 sm:in-[[data-slot=input-group]:has([data-slot=input-control],[data-slot=textarea-control])]:[&_svg:not([class*='size-'])]:size-4 [&_svg]:-mx-0.5 not-has-[button]:**:[svg:not([class*='opacity-'])]:opacity-80\",\n  {\n    defaultVariants: {\n      align: \"inline-start\",\n    },\n    variants: {\n      align: {\n        \"block-end\":\n          \"order-last w-full justify-start px-[calc(--spacing(3)-1px)] pb-[calc(--spacing(3)-1px)] [.border-t]:pt-[calc(--spacing(3)-1px)] [[data-size=sm]+&]:px-[calc(--spacing(2.5)-1px)]\",\n        \"block-start\":\n          \"order-first w-full justify-start px-[calc(--spacing(3)-1px)] pt-[calc(--spacing(3)-1px)] [.border-b]:pb-[calc(--spacing(3)-1px)] [[data-size=sm]+&]:px-[calc(--spacing(2.5)-1px)]\",\n        \"inline-end\":\n          \"order-last pe-[calc(--spacing(3)-1px)] has-[>:last-child[data-slot=badge]]:-me-1.5 has-[>button]:-me-2 has-[>kbd:last-child]:me-[-0.35rem] [[data-size=sm]+&]:pe-[calc(--spacing(2.5)-1px)]\",\n        \"inline-start\":\n          \"order-first ps-[calc(--spacing(3)-1px)] has-[>:last-child[data-slot=badge]]:-ms-1.5 has-[>button]:-ms-2 has-[>kbd:last-child]:ms-[-0.35rem] [[data-size=sm]+&]:ps-[calc(--spacing(2.5)-1px)]\",\n      },\n    },\n  },\n);\n\nexport function InputGroup({\n  className,\n  variant = \"default\",\n  ...props\n}: React.ComponentProps<\"div\"> & {\n  variant?: \"default\" | \"soft\";\n}): React.ReactElement {\n  return (\n    <div\n      className={cn(\n        variant === \"soft\"\n          ? surfaceClassNames.formControlCompositeSoft\n          : surfaceClassNames.formControlComposite,\n        \"has-[textarea]:h-auto has-autofill:bg-foreground/4 has-data-[size=xl]:text-base has-data-[align=block-end]:h-auto has-data-[align=block-start]:h-auto has-data-[align=block-end]:flex-col has-data-[align=block-start]:flex-col dark:has-autofill:bg-foreground/8 sm:has-data-[size=xl]:text-base has-data-[align=inline-start]:**:[[data-size=sm]_input]:ps-1.5 has-data-[align=inline-end]:**:[[data-size=sm]_input]:pe-1.5 *:[[data-slot=input-control],[data-slot=textarea-control]]:contents *:[[data-slot=input-control],[data-slot=textarea-control]]:before:hidden has-[[data-align=block-start],[data-align=block-end]]:**:[input]:h-auto has-data-[align=inline-start]:**:[input]:ps-2 has-data-[align=inline-end]:**:[input]:pe-2 has-data-[align=block-end]:**:[input]:pt-1.5 has-data-[align=block-start]:**:[input]:pb-1.5 **:[textarea]:min-h-20.5 **:[textarea]:resize-y **:[textarea]:py-[calc(--spacing(3)-1px)] **:[textarea]:max-sm:min-h-23.5 **:[textarea_button]:rounded-[calc(var(--radius-md)-1px)]\",\n        className,\n      )}\n      data-slot=\"input-group\"\n      data-variant={variant}\n      role=\"group\"\n      {...props}\n    />\n  );\n}\n\nexport function InputGroupAddon({\n  className,\n  align = \"inline-start\",\n  ...props\n}: React.ComponentProps<\"div\"> &\n  VariantProps<typeof inputGroupAddonVariants>): React.ReactElement {\n  return (\n    <div\n      className={cn(inputGroupAddonVariants({ align }), className)}\n      data-align={align}\n      data-slot=\"input-group-addon\"\n      onMouseDown={(e: React.MouseEvent<HTMLDivElement>) => {\n        const target = e.target as HTMLElement;\n        const isInteractive = target.closest(\n          \"button, a, input, select, textarea, [role='button'], [role='combobox'], [role='listbox'], [data-slot='select-trigger']\",\n        );\n        if (isInteractive) return;\n        e.preventDefault();\n        const parent = e.currentTarget.parentElement;\n        const input = parent?.querySelector<\n          HTMLInputElement | HTMLTextAreaElement\n        >(\"input, textarea\");\n        if (input && !parent?.querySelector(\"input:focus, textarea:focus\")) {\n          input.focus();\n        }\n      }}\n      {...props}\n    />\n  );\n}\n\nexport function InputGroupText({\n  className,\n  ...props\n}: React.ComponentProps<\"span\">): React.ReactElement {\n  return (\n    <span\n      className={cn(\n        \"line-clamp-1 flex items-center gap-2 whitespace-nowrap text-muted-foreground leading-none in-[[data-slot=input-group]:has([data-slot=input-control],[data-slot=textarea-control])]:[&_svg:not([class*='size-'])]:size-4.5 sm:in-[[data-slot=input-group]:has([data-slot=input-control],[data-slot=textarea-control])]:[&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:-mx-0.5\",\n        className,\n      )}\n      {...props}\n    />\n  );\n}\n\nexport function InputGroupInput({\n  className,\n  ...props\n}: InputProps): React.ReactElement {\n  return <Input className={className} unstyled {...props} />;\n}\n\nexport function InputGroupTextarea({\n  className,\n  ...props\n}: TextareaProps): React.ReactElement {\n  return <Textarea className={className} unstyled {...props} />;\n}\n"
    }
  ],
  "categories": [
    "form-controls"
  ],
  "docs": "# Input Group\n\n> Siteplane UI release `0.1.1`.\n\n## Public Purpose\n\nInput Group combines an input or textarea with tightly related icons, units,\ntext, keyboard shortcuts, or inline actions.\n\n## Import\n\n`import { InputGroup, InputGroupAddon, InputGroupInput, InputGroupText, InputGroupTextarea } from \"@/components/ui/input-group\";`\n\n## Public API\n\n- `InputGroupAddon align` accepts `\"inline-start\"`, `\"inline-end\"`,\n  `\"block-start\"`, or `\"block-end\"`. Block start places the addon row above\n  the field.\n- Use `InputGroupText` for non-interactive prefixes, suffixes, and units.\n- Kbd may be placed in an addon and receives the native radius and spacing\n  treatment.\n- Put real Button controls in an addon for copy, reveal, submit, or composer\n  actions. Textarea groups include native Button layout for action rows.\n- Use Input Group only when the addon is tightly coupled to the field value.\n\n## Public Motion\n\n- Focus and invalid rings wrap the complete group.\n- Empty addon space may focus the field; an interactive child keeps its own\n  Button action.\n- The group itself does not animate, and invalid or disabled state must not\n  change its dimensions.\n\n## Public Accessibility\n\n- Give every input or textarea a visible FieldLabel, `aria-label`, or\n  `aria-labelledby`.\n- Every interactive addon Button needs its own accessible name.\n- Supporting text, icons, units, and Kbd hints must not become the field's only\n  label.\n- Connect invalid state to the field and render a visible FieldError.\n\n## Public Agent Guidance\n\n- Use `align` instead of custom addon layout.\n- Use Input for a plain field without closely related addons.\n- Preserve focus routing, group rings, textarea action layout, and child control\n  semantics.\n\n## Public Links\n\n- [Documentation and preview](https://ui.siteplane.io/docs/components/form-controls/input-group)\n\n- [Registry source](https://ui.siteplane.io/r/input-group.json)\n",
  "meta": {
    "siteplane:agentContractVersion": 1,
    "siteplane:docs": "https://ui.siteplane.io/docs/components/form-controls/input-group",
    "siteplane:releaseVersion": "0.1.1",
    "siteplane:sourceOwned": true
  },
  "devDependencies": []
}
