{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "period-grid",
  "title": "Period Grid",
  "description": "The keyboard-navigable grid of month, year and quarter cells behind the period pickers.",
  "files": [
    {
      "path": "registry/tealmac/period-grid.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\nexport interface PeriodCell {\n  id: string\n  label: string\n  /** Spoken name when the visible label is short (\"Jan\" -> \"January 2026\"). */\n  ariaLabel?: string\n  disabled?: boolean\n  selected?: boolean\n  /** Range styling. */\n  inRange?: boolean\n  rangeStart?: boolean\n  rangeEnd?: boolean\n  /** The current period (this month, this year). */\n  current?: boolean\n}\n\nexport interface PeriodGridProps extends Omit<\n  React.ComponentProps<\"div\">,\n  \"onSelect\" | \"role\"\n> {\n  cells: PeriodCell[]\n  columns: number\n  /** The cell that holds the tab stop. */\n  focusId: string\n  onFocusChange: (id: string) => void\n  /** Arrow keys report a move in cells: -1, +1, -columns, +columns. */\n  onNavigate: (delta: number, focusId: string) => void\n  /** Page Up / Page Down. */\n  onPage?: (direction: -1 | 1) => void\n  onSelect: (id: string) => void\n  onHover?: (id: string | null) => void\n  label: string\n}\n\nfunction PeriodGrid({\n  cells,\n  columns,\n  focusId,\n  onFocusChange,\n  onNavigate,\n  onPage,\n  onSelect,\n  onHover,\n  label,\n  className,\n  ...props\n}: PeriodGridProps) {\n  const root = React.useRef<HTMLDivElement>(null)\n  const wantFocus = React.useRef(false)\n\n  React.useEffect(() => {\n    if (!wantFocus.current) return\n    wantFocus.current = false\n    const scope =\n      root.current?.closest<HTMLElement>('[role=\"group\"]') ?? root.current\n    scope?.querySelector<HTMLElement>(`[data-id=\"${focusId}\"]`)?.focus()\n  })\n\n  const rows: PeriodCell[][] = []\n  for (let i = 0; i < cells.length; i += columns)\n    rows.push(cells.slice(i, i + columns))\n\n  function onKeyDown(e: React.KeyboardEvent<HTMLElement>, id: string) {\n    const rtl =\n      (e.currentTarget.closest(\"[dir]\")?.getAttribute(\"dir\") ??\n        document.documentElement.dir) === \"rtl\"\n    const index = cells.findIndex((c) => c.id === id)\n    let delta: number | null = null\n    switch (e.key) {\n      case \"ArrowLeft\":\n        delta = rtl ? 1 : -1\n        break\n      case \"ArrowRight\":\n        delta = rtl ? -1 : 1\n        break\n      case \"ArrowUp\":\n        delta = -columns\n        break\n      case \"ArrowDown\":\n        delta = columns\n        break\n      case \"Home\":\n        delta = -(index % columns)\n        break\n      case \"End\":\n        delta = columns - 1 - (index % columns)\n        break\n      case \"PageUp\":\n      case \"PageDown\":\n        e.preventDefault()\n        wantFocus.current = true\n        onPage?.(e.key === \"PageUp\" ? -1 : 1)\n        return\n      default:\n        return\n    }\n    e.preventDefault()\n    wantFocus.current = true\n    onNavigate(delta, id)\n  }\n\n  return (\n    <div\n      ref={root}\n      role=\"grid\"\n      aria-label={label}\n      data-slot=\"period-grid\"\n      className={cn(\"flex flex-col gap-1\", className)}\n      {...props}\n    >\n      {rows.map((row, r) => (\n        <div role=\"row\" key={r} className=\"flex gap-1\">\n          {row.map((c) => (\n            <span\n              key={c.id}\n              role=\"gridcell\"\n              aria-selected={\n                c.selected ||\n                c.rangeStart ||\n                c.rangeEnd ||\n                c.inRange ||\n                undefined\n              }\n              aria-disabled={c.disabled || undefined}\n              className={cn(\n                \"flex flex-1\",\n                c.inRange && \"bg-accent\",\n                c.rangeStart && \"bg-accent rounded-s-md\",\n                c.rangeEnd && \"bg-accent rounded-e-md\"\n              )}\n            >\n              <button\n                type=\"button\"\n                data-id={c.id}\n                data-current={c.current ? \"\" : undefined}\n                data-selected={\n                  c.selected || c.rangeStart || c.rangeEnd ? \"\" : undefined\n                }\n                disabled={c.disabled}\n                tabIndex={c.id === focusId ? 0 : -1}\n                aria-label={c.ariaLabel}\n                aria-current={c.current ? \"date\" : undefined}\n                onClick={() => onSelect(c.id)}\n                onFocus={() => onFocusChange(c.id)}\n                onMouseEnter={() => onHover?.(c.id)}\n                onMouseLeave={() => onHover?.(null)}\n                onKeyDown={(e) => onKeyDown(e, c.id)}\n                className={cn(\n                  \"hover:bg-accent hover:text-accent-foreground focus-visible:ring-ring/50 flex h-9 min-w-12 flex-1 items-center justify-center rounded-md px-2 text-sm outline-none focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-40\",\n                  c.current &&\n                    !(c.selected || c.rangeStart || c.rangeEnd) &&\n                    \"border-border border font-semibold\",\n                  (c.selected || c.rangeStart || c.rangeEnd) &&\n                    \"bg-primary text-primary-foreground hover:bg-primary hover:text-primary-foreground\",\n                  c.inRange && \"bg-transparent\"\n                )}\n              >\n                {c.label}\n              </button>\n            </span>\n          ))}\n        </div>\n      ))}\n    </div>\n  )\n}\n\nfunction StepButton({\n  label,\n  disabled,\n  onClick,\n  children,\n}: {\n  label: string\n  disabled?: boolean\n  onClick: () => void\n  children: React.ReactNode\n}) {\n  return (\n    <button\n      type=\"button\"\n      aria-label={label}\n      disabled={disabled}\n      onClick={onClick}\n      className=\"hover:bg-accent focus-visible:ring-ring/50 inline-flex size-8 items-center justify-center rounded-md outline-none focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-40\"\n    >\n      {children}\n    </button>\n  )\n}\n\nexport { PeriodGrid, StepButton }\n",
      "type": "registry:ui"
    }
  ],
  "type": "registry:ui"
}