{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "period-tabs",
  "title": "Period Tabs",
  "description": "A small segmented control for switching a chart between week, month, and year.",
  "registryDependencies": [
    "tabs"
  ],
  "files": [
    {
      "path": "registry/dashboardcn/ui/period-tabs.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Tabs, TabsList, TabsTrigger } from \"@/components/ui/tabs\"\n\nexport interface PeriodOption {\n  value: string\n  label: string\n}\n\nexport const defaultPeriods: PeriodOption[] = [\n  { value: \"week\", label: \"Week\" },\n  { value: \"month\", label: \"Month\" },\n  { value: \"year\", label: \"Year\" },\n]\n\nexport interface PeriodTabsProps\n  extends Omit<React.ComponentProps<typeof Tabs>, \"children\"> {\n  options?: PeriodOption[]\n  size?: \"sm\" | \"default\"\n  /** Slide a single pill between tabs instead of swapping backgrounds. */\n  animated?: boolean\n}\n\ninterface IndicatorRect {\n  left: number\n  top: number\n  width: number\n  height: number\n}\n\n/** Small segmented control for switching a chart's time range. */\nfunction PeriodTabs({\n  options = defaultPeriods,\n  size = \"sm\",\n  animated = false,\n  className,\n  value,\n  defaultValue,\n  onValueChange,\n  ...props\n}: PeriodTabsProps) {\n  const listRef = React.useRef<HTMLDivElement>(null)\n  const [internalValue, setInternalValue] = React.useState(\n    defaultValue ?? options[0]?.value\n  )\n  const active = value ?? internalValue\n  const [rect, setRect] = React.useState<IndicatorRect | null>(null)\n\n  const measure = React.useCallback(() => {\n    const list = listRef.current\n    if (!list) return\n    const trigger = list.querySelector<HTMLElement>('[data-state=\"active\"]')\n    if (!trigger) return\n    setRect({\n      left: trigger.offsetLeft,\n      top: trigger.offsetTop,\n      width: trigger.offsetWidth,\n      height: trigger.offsetHeight,\n    })\n  }, [])\n\n  React.useLayoutEffect(() => {\n    if (!animated) return\n    measure()\n  }, [animated, active, options, size, measure])\n\n  React.useEffect(() => {\n    if (!animated || !listRef.current) return\n    const observer = new ResizeObserver(measure)\n    observer.observe(listRef.current)\n    return () => observer.disconnect()\n  }, [animated, measure])\n\n  return (\n    <Tabs\n      data-slot=\"period-tabs\"\n      className={cn(\"w-fit\", className)}\n      value={value}\n      defaultValue={defaultValue}\n      onValueChange={(next) => {\n        setInternalValue(next)\n        onValueChange?.(next)\n      }}\n      {...props}\n    >\n      <TabsList\n        ref={listRef}\n        className={cn(\n          \"relative\",\n          size === \"sm\" && \"group-data-[orientation=horizontal]/tabs:h-8 p-1\"\n        )}\n      >\n        {animated && rect ? (\n          <span\n            aria-hidden\n            data-slot=\"period-tabs-indicator\"\n            className=\"pointer-events-none absolute rounded-md bg-background shadow-sm transition-[left,top,width,height] duration-300 ease-[cubic-bezier(0.25,1,0.5,1)] motion-reduce:transition-none dark:border dark:border-input dark:bg-input/30\"\n            style={rect}\n          />\n        ) : null}\n        {options.map((option) => (\n          <TabsTrigger\n            key={option.value}\n            value={option.value}\n            className={cn(\n              size === \"sm\" && \"h-6 px-2.5 text-xs\",\n              animated &&\n                \"relative z-10 data-[state=active]:bg-transparent group-data-[variant=default]/tabs-list:data-[state=active]:shadow-none dark:data-[state=active]:border-transparent dark:data-[state=active]:bg-transparent\"\n            )}\n          >\n            {option.label}\n          </TabsTrigger>\n        ))}\n      </TabsList>\n    </Tabs>\n  )\n}\n\nexport { PeriodTabs }\n",
      "type": "registry:ui"
    }
  ],
  "type": "registry:ui"
}