{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "select",
  "title": "Select",
  "description": "Dropdown for one choice from a list, with a placeholder, groups, a check on the chosen row and full keyboard support.",
  "dependencies": [
    "radix-ui",
    "lucide-react",
    "motion"
  ],
  "registryDependencies": [
    "utils",
    "https://miseui.junsu4621.workers.dev/r/motion.json"
  ],
  "files": [
    {
      "path": "registry/miseui/ui/select.tsx",
      "content": "import type * as React from \"react\"\nimport { Select as SelectPrimitive } from \"radix-ui\"\nimport { Check, ChevronDown, ChevronUp } from \"lucide-react\"\nimport { cn } from \"@/registry/miseui/lib/utils\"\nimport {\n  SELECT_MATERIALIZE_CLASS,\n  SELECT_SPRING_CONTENT_CLASS,\n  SELECT_SPRING_ITEM_CLASS,\n  SelectHighlight,\n  SelectSpringScope,\n  useSelectItemHighlight,\n  type SelectEffect,\n} from \"@/registry/miseui/ui/select-effects\"\n\nconst PLAIN_MOTION_CLASS = [\n  \"duration-(--duration-fast) ease-(--ease-mise)\",\n  \"data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95\",\n  \"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95\",\n  \"data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2\",\n  \"data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2\",\n]\n\nfunction Select({ ...props }: React.ComponentProps<typeof SelectPrimitive.Root>) {\n  return <SelectPrimitive.Root data-slot=\"select\" {...props} />\n}\n\nfunction SelectGroup({ ...props }: React.ComponentProps<typeof SelectPrimitive.Group>) {\n  return <SelectPrimitive.Group data-slot=\"select-group\" {...props} />\n}\n\nfunction SelectValue({ ...props }: React.ComponentProps<typeof SelectPrimitive.Value>) {\n  return <SelectPrimitive.Value data-slot=\"select-value\" {...props} />\n}\n\ntype SelectTriggerProps = React.ComponentProps<typeof SelectPrimitive.Trigger> & {\n  size?: \"sm\" | \"default\"\n}\n\nfunction SelectTrigger({ className, size = \"default\", children, ...props }: SelectTriggerProps) {\n  return (\n    <SelectPrimitive.Trigger\n      data-slot=\"select-trigger\"\n      data-size={size}\n      className={cn(\n        \"flex w-fit items-center justify-between gap-2 rounded-md border border-input bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs\",\n        \"data-[size=default]:h-9 data-[size=sm]:h-8\",\n        \"transition-[color,box-shadow] duration-(--duration-fast) ease-(--ease-mise)\",\n        \"outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50\",\n        \"disabled:cursor-not-allowed disabled:opacity-50 data-[placeholder]:text-muted-foreground\",\n        \"aria-invalid:border-destructive aria-invalid:ring-destructive/20\",\n        \"*:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2\",\n        \"[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground\",\n        className,\n      )}\n      {...props}\n    >\n      {children}\n      <SelectPrimitive.Icon asChild>\n        <ChevronDown className=\"size-4 opacity-50\" />\n      </SelectPrimitive.Icon>\n    </SelectPrimitive.Trigger>\n  )\n}\n\nfunction SelectScrollUpButton({ className, ...props }: React.ComponentProps<typeof SelectPrimitive.ScrollUpButton>) {\n  return (\n    <SelectPrimitive.ScrollUpButton\n      data-slot=\"select-scroll-up-button\"\n      className={cn(\"flex cursor-default items-center justify-center py-1\", className)}\n      {...props}\n    >\n      <ChevronUp className=\"size-4\" />\n    </SelectPrimitive.ScrollUpButton>\n  )\n}\n\nfunction SelectScrollDownButton({\n  className,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollDownButton>) {\n  return (\n    <SelectPrimitive.ScrollDownButton\n      data-slot=\"select-scroll-down-button\"\n      className={cn(\"flex cursor-default items-center justify-center py-1\", className)}\n      {...props}\n    >\n      <ChevronDown className=\"size-4\" />\n    </SelectPrimitive.ScrollDownButton>\n  )\n}\n\ntype SelectContentProps = React.ComponentProps<typeof SelectPrimitive.Content> & {\n  /** `materialize` grows the list out of the trigger; `spring` slides one highlight between the rows. */\n  effect?: SelectEffect\n}\n\nfunction SelectContent({ className, children, position = \"popper\", effect, ...props }: SelectContentProps) {\n  return (\n    <SelectSpringScope enabled={effect === \"spring\"}>\n      <SelectPrimitive.Portal>\n        <SelectPrimitive.Content\n          data-slot=\"select-content\"\n          data-effect={effect}\n          position={position}\n          className={cn(\n            \"relative z-50 max-h-(--radix-select-content-available-height) min-w-32 overflow-x-hidden overflow-y-auto rounded-md border bg-popover text-popover-foreground shadow-md\",\n            \"origin-(--radix-select-content-transform-origin)\",\n            effect === \"materialize\" ? SELECT_MATERIALIZE_CLASS : PLAIN_MOTION_CLASS,\n            effect === \"spring\" && SELECT_SPRING_CONTENT_CLASS,\n            position === \"popper\" &&\n              \"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1\",\n            className,\n          )}\n          {...props}\n        >\n          <SelectScrollUpButton />\n          <SelectPrimitive.Viewport\n            className={cn(\n              \"p-1\",\n              position === \"popper\" && \"h-(--radix-select-trigger-height) w-full min-w-(--radix-select-trigger-width) scroll-my-1\",\n            )}\n          >\n            {children}\n          </SelectPrimitive.Viewport>\n          <SelectScrollDownButton />\n        </SelectPrimitive.Content>\n      </SelectPrimitive.Portal>\n    </SelectSpringScope>\n  )\n}\n\nfunction SelectLabel({ className, ...props }: React.ComponentProps<typeof SelectPrimitive.Label>) {\n  return (\n    <SelectPrimitive.Label\n      data-slot=\"select-label\"\n      className={cn(\"px-2 py-1.5 text-xs text-muted-foreground\", className)}\n      {...props}\n    />\n  )\n}\n\nfunction SelectItem({\n  className,\n  children,\n  onFocus,\n  onBlur,\n  ...props\n}: React.ComponentProps<typeof SelectPrimitive.Item>) {\n  const highlight = useSelectItemHighlight({ onFocus, onBlur })\n  return (\n    <SelectPrimitive.Item\n      data-slot=\"select-item\"\n      className={cn(\n        \"relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none\",\n        \"transition-[color,background-color] duration-(--duration-fast) ease-(--ease-mise)\",\n        \"focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50\",\n        \"[&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground\",\n        highlight.spring && SELECT_SPRING_ITEM_CLASS,\n        className,\n      )}\n      onFocus={highlight.onFocus}\n      onBlur={highlight.onBlur}\n      {...props}\n    >\n      {highlight.highlighted ? <SelectHighlight reduceMotion={highlight.reduceMotion} /> : null}\n      <span className=\"absolute right-2 flex size-3.5 items-center justify-center\">\n        <SelectPrimitive.ItemIndicator>\n          <Check className=\"size-4\" />\n        </SelectPrimitive.ItemIndicator>\n      </span>\n      <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n    </SelectPrimitive.Item>\n  )\n}\n\nfunction SelectSeparator({ className, ...props }: React.ComponentProps<typeof SelectPrimitive.Separator>) {\n  return (\n    <SelectPrimitive.Separator\n      data-slot=\"select-separator\"\n      className={cn(\"pointer-events-none -mx-1 my-1 h-px bg-border\", className)}\n      {...props}\n    />\n  )\n}\n\nexport {\n  Select,\n  SelectTrigger,\n  SelectValue,\n  SelectContent,\n  SelectItem,\n  SelectGroup,\n  SelectLabel,\n  SelectSeparator,\n  type SelectTriggerProps,\n  type SelectContentProps,\n  type SelectEffect,\n}\n",
      "type": "registry:ui"
    },
    {
      "path": "registry/miseui/ui/select-effects.tsx",
      "content": "import type * as React from \"react\"\nimport { createContext, useContext, useId, useMemo, useState } from \"react\"\nimport { LayoutGroup, motion, useReducedMotion } from \"motion/react\"\nimport { SPRING_DEFAULT } from \"@/registry/miseui/lib/motion\"\n\ntype SelectEffect = \"materialize\" | \"spring\"\n\n/** The enter and exit values stay unqualified so the media overrides below win on source order. */\nconst SELECT_MATERIALIZE_CLASS = [\n  \"duration-(--duration-base) ease-(--ease-mise-out) will-change-[transform,opacity,filter]\",\n  \"data-[state=open]:animate-in data-[state=closed]:animate-out\",\n  \"fade-in-0 zoom-in-90 blur-in-sm fade-out-0 zoom-out-90 blur-out-sm\",\n  \"motion-reduce:zoom-in-100 motion-reduce:zoom-out-100 motion-reduce:blur-in-0 motion-reduce:blur-out-0\",\n  \"[@media(prefers-reduced-transparency:reduce)]:blur-in-0 [@media(prefers-reduced-transparency:reduce)]:blur-out-0\",\n]\n\n/** One stacking context for the list keeps a flying highlight behind every label, not just its own. */\nconst SELECT_SPRING_CONTENT_CLASS = \"isolate\"\nconst SELECT_SPRING_ITEM_CLASS = \"focus:bg-transparent focus:text-foreground\"\n\nconst SelectSpringContext = createContext<{ reduceMotion: boolean } | null>(null)\n\nfunction SelectSpringScope({ enabled, children }: { enabled: boolean; children: React.ReactNode }) {\n  // layoutId is global to the page; without a per-instance group two open lists would share one highlight.\n  const groupId = useId()\n  const reduceMotion = useReducedMotion() ?? false\n  const value = useMemo(() => ({ reduceMotion }), [reduceMotion])\n  if (!enabled) return children\n  return (\n    <SelectSpringContext.Provider value={value}>\n      <LayoutGroup id={groupId}>{children}</LayoutGroup>\n    </SelectSpringContext.Provider>\n  )\n}\n\ninterface FocusHandlers {\n  onFocus?: React.FocusEventHandler<HTMLDivElement>\n  onBlur?: React.FocusEventHandler<HTMLDivElement>\n}\n\n/** Radix highlights an item by focusing it, for the keyboard and the pointer alike, so focus is the one signal needed. */\nfunction useSelectItemHighlight({ onFocus, onBlur }: FocusHandlers) {\n  const scope = useContext(SelectSpringContext)\n  const [focused, setFocused] = useState(false)\n  if (!scope) return { spring: false, highlighted: false, reduceMotion: false, onFocus, onBlur }\n  return {\n    spring: true,\n    highlighted: focused,\n    reduceMotion: scope.reduceMotion,\n    onFocus: (event: React.FocusEvent<HTMLDivElement>) => {\n      onFocus?.(event)\n      setFocused(true)\n    },\n    onBlur: (event: React.FocusEvent<HTMLDivElement>) => {\n      onBlur?.(event)\n      setFocused(false)\n    },\n  }\n}\n\nfunction SelectHighlight({ reduceMotion }: { reduceMotion: boolean }) {\n  return (\n    <motion.span\n      aria-hidden=\"true\"\n      data-slot=\"select-highlight\"\n      data-reduced={reduceMotion ? \"true\" : \"false\"}\n      layoutId={reduceMotion ? undefined : \"select-highlight\"}\n      transition={SPRING_DEFAULT}\n      className=\"absolute inset-0 -z-10 rounded-sm bg-mise-soft\"\n    />\n  )\n}\n\nexport {\n  SELECT_MATERIALIZE_CLASS,\n  SELECT_SPRING_CONTENT_CLASS,\n  SELECT_SPRING_ITEM_CLASS,\n  SelectHighlight,\n  SelectSpringScope,\n  useSelectItemHighlight,\n  type SelectEffect,\n}\n",
      "type": "registry:ui"
    }
  ],
  "categories": [
    "forms"
  ],
  "type": "registry:ui"
}