{
  "$schema": "https://shadcn-vue.com/schema/registry-item.json",
  "name": "select",
  "title": "Select",
  "type": "registry:ui",
  "files": [
    {
      "path": "packages/registry-vue/components/select/Select.vue",
      "content": "<script setup lang=\"ts\">\nimport type { SelectRootEmits, SelectRootProps } from 'reka-ui'\nimport { SelectRoot, useForwardPropsEmits } from 'reka-ui'\n\nconst props = defineProps<SelectRootProps>()\nconst emits = defineEmits<SelectRootEmits>()\n\nconst forwarded = useForwardPropsEmits(props, emits)\n</script>\n\n<template>\n  <SelectRoot v-slot=\"slotProps\" data-uipkge data-slot=\"select\" v-bind=\"forwarded\">\n    <slot v-bind=\"slotProps\" />\n  </SelectRoot>\n</template>\n",
      "type": "registry:ui",
      "target": "~/app/components/ui/select/Select.vue"
    },
    {
      "path": "packages/registry-vue/components/select/SelectContent.vue",
      "content": "<script setup lang=\"ts\">\nimport type { SelectContentEmits, SelectContentProps } from 'reka-ui'\nimport type { HTMLAttributes } from 'vue'\nimport { reactiveOmit } from '@vueuse/core'\nimport { SelectContent, SelectPortal, SelectViewport, useForwardPropsEmits } from 'reka-ui'\nimport { cn } from '@/lib/utils'\nimport { SelectScrollDownButton, SelectScrollUpButton } from '.'\n\ndefineOptions({\n  inheritAttrs: false,\n})\n\nconst props = withDefaults(defineProps<SelectContentProps & { class?: HTMLAttributes['class'] }>(), {\n  position: 'popper',\n})\nconst emits = defineEmits<SelectContentEmits>()\n\nconst delegatedProps = reactiveOmit(props, 'class')\n\nconst forwarded = useForwardPropsEmits(delegatedProps, emits)\n</script>\n\n<template>\n  <SelectPortal>\n    <SelectContent\n      data-uipkge\n      data-slot=\"select-content\"\n      v-bind=\"{ ...$attrs, ...forwarded }\"\n      :class=\"\n        cn(\n          'bg-popover text-popover-foreground motion-safe:data-[state=open]:animate-in motion-safe:data-[state=closed]:animate-out motion-safe:data-[state=closed]:fade-out-0 motion-safe:data-[state=open]:fade-in-0 motion-safe:data-[state=closed]:zoom-out-95 motion-safe:data-[state=open]:zoom-in-95 motion-safe:data-[side=bottom]:slide-in-from-top-2 motion-safe:data-[side=left]:slide-in-from-right-2 motion-safe:data-[side=right]:slide-in-from-left-2 motion-safe:data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-(--reka-select-content-available-height) min-w-[8rem] overflow-x-hidden overflow-y-auto rounded-md border shadow-md',\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          props.class,\n        )\n      \"\n    >\n      <SelectScrollUpButton />\n      <SelectViewport\n        :class=\"\n          cn(\n            'p-1',\n            position === 'popper' &&\n              'h-[var(--reka-select-trigger-height)] w-full min-w-[var(--reka-select-trigger-width)] scroll-my-1',\n          )\n        \"\n      >\n        <slot />\n      </SelectViewport>\n      <SelectScrollDownButton />\n    </SelectContent>\n  </SelectPortal>\n</template>\n",
      "type": "registry:ui",
      "target": "~/app/components/ui/select/SelectContent.vue"
    },
    {
      "path": "packages/registry-vue/components/select/SelectGroup.vue",
      "content": "<script setup lang=\"ts\">\nimport type { SelectGroupProps } from 'reka-ui'\nimport { SelectGroup } from 'reka-ui'\n\nconst props = defineProps<SelectGroupProps>()\n</script>\n\n<template>\n  <SelectGroup data-uipkge data-slot=\"select-group\" v-bind=\"props\">\n    <slot />\n  </SelectGroup>\n</template>\n",
      "type": "registry:ui",
      "target": "~/app/components/ui/select/SelectGroup.vue"
    },
    {
      "path": "packages/registry-vue/components/select/SelectItem.vue",
      "content": "<script setup lang=\"ts\">\nimport type { SelectItemProps } from 'reka-ui'\nimport type { HTMLAttributes } from 'vue'\nimport { reactiveOmit } from '@vueuse/core'\nimport { Check } from 'lucide-vue-next'\nimport { SelectItem, SelectItemIndicator, SelectItemText, useForwardProps } from 'reka-ui'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<SelectItemProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = reactiveOmit(props, 'class')\n\nconst forwardedProps = useForwardProps(delegatedProps)\n</script>\n\n<template>\n  <SelectItem\n    data-uipkge\n    data-slot=\"select-item\"\n    v-bind=\"forwardedProps\"\n    :class=\"\n      cn(\n        'focus:bg-accent focus:text-accent-foreground [&_svg:not([class*=\\'text-\\'])]:text-muted-foreground 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 data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*=\\'size-\\'])]:size-4 *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2',\n        props.class,\n      )\n    \"\n  >\n    <span class=\"absolute right-2 flex size-3.5 items-center justify-center\">\n      <SelectItemIndicator>\n        <slot name=\"indicator-icon\">\n          <Check class=\"size-4\" aria-hidden=\"true\" />\n        </slot>\n      </SelectItemIndicator>\n    </span>\n\n    <SelectItemText>\n      <slot />\n    </SelectItemText>\n  </SelectItem>\n</template>\n",
      "type": "registry:ui",
      "target": "~/app/components/ui/select/SelectItem.vue"
    },
    {
      "path": "packages/registry-vue/components/select/SelectItemText.vue",
      "content": "<script setup lang=\"ts\">\nimport type { SelectItemTextProps } from 'reka-ui'\nimport { SelectItemText } from 'reka-ui'\n\nconst props = defineProps<SelectItemTextProps>()\n</script>\n\n<template>\n  <SelectItemText data-uipkge data-slot=\"select-item-text\" v-bind=\"props\">\n    <slot />\n  </SelectItemText>\n</template>\n",
      "type": "registry:ui",
      "target": "~/app/components/ui/select/SelectItemText.vue"
    },
    {
      "path": "packages/registry-vue/components/select/SelectLabel.vue",
      "content": "<script setup lang=\"ts\">\nimport type { SelectLabelProps } from 'reka-ui'\nimport type { HTMLAttributes } from 'vue'\nimport { SelectLabel } from 'reka-ui'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<SelectLabelProps & { class?: HTMLAttributes['class'] }>()\n</script>\n\n<template>\n  <SelectLabel\n    data-uipkge\n    data-slot=\"select-label\"\n    :class=\"cn('text-muted-foreground px-2 py-1.5 text-xs', props.class)\"\n  >\n    <slot />\n  </SelectLabel>\n</template>\n",
      "type": "registry:ui",
      "target": "~/app/components/ui/select/SelectLabel.vue"
    },
    {
      "path": "packages/registry-vue/components/select/SelectScrollDownButton.vue",
      "content": "<script setup lang=\"ts\">\nimport type { SelectScrollDownButtonProps } from 'reka-ui'\nimport type { HTMLAttributes } from 'vue'\nimport { reactiveOmit } from '@vueuse/core'\nimport { ChevronDown } from 'lucide-vue-next'\nimport { SelectScrollDownButton, useForwardProps } from 'reka-ui'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<SelectScrollDownButtonProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = reactiveOmit(props, 'class')\n\nconst forwardedProps = useForwardProps(delegatedProps)\n</script>\n\n<template>\n  <SelectScrollDownButton\n    data-uipkge\n    data-slot=\"select-scroll-down-button\"\n    v-bind=\"forwardedProps\"\n    :class=\"cn('flex cursor-default items-center justify-center py-1', props.class)\"\n  >\n    <slot>\n      <ChevronDown class=\"size-4\" aria-hidden=\"true\" />\n    </slot>\n  </SelectScrollDownButton>\n</template>\n",
      "type": "registry:ui",
      "target": "~/app/components/ui/select/SelectScrollDownButton.vue"
    },
    {
      "path": "packages/registry-vue/components/select/SelectScrollUpButton.vue",
      "content": "<script setup lang=\"ts\">\nimport type { SelectScrollUpButtonProps } from 'reka-ui'\nimport type { HTMLAttributes } from 'vue'\nimport { reactiveOmit } from '@vueuse/core'\nimport { ChevronUp } from 'lucide-vue-next'\nimport { SelectScrollUpButton, useForwardProps } from 'reka-ui'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<SelectScrollUpButtonProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = reactiveOmit(props, 'class')\n\nconst forwardedProps = useForwardProps(delegatedProps)\n</script>\n\n<template>\n  <SelectScrollUpButton\n    data-uipkge\n    data-slot=\"select-scroll-up-button\"\n    v-bind=\"forwardedProps\"\n    :class=\"cn('flex cursor-default items-center justify-center py-1', props.class)\"\n  >\n    <slot>\n      <ChevronUp class=\"size-4\" aria-hidden=\"true\" />\n    </slot>\n  </SelectScrollUpButton>\n</template>\n",
      "type": "registry:ui",
      "target": "~/app/components/ui/select/SelectScrollUpButton.vue"
    },
    {
      "path": "packages/registry-vue/components/select/SelectSeparator.vue",
      "content": "<script setup lang=\"ts\">\nimport type { SelectSeparatorProps } from 'reka-ui'\nimport type { HTMLAttributes } from 'vue'\nimport { reactiveOmit } from '@vueuse/core'\nimport { SelectSeparator } from 'reka-ui'\nimport { cn } from '@/lib/utils'\n\nconst props = defineProps<SelectSeparatorProps & { class?: HTMLAttributes['class'] }>()\n\nconst delegatedProps = reactiveOmit(props, 'class')\n</script>\n\n<template>\n  <SelectSeparator\n    data-uipkge\n    data-slot=\"select-separator\"\n    v-bind=\"delegatedProps\"\n    :class=\"cn('bg-border pointer-events-none -mx-1 my-1 h-px', props.class)\"\n  />\n</template>\n",
      "type": "registry:ui",
      "target": "~/app/components/ui/select/SelectSeparator.vue"
    },
    {
      "path": "packages/registry-vue/components/select/SelectTrigger.vue",
      "content": "<script setup lang=\"ts\">\nimport type { SelectTriggerProps } from 'reka-ui'\nimport type { HTMLAttributes } from 'vue'\nimport { reactiveOmit } from '@vueuse/core'\nimport { ChevronDown, Loader } from 'lucide-vue-next'\nimport { SelectIcon, SelectTrigger, useForwardProps } from 'reka-ui'\nimport { cn } from '@/lib/utils'\n\nconst props = withDefaults(\n  defineProps<\n    SelectTriggerProps & {\n      class?: HTMLAttributes['class']\n      size?: 'sm' | 'default' | 'lg'\n      state?: 'default' | 'error' | 'success'\n      loading?: boolean\n    }\n  >(),\n  { size: 'default', state: 'default', loading: false },\n)\n\nconst delegatedProps = reactiveOmit(props, 'class', 'size', 'state', 'loading')\nconst forwardedProps = useForwardProps(delegatedProps)\n\nconst sizeClasses = {\n  sm: 'h-8 text-sm px-2.5 py-1.5',\n  default: 'h-9 text-sm px-3 py-2',\n  lg: 'h-11 text-base px-4 py-2.5',\n}\n\nconst stateClasses = {\n  default: 'border-input dark:hover:bg-input/50',\n  error:\n    'border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive',\n  success: 'border-[var(--success)] focus-visible:border-[var(--success)]',\n}\n</script>\n\n<template>\n  <SelectTrigger\n    data-uipkge\n    data-slot=\"select-trigger\"\n    :data-size=\"size\"\n    :data-state-value=\"state\"\n    v-bind=\"forwardedProps\"\n    :disabled=\"disabled || loading\"\n    :aria-busy=\"loading\"\n    :class=\"\n      cn(\n        'border-input data-[placeholder]:text-muted-foreground [&_svg:not([class*=\\'text-\\'])]:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 flex w-full items-center justify-between gap-2 rounded-md border bg-transparent text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50',\n        sizeClasses[size],\n        stateClasses[state],\n        props.class,\n      )\n    \"\n  >\n    <slot />\n    <SelectIcon v-if=\"!loading\" as-child>\n      <ChevronDown class=\"size-4 opacity-50\" aria-hidden=\"true\" />\n    </SelectIcon>\n    <Loader v-else class=\"size-4 animate-spin opacity-50\" />\n  </SelectTrigger>\n</template>\n",
      "type": "registry:ui",
      "target": "~/app/components/ui/select/SelectTrigger.vue"
    },
    {
      "path": "packages/registry-vue/components/select/SelectValue.vue",
      "content": "<script setup lang=\"ts\">\nimport type { SelectValueProps } from 'reka-ui'\nimport { SelectValue } from 'reka-ui'\n\nconst props = defineProps<SelectValueProps>()\n</script>\n\n<template>\n  <SelectValue data-uipkge data-slot=\"select-value\" v-bind=\"props\">\n    <slot />\n  </SelectValue>\n</template>\n",
      "type": "registry:ui",
      "target": "~/app/components/ui/select/SelectValue.vue"
    },
    {
      "path": "packages/registry-vue/components/select/index.ts",
      "content": "export { default as Select } from './Select.vue'\nexport { default as SelectContent } from './SelectContent.vue'\nexport { default as SelectGroup } from './SelectGroup.vue'\nexport { default as SelectItem } from './SelectItem.vue'\nexport { default as SelectItemText } from './SelectItemText.vue'\nexport { default as SelectLabel } from './SelectLabel.vue'\nexport { default as SelectScrollDownButton } from './SelectScrollDownButton.vue'\nexport { default as SelectScrollUpButton } from './SelectScrollUpButton.vue'\nexport { default as SelectSeparator } from './SelectSeparator.vue'\nexport { default as SelectTrigger } from './SelectTrigger.vue'\nexport { default as SelectValue } from './SelectValue.vue'\nexport { type SelectOption, readKey } from './option-types'\n",
      "type": "registry:ui",
      "target": "~/app/components/ui/select/index.ts"
    },
    {
      "path": "packages/registry-vue/components/select/option-types.ts",
      "content": "/**\n * Shared option shape for `AdvanceSelect` and any future options-driven select.\n * Components accept this canonical shape OR any object shape if `value-key` /\n * `label-key` are provided.\n */\nexport interface SelectOption<V = string> {\n  label: string\n  value: V\n  disabled?: boolean\n  /** Items sharing this key render under one heading. */\n  group?: string\n}\n\n/**\n * Resolve `option[key]` with a default fallback. Used by AdvanceSelect so every\n * accessor obeys `value-key` / `label-key`.\n */\nexport function readKey<T>(option: T, key: string, fallback?: unknown): unknown {\n  if (option == null || typeof option !== 'object') return fallback\n  const v = (option as Record<string, unknown>)[key]\n  return v === undefined ? fallback : v\n}\n",
      "type": "registry:ui",
      "target": "~/app/components/ui/select/option-types.ts"
    }
  ],
  "dependencies": [
    "@vueuse/core",
    "lucide-vue-next",
    "reka-ui"
  ],
  "devDependencies": [],
  "registryDependencies": [],
  "description": "Dropdown select primitive — single-select, with optional groups, descriptions per item, and a search input via the AdvanceSelect variant. Built on reka-ui.",
  "categories": [
    "control"
  ]
}