{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "toggle-group",
  "title": "UI Toggle Group",
  "description": "A segmented control whose active value is a pure function of the timeline; a raised thumb SLIDES between segments (position + width derived from a float indicator offset, no jumps) and the labels crossfade color via mixOklch. The tabs precedent without content panels.",
  "dependencies": ["remotion"],
  "registryDependencies": ["@remocn/remocn-ui"],
  "files": [
    {
      "path": "registry/remocn-ui/toggle-group/index.tsx",
      "content": "\"use client\";\n\nimport type { ReactNode } from \"react\";\nimport { mixOklch, type RemocnTheme, useRemocnTheme } from \"@/lib/remocn-ui\";\n\nexport type ToggleGroupState = string;\n\nexport type ToggleGroupSize = \"default\" | \"sm\";\n\nexport interface ToggleGroupItem {\n  value: string;\n  label: string;\n  icon?: ReactNode;\n}\n\nexport interface ToggleGroupProps {\n  state?: ToggleGroupState;\n  style?: ToggleGroupStyle;\n  items?: ToggleGroupItem[];\n  size?: ToggleGroupSize;\n  theme?: Partial<RemocnTheme>;\n  align?: \"start\" | \"center\" | \"end\";\n  className?: string;\n}\n\nfunction justify(align: \"start\" | \"center\" | \"end\"): string {\n  return align === \"start\"\n    ? \"flex-start\"\n    : align === \"end\"\n      ? \"flex-end\"\n      : \"center\";\n}\n\nconst DEFAULT_ITEMS: ToggleGroupItem[] = [\n  { value: \"Monthly\", label: \"Monthly\" },\n  { value: \"Yearly\", label: \"Yearly\" },\n];\n\nconst SIZE_STYLES: Record<\n  ToggleGroupSize,\n  {\n    height: number;\n    segMinWidth: number;\n    fontSize: number;\n    pad: number;\n    gap: number;\n  }\n> = {\n  sm: { height: 32, segMinWidth: 72, fontSize: 13, pad: 3, gap: 6 },\n  default: { height: 36, segMinWidth: 88, fontSize: 14, pad: 4, gap: 8 },\n};\n\nexport interface ToggleGroupStyle {\n  indicatorOffset: number;\n}\n\nexport interface ToggleGroupStyleContext {\n  items: ToggleGroupItem[];\n  trackBg: string;\n  thumbBg: string;\n  activeFg: string;\n  inactiveFg: string;\n  radius: number;\n}\n\nexport function toggleGroupStyleContext(\n  items: ToggleGroupItem[],\n  theme: RemocnTheme,\n): ToggleGroupStyleContext {\n  return {\n    items,\n    trackBg: theme.muted,\n    thumbBg: theme.background,\n    activeFg: theme.foreground,\n    inactiveFg: theme.mutedForeground,\n    radius: theme.radius,\n  };\n}\n\nexport function toggleGroupStyle(\n  state: ToggleGroupState,\n  ctx: ToggleGroupStyleContext,\n): ToggleGroupStyle {\n  const i = ctx.items.findIndex((it) => it.value === state);\n  return { indicatorOffset: i < 0 ? 0 : i };\n}\n\nexport function ToggleGroup({\n  state = DEFAULT_ITEMS[0].value,\n  style,\n  items = DEFAULT_ITEMS,\n  size = \"default\",\n  theme: themeOverride,\n  align = \"center\",\n  className,\n}: ToggleGroupProps) {\n  const theme = useRemocnTheme(themeOverride, \"light\");\n  const ctx = toggleGroupStyleContext(items, theme);\n  const v = style ?? toggleGroupStyle(state, ctx);\n\n  const sizeStyle = SIZE_STYLES[size];\n  const { pad } = sizeStyle;\n  const segmentWidth = sizeStyle.segMinWidth;\n  const thumbX = pad + v.indicatorOffset * segmentWidth;\n\n  return (\n    <div\n      className={className}\n      style={{\n        position: \"absolute\",\n        inset: 0,\n        display: \"flex\",\n        alignItems: \"center\",\n        justifyContent: justify(align),\n        background: \"transparent\",\n        fontFamily:\n          \"var(--font-geist-sans), -apple-system, BlinkMacSystemFont, sans-serif\",\n      }}\n    >\n      <div\n        style={{\n          position: \"relative\",\n          display: \"flex\",\n          height: sizeStyle.height,\n          padding: pad,\n          boxSizing: \"border-box\",\n          background: ctx.trackBg,\n          borderRadius: ctx.radius,\n        }}\n      >\n        {}\n        <div\n          style={{\n            position: \"absolute\",\n            top: pad,\n            left: thumbX,\n            width: segmentWidth,\n            height: sizeStyle.height - pad * 2,\n            background: ctx.thumbBg,\n            borderRadius: Math.max(2, ctx.radius - 3),\n            boxShadow: \"0 1px 2px rgba(0,0,0,0.1)\",\n          }}\n        />\n        {}\n        {items.map((item, i) => {\n          const proximity = Math.max(0, 1 - Math.abs(i - v.indicatorOffset));\n          return (\n            <span\n              key={item.value}\n              style={{\n                position: \"relative\",\n                width: segmentWidth,\n                display: \"flex\",\n                alignItems: \"center\",\n                justifyContent: \"center\",\n                gap: sizeStyle.gap,\n                fontSize: sizeStyle.fontSize,\n                fontWeight: 500,\n                letterSpacing: \"-0.01em\",\n                color: mixOklch(ctx.inactiveFg, ctx.activeFg, proximity),\n              }}\n            >\n              {item.icon}\n              {item.label}\n            </span>\n          );\n        })}\n      </div>\n    </div>\n  );\n}\n",
      "type": "registry:component",
      "target": "components/remocn/toggle-group.tsx"
    },
    {
      "path": "registry/remocn-ui/toggle-group/use-toggle-group-transition.ts",
      "content": "\"use client\";\n\nimport {\n  type ToggleGroupItem,\n  type ToggleGroupState,\n  type ToggleGroupStyle,\n  toggleGroupStyle,\n  toggleGroupStyleContext,\n} from \"@/components/remocn/toggle-group\";\nimport {\n  easings,\n  type RemocnTheme,\n  type Step,\n  useRemocnTheme,\n  useStateTransition,\n} from \"@/lib/remocn-ui\";\n\nconst DEFAULT_ITEMS: ToggleGroupItem[] = [\n  { value: \"Monthly\", label: \"Monthly\" },\n  { value: \"Yearly\", label: \"Yearly\" },\n];\n\nexport const DEFAULT_DURATION = 14;\n\nexport function tweenToggleGroupStyle(\n  a: ToggleGroupStyle,\n  b: ToggleGroupStyle,\n  t: number,\n): ToggleGroupStyle {\n  return {\n    indicatorOffset:\n      a.indicatorOffset + (b.indicatorOffset - a.indicatorOffset) * t,\n  };\n}\n\nexport interface ToggleGroupTransitionOptions {\n  items?: ToggleGroupItem[];\n  theme?: Partial<RemocnTheme>;\n  mode?: \"light\" | \"dark\";\n  speed?: number;\n  defaultDuration?: number;\n}\n\nexport function useToggleGroupTransition(\n  steps: Step<ToggleGroupState>[],\n  opts: ToggleGroupTransitionOptions = {},\n): ToggleGroupStyle {\n  const {\n    items = DEFAULT_ITEMS,\n    theme: themeOverride,\n    mode,\n    speed = 1,\n    defaultDuration = DEFAULT_DURATION,\n  } = opts;\n  const theme = useRemocnTheme(themeOverride, mode);\n  const ctx = toggleGroupStyleContext(items, theme);\n  const { from, to, progress } = useStateTransition(\n    steps,\n    items[0].value,\n    speed,\n    defaultDuration,\n  );\n  const t = easings.out(progress);\n  return tweenToggleGroupStyle(\n    toggleGroupStyle(from, ctx),\n    toggleGroupStyle(to, ctx),\n    t,\n  );\n}\n",
      "type": "registry:component",
      "target": "components/remocn/use-toggle-group-transition.ts"
    }
  ],
  "type": "registry:component"
}
