{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "input-group",
  "type": "registry:ui",
  "title": "Input Group",
  "description": "Composable input group primitives for Tile UI.",
  "devDependencies": [
    "sass"
  ],
  "registryDependencies": [
    "@tile-ui/core",
    "button",
    "@tile-ui/styles"
  ],
  "files": [
    {
      "path": "packages/react/src/components/input-group/input-group.tsx",
      "type": "registry:ui",
      "target": "components/ui/input-group/input-group.tsx",
      "content": "import React from 'react';\nimport { getInputGroupAddonStyleKeys, getInputGroupStyleKeys, inputGroupStyleKeys } from '../lib/core';\nimport type {\n\tInputGroupAddonBaseProps,\n\tInputGroupBaseProps,\n\tInputGroupButtonBaseProps,\n\tInputGroupInputBaseProps,\n\tInputGroupTextareaBaseProps,\n\tInputGroupTextBaseProps,\n\tButtonVariant,\n\tButtonSize,\n} from '../lib/core';\nimport styles from './input-group.module.scss';\nimport { Button } from '../button';\n\nexport interface InputGroupProps extends React.HTMLAttributes<HTMLDivElement>, InputGroupBaseProps {}\n\nconst InputGroup = React.forwardRef<HTMLDivElement, InputGroupProps>(({ className = '', variant = 'default', children, ...props }, ref) => {\n\tconst styleKeys = getInputGroupStyleKeys(variant);\n\tconst classes = [styles[styleKeys.base], styles[styleKeys.variant], className].filter(Boolean).join(' ');\n\n\treturn (\n\t\t<div ref={ref} role=\"group\" data-slot=\"input-group\" data-variant={variant} className={classes} {...props}>\n\t\t\t{children}\n\t\t</div>\n\t);\n});\nInputGroup.displayName = 'InputGroup';\n\nexport interface InputGroupAddonProps extends React.HTMLAttributes<HTMLDivElement>, InputGroupAddonBaseProps {}\n\nconst InputGroupAddon = React.forwardRef<HTMLDivElement, InputGroupAddonProps>(({ className = '', variant = 'default', align = 'inline-start', onClick, ...props }, ref) => {\n\tconst styleKeys = getInputGroupAddonStyleKeys(variant);\n\tconst classes = [styles[styleKeys.base], styles[styleKeys.variant], className].filter(Boolean).join(' ');\n\n\tfunction handleClick(event: React.MouseEvent<HTMLDivElement>) {\n\t\tif ((event.target as HTMLElement).closest('button')) {\n\t\t\treturn;\n\t\t}\n\t\tevent.currentTarget.parentElement?.querySelector('input')?.focus();\n\t\tonClick?.(event);\n\t}\n\n\treturn <div ref={ref} role=\"group\" data-slot=\"input-group-addon\" data-variant={variant} data-align={align} className={classes} onClick={handleClick} {...props} />;\n});\nInputGroupAddon.displayName = 'InputGroupAddon';\n\nexport interface InputGroupButtonProps extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'type' | 'size'>, InputGroupButtonBaseProps {\n\ttype?: 'button' | 'submit' | 'reset';\n\tvariant?: ButtonVariant;\n\tsize?: ButtonSize;\n}\n\nconst InputGroupButton = React.forwardRef<HTMLButtonElement, InputGroupButtonProps>(\n\t({ className = '', type = 'button', variant = 'ghost', size = 'sm', children, ...props }, ref) => {\n\t\treturn (\n\t\t\t<Button ref={ref} type={type} variant={variant} size={size} className={`${styles[inputGroupStyleKeys.button]} ${className}`} {...props}>\n\t\t\t\t{children}\n\t\t\t</Button>\n\t\t);\n\t},\n);\nInputGroupButton.displayName = 'InputGroupButton';\n\nexport interface InputGroupTextProps extends React.HTMLAttributes<HTMLSpanElement>, InputGroupTextBaseProps {}\n\nconst InputGroupText = React.forwardRef<HTMLSpanElement, InputGroupTextProps>(({ className = '', children, ...props }, ref) => {\n\treturn (\n\t\t<span ref={ref} data-slot=\"input-group-text\" className={`${styles[inputGroupStyleKeys.text]} ${className}`} {...props}>\n\t\t\t{children}\n\t\t</span>\n\t);\n});\nInputGroupText.displayName = 'InputGroupText';\n\nexport interface InputGroupInputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size'>, InputGroupInputBaseProps {}\n\nconst InputGroupInput = React.forwardRef<HTMLInputElement, InputGroupInputProps>(({ className = '', ...props }, ref) => {\n\treturn <input ref={ref} data-slot=\"input-group-control\" className={`${styles[inputGroupStyleKeys.input]} ${className}`} {...props} />;\n});\nInputGroupInput.displayName = 'InputGroupInput';\n\nexport interface InputGroupTextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement>, InputGroupTextareaBaseProps {}\n\nconst InputGroupTextarea = React.forwardRef<HTMLTextAreaElement, InputGroupTextareaProps>(({ className = '', ...props }, ref) => {\n\treturn <textarea ref={ref} data-slot=\"input-group-control\" className={`${styles[inputGroupStyleKeys.textarea]} ${className}`} {...props} />;\n});\nInputGroupTextarea.displayName = 'InputGroupTextarea';\n\nexport { InputGroup, InputGroupAddon, InputGroupButton, InputGroupText, InputGroupInput, InputGroupTextarea };\nexport default InputGroup;\n"
    },
    {
      "path": "packages/styles/scss/components/input-group.module.scss",
      "type": "registry:file",
      "target": "components/ui/input-group/input-group.module.scss",
      "content": "@use '../../../styles/variables/colors' as *;\n\n.inputGroup {\n\tposition: relative;\n\tdisplay: flex;\n\twidth: 100%;\n\talign-items: center;\n\tborder-radius: var(--tile-input-group-radius, #{$radius});\n\tborder: var(--tile-input-group-border-width, 1px) solid var(--tile-input-group-border, #{$input});\n\ttransition:\n\t\tborder-color $transition-fast,\n\t\tbox-shadow $transition-fast;\n\toutline: none;\n\n\t&:focus-within {\n\t\tborder-color: var(--tile-input-group-focus-border, #{$ring});\n\t\tbox-shadow: var(--tile-input-group-focus-shadow, 0 0 0 3px color-mix(in srgb, #{$ring} 50%, transparent));\n\t}\n\n\t&:has([aria-invalid='true']) {\n\t\tborder-color: $destructive;\n\t\tbox-shadow: var(--tile-input-group-error-shadow, none);\n\n\t\t&:focus-within {\n\t\t\tbox-shadow: var(--tile-input-group-error-focus-shadow, 0 0 0 3px color-mix(in srgb, #{$destructive} 20%, transparent));\n\t\t}\n\t}\n\n\t&:has(> textarea) {\n\t\talign-items: flex-start;\n\t}\n\n\t&:has(> .addon[data-align='block-start'], > .addon[data-align='block-end']) {\n\t\tflex-wrap: wrap;\n\t}\n\n\t// 样式变体\n\t&.variantDefault {\n\t\tbackground-color: var(--tile-input-group-background, transparent);\n\t\tbox-shadow: var(--tile-input-group-shadow, #{$shadow-sm});\n\n\t\t&:focus-within {\n\t\t\tbox-shadow: var(--tile-input-group-focus-shadow, #{$shadow-sm});\n\n\t\t\t&:has([aria-invalid='true']) {\n\t\t\t\tbox-shadow: var(--tile-input-group-error-focus-shadow, #{$shadow-sm});\n\t\t\t}\n\t\t}\n\t}\n\n\t&.variantOutline {\n\t\tbackground-color: var(--tile-input-group-outline-background, #{$field-subtle});\n\t\tbox-shadow: var(--tile-input-group-outline-shadow, none);\n\n\t\t&:focus-within {\n\t\t\tbox-shadow: var(--tile-input-group-focus-shadow, none);\n\n\t\t\t&:has([aria-invalid='true']) {\n\t\t\t\tbox-shadow: var(--tile-input-group-error-focus-shadow, none);\n\t\t\t}\n\t\t}\n\t}\n}\n\n.addon {\n\tdisplay: flex;\n\tflex-shrink: 0;\n\talign-items: center;\n\tjustify-content: center;\n\tgap: $spacing-2;\n\tcursor: text;\n\tpadding: $spacing-1_5 0;\n\tfont-size: $text-sm;\n\tfont-weight: $font-medium;\n\tcolor: $muted-foreground;\n\tuser-select: none;\n\n\tsvg {\n\t\tpointer-events: none;\n\t\twidth: 1rem;\n\t\theight: 1rem;\n\t}\n\n\tbutton {\n\t\tborder-radius: $radius-sm;\n\t}\n\n\t// 样式变体\n\t&.variantDefault {\n\t\tbackground-color: var(--tile-input-group-addon-background, #{$muted});\n\t}\n\n\t&.variantOutline {\n\t\tbackground-color: transparent;\n\t}\n\n\t// 对齐方式\n\t&[data-align='inline-start'] {\n\t\torder: -1;\n\t\tpadding-left: $spacing-3;\n\t}\n\n\t&[data-align='inline-end'] {\n\t\torder: 1;\n\t\tpadding-right: $spacing-3;\n\t}\n\n\t&[data-align='block-start'] {\n\t\torder: -1;\n\t\tflex-basis: 100%;\n\t\twidth: 100%;\n\t\tjustify-content: flex-start;\n\t\tpadding: $spacing-3 $spacing-3 0;\n\n\t\t.inputGroup:has(> input) & {\n\t\t\tpadding-bottom: $spacing-2_5;\n\t\t}\n\t}\n\n\t&[data-align='block-end'] {\n\t\torder: 1;\n\t\tflex-basis: 100%;\n\t\twidth: 100%;\n\t\tjustify-content: flex-start;\n\t\tpadding: 0 $spacing-3 $spacing-3;\n\n\t\t.inputGroup:has(> input) & {\n\t\t\tpadding-top: $spacing-2_5;\n\t\t}\n\t}\n}\n\n.button {\n\tflex-shrink: 0;\n\tborder-radius: 0;\n\tborder: none;\n\tbox-shadow: none;\n}\n\n.text {\n\tdisplay: flex;\n\tflex-shrink: 0;\n\talign-items: center;\n\tgap: $spacing-2;\n\tfont-size: $text-sm;\n\tcolor: $muted-foreground;\n\n\tsvg {\n\t\tpointer-events: none;\n\t\twidth: 1rem;\n\t\theight: 1rem;\n\t}\n}\n\n.input {\n\tflex: 1;\n\tmin-width: 0;\n\theight: var(--tile-input-group-height, 2.25rem);\n\tborder: none;\n\tbackground-color: transparent;\n\tpadding: 0 $spacing-3;\n\tfont-size: var(--tile-input-group-font-size, #{$text-sm});\n\tline-height: var(--tile-input-group-line-height, inherit);\n\tcolor: $foreground;\n\toutline: none;\n\n\t&::placeholder {\n\t\tcolor: $muted-foreground;\n\t}\n\n\t&:focus-visible {\n\t\toutline: none;\n\t}\n\n\t&:disabled {\n\t\tpointer-events: none;\n\t\topacity: 0.5;\n\t}\n}\n\n.textarea {\n\tflex: 1;\n\tmin-width: 0;\n\tborder: none;\n\tbackground-color: transparent;\n\tpadding: $spacing-3;\n\tfont-size: var(--tile-input-group-font-size, #{$text-sm});\n\tline-height: var(--tile-input-group-line-height, inherit);\n\tcolor: $foreground;\n\tresize: none;\n\toutline: none;\n\n\t&::placeholder {\n\t\tcolor: $muted-foreground;\n\t}\n\n\t&:focus-visible {\n\t\toutline: none;\n\t}\n\n\t&:disabled {\n\t\tpointer-events: none;\n\t\topacity: 0.5;\n\t}\n}\n"
    },
    {
      "path": "packages/react/src/components/input-group/index.ts",
      "type": "registry:ui",
      "target": "components/ui/input-group/index.ts",
      "content": "export {\n\tInputGroup,\n\tInputGroupAddon,\n\tInputGroupButton,\n\tInputGroupText,\n\tInputGroupInput,\n\tInputGroupTextarea,\n\ttype InputGroupProps,\n\ttype InputGroupAddonProps,\n\ttype InputGroupButtonProps,\n\ttype InputGroupTextProps,\n\ttype InputGroupInputProps,\n\ttype InputGroupTextareaProps,\n} from './input-group';\n"
    }
  ]
}
