{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "Combobox",
  "dependencies": [
    "@base-ui/react",
    "cn",
    "lucide-react",
    "rescript-base-ui"
  ],
  "registryDependencies": [
    "@rescript-shadcn/Button",
    "@rescript-shadcn/Icons",
    "@rescript-shadcn/InputGroup"
  ],
  "files": [
    {
      "path": "registry/base/ui/Combobox.res",
      "content": "@@jsxConfig({version: 4, mode: \"automatic\", module_: \"BaseUi.BaseUiJsxDOM\"})\n\n@@directive(\"'use client'\")\n\nopen BaseUi.Types\n\n@module(\"cn\")\nexternal cn: (string, option<string>) => string = \"cn\"\n\nlet make = BaseUi.Combobox.Root.make\n\nmodule Multiple = {\n  @react.componentWithProps(BaseUi.Combobox.Root.Multiple.props)\n  let make = (props: BaseUi.Combobox.Root.Multiple.props<'item>) =>\n    <BaseUi.Combobox.Root.Multiple {...props} multiple=True />\n}\n\nmodule Value = {\n  @react.componentWithProps(BaseUi.Combobox.Value.props)\n  let make = (props: BaseUi.Combobox.Value.props<'value>) => {\n    let dataSlot = props.dataSlot->Option.getOr(\"combobox-value\")\n    <BaseUi.Combobox.Value {...props} dataSlot />\n  }\n}\n\nmodule Trigger = {\n  @react.componentWithProps(BaseUi.Combobox.Trigger.props)\n  let make = (props: BaseUi.Combobox.Trigger.props) =>\n    <BaseUi.Combobox.Trigger\n      {...props}\n      dataSlot={props.dataSlot->Option.getOr(\"combobox-trigger\")}\n      className={cn(\"[&_svg:not([class*='size-'])]:size-4\", props.className)}\n    >\n      {props.children->Option.getOr(React.null)}\n      <Icons.ChevronDown className=\"text-muted-foreground size-4 pointer-events-none\" />\n    </BaseUi.Combobox.Trigger>\n}\n\nmodule Clear = {\n  @react.componentWithProps(InputGroup.Button.props)\n  let make = (props: InputGroup.Button.props) =>\n    <BaseUi.Combobox.Clear\n      dataSlot=\"combobox-clear\"\n      render={<InputGroup.Button\n        {...props}\n        variant={props.variant->Option.getOr(Ghost)}\n        size={props.size->Option.getOr(IconXs)}\n        className={cn(props.className)}\n      />}\n    >\n      <Icons.X className=\"pointer-events-none\" />\n    </BaseUi.Combobox.Clear>\n}\n\nmodule Input = {\n  type inputProps = {\n    showTrigger?: bool,\n    showClear?: bool,\n    ...BaseUi.Combobox.Input.props,\n  }\n  let toBaseUiProps: inputProps => BaseUi.Combobox.Input.props = %raw(`({className, children, disabled, showTrigger, showClear,...rest}) => rest`)\n  @react.componentWithProps(inputProps)\n  let make = (props: inputProps) => {\n    let disabled = props.disabled->Option.getOr(false)\n    let showTrigger = props.showTrigger->Option.getOr(true)\n    let showClear = props.showClear->Option.getOr(false)\n    let baseUiProps = toBaseUiProps(props)\n    <InputGroup className={cn(\" w-auto\", props.className)}>\n      <BaseUi.Combobox.Input {...baseUiProps} render={<InputGroup.Input disabled />} />\n      <InputGroup.Addon align=InlineEnd>\n        {showTrigger\n          ? <InputGroup.Button\n              size=IconXs\n              variant=Ghost\n              render={<Trigger />}\n              dataSlot=\"input-group-button\"\n              className=\"group-has-data-[slot=combobox-clear]/input-group:hidden data-pressed:bg-transparent\"\n              disabled\n            />\n          : React.null}\n        {showClear ? <Clear disabled /> : React.null}\n      </InputGroup.Addon>\n      {props.children->Option.getOr(React.null)}\n    </InputGroup>\n  }\n}\n\nmodule Content = {\n  type props = {\n    ...BaseUi.Types.BaseUIComponentProps.t,\n    side?: Side.t,\n    sideOffset?: float,\n    align?: Align.t,\n    alignOffset?: float,\n    anchor?: ReactDOM.domRef,\n  }\n\n  let toBaseUiProps: props => BaseUi.Types.BaseUIComponentProps.t = %raw(`({side, sideOffset, align, alignOffset, anchor, ...props}) => props`)\n\n  @react.componentWithProps(props)\n  let make = (props: props) => {\n    let side = props.side->Option.getOr(Side.Bottom)\n    let sideOffset = props.sideOffset->Option.getOr(6.)\n    let align = props.align->Option.getOr(Align.Start)\n    let alignOffset = props.alignOffset->Option.getOr(0.)\n    let anchor = props.anchor\n    <BaseUi.Combobox.Portal>\n      <BaseUi.Combobox.Positioner\n        side\n        sideOffset={Const(sideOffset)}\n        align\n        alignOffset={Const(alignOffset)}\n        ?anchor\n        className=\"isolate z-50\"\n      >\n        <BaseUi.Combobox.Popup\n          {...props->toBaseUiProps}\n          dataSlot={props.dataSlot->Option.getOr(\"combobox-content\")}\n          dataChips={anchor->Option.isSome}\n          className={cn(\n            \"bg-popover text-popover-foreground data-open:animate-in data-closed:animate-out data-closed:fade-out-0 data-open:fade-in-0 data-closed:zoom-out-95 data-open:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 ring-foreground/10 *:data-[slot=input-group]:bg-input/30 *:data-[slot=input-group]:border-input/30 overflow-hidden rounded-lg shadow-md ring-1 duration-100 *:data-[slot=input-group]:m-1 *:data-[slot=input-group]:mb-0 *:data-[slot=input-group]:h-8 *:data-[slot=input-group]:shadow-none data-[side=inline-start]:slide-in-from-right-2 data-[side=inline-end]:slide-in-from-left-2 group/combobox-content relative max-h-(--available-height) w-(--anchor-width) max-w-(--available-width) min-w-[calc(var(--anchor-width)+--spacing(7))] origin-(--transform-origin) data-[chips=true]:min-w-(--anchor-width)\",\n            props.className,\n          )}\n        />\n      </BaseUi.Combobox.Positioner>\n    </BaseUi.Combobox.Portal>\n  }\n}\n\nmodule List = {\n  @react.componentWithProps(BaseUi.Combobox.List.props)\n  let make = (props: BaseUi.Combobox.List.props<'item>) => {\n    let children = props.children\n    <BaseUi.Combobox.List\n      {...props}\n      dataSlot={props.dataSlot->Option.getOr(\"combobox-list\")}\n      className={cn(\n        \"no-scrollbar max-h-[min(calc(--spacing(72)---spacing(9)),calc(var(--available-height)---spacing(9)))] scroll-py-1 overflow-y-auto p-1 data-empty:p-0 overflow-y-auto overscroll-contain\",\n        props.className,\n      )}\n    >\n      {children}\n    </BaseUi.Combobox.List>\n  }\n}\n\nmodule Item = {\n  @react.componentWithProps(BaseUi.Combobox.Item.props)\n  let make = (props: BaseUi.Combobox.Item.props<'value>) => {\n    let dataSlot = props.dataSlot->Option.getOr(\"combobox-item\")\n    <BaseUi.Combobox.Item\n      {...props}\n      dataSlot\n      className={cn(\n        \"data-highlighted:bg-accent data-highlighted:text-accent-foreground not-data-[variant=destructive]:data-highlighted:**:text-accent-foreground gap-2 rounded-md py-1 pr-8 pl-1.5 text-sm [&_svg:not([class*='size-'])]:size-4 relative flex w-full cursor-default items-center outline-hidden select-none data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0\",\n        props.className,\n      )}\n    >\n      {props.children->Option.getOr(React.null)}\n      <BaseUi.Combobox.ItemIndicator\n        render={<span\n          className=\"pointer-events-none absolute right-2 flex size-4 items-center justify-center\"\n        />}\n      >\n        <Icons.Check className=\"pointer-events-none\" />\n      </BaseUi.Combobox.ItemIndicator>\n    </BaseUi.Combobox.Item>\n  }\n}\n\nmodule Group = {\n  @react.componentWithProps(BaseUi.Combobox.Group.props)\n  let make = (props: BaseUi.Combobox.Group.props<'value>) => {\n    let children = props.children->Option.getOr(React.null)\n    <BaseUi.Combobox.Group\n      {...props}\n      dataSlot={props.dataSlot->Option.getOr(\"combobox-group\")}\n      className={cn(\"\", props.className)}\n    >\n      {children}\n    </BaseUi.Combobox.Group>\n  }\n}\n\nmodule Label = {\n  @react.componentWithProps(BaseUi.Types.BaseUIComponentProps.t)\n  let make = (props: BaseUi.Types.BaseUIComponentProps.t) =>\n    <BaseUi.Combobox.GroupLabel\n      {...props}\n      dataSlot={props.dataSlot->Option.getOr(\"combobox-label\")}\n      className={cn(\"text-muted-foreground px-2 py-1.5 text-xs\", props.className)}\n    />\n}\n\nmodule Collection = {\n  @react.componentWithProps(BaseUi.Combobox.Collection.props)\n  let make = (props: BaseUi.Combobox.Collection.props<'item>) => {\n    let children = props.children\n    <BaseUi.Combobox.Collection\n      {...props} dataSlot={props.dataSlot->Option.getOr(\"combobox-collection\")}\n    >\n      {children}\n    </BaseUi.Combobox.Collection>\n  }\n}\n\nmodule Empty = {\n  @react.componentWithProps(BaseUi.Types.BaseUIComponentProps.t)\n  let make = (props: BaseUi.Types.BaseUIComponentProps.t) =>\n    <BaseUi.Combobox.Empty\n      {...props}\n      dataSlot={props.dataSlot->Option.getOr(\"combobox-empty\")}\n      className={cn(\n        \"text-muted-foreground hidden w-full justify-center py-2 text-center text-sm group-data-empty/combobox-content:flex\",\n        props.className,\n      )}\n    />\n}\n\nmodule Separator = {\n  @react.componentWithProps(BaseUi.Types.BaseUIComponentProps.t)\n  let make = (props: BaseUi.Types.BaseUIComponentProps.t) =>\n    <BaseUi.Combobox.Separator\n      {...props}\n      dataSlot={props.dataSlot->Option.getOr(\"combobox-separator\")}\n      className={cn(\"bg-border -mx-1 my-1 h-px\", props.className)}\n    />\n}\n\nmodule Chips = {\n  @react.componentWithProps(BaseUi.Types.BaseUIComponentProps.t)\n  let make = (props: BaseUi.Types.BaseUIComponentProps.t) => {\n    let dataSlot = props.dataSlot->Option.getOr(\"combobox-chips\")\n    <BaseUi.Combobox.Chips\n      {...props}\n      dataSlot\n      className={cn(\n        \"dark:bg-input/30 border-input focus-within:border-ring focus-within:ring-ring/50 has-aria-invalid:ring-destructive/20 dark:has-aria-invalid:ring-destructive/40 has-aria-invalid:border-destructive dark:has-aria-invalid:border-destructive/50 flex min-h-8 flex-wrap items-center gap-1 rounded-lg border bg-transparent bg-clip-padding px-2.5 py-1 text-sm transition-colors focus-within:ring-3 has-aria-invalid:ring-3 has-data-[slot=combobox-chip]:px-1\",\n        props.className,\n      )}\n    />\n  }\n}\n\ntype chipProps = {\n  ...BaseUi.Types.BaseUIComponentProps.t,\n  showRemove?: bool,\n}\n\nlet comboboxChipToBase: chipProps => BaseUi.Types.BaseUIComponentProps.t = %raw(`({ showRemove, ...rest }) => rest`)\n\nmodule Chip = {\n  @react.componentWithProps(chipProps)\n  let make = (props: chipProps) => {\n    let dataSlot = props.dataSlot->Option.getOr(\"combobox-chip\")\n    let showRemove = props.showRemove->Option.getOr(true)\n    <BaseUi.Combobox.Chip\n      {...props->comboboxChipToBase}\n      dataSlot\n      className={cn(\n        \"bg-muted text-foreground flex h-[calc(--spacing(5.25))] w-fit items-center justify-center gap-1 rounded-sm px-1.5 text-xs font-medium whitespace-nowrap has-data-[slot=combobox-chip-remove]:pr-0 has-disabled:pointer-events-none has-disabled:cursor-not-allowed has-disabled:opacity-50\",\n        props.className,\n      )}\n    >\n      {props.children->Option.getOr(React.null)}\n      {showRemove\n        ? <BaseUi.Combobox.ChipRemove\n            render={<Button variant=Ghost size=IconXs />}\n            className=\"-ml-1 opacity-50 hover:opacity-100\"\n            dataSlot=\"combobox-chip-remove\"\n          >\n            <Icons.X className=\"pointer-events-none\" />\n          </BaseUi.Combobox.ChipRemove>\n        : React.null}\n    </BaseUi.Combobox.Chip>\n  }\n}\n\nmodule ChipsInput = {\n  @react.componentWithProps(BaseUi.Combobox.Input.props)\n  let make = (props: BaseUi.Combobox.Input.props) => {\n    let dataSlot = props.dataSlot->Option.getOr(\"combobox-chip-input\")\n    <BaseUi.Combobox.Input\n      {...props} dataSlot className={cn(\" min-w-16 flex-1 outline-none\", props.className)}\n    />\n  }\n}\n\nlet useAnchor = () => React.useRef(null)->ReactDOM.Ref.domRef\n",
      "type": "registry:file",
      "target": "@ui/Combobox.res"
    }
  ],
  "type": "registry:ui"
}