{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "input-group-story",
  "title": "Input Group Story",
  "author": "Lloyd Richards <lloyd.d.richards@gmail.com>",
  "description": "Interactive Storybook stories demonstrating input group component usage and variants",
  "registryDependencies": [
    "button-group",
    "dropdown-menu",
    "input-group",
    "label",
    "popover",
    "spinner",
    "tooltip"
  ],
  "files": [
    {
      "path": "registry/ui/input-group-story/input-group-base.stories.tsx",
      "content": "// Replace nextjs-vite with the name of your framework\nimport type { Meta, StoryObj } from \"@storybook/nextjs-vite\";\nimport {\n  Check,\n  CheckIcon,\n  ChevronDownIcon,\n  Code,\n  Copy,\n  CornerDownLeft,\n  CreditCardIcon,\n  HelpCircle,\n  Info,\n  InfoIcon,\n  Link2Icon,\n  LoaderIcon,\n  MailIcon,\n  MoreHorizontal,\n  RefreshCcw,\n  SearchIcon,\n  Star,\n  StarIcon,\n} from \"lucide-react\";\nimport * as React from \"react\";\n\nimport {\n  ButtonGroup,\n  ButtonGroupText,\n} from \"@/components/ui/button-group\";\nimport {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuTrigger,\n} from \"@/components/ui/dropdown-menu\";\nimport {\n  InputGroup,\n  InputGroupAddon,\n  InputGroupButton,\n  InputGroupInput,\n  InputGroupText,\n  InputGroupTextarea,\n} from \"@/components/ui/input-group\";\nimport { Label } from \"@/components/ui/label\";\nimport {\n  Popover,\n  PopoverContent,\n  PopoverTrigger,\n} from \"@/components/ui/popover\";\nimport { Spinner } from \"@/components/ui/spinner\";\nimport {\n  Tooltip,\n  TooltipContent,\n  TooltipProvider,\n  TooltipTrigger,\n} from \"@/components/ui/tooltip\";\n\n/**\n * Display additional information or actions to an input or textarea.\n */\nconst meta: Meta<typeof InputGroup> = {\n  title: \"ui/base/InputGroup\",\n  component: InputGroup,\n  tags: [\"autodocs\"],\n  parameters: {\n    layout: \"centered\",\n  },\n} satisfies Meta<typeof InputGroup>;\n\nexport default meta;\n\ntype Story = StoryObj<typeof meta>;\n\n/**\n * Input groups with icon addons for visual enhancement.\n */\nexport const WithIcons: Story = {\n  render: (args) => (\n    <div className=\"grid w-full max-w-sm gap-6\">\n      <InputGroup {...args}>\n        <InputGroupInput placeholder=\"Search...\" />\n        <InputGroupAddon>\n          <SearchIcon />\n        </InputGroupAddon>\n      </InputGroup>\n      <InputGroup {...args}>\n        <InputGroupInput type=\"email\" placeholder=\"Enter your email\" />\n        <InputGroupAddon>\n          <MailIcon />\n        </InputGroupAddon>\n      </InputGroup>\n      <InputGroup {...args}>\n        <InputGroupInput placeholder=\"Card number\" />\n        <InputGroupAddon>\n          <CreditCardIcon />\n        </InputGroupAddon>\n        <InputGroupAddon align=\"inline-end\">\n          <CheckIcon />\n        </InputGroupAddon>\n      </InputGroup>\n      <InputGroup {...args}>\n        <InputGroupInput placeholder=\"Card number\" />\n        <InputGroupAddon align=\"inline-end\">\n          <StarIcon />\n          <InfoIcon />\n        </InputGroupAddon>\n      </InputGroup>\n    </div>\n  ),\n};\n\n/**\n * Display additional text information alongside inputs.\n */\nexport const WithText: Story = {\n  render: (args) => (\n    <div className=\"grid w-full max-w-sm gap-6\">\n      <InputGroup {...args}>\n        <InputGroupAddon>\n          <InputGroupText>$</InputGroupText>\n        </InputGroupAddon>\n        <InputGroupInput placeholder=\"0.00\" />\n        <InputGroupAddon align=\"inline-end\">\n          <InputGroupText>USD</InputGroupText>\n        </InputGroupAddon>\n      </InputGroup>\n      <InputGroup {...args}>\n        <InputGroupAddon>\n          <InputGroupText>https://</InputGroupText>\n        </InputGroupAddon>\n        <InputGroupInput placeholder=\"example.com\" className=\"!pl-0.5\" />\n        <InputGroupAddon align=\"inline-end\">\n          <InputGroupText>.com</InputGroupText>\n        </InputGroupAddon>\n      </InputGroup>\n      <InputGroup {...args}>\n        <InputGroupInput placeholder=\"Enter your username\" />\n        <InputGroupAddon align=\"inline-end\">\n          <InputGroupText>@company.com</InputGroupText>\n        </InputGroupAddon>\n      </InputGroup>\n      <InputGroup {...args}>\n        <InputGroupTextarea placeholder=\"Enter your message\" />\n        <InputGroupAddon align=\"block-end\">\n          <InputGroupText className=\"text-muted-foreground text-xs\">\n            120 characters left\n          </InputGroupText>\n        </InputGroupAddon>\n      </InputGroup>\n    </div>\n  ),\n};\n\n/**\n * Add buttons to perform actions within the input group.\n */\nexport const WithButtons: Story = {\n  render: (args) => {\n    const [isCopied, setIsCopied] = React.useState(false);\n    const [isFavorite, setIsFavorite] = React.useState(false);\n\n    const copyToClipboard = (text: string) => {\n      navigator.clipboard.writeText(text);\n      setIsCopied(true);\n      setTimeout(() => setIsCopied(false), 2000);\n    };\n\n    return (\n      <div className=\"grid w-full max-w-sm gap-6\">\n        <InputGroup {...args}>\n          <InputGroupInput placeholder=\"https://x.com/shadcn\" readOnly />\n          <InputGroupAddon align=\"inline-end\">\n            <InputGroupButton\n              aria-label=\"Copy\"\n              title=\"Copy\"\n              size=\"icon-xs\"\n              nativeButton\n              onClick={() => {\n                copyToClipboard(\"https://x.com/shadcn\");\n              }}\n            >\n              {isCopied ? <Check /> : <Copy />}\n            </InputGroupButton>\n          </InputGroupAddon>\n        </InputGroup>\n        <InputGroup className=\"[--radius:9999px]\">\n          <Popover>\n            <InputGroupAddon>\n              <PopoverTrigger\n                nativeButton\n                render={\n                  <InputGroupButton\n                    variant=\"secondary\"\n                    size=\"icon-xs\"\n                    nativeButton\n                  />\n                }\n              >\n                <Info />\n              </PopoverTrigger>\n            </InputGroupAddon>\n            <PopoverContent\n              align=\"start\"\n              className=\"flex flex-col gap-1 rounded-xl text-sm\"\n            >\n              <p className=\"font-medium\">Your connection is not secure.</p>\n              <p>\n                You should not enter any sensitive information on this site.\n              </p>\n            </PopoverContent>\n          </Popover>\n          <InputGroupAddon className=\"text-muted-foreground pl-1.5\">\n            https://\n          </InputGroupAddon>\n          <InputGroupInput id=\"input-secure-19\" />\n          <InputGroupAddon align=\"inline-end\">\n            <InputGroupButton\n              onClick={() => setIsFavorite(!isFavorite)}\n              size=\"icon-xs\"\n              nativeButton\n            >\n              <Star\n                data-favorite={isFavorite}\n                className=\"data-[favorite=true]:fill-blue-600 data-[favorite=true]:stroke-blue-600\"\n              />\n            </InputGroupButton>\n          </InputGroupAddon>\n        </InputGroup>\n        <InputGroup {...args}>\n          <InputGroupInput placeholder=\"Type to search...\" />\n          <InputGroupAddon align=\"inline-end\">\n            <InputGroupButton variant=\"secondary\" nativeButton>\n              Search\n            </InputGroupButton>\n          </InputGroupAddon>\n        </InputGroup>\n      </div>\n    );\n  },\n};\n\n/**\n * Add tooltips to provide additional context or help.\n */\nexport const WithTooltips: Story = {\n  render: (args) => (\n    <div className=\"grid w-full max-w-sm gap-4\">\n      <TooltipProvider>\n        <InputGroup {...args}>\n          <InputGroupInput placeholder=\"Enter password\" type=\"password\" />\n          <InputGroupAddon align=\"inline-end\">\n            <Tooltip>\n              <InputGroupButton\n                render={<TooltipTrigger />}\n                variant=\"ghost\"\n                aria-label=\"Info\"\n                size=\"icon-xs\"\n              >\n                <InfoIcon />\n              </InputGroupButton>\n              <TooltipContent>\n                <p>Password must be at least 8 characters</p>\n              </TooltipContent>\n            </Tooltip>\n          </InputGroupAddon>\n        </InputGroup>\n        <InputGroup {...args}>\n          <InputGroupInput placeholder=\"Your email address\" />\n          <InputGroupAddon align=\"inline-end\">\n            <Tooltip>\n              <InputGroupButton\n                render={<TooltipTrigger />}\n                variant=\"ghost\"\n                aria-label=\"Help\"\n                size=\"icon-xs\"\n              >\n                <HelpCircle />\n              </InputGroupButton>\n              <TooltipContent>\n                <p>We'll use this to send you notifications</p>\n              </TooltipContent>\n            </Tooltip>\n          </InputGroupAddon>\n        </InputGroup>\n        <InputGroup {...args}>\n          <InputGroupInput placeholder=\"Enter API key\" />\n          <Tooltip>\n            <TooltipTrigger render={<InputGroupAddon />}>\n              <InputGroupButton\n                variant=\"ghost\"\n                aria-label=\"Help\"\n                size=\"icon-xs\"\n              >\n                <HelpCircle />\n              </InputGroupButton>\n            </TooltipTrigger>\n            <TooltipContent side=\"left\">\n              <p>Click for help with API keys</p>\n            </TooltipContent>\n          </Tooltip>\n        </InputGroup>\n      </TooltipProvider>\n    </div>\n  ),\n};\n\n/**\n * Input groups also work with textarea components.\n */\nexport const WithTextarea: Story = {\n  render: (args) => {\n    return (\n      <div className=\"grid w-full max-w-md gap-4\">\n        <InputGroup {...args}>\n          <InputGroupTextarea\n            id=\"textarea-code-32\"\n            placeholder=\"console.log('Hello, world!');\"\n            className=\"min-h-[200px]\"\n          />\n          <InputGroupAddon align=\"block-end\" className=\"border-t\">\n            <InputGroupText>Line 1, Column 1</InputGroupText>\n            <InputGroupButton size=\"sm\" className=\"ml-auto\" variant=\"default\">\n              Run <CornerDownLeft />\n            </InputGroupButton>\n          </InputGroupAddon>\n          <InputGroupAddon align=\"block-start\" className=\"border-b\">\n            <InputGroupText className=\"font-mono font-medium\">\n              <Code />\n              script.js\n            </InputGroupText>\n            <InputGroupButton className=\"ml-auto\" size=\"icon-xs\">\n              <RefreshCcw />\n            </InputGroupButton>\n            <InputGroupButton variant=\"ghost\" size=\"icon-xs\">\n              <Copy />\n            </InputGroupButton>\n          </InputGroupAddon>\n        </InputGroup>\n      </div>\n    );\n  },\n};\n\n/**\n * Show loading indicators while processing input.\n */\nexport const WithSpinner: Story = {\n  render: (args) => (\n    <div className=\"grid w-full max-w-sm gap-4\">\n      <InputGroup {...args} data-disabled>\n        <InputGroupInput placeholder=\"Searching...\" disabled />\n        <InputGroupAddon align=\"inline-end\">\n          <Spinner />\n        </InputGroupAddon>\n      </InputGroup>\n      <InputGroup data-disabled>\n        <InputGroupInput placeholder=\"Processing...\" disabled />\n        <InputGroupAddon>\n          <Spinner />\n        </InputGroupAddon>\n      </InputGroup>\n      <InputGroup data-disabled>\n        <InputGroupInput placeholder=\"Saving changes...\" disabled />\n        <InputGroupAddon align=\"inline-end\">\n          <InputGroupText>Saving...</InputGroupText>\n          <Spinner />\n        </InputGroupAddon>\n      </InputGroup>\n      <InputGroup data-disabled>\n        <InputGroupInput placeholder=\"Refreshing data...\" disabled />\n        <InputGroupAddon>\n          <LoaderIcon className=\"animate-spin\" />\n        </InputGroupAddon>\n        <InputGroupAddon align=\"inline-end\">\n          <InputGroupText className=\"text-muted-foreground\">\n            Please wait...\n          </InputGroupText>\n        </InputGroupAddon>\n      </InputGroup>\n    </div>\n  ),\n};\n\n/**\n * Add labels within input groups to improve accessibility.\n */\nexport const WithLabels: Story = {\n  render: (args) => (\n    <div className=\"grid w-full max-w-sm gap-4\">\n      <TooltipProvider>\n        <InputGroup {...args}>\n          <InputGroupInput id=\"email\" placeholder=\"shadcn\" />\n          <InputGroupAddon>\n            <Label htmlFor=\"email\">@</Label>\n          </InputGroupAddon>\n        </InputGroup>\n        <InputGroup {...args}>\n          <InputGroupInput id=\"email-2\" placeholder=\"shadcn@vercel.com\" />\n          <InputGroupAddon align=\"block-start\">\n            <Label htmlFor=\"email-2\" className=\"text-foreground\">\n              Email\n            </Label>\n            <Tooltip>\n              <InputGroupButton\n                render={<TooltipTrigger />}\n                variant=\"ghost\"\n                aria-label=\"Help\"\n                className=\"ml-auto rounded-full\"\n                size=\"icon-xs\"\n              >\n                <InfoIcon />\n              </InputGroupButton>\n              <TooltipContent>\n                <p>We'll use this to send you notifications</p>\n              </TooltipContent>\n            </Tooltip>\n          </InputGroupAddon>\n        </InputGroup>\n      </TooltipProvider>\n    </div>\n  ),\n};\n\n/**\n * Pair input groups with dropdown menus for complex interactions.\n */\nexport const WithDropdowns: Story = {\n  render: (args) => (\n    <div className=\"grid w-full max-w-sm gap-4\">\n      <InputGroup {...args}>\n        <InputGroupInput placeholder=\"Enter file name\" />\n        <InputGroupAddon align=\"inline-end\">\n          <DropdownMenu>\n            <DropdownMenuTrigger\n              render={\n                <InputGroupButton\n                  variant=\"ghost\"\n                  aria-label=\"More\"\n                  size=\"icon-xs\"\n                />\n              }\n            >\n              <MoreHorizontal />\n            </DropdownMenuTrigger>\n            <DropdownMenuContent align=\"end\">\n              <DropdownMenuItem>Settings</DropdownMenuItem>\n              <DropdownMenuItem>Copy path</DropdownMenuItem>\n              <DropdownMenuItem>Open location</DropdownMenuItem>\n            </DropdownMenuContent>\n          </DropdownMenu>\n        </InputGroupAddon>\n      </InputGroup>\n      <InputGroup className=\"[--radius:1rem]\">\n        <InputGroupInput placeholder=\"Enter search query\" />\n        <InputGroupAddon align=\"inline-end\">\n          <DropdownMenu>\n            <DropdownMenuTrigger\n              render={\n                <InputGroupButton variant=\"ghost\" className=\"!pr-1.5 text-xs\" />\n              }\n            >\n              Search In... <ChevronDownIcon className=\"size-3\" />\n            </DropdownMenuTrigger>\n            <DropdownMenuContent align=\"end\" className=\"[--radius:0.95rem]\">\n              <DropdownMenuItem>Documentation</DropdownMenuItem>\n              <DropdownMenuItem>Blog Posts</DropdownMenuItem>\n              <DropdownMenuItem>Changelog</DropdownMenuItem>\n            </DropdownMenuContent>\n          </DropdownMenu>\n        </InputGroupAddon>\n      </InputGroup>\n    </div>\n  ),\n};\n\n/**\n * Wrap input groups with button groups to create prefixes and suffixes.\n */\nexport const WithButtonGroup: Story = {\n  render: (args) => (\n    <div className=\"grid w-full max-w-sm gap-6\">\n      <ButtonGroup>\n        <ButtonGroupText render={<Label htmlFor=\"url\" />}>\n          https://\n        </ButtonGroupText>\n        <InputGroup {...args}>\n          <InputGroupInput id=\"url\" />\n          <InputGroupAddon align=\"inline-end\">\n            <Link2Icon />\n          </InputGroupAddon>\n        </InputGroup>\n        <ButtonGroupText>.com</ButtonGroupText>\n      </ButtonGroup>\n    </div>\n  ),\n};\n",
      "type": "registry:component"
    }
  ],
  "categories": [
    "ui",
    "storybook",
    "input",
    "form"
  ],
  "type": "registry:component"
}