{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "InputGroup",
  "dependencies": [
    "cn",
    "rescript-base-ui"
  ],
  "registryDependencies": [
    "@rescript-shadcn/Button",
    "@rescript-shadcn/Input",
    "@rescript-shadcn/Textarea"
  ],
  "files": [
    {
      "path": "registry/base/ui/InputGroup.res",
      "content": "@@jsxConfig({version: 4, mode: \"automatic\", module_: \"BaseUi.BaseUiJsxDOM\"})\n\n@@directive(\"'use client'\")\n\n@module(\"cn\")\nexternal cn: (string, option<string>) => string = \"cn\"\n\n@module(\"cn\")\nexternal cn3: (string, string, option<string>) => string = \"cn\"\n\nmodule Align = {\n  @unboxed\n  type t =\n    | @as(\"inline-start\") InlineStart\n    | @as(\"inline-end\") InlineEnd\n    | @as(\"block-start\") BlockStart\n    | @as(\"block-end\") BlockEnd\n}\n\nmodule Size = {\n  @unboxed\n  type t =\n    | @as(\"xs\") Xs\n    | @as(\"sm\") Sm\n    | @as(\"icon-xs\") IconXs\n    | @as(\"icon-sm\") IconSm\n}\n\nmodule Variant = {\n  @unboxed\n  type t =\n    | @as(\"ghost\") Ghost\n    | @as(\"default\") Default\n    | @as(\"secondary\") Secondary\n    | @as(\"outline\") Outline\n    | @as(\"destructive\") Destructive\n}\n\n@get external mouseEventTarget: JsxEvent.Mouse.t => Dom.element = \"target\"\n@get external mouseEventCurrentTarget: JsxEvent.Mouse.t => Dom.element = \"currentTarget\"\n@get external parentElement: Dom.element => nullable<Dom.element> = \"parentElement\"\n@send external closest: (Dom.element, string) => nullable<Dom.element> = \"closest\"\n@send external querySelector: (Dom.element, string) => nullable<Dom.element> = \"querySelector\"\n@send external focusElement: Dom.element => unit = \"focus\"\n\n@react.componentWithProps(BaseUi.Types.DomProps.t)\nlet make = (props: BaseUi.Types.DomProps.t) => {\n  let role = props.role->Option.getOr(\"group\")\n  let dataSlot = props.dataSlot->Option.getOr(\"input-group\")\n  <div\n    {...props}\n    dataSlot\n    role\n    className={cn(\n      \"border-input dark:bg-input/30 has-[[data-slot=input-group-control]:focus-visible]:border-ring has-[[data-slot=input-group-control]:focus-visible]:ring-ring/50 has-[[data-slot][aria-invalid=true]]:ring-destructive/20 has-[[data-slot][aria-invalid=true]]:border-destructive dark:has-[[data-slot][aria-invalid=true]]:ring-destructive/40 has-disabled:bg-input/50 dark:has-disabled:bg-input/80 h-8 rounded-lg border transition-colors in-data-[slot=combobox-content]:focus-within:border-inherit in-data-[slot=combobox-content]:focus-within:ring-0 has-disabled:opacity-50 has-[[data-slot=input-group-control]:focus-visible]:ring-3 has-[[data-slot][aria-invalid=true]]:ring-3 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-[>[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 group/input-group relative flex w-full min-w-0 items-center outline-none has-[>textarea]:h-auto\",\n      props.className,\n    )}\n  />\n}\n\nmodule Addon = {\n  let baseClass = \"text-muted-foreground h-auto gap-2 py-1.5 text-sm font-medium group-data-[disabled=true]/input-group:opacity-50 [&>kbd]:rounded-[calc(var(--radius)-5px)] [&>svg:not([class*='size-'])]:size-4 flex cursor-text items-center justify-center select-none\"\n\n  let alignClass = (~align=Align.InlineStart) =>\n    switch align {\n    | InlineStart => \"pl-2 has-[>button]:ml-[-0.3rem] has-[>kbd]:ml-[-0.15rem] order-first\"\n    | InlineEnd => \"pr-2 has-[>button]:mr-[-0.3rem] has-[>kbd]:mr-[-0.15rem] order-last\"\n    | BlockStart => \"px-2.5 pt-2 group-has-[>input]/input-group:pt-2 [.border-b]:pb-2 order-first w-full justify-start\"\n    | BlockEnd => \"px-2.5 pb-2 group-has-[>input]/input-group:pb-2 [.border-t]:pt-2 order-last w-full justify-start\"\n    }\n\n  type props = {align?: Align.t, ...BaseUi.Types.DomProps.t}\n  let toDomProps: props => BaseUi.Types.DomProps.t = %raw(`({align, ...props}) => props`)\n\n  @react.componentWithProps(props)\n  let make = (props: props) => {\n    let align = props.align->Option.getOr(InlineStart)\n    <div\n      {...props->toDomProps}\n      onClick={props.onClick->Option.getOr(event => {\n        let target = event->mouseEventTarget\n        switch target->closest(\"button\") {\n        | Value(_) => ()\n        | Null | Undefined =>\n          event\n          ->mouseEventCurrentTarget\n          ->parentElement\n          ->Nullable.flatMap(parent => parent->querySelector(\"input\"))\n          ->Nullable.forEach(focusElement)\n        }\n      })}\n      dataSlot={props.dataSlot->Option.getOr(\"input-group-addon\")}\n      dataAlign={props.dataAlign->Option.getOr((align :> string))}\n      role={props.role->Option.getOr(\"group\")}\n      className={cn3(baseClass, alignClass(~align), props.className)}\n    />\n  }\n}\n\nmodule Button = {\n  module Type = BaseUi.Types.ButtonType\n\n  let sizeClass = (~size: Size.t) =>\n    switch size {\n    | Xs => \"h-6 gap-1 rounded-[calc(var(--radius)-3px)] px-1.5 [&>svg:not([class*='size-'])]:size-3.5\"\n    | Sm => \"\"\n    | IconXs => \"size-6 rounded-[calc(var(--radius)-3px)] p-0 has-[>svg]:p-0\"\n    | IconSm => \"size-8 p-0 has-[>svg]:p-0\"\n    }\n\n  let baseClass = \"gap-2 text-sm flex items-center shadow-none\"\n\n  type props = {\n    size?: Size.t,\n    variant?: Variant.t,\n    ...BaseUi.Types.NativeButtonProps.t,\n  }\n  let toButtonProps: props => Button.props = %raw(`({variant, size, ...props}) => props`)\n\n  @react.componentWithProps(props)\n  let make = (props: props) => {\n    let size = props.size->Option.getOr(Xs)\n    let variant = props.variant->Option.getOr(Ghost)\n    <Button\n      {...props->toButtonProps}\n      type_={props.type_->Option.getOr(Button)}\n      variant={(variant :> Button.Variant.t)}\n      dataSize={props.dataSize->Option.getOr((size :> string))}\n      className={cn3(baseClass, sizeClass(~size), props.className)}\n    />\n  }\n}\n\nmodule Text = {\n  @react.componentWithProps(BaseUi.Types.DomProps.t)\n  let make = (props: BaseUi.Types.DomProps.t) =>\n    <span\n      {...props}\n      className={cn(\n        \"text-muted-foreground gap-2 text-sm [&_svg:not([class*='size-'])]:size-4 flex items-center [&_svg]:pointer-events-none\",\n        props.className,\n      )}\n    />\n}\n\nmodule Input = {\n  @react.componentWithProps(BaseUi.Input.props)\n  let make = (props: BaseUi.Input.props) =>\n    <Input\n      {...props}\n      dataSlot={props.dataSlot->Option.getOr(\"input-group-control\")}\n      className={cn(\n        \"rounded-none border-0 bg-transparent shadow-none ring-0 focus-visible:ring-0 disabled:bg-transparent aria-invalid:ring-0 dark:bg-transparent dark:disabled:bg-transparent flex-1\",\n        props.className,\n      )}\n    />\n}\n\nmodule Textarea = {\n  @react.componentWithProps(BaseUi.Types.DomProps.t)\n  let make = (props: BaseUi.Types.DomProps.t) =>\n    <Textarea\n      {...props}\n      dataSlot={props.dataSlot->Option.getOr(\"input-group-control\")}\n      className={cn(\n        \"rounded-none border-0 bg-transparent py-2 shadow-none ring-0 focus-visible:ring-0 disabled:bg-transparent aria-invalid:ring-0 dark:bg-transparent dark:disabled:bg-transparent flex-1 resize-none\",\n        props.className,\n      )}\n    />\n}\n",
      "type": "registry:file",
      "target": "@ui/InputGroup.res"
    }
  ],
  "type": "registry:ui"
}