{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "dependencies": [
    "@base-ui/react@1.8.0"
  ],
  "description": "A segmented control whose glass indicator slides between options.",
  "docs": "Two steps after installing: import the copied stylesheet once at your app entry — it lands at `styles/liquefy-ui.css` — or `@import` it from your global CSS *before* `tailwindcss`, so Tailwind utilities keep winning over component styles. Then wrap the tree in `<LiquefyProvider>`, which is where every component reads its tokens from. Every copied file already carries its own 'use client' directive. Full documentation: https://liquefy-ui.com/#/docs/installation",
  "files": [
    {
      "content": "'use client'\n\nimport { Toggle } from '@base-ui/react/toggle'\nimport { ToggleGroup } from '@base-ui/react/toggle-group'\nimport { forwardRef, useRef, useState, type HTMLAttributes, type ReactNode } from 'react'\nimport { useLiquefyConfig } from '@/lib/provider'\nimport { useLiquidStyles, type LiquidStyleProps } from '@/lib/styles-prop'\n\n// This used to claim `role=\"tablist\"` and `role=\"tab\"` without ever rendering a\n// tabpanel, which tells a screen reader to expect panels that do not exist and\n// leaves the arrow keys doing nothing. A toggle group is what this control\n// actually is: one pressed button out of several, with roving focus.\n\nexport type LiquidSegmentedOption = {\n  disabled?: boolean\n  icon?: ReactNode\n  label: ReactNode\n  value: string\n}\n\nexport type LiquidSegmentedProps = Omit<HTMLAttributes<HTMLDivElement>, 'defaultValue' | 'onChange'> & LiquidStyleProps & {\n  defaultValue?: string\n  label?: string\n  onValueChange?: (value: string) => void\n  options: LiquidSegmentedOption[]\n  size?: 'sm' | 'md'\n  value?: string\n}\n\nexport const LiquidSegmented = forwardRef<HTMLDivElement, LiquidSegmentedProps>(({\n  className,\n  defaultValue,\n  label,\n  onValueChange,\n  options,\n  size = 'md',\n  style,\n  styles,\n  value,\n  ...props\n}, ref) => {\n  const config = useLiquefyConfig()\n  const indicatorRef = useRef<HTMLSpanElement>(null)\n  const [internalValue, setInternalValue] = useState(defaultValue ?? options[0]?.value)\n  const resolvedValue = value ?? internalValue\n  const activeIndex = Math.max(0, options.findIndex((option) => option.value === resolvedValue))\n\n  const root = useLiquidStyles('lq-segmented', {\n    className,\n    style,\n    styles,\n    vars: { '--lq-segment-count': options.length, '--lq-segment-index': activeIndex },\n  })\n\n  return (\n    <ToggleGroup\n      aria-label={label}\n      className={root.className}\n      data-liquid-size={size}\n      onValueChange={(next, details) => {\n        // A segmented control always has exactly one option chosen, so pressing\n        // the pressed one again is a no-op rather than a way to clear it.\n        const [nextValue] = next\n        if (!nextValue || nextValue === resolvedValue) return\n\n        if (value === undefined) setInternalValue(nextValue)\n        onValueChange?.(nextValue)\n\n        // Squash-and-stretch the sliding indicator (and pop the picked item) so\n        // switching options reads as a springy jelly wobble, not a flat slide.\n        if (config.motion === false) return\n\n        indicatorRef.current?.animate(\n          [\n            { scale: '1 1' },\n            { scale: '1.16 0.8' },\n            { scale: '0.94 1.07' },\n            { scale: '1.02 0.98' },\n            { scale: '1 1' },\n          ],\n          { duration: 560, easing: 'cubic-bezier(0.2, 0.9, 0.25, 1)' },\n        )\n        details.trigger?.animate(\n          [{ scale: '1' }, { scale: '1.14' }, { scale: '0.98' }, { scale: '1' }],\n          { duration: 460, easing: 'cubic-bezier(0.2, 0.9, 0.25, 1)' },\n        )\n      }}\n      ref={ref}\n      style={root.style}\n      value={resolvedValue === undefined ? [] : [resolvedValue]}\n      {...props}\n    >\n      <span aria-hidden=\"true\" className=\"lq-segmented__indicator\" ref={indicatorRef} />\n      {options.map((option) => (\n        <Toggle\n          className=\"lq-segmented__item\"\n          disabled={option.disabled}\n          key={option.value}\n          value={option.value}\n        >\n          {option.icon && <span className=\"lq-segmented__icon\">{option.icon}</span>}\n          <span>{option.label}</span>\n        </Toggle>\n      ))}\n    </ToggleGroup>\n  )\n})\n\nLiquidSegmented.displayName = 'LiquidSegmented'\n",
      "path": "registry/liquid-segmented.tsx",
      "type": "registry:ui"
    }
  ],
  "name": "liquid-segmented",
  "registryDependencies": [
    "https://liquefy-ui.com/r/liquefy-ui.json",
    "https://liquefy-ui.com/r/provider.json",
    "https://liquefy-ui.com/r/styles-prop.json"
  ],
  "title": "LiquidSegmented",
  "type": "registry:ui"
}
