{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "input",
  "title": "Input",
  "author": "Ballmac <https://ui.ballmac.com>",
  "description": "A text input in three heights that match Button, plus InputGroup and InputGroupAddon for leading or trailing icons, units and domains.",
  "dependencies": [
    "class-variance-authority"
  ],
  "registryDependencies": [
    "utils"
  ],
  "files": [
    {
      "path": "registry/ballmac/components/input.tsx",
      "content": "// Ballmac UI: Input. https://ui.ballmac.com/components/input\n// Based on shadcn/ui's Input (MIT, Copyright (c) 2023 shadcn), restyled with sizes and an InputGroup for addons.\n\"use client\"\n\nimport * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst inputVariants = cva(\n  \"flex w-full min-w-0 rounded-md border border-input bg-background text-foreground shadow-xs outline-none transition-[color,border-color,box-shadow] duration-150 selection:bg-primary selection:text-primary-foreground placeholder:text-muted-foreground file:inline-flex file:h-6 file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:bg-input/30\",\n  {\n    variants: {\n      size: {\n        sm: \"h-8 px-2.5 text-[13px]\",\n        default: \"h-9 px-3 text-sm\",\n        lg: \"h-11 px-4 text-[15px]\",\n      },\n    },\n    defaultVariants: { size: \"default\" },\n  }\n)\n\ntype InputProps = Omit<React.ComponentProps<\"input\">, \"size\"> &\n  VariantProps<typeof inputVariants> & {\n    /** Native `size` attribute (visible character width). `size` is the height variant. */\n    htmlSize?: number\n  }\n\nfunction Input({ className, type = \"text\", size = \"default\", htmlSize, ...props }: InputProps) {\n  return (\n    <input\n      type={type}\n      data-slot=\"input\"\n      size={htmlSize}\n      className={cn(inputVariants({ size }), className)}\n      {...props}\n    />\n  )\n}\n\nconst inputGroupVariants = cva(\"\", {\n  variants: {\n    size: {\n      sm: \"h-8 [&>[data-slot=input]]:text-[13px]\",\n      default: \"h-9\",\n      lg: \"h-11 [&>[data-slot=input]]:text-[15px]\",\n    },\n  },\n  defaultVariants: { size: \"default\" },\n})\n\ntype InputGroupProps = React.ComponentProps<\"div\"> & VariantProps<typeof inputGroupVariants>\n\n/**\n * Wraps an Input with leading or trailing addons (icons, units, domains).\n * The group draws the border, height and focus ring; the inner input goes borderless.\n */\nfunction InputGroup({ className, size = \"default\", ...props }: InputGroupProps) {\n  return (\n    <div\n      data-slot=\"input-group\"\n      role=\"group\"\n      className={cn(\n        inputGroupVariants({ size }),\n        \"relative flex w-full min-w-0 items-center rounded-md border border-input bg-background shadow-xs transition-[color,border-color,box-shadow] duration-150 dark:bg-input/30\",\n        \"has-[[data-slot=input]:focus-visible]:border-ring has-[[data-slot=input]:focus-visible]:ring-[3px] has-[[data-slot=input]:focus-visible]:ring-ring/50\",\n        \"has-[[data-slot=input][aria-invalid=true]]:border-destructive has-[[data-slot=input][aria-invalid=true]]:ring-destructive/20\",\n        \"has-[[data-slot=input]:disabled]:opacity-50\",\n        \"[&>[data-slot=input]]:h-full [&>[data-slot=input]]:flex-1 [&>[data-slot=input]]:border-0 [&>[data-slot=input]]:bg-transparent [&>[data-slot=input]]:shadow-none [&>[data-slot=input]]:ring-0 [&>[data-slot=input]]:focus-visible:ring-0 [&>[data-slot=input]]:dark:bg-transparent\",\n        \"has-[>[data-align=start]]:[&>[data-slot=input]]:ps-1.5 has-[>[data-align=end]]:[&>[data-slot=input]]:pe-1.5\",\n        className\n      )}\n      {...props}\n    />\n  )\n}\n\ntype InputGroupAddonProps = React.ComponentProps<\"div\"> & {\n  /** Which side of the input the addon sits on (visual order; keep markup order the same for screen readers). */\n  align?: \"start\" | \"end\"\n}\n\nfunction InputGroupAddon({ className, align = \"start\", onMouseDown, ...props }: InputGroupAddonProps) {\n  return (\n    <div\n      data-slot=\"input-group-addon\"\n      data-align={align}\n      className={cn(\n        \"flex h-full shrink-0 select-none items-center gap-1.5 text-sm text-muted-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n        align === \"start\" ? \"order-first ps-3\" : \"order-last pe-3\",\n        className\n      )}\n      onMouseDown={(event) => {\n        onMouseDown?.(event)\n        // Clicking an addon focuses the input, like a label would.\n        if (event.defaultPrevented || (event.target as HTMLElement).closest(\"button, a, input, select, textarea\")) return\n        const input = event.currentTarget.parentElement?.querySelector<HTMLInputElement>(\"[data-slot=input]\")\n        if (input) {\n          event.preventDefault()\n          input.focus()\n        }\n      }}\n      {...props}\n    />\n  )\n}\n\nexport { Input, InputGroup, InputGroupAddon, inputVariants, inputGroupVariants, type InputProps, type InputGroupProps, type InputGroupAddonProps }\n",
      "type": "registry:ui",
      "target": "@components/ballmac/input.tsx"
    }
  ],
  "meta": {
    "schema": 1,
    "tier": "free",
    "tags": [
      "input",
      "text-field",
      "form",
      "search"
    ],
    "version": "1.0.0",
    "updated": "2026-09-28",
    "ai": {
      "summary": "Single-line text field. Use size to match neighbouring buttons, wrap in InputGroup with InputGroupAddon (align start or end) for icons or text like \".com\", and set aria-invalid for error styling.",
      "whenToUse": [
        "Any single-line form field (email, name, URL, search)",
        "Search boxes with a leading icon",
        "Fields with a fixed unit or domain suffix"
      ],
      "whenNotToUse": [
        "Multi-line text (use textarea)",
        "Choosing from a fixed list (use select)",
        "On/off settings (use switch or checkbox)"
      ],
      "composesWith": [
        "label",
        "button",
        "kbd",
        "tooltip",
        "dialog"
      ],
      "a11y": [
        {
          "keys": "Tab",
          "action": "Moves focus to the input"
        },
        {
          "keys": "Click on an addon",
          "action": "Focuses the input"
        }
      ],
      "customization": [
        "size: sm | default | lg (h-8 / h-9 / h-11)",
        "InputGroup size: sm | default | lg; InputGroupAddon align: start | end",
        "aria-invalid=\"true\" switches to destructive border and ring",
        "htmlSize maps to the native size attribute"
      ]
    },
    "source": {
      "name": "shadcn/ui Input",
      "url": "https://github.com/shadcn-ui/ui",
      "license": "MIT",
      "copyright": "Copyright (c) 2023 shadcn",
      "modified": true
    },
    "examples": [
      "input-demo",
      "input-with-icon",
      "input-invalid"
    ],
    "url": "https://ui.ballmac.com/components/input"
  },
  "categories": [
    "primitives"
  ],
  "type": "registry:ui"
}