{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "segmented-control",
  "type": "registry:component",
  "title": "Segmented Control",
  "description": "Shared segmented control for compact workspace switching.",
  "dependencies": [],
  "registryDependencies": [
    "https://steez-ui-6v5.pages.dev/r-steez/theme-tokens.json"
  ],
  "docs": "Files install at the project root. Import styles/steez/tokens.css once from your global stylesheet or root layout, then import components from components/steez. No Steez npm packages are required.",
  "files": [
    {
      "path": "components/steez/SegmentedControl.tsx",
      "type": "registry:file",
      "target": "components/steez/SegmentedControl.tsx",
      "content": "\"use client\";\n\nimport React from \"react\";\n\nimport styles from \"./SegmentedControl.module.css\";\n\nexport interface SegmentedControlOption {\n  value: string;\n  label: string;\n}\n\nexport interface SegmentedControlProps {\n  value: string;\n  options: SegmentedControlOption[];\n  onChange: (value: string) => void;\n  label?: string;\n  hint?: string;\n  ariaLabel?: string;\n  className?: string;\n  compact?: boolean;\n}\n\nexport function SegmentedControl({\n  value,\n  options,\n  onChange,\n  label,\n  hint,\n  ariaLabel,\n  className = \"\",\n  compact = false,\n}: SegmentedControlProps) {\n  const optionRefs = React.useRef<Map<string, HTMLButtonElement>>(new Map());\n\n  const setOptionRef = React.useCallback((optionValue: string, node: HTMLButtonElement | null) => {\n    if (node) {\n      optionRefs.current.set(optionValue, node);\n    } else {\n      optionRefs.current.delete(optionValue);\n    }\n  }, []);\n\n  const focusOption = React.useCallback((optionValue: string) => {\n    optionRefs.current.get(optionValue)?.focus();\n  }, []);\n\n  const handleOptionKeyDown = React.useCallback(\n    (event: React.KeyboardEvent<HTMLButtonElement>, optionValue: string) => {\n      if (!options.length) {\n        return;\n      }\n\n      const currentIndex = options.findIndex((option) => option.value === optionValue);\n      if (currentIndex === -1) {\n        return;\n      }\n\n      let nextIndex: number | null = null;\n\n      switch (event.key) {\n        case \"ArrowRight\":\n        case \"ArrowDown\":\n          nextIndex = (currentIndex + 1) % options.length;\n          break;\n        case \"ArrowLeft\":\n        case \"ArrowUp\":\n          nextIndex = (currentIndex - 1 + options.length) % options.length;\n          break;\n        case \"Home\":\n          nextIndex = 0;\n          break;\n        case \"End\":\n          nextIndex = options.length - 1;\n          break;\n        default:\n          return;\n      }\n\n      event.preventDefault();\n      const nextValue = options[nextIndex]!.value;\n      onChange(nextValue);\n      queueMicrotask(() => focusOption(nextValue));\n    },\n    [focusOption, onChange, options],\n  );\n\n  return (\n    <div className={`${styles.wrapper} ${className}`.trim()}>\n      {label ? <div className={styles.label}>{label}</div> : null}\n      <div\n        className={`${styles.track} ${compact ? styles.trackCompact : \"\"}`.trim()}\n        role=\"radiogroup\"\n        aria-label={ariaLabel || label}\n      >\n        {options.map((option) => {\n          const isActive = option.value === value;\n          return (\n            <button\n              key={option.value}\n              ref={(node) => setOptionRef(option.value, node)}\n              type=\"button\"\n              role=\"radio\"\n              aria-checked={isActive}\n              tabIndex={isActive ? 0 : -1}\n              className={`${styles.option} ${isActive ? styles.optionActive : \"\"} ${compact ? styles.optionCompact : \"\"}`.trim()}\n              onClick={() => onChange(option.value)}\n              onKeyDown={(event) => handleOptionKeyDown(event, option.value)}\n            >\n              {option.label}\n            </button>\n          );\n        })}\n      </div>\n      {hint ? <div className={styles.hint}>{hint}</div> : null}\n    </div>\n  );\n}\n",
      "source": "packages/ui/src/components/SegmentedControl.tsx"
    },
    {
      "path": "components/steez/SegmentedControl.module.css",
      "type": "registry:file",
      "target": "components/steez/SegmentedControl.module.css",
      "content": ".wrapper {\n  display: flex;\n  flex-direction: column;\n  gap: 0.5rem;\n}\n\n.label {\n  color: var(--text-primary);\n  font-size: 0.875rem;\n  font-weight: 500;\n}\n\n.hint {\n  color: var(--text-secondary);\n  font-size: 0.75rem;\n}\n\n.track {\n  display: inline-flex;\n  gap: 4px;\n  padding: 4px;\n  border: 1px solid var(--border-color);\n  background: color-mix(in srgb, var(--bg-secondary) 85%, transparent);\n  border-radius: 999px;\n}\n\n.trackCompact {\n  padding: 2px;\n}\n\n.option {\n  border: none;\n  background: transparent;\n  color: var(--text-secondary);\n  padding: 0.5rem 0.875rem;\n  border-radius: 999px;\n  font-family: var(--font-mono);\n  font-size: 0.8125rem;\n  cursor: pointer;\n  transition: color var(--transition-fast), background-color var(--transition-fast);\n}\n\n.optionCompact {\n  padding: 0.35rem 0.7rem;\n}\n\n.optionActive {\n  background: var(--interactive-primary-bg);\n  color: var(--interactive-primary-fg);\n}\n\n",
      "source": "packages/ui/src/components/SegmentedControl.module.css"
    }
  ]
}
