{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "model-picker",
  "title": "Model Picker",
  "description": "A searchable list of models in a popover, with the highlighted model's details beside it.",
  "dependencies": [
    "@base-ui/react",
    "@hugeicons/core-free-icons",
    "@hugeicons/react",
    "@stylexjs/stylex"
  ],
  "registryDependencies": [
    "https://constella.aayush.cv/r/base.json",
    "https://constella.aayush.cv/r/button.json",
    "https://constella.aayush.cv/r/command.json",
    "https://constella.aayush.cv/r/popover.json"
  ],
  "files": [
    {
      "path": "src/components/ai/model-picker.tsx",
      "content": "\"use client\";\n\nimport { mergeProps } from \"@base-ui/react/merge-props\";\nimport { Popover as PopoverPrimitive } from \"@base-ui/react/popover\";\nimport { useRender } from \"@base-ui/react/use-render\";\nimport { Tick02Icon, UnfoldMoreIcon } from \"@hugeicons/core-free-icons\";\nimport { HugeiconsIcon } from \"@hugeicons/react\";\nimport * as stylex from \"@stylexjs/stylex\";\nimport {\n  createContext,\n  use,\n  useEffect,\n  useId,\n  useMemo,\n  useRef,\n  useState,\n} from \"react\";\nimport type { ComponentProps, RefObject } from \"react\";\n\nimport { Button } from \"@/components/primitives/button\";\nimport type { ButtonProps } from \"@/components/primitives/button\";\nimport { Command, CommandItem } from \"@/components/primitives/command\";\nimport type { CommandProps } from \"@/components/primitives/command\";\nimport {\n  Popover,\n  popoverStyles,\n  PopoverTrigger,\n} from \"@/components/primitives/popover\";\nimport type { PopoverContentProps } from \"@/components/primitives/popover\";\nimport type { Sx } from \"@/lib/constella/styles\";\nimport {\n  colors,\n  durations,\n  fontWeights,\n  lineHeights,\n  offsets,\n  shadows,\n  sizes,\n  space,\n  strokes,\n} from \"@/lib/constella/tokens.stylex\";\n\nconst modelPickerDetailsSides = [\"inline-start\", \"inline-end\"] as const;\n\ntype Styled<T> = Omit<T, \"className\" | \"style\"> & {\n  sx?: Sx;\n};\n\nconst hoverDelay = Number(durations.hoverCardDelay.slice(0, -\"ms\".length));\n\nconst rowGap = `calc(${space.xs} - ${space.xxxs})`;\n\nconst styles = stylex.create({\n  content: {\n    alignItems: { default: \"flex-start\", \":is([data-side='top'])\": \"flex-end\" },\n    display: \"flex\",\n    flexWrap: \"wrap\",\n    gap: space.xs,\n    maxWidth: \"var(--available-width)\",\n  },\n  detailsStart: {\n    flexDirection: \"row-reverse\",\n  },\n  instant: {\n    transitionDuration: \"0s\",\n  },\n  command: {\n    boxShadow: shadows.lg,\n    maxWidth: \"100%\",\n    width: sizes.modelPicker,\n  },\n  check: {\n    color: colors.textPrimary,\n    display: \"flex\",\n    marginInlineStart: \"auto\",\n  },\n  logo: {\n    backgroundColor: \"currentColor\",\n    flexShrink: 0,\n    height: sizes.icon,\n    maskPosition: \"center\",\n    maskRepeat: \"no-repeat\",\n    maskSize: \"contain\",\n    width: sizes.icon,\n  },\n  mask: (image: string) => ({ maskImage: image }),\n  details: {\n    maxWidth: \"100%\",\n  },\n  title: {\n    alignItems: \"center\",\n    display: \"flex\",\n    fontWeight: fontWeights.medium,\n    gap: rowGap,\n    lineHeight: lineHeights.textSm,\n  },\n  description: {\n    color: colors.textSecondary,\n    lineHeight: lineHeights.textSm,\n    marginBlockEnd: 0,\n    marginBlockStart: 0,\n  },\n});\n\ninterface Picker {\n  actions: RefObject<PopoverPrimitive.Root.Actions | null>;\n  cancelShow: () => void;\n  detailsId: string;\n  picked: boolean;\n  setPicked: (picked: boolean) => void;\n  setShown: (shown: boolean) => void;\n  showAfterRest: () => void;\n  shown: boolean;\n}\n\nconst PickerContext = createContext<Picker | null>(null);\n\nfunction usePicker() {\n  const picker = use(PickerContext);\n  if (picker === null) {\n    throw new Error(\"Model picker parts must be inside a ModelPicker.\");\n  }\n  return picker;\n}\n\nfunction ModelPicker({\n  actionsRef,\n  onOpenChangeComplete,\n  ...props\n}: PopoverPrimitive.Root.Props) {\n  const ownActions = useRef<PopoverPrimitive.Root.Actions | null>(null);\n  const actions = actionsRef ?? ownActions;\n  const [picked, setPicked] = useState(false);\n  const [shown, setShown] = useState(false);\n  const timer = useRef(0);\n  const detailsId = useId();\n  useEffect(\n    () => () => {\n      clearTimeout(timer.current);\n    },\n    []\n  );\n  const picker = useMemo(\n    () => ({\n      actions,\n      cancelShow: () => {\n        clearTimeout(timer.current);\n      },\n      detailsId,\n      picked,\n      setPicked,\n      setShown: (next: boolean) => {\n        clearTimeout(timer.current);\n        setShown(next);\n      },\n      showAfterRest: () => {\n        clearTimeout(timer.current);\n        timer.current = window.setTimeout(() => {\n          setShown(true);\n        }, hoverDelay);\n      },\n      shown,\n    }),\n    [actions, detailsId, picked, shown]\n  );\n  return (\n    <PickerContext value={picker}>\n      <Popover\n        actionsRef={actions}\n        // Reset once closed, since a controlled `open` never calls `onOpenChange`.\n        onOpenChangeComplete={(open) => {\n          if (!open) {\n            setPicked(false);\n            setShown(false);\n          }\n          onOpenChangeComplete?.(open);\n        }}\n        {...props}\n      />\n    </PickerContext>\n  );\n}\n\n/** A ghost button by default, ending in the picker's chevron. */\nfunction ModelPickerTrigger({\n  children,\n  size = \"sm\",\n  variant = \"ghost\",\n  ...props\n}: ButtonProps) {\n  return (\n    <PopoverTrigger\n      data-slot=\"model-picker-trigger\"\n      render={<Button size={size} variant={variant} {...props} />}\n    >\n      {children}\n      <HugeiconsIcon\n        aria-hidden\n        icon={UnfoldMoreIcon}\n        size={sizes.icon}\n        strokeWidth={Number(strokes.icon)}\n      />\n    </PopoverTrigger>\n  );\n}\n\n/** Renders the portal, the positioner and a popup that is no surface, so the command and details card beside it are. */\nfunction ModelPickerContent({\n  align = \"start\",\n  alignOffset = 0,\n  detailsSide = \"inline-end\",\n  side = \"bottom\",\n  sideOffset = Number(offsets.popover),\n  sx,\n  ...props\n}: PopoverContentProps & {\n  /** Which side of the list the details card opens on; `inline-start` for a picker at the end of a row. */\n  detailsSide?: (typeof modelPickerDetailsSides)[number];\n}) {\n  const { picked } = usePicker();\n  return (\n    <PopoverPrimitive.Portal>\n      <PopoverPrimitive.Positioner\n        align={align}\n        alignOffset={alignOffset}\n        side={side}\n        sideOffset={sideOffset}\n        {...stylex.props(popoverStyles.positioner)}\n      >\n        <PopoverPrimitive.Popup\n          data-details-side={detailsSide}\n          data-slot=\"model-picker-content\"\n          {...props}\n          {...stylex.props(\n            popoverStyles.motion,\n            styles.content,\n            detailsSide === \"inline-start\" && styles.detailsStart,\n            picked && styles.instant,\n            sx\n          )}\n        />\n      </PopoverPrimitive.Positioner>\n    </PopoverPrimitive.Portal>\n  );\n}\n\n/**\n * A `Command` at `sizes.modelPicker` that keeps its highlight when the pointer leaves for the details card.\n * The card shows once a row is reached by arrow key, or rested on with the pointer.\n */\nfunction ModelPickerCommand({\n  keepHighlight = true,\n  onItemHighlighted,\n  sx,\n  ...props\n}: CommandProps) {\n  const { setShown } = usePicker();\n  return (\n    <Command\n      data-slot=\"model-picker-command\"\n      keepHighlight={keepHighlight}\n      onItemHighlighted={(value, details) => {\n        if (value === undefined) {\n          setShown(false);\n        } else if (details.reason === \"keyboard\") {\n          setShown(true);\n        }\n        onItemHighlighted?.(value, details);\n      }}\n      {...props}\n      sx={[styles.command, sx]}\n    />\n  );\n}\n\n/**\n * A `CommandItem` that closes the picker once picked, with a tick when `selected`.\n * Every row is described by the details card, which always shows the highlighted row's model.\n */\nfunction ModelPickerItem({\n  children,\n  onClick,\n  onPointerEnter,\n  onPointerLeave,\n  selected = false,\n  ...props\n}: ComponentProps<typeof CommandItem> & { selected?: boolean }) {\n  const { actions, cancelShow, detailsId, setPicked, showAfterRest, shown } =\n    usePicker();\n  return (\n    <CommandItem\n      aria-checked={selected}\n      aria-describedby={shown ? detailsId : undefined}\n      onClick={(event) => {\n        onClick?.(event);\n        setPicked(true);\n        actions.current?.close();\n      }}\n      onPointerEnter={(event) => {\n        onPointerEnter?.(event);\n        showAfterRest();\n      }}\n      onPointerLeave={(event) => {\n        onPointerLeave?.(event);\n        cancelShow();\n      }}\n      {...props}\n    >\n      {children}\n      {selected && (\n        <span {...stylex.props(styles.check)}>\n          <HugeiconsIcon\n            aria-hidden\n            icon={Tick02Icon}\n            size={sizes.icon}\n            strokeWidth={Number(strokes.icon)}\n          />\n        </span>\n      )}\n    </CommandItem>\n  );\n}\n\n/** A provider's one-color logo, painted in the text's color so it follows the theme. */\nfunction ModelPickerLogo({\n  src,\n  sx,\n  ...props\n}: Styled<ComponentProps<\"span\">> & { src: string }) {\n  return (\n    <span\n      aria-hidden\n      data-slot=\"model-picker-logo\"\n      {...props}\n      {...stylex.props(styles.logo, styles.mask(`url(\"${src}\")`), sx)}\n    />\n  );\n}\n\n/** The highlighted model's card, beside the command. Hidden until a row is reached by key or rested on. */\nfunction ModelPickerDetails({ sx, ...props }: Styled<ComponentProps<\"div\">>) {\n  const { detailsId, shown } = usePicker();\n  if (!shown) {\n    return null;\n  }\n  return (\n    <div\n      data-slot=\"model-picker-details\"\n      {...props}\n      id={detailsId}\n      {...stylex.props(popoverStyles.surface, styles.details, sx)}\n    />\n  );\n}\n\nfunction ModelPickerTitle({\n  render,\n  sx,\n  ...props\n}: Styled<useRender.ComponentProps<\"div\">>) {\n  return useRender({\n    defaultTagName: \"div\",\n    props: mergeProps<\"div\">(props, stylex.props(styles.title, sx)),\n    render,\n    state: { slot: \"model-picker-title\" },\n  });\n}\n\nfunction ModelPickerDescription({ sx, ...props }: Styled<ComponentProps<\"p\">>) {\n  return (\n    <p\n      data-slot=\"model-picker-description\"\n      {...props}\n      {...stylex.props(styles.description, sx)}\n    />\n  );\n}\n\nexport {\n  ModelPicker,\n  ModelPickerCommand,\n  ModelPickerContent,\n  ModelPickerDescription,\n  ModelPickerDetails,\n  modelPickerDetailsSides,\n  ModelPickerItem,\n  ModelPickerLogo,\n  ModelPickerTitle,\n  ModelPickerTrigger,\n};\n",
      "type": "registry:component"
    }
  ],
  "docs": "Usage: https://constella.aayush.cv/docs/components/model-picker/index.md",
  "type": "registry:ui"
}