{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "select",
  "title": "UI Select",
  "description": "A select whose opened/closed state is a pure function of the timeline; the trigger reuses the Button primitive and the reveal panel composes SelectItem rows. The panel fade, scale, lift, and chevron are keyframed presets.",
  "dependencies": ["remotion"],
  "registryDependencies": [
    "@remocn/remocn-ui",
    "@remocn/button",
    "@remocn/select-item"
  ],
  "files": [
    {
      "path": "registry/remocn-ui/select/index.tsx",
      "content": "\"use client\";\n\nimport {\n  type ButtonStyle,\n  type ButtonStyleContext,\n  buttonStyle,\n  buttonStyleContext,\n} from \"@/components/remocn/button\";\nimport {\n  SelectItemRow,\n  type SelectItemState,\n  type SelectItemStyle,\n  type SelectItemStyleContext,\n  selectItemStyle,\n  selectItemStyleContext,\n} from \"@/components/remocn/select-item\";\nimport { type RemocnTheme, useRemocnTheme } from \"@/lib/remocn-ui\";\n\nexport type SelectState = \"opened\" | \"closed\";\n\nexport interface SelectProps {\n  state?: SelectState;\n  style?: SelectStyle;\n  label?: string;\n  triggerStyle?: ButtonStyle;\n  items?: string[];\n  selectedIndex?: number;\n  highlightedIndex?: number;\n  pressedIndex?: number;\n  itemStyles?: (SelectItemStyle | undefined)[];\n  theme?: Partial<RemocnTheme>;\n  className?: string;\n}\n\nconst WIDTH = 260;\n\nexport interface SelectStyle {\n  panelOpacity: number;\n  panelScale: number;\n  panelTranslateY: number;\n  chevronRotation: number;\n}\n\nexport interface SelectStyleContext {\n  triggerCtx: ButtonStyleContext;\n  panelBg: string;\n  panelBorder: string;\n  triggerFg: string;\n  mutedFg: string;\n  radius: number;\n  itemCtx: SelectItemStyleContext;\n}\n\nexport function selectStyleContext(theme: RemocnTheme): SelectStyleContext {\n  return {\n    triggerCtx: buttonStyleContext(\"outline\", theme),\n    panelBg: theme.popover,\n    panelBorder: theme.border,\n    triggerFg: theme.foreground,\n    mutedFg: theme.mutedForeground,\n    radius: theme.radius,\n    itemCtx: selectItemStyleContext(theme),\n  };\n}\n\nexport function selectStyle(\n  state: SelectState,\n  _ctx: SelectStyleContext,\n): SelectStyle {\n  switch (state) {\n    case \"opened\":\n      return {\n        panelOpacity: 1,\n        panelScale: 1,\n        panelTranslateY: 0,\n        chevronRotation: 180,\n      };\n    default:\n      return {\n        panelOpacity: 0,\n        panelScale: 0.96,\n        panelTranslateY: -4,\n        chevronRotation: 0,\n      };\n  }\n}\n\nfunction rowState(\n  i: number,\n  selectedIndex: number,\n  highlightedIndex: number,\n  pressedIndex: number,\n): SelectItemState {\n  if (i === pressedIndex) return \"press\";\n  if (i === selectedIndex) return \"selected\";\n  if (i === highlightedIndex) return \"hover\";\n  return \"idle\";\n}\n\nexport function Select({\n  state = \"closed\",\n  style,\n  label = \"Select a fruit\",\n  triggerStyle,\n  items = [\"Apple\", \"Banana\", \"Orange\", \"Grape\"],\n  selectedIndex = -1,\n  highlightedIndex = -1,\n  pressedIndex = -1,\n  itemStyles,\n  theme: themeOverride,\n  className,\n}: SelectProps) {\n  const theme = useRemocnTheme(themeOverride, \"light\");\n  const ctx = selectStyleContext(theme);\n  const v = style ?? selectStyle(state, ctx);\n\n  const trigger: ButtonStyle =\n    triggerStyle ?? buttonStyle(\"idle\", ctx.triggerCtx);\n\n  return (\n    <div\n      className={className}\n      style={{\n        position: \"absolute\",\n        inset: 0,\n        display: \"flex\",\n        alignItems: \"center\",\n        justifyContent: \"center\",\n        background: \"transparent\",\n        fontFamily:\n          \"var(--font-geist-sans), -apple-system, BlinkMacSystemFont, sans-serif\",\n      }}\n    >\n      <div style={{ position: \"relative\", width: WIDTH }}>\n        {}\n        <div\n          style={{\n            width: WIDTH,\n            boxSizing: \"border-box\",\n            display: \"flex\",\n            alignItems: \"center\",\n            justifyContent: \"space-between\",\n            gap: 8,\n            height: 40,\n            padding: \"0 16px\",\n            fontSize: 15,\n            fontWeight: 500,\n            letterSpacing: \"-0.01em\",\n            color: ctx.triggerFg,\n            transform: `translateY(${trigger.translateY}px) scale(${trigger.scale})`,\n            background: trigger.background,\n            border: `1px solid ${ctx.panelBorder}`,\n            borderRadius: ctx.radius,\n          }}\n        >\n          <span>{label}</span>\n          <svg\n            width={16}\n            height={16}\n            viewBox=\"0 0 24 24\"\n            fill=\"none\"\n            style={{\n              flexShrink: 0,\n              transform: `rotate(${v.chevronRotation}deg)`,\n            }}\n          >\n            <path\n              d=\"M6 9l6 6 6-6\"\n              stroke={ctx.mutedFg}\n              strokeWidth=\"2.2\"\n              strokeLinecap=\"round\"\n              strokeLinejoin=\"round\"\n            />\n          </svg>\n        </div>\n        {}\n        <div\n          style={{\n            position: \"absolute\",\n            top: \"calc(100% + 6px)\",\n            left: 0,\n            width: WIDTH,\n            boxSizing: \"border-box\",\n            transformOrigin: \"top\",\n            transform: `translateY(${v.panelTranslateY}px) scale(${v.panelScale})`,\n            opacity: v.panelOpacity,\n            background: ctx.panelBg,\n            border: `1px solid ${ctx.panelBorder}`,\n            borderRadius: ctx.radius,\n            padding: 4,\n            display: \"flex\",\n            flexDirection: \"column\",\n            gap: 2,\n            boxShadow: \"0 16px 32px -12px rgba(0,0,0,0.25)\",\n          }}\n        >\n          {items.map((item, i) => {\n            const override = itemStyles?.[i];\n            return (\n              <SelectItemRow\n                key={item}\n                style={\n                  override ??\n                  selectItemStyle(\n                    rowState(i, selectedIndex, highlightedIndex, pressedIndex),\n                    ctx.itemCtx,\n                  )\n                }\n                ctx={ctx.itemCtx}\n                label={item}\n                width={WIDTH - 8}\n                radius={theme.radius}\n                check={ctx.itemCtx.check}\n              />\n            );\n          })}\n        </div>\n      </div>\n    </div>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/remocn/select.tsx"
    },
    {
      "path": "registry/remocn-ui/select/use-select-transition.ts",
      "content": "\"use client\";\n\nimport {\n  type SelectState,\n  type SelectStyle,\n  selectStyle,\n  selectStyleContext,\n} from \"@/components/remocn/select\";\nimport {\n  easings,\n  type RemocnTheme,\n  type Step,\n  useRemocnTheme,\n  useStateTransition,\n} from \"@/lib/remocn-ui\";\n\nexport const DEFAULT_DURATION = 12;\n\nexport function tweenSelectStyle(\n  a: SelectStyle,\n  b: SelectStyle,\n  t: number,\n): SelectStyle {\n  return {\n    panelOpacity: a.panelOpacity + (b.panelOpacity - a.panelOpacity) * t,\n    panelScale: a.panelScale + (b.panelScale - a.panelScale) * t,\n    panelTranslateY:\n      a.panelTranslateY + (b.panelTranslateY - a.panelTranslateY) * t,\n    chevronRotation:\n      a.chevronRotation + (b.chevronRotation - a.chevronRotation) * t,\n  };\n}\n\nexport interface SelectTransitionOptions {\n  theme?: Partial<RemocnTheme>;\n  mode?: \"light\" | \"dark\";\n  speed?: number;\n  defaultDuration?: number;\n}\n\nexport function useSelectTransition(\n  steps: Step<SelectState>[],\n  opts: SelectTransitionOptions = {},\n): SelectStyle {\n  const {\n    theme: themeOverride,\n    mode,\n    speed = 1,\n    defaultDuration = DEFAULT_DURATION,\n  } = opts;\n  const theme = useRemocnTheme(themeOverride, mode);\n  const ctx = selectStyleContext(theme);\n  const { from, to, progress } = useStateTransition(\n    steps,\n    \"closed\",\n    speed,\n    defaultDuration,\n  );\n  const t = easings.out(progress);\n  return tweenSelectStyle(selectStyle(from, ctx), selectStyle(to, ctx), t);\n}\n",
      "type": "registry:component",
      "target": "components/remocn/use-select-transition.ts"
    }
  ],
  "type": "registry:component"
}
