{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "combobox",
  "type": "registry:item",
  "title": "Combobox",
  "description": "A searchable select component.",
  "registryDependencies": [
    "https://roiui.com/r/input.json"
  ],
  "files": [
    {
      "path": "registry/brook/ui/combobox/combobox.tsx",
      "content": "\"use client\";\n\nimport { Combobox } from \"@base-ui/react/combobox\";\nimport { Check, ChevronsUpDown, X } from \"lucide-react\";\nimport type React from \"react\";\nimport { cn } from \"@/lib/utils\";\nimport { Input } from \"@/registry/brook/ui/input/input\";\nimport styles from \"./combobox.module.css\";\n\nfunction ComboboxRoot<ItemValue, Multiple extends boolean | undefined = undefined>(\n  props: React.ComponentProps<typeof Combobox.Root<ItemValue, Multiple>>\n) {\n  return <Combobox.Root<ItemValue, Multiple> {...props} />;\n}\n\nfunction ComboboxTrigger({ className, children, ...props }: Combobox.Trigger.Props) {\n  return (\n    <Combobox.Trigger className={cn(styles.trigger, className)} data-slot=\"combobox-trigger\" {...props}>\n      {children}\n      <ChevronsUpDown className={styles.icon} size={16} />\n    </Combobox.Trigger>\n  );\n}\n\nfunction ComboboxInput({ className, ...props }: Combobox.Input.Props) {\n  return (\n    <Combobox.Input className={cn(styles.input, className)} data-slot=\"combobox-input\" render={<Input />} {...props} />\n  );\n}\n\nfunction ComboboxClear({ className, children, ...props }: Combobox.Clear.Props) {\n  return (\n    <Combobox.Clear className={cn(styles.clear, className)} {...props}>\n      {children || <X size={16} />}\n    </Combobox.Clear>\n  );\n}\n\nconst ComboboxPortal = Combobox.Portal;\n\nfunction ComboboxPositioner({ className, ...props }: Combobox.Positioner.Props) {\n  return (\n    <Combobox.Positioner\n      className={cn(styles.positioner, className)}\n      data-slot=\"combobox-positioner\"\n      sideOffset={4}\n      {...props}\n    />\n  );\n}\n\nfunction ComboboxPopup({ className, children, ...props }: Combobox.Popup.Props) {\n  return (\n    <Combobox.Popup className={cn(styles.popup, className)} {...props}>\n      <ComboboxSpacer />\n      {children}\n      <ComboboxSpacer />\n    </Combobox.Popup>\n  );\n}\n\nfunction ComboboxSpacer() {\n  return <div style={{ height: \"4px\", width: \"100%\", flexShrink: 0 }} />;\n}\n\nfunction ComboboxList({ className, ...props }: Combobox.List.Props) {\n  return <Combobox.List className={cn(styles.list, className)} data-slot=\"combobox-list\" {...props} />;\n}\n\nfunction ComboboxEmpty({ className, children, ...props }: Combobox.Empty.Props) {\n  return (\n    <Combobox.Empty className={cn(styles.empty, className)} {...props}>\n      {children || \"No items found\"}\n    </Combobox.Empty>\n  );\n}\n\nfunction ComboboxItem({\n  className,\n  children,\n  indicatorPosition = \"left\",\n  ...props\n}: Combobox.Item.Props & {\n  indicatorPosition?: \"left\" | \"right\";\n}) {\n  return (\n    <Combobox.Item className={cn(styles.item, className)} {...props}>\n      {indicatorPosition === \"left\" && (\n        <Combobox.ItemIndicator className={styles.itemIndicator}>\n          <Check size={16} />\n        </Combobox.ItemIndicator>\n      )}\n      {children}\n      {indicatorPosition === \"right\" && (\n        <Combobox.ItemIndicator className={styles.itemIndicator}>\n          <Check size={16} />\n        </Combobox.ItemIndicator>\n      )}\n    </Combobox.Item>\n  );\n}\n\nfunction ComboboxItemIndicator({ className, children, ...props }: Combobox.ItemIndicator.Props) {\n  return (\n    <Combobox.ItemIndicator\n      className={cn(styles.itemIndicator, className)}\n      data-slot=\"combobox-itemindicator\"\n      {...props}\n    >\n      {children || <Check size={16} />}\n    </Combobox.ItemIndicator>\n  );\n}\n\nfunction ComboboxGroup({ className, ...props }: Combobox.Group.Props) {\n  return <Combobox.Group className={cn(styles.group, className)} {...props} />;\n}\n\nfunction ComboboxGroupLabel({ className, ...props }: Combobox.GroupLabel.Props) {\n  return (\n    <Combobox.GroupLabel className={cn(styles.groupLabel, className)} data-slot=\"combobox-grouplabel\" {...props} />\n  );\n}\n\nfunction ComboboxArrow({ className, ...props }: Combobox.Arrow.Props) {\n  return <Combobox.Arrow className={cn(styles.arrow, className)} {...props} />;\n}\n\nfunction ComboboxNoItems({ className, children, ...props }: React.ComponentProps<\"div\">) {\n  return (\n    <div className={cn(styles.noItems, className)} {...props}>\n      {children || \"No items found\"}\n    </div>\n  );\n}\n\nfunction ComboboxChips({ className, ref, ...props }: Combobox.Chips.Props & { ref?: React.Ref<HTMLDivElement> }) {\n  return <Combobox.Chips className={cn(styles.chips, className)} ref={ref} {...props} />;\n}\n\nfunction ComboboxChip({ className, ...props }: Combobox.Chip.Props) {\n  return <Combobox.Chip className={cn(styles.chip, className)} {...props} />;\n}\n\nfunction ComboboxChipRemove({ className, children, ...props }: Combobox.ChipRemove.Props) {\n  return (\n    <Combobox.ChipRemove className={cn(styles.chipRemove, className)} {...props}>\n      {children || <X size={14} />}\n    </Combobox.ChipRemove>\n  );\n}\n\nfunction ComboboxChipsInput({ className, ...props }: Combobox.Input.Props) {\n  return <Combobox.Input className={cn(styles.chipsInput, className)} {...props} />;\n}\n\nconst ComboboxValue = Combobox.Value;\n\nexport {\n  ComboboxRoot as Combobox,\n  ComboboxArrow,\n  ComboboxChip,\n  ComboboxChipRemove,\n  ComboboxChips,\n  ComboboxChipsInput,\n  ComboboxClear,\n  ComboboxEmpty,\n  ComboboxGroup,\n  ComboboxGroupLabel,\n  ComboboxInput,\n  ComboboxItem,\n  ComboboxItemIndicator,\n  ComboboxList,\n  ComboboxNoItems,\n  ComboboxPopup,\n  ComboboxPortal,\n  ComboboxPositioner,\n  ComboboxSpacer,\n  ComboboxTrigger,\n  ComboboxValue,\n};\n",
      "type": "registry:file",
      "target": "~/components/ui/combobox/combobox.tsx"
    },
    {
      "path": "registry/brook/ui/combobox/combobox.module.css",
      "content": ".input {\n  @media (max-width: 640px) {\n    font-size: 0.9375rem;\n\n    &::placeholder {\n      font-size: 0.9375rem;\n    }\n  }\n}\n\n.trigger {\n  position: absolute;\n  top: 50%;\n  right: 0.5rem;\n  transform: translateY(-50%);\n  display: flex;\n  justify-content: center;\n  align-items: center;\n  padding: 0.25rem;\n  border: none;\n  background: transparent;\n  cursor: pointer;\n\n  &:focus-visible {\n    outline: none;\n  }\n\n  &[data-disabled] {\n    opacity: 0.5;\n    cursor: not-allowed;\n  }\n}\n\n.clear {\n  position: absolute;\n  top: 50%;\n  right: 0.5rem;\n  transform: translateY(-50%);\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  padding: 0.25rem;\n  border-radius: calc(var(--radius) - 2px);\n  cursor: pointer;\n  color: var(--muted-foreground);\n  transition: all 150ms ease;\n\n  &:hover {\n    color: var(--foreground);\n    background: var(--accent);\n  }\n}\n\n.icon {\n  margin-left: 0.5rem;\n  height: 1rem;\n  width: 1rem;\n  flex-shrink: 0;\n  color: var(--muted-foreground);\n}\n\n.positioner {\n  position: absolute;\n  top: 100%;\n  left: 0;\n  z-index: 150;\n  width: var(--anchor-width);\n}\n\n.popup {\n  box-sizing: border-box;\n  display: flex;\n  flex-direction: column;\n  max-height: min(var(--available-height), 20rem);\n  width: var(--anchor-width);\n  max-width: var(--available-width);\n  overflow-y: auto;\n  scroll-padding-block: 0.5rem;\n  overscroll-behavior: contain;\n  background: var(--popover);\n  border: none;\n  border-radius: var(--radius);\n  box-shadow:\n    0 0 0 0.5px oklch(from var(--border) l c h / 0.8),\n    var(--shadow-border-stack);\n  outline: none;\n  transform-origin: var(--transform-origin);\n  transition:\n    transform 250ms var(--ease-out-expo),\n    opacity 250ms var(--ease-out-expo);\n\n  &[data-starting-style] {\n    opacity: 0;\n    transform: scale(0.95);\n  }\n\n  &[data-ending-style] {\n    transition: none;\n  }\n\n  @media (max-width: 640px) {\n    max-width: calc(100vw - 2rem);\n  }\n}\n\n@keyframes slideDown {\n  from {\n    opacity: 0;\n    transform: translateY(-0.5rem);\n  }\n  to {\n    opacity: 1;\n    transform: translateY(0);\n  }\n}\n\n.itemIndicator {\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  height: 1rem;\n  width: 1rem;\n  opacity: 0;\n  transition: opacity 150ms ease;\n}\n\n.item {\n  display: flex;\n  align-items: center;\n  justify-content: flex-start;\n  gap: 0.75rem;\n  padding-inline: 8px 6px;\n  margin-inline: 4px;\n  min-height: 32px;\n  font-size: 0.875rem;\n  font-weight: 400;\n  line-height: 1.2;\n  color: var(--foreground);\n  cursor: pointer;\n  user-select: none;\n  background-color: transparent;\n  position: relative;\n  isolation: isolate;\n\n  &::before {\n    content: \"\";\n    position: absolute;\n    inset: 0;\n    border-radius: calc(var(--radius) - 4px);\n    background-color: transparent;\n    z-index: -1;\n  }\n\n  &[data-highlighted]::before,\n  &:hover::before,\n  &:focus::before {\n    background-color: var(--accent);\n  }\n\n  &:focus,\n  &:focus-visible {\n    outline: none;\n  }\n\n  &[data-disabled] {\n    opacity: 0.5;\n    cursor: not-allowed;\n\n    &:hover::before {\n      background: transparent;\n    }\n  }\n\n  &[data-selected] {\n    .itemIndicator {\n      opacity: 1;\n      margin: 4px;\n    }\n  }\n\n  @media (max-width: 640px) {\n    padding: 0.625rem 0.75rem;\n    font-size: 0.9375rem;\n    gap: 0.75rem;\n    min-height: 2.75rem;\n  }\n}\n\n.list {\n  display: flex;\n  flex-direction: column;\n  gap: 1px;\n  outline: none;\n}\n\n.itemText {\n  flex: 1;\n}\n\n.group {\n  padding: 0.25rem 0;\n}\n\n.groupLabel {\n  padding: 0.5rem 0.75rem;\n  font-size: 0.75rem;\n  font-weight: 500;\n  color: var(--muted-foreground);\n}\n\n.arrow {\n  position: absolute;\n  top: -0.25rem;\n  left: 1rem;\n  width: 0.5rem;\n  height: 0.5rem;\n  background: var(--card);\n  border-top: 1px solid var(--border);\n  border-left: 1px solid var(--border);\n  transform: rotate(45deg);\n}\n\n.noItems,\n.empty:not(:empty) {\n  padding: 2rem 1rem;\n  text-align: center;\n  font-size: 0.875rem;\n  color: var(--muted-foreground);\n\n  @media (max-width: 640px) {\n    padding: 1.5rem 1rem;\n    font-size: 0.9375rem;\n  }\n}\n\n.chips {\n  box-sizing: border-box;\n  display: flex;\n  flex-wrap: wrap;\n  align-items: center;\n  gap: 0.25rem;\n  border-radius: var(--radius);\n  padding: 0.25rem 0.375rem;\n  width: 100%;\n  background-color: var(--popover);\n  box-shadow: 0 0 0 1px oklch(from var(--border) l c h / 0.5);\n\n  &:focus-within {\n    box-shadow:\n      0 0 0 1px var(--ring),\n      0 0 0 3px oklch(from var(--ring) l c h / 0.2);\n  }\n}\n\n.chip {\n  display: flex;\n  align-items: center;\n  background-color: var(--secondary);\n  color: var(--foreground);\n  border-radius: calc(var(--radius) - 2px);\n  font-size: 0.875rem;\n  padding: 0.125rem 0.125rem 0.125rem 0.5rem;\n  overflow: hidden;\n  gap: 0.25rem;\n  outline: 0;\n  cursor: default;\n\n  &:focus-within,\n  &[data-highlighted] {\n    background-color: var(--primary);\n    color: var(--primary-foreground);\n  }\n\n  @media (max-width: 640px) {\n    font-size: 0.9375rem;\n  }\n}\n\n.chipRemove {\n  border: none;\n  background: none;\n  padding: 0.25rem;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  color: inherit;\n  border-radius: calc(var(--radius) - 4px);\n  cursor: pointer;\n\n  &:hover {\n    background-color: oklch(from var(--foreground) l c h / 0.1);\n  }\n}\n\n.chipsInput {\n  flex: 1;\n  box-sizing: border-box;\n  padding-left: 0.5rem;\n  margin: 0;\n  border: none;\n  height: 2rem;\n  border-radius: var(--radius);\n  font-family: inherit;\n  font-size: 0.875rem;\n  background-color: transparent;\n  color: var(--foreground);\n  min-width: 3rem;\n\n  &::placeholder {\n    color: var(--muted-foreground);\n  }\n\n  &:focus {\n    outline: none;\n  }\n\n  @media (max-width: 640px) {\n    font-size: 0.9375rem;\n  }\n}\n",
      "type": "registry:file",
      "target": "~/components/ui/combobox/combobox.module.css"
    }
  ]
}