gridsmith-ui 0.29.1 → 0.30.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/CHANGELOG.md +94 -0
  2. package/README.md +5 -1
  3. package/dist/DropdownMenu-DqT7ZQ0D.d.ts +39 -0
  4. package/dist/charts.js +24 -9
  5. package/dist/charts.js.map +1 -1
  6. package/dist/chat.js +7 -7
  7. package/dist/{chunk-MFAWJSMJ.js → chunk-6C2IUMY7.js} +4 -23
  8. package/dist/chunk-6C2IUMY7.js.map +1 -0
  9. package/dist/{chunk-OYNUU346.js → chunk-7QLXYRPD.js} +3 -12
  10. package/dist/chunk-7QLXYRPD.js.map +1 -0
  11. package/dist/{chunk-FD4YED7O.js → chunk-DBHVJ7Z3.js} +5 -49
  12. package/dist/chunk-DBHVJ7Z3.js.map +1 -0
  13. package/dist/chunk-IELIF4PJ.js +110 -0
  14. package/dist/chunk-IELIF4PJ.js.map +1 -0
  15. package/dist/chunk-ISONVOA7.js +316 -0
  16. package/dist/chunk-ISONVOA7.js.map +1 -0
  17. package/dist/{chunk-4TUJXDRU.js → chunk-KMKBOTFR.js} +93 -32
  18. package/dist/chunk-KMKBOTFR.js.map +1 -0
  19. package/dist/{chunk-MKFWHWBK.js → chunk-L6HWACK7.js} +7 -7
  20. package/dist/chunk-L6HWACK7.js.map +1 -0
  21. package/dist/chunk-LJYSVZMI.js +25 -0
  22. package/dist/chunk-LJYSVZMI.js.map +1 -0
  23. package/dist/{chunk-6A5RHW2W.js → chunk-NEUWZUK6.js} +4 -5
  24. package/dist/chunk-NEUWZUK6.js.map +1 -0
  25. package/dist/chunk-NKUCS67T.js +13 -0
  26. package/dist/chunk-NKUCS67T.js.map +1 -0
  27. package/dist/{chunk-RECCCA7Z.js → chunk-OVHBQT3Z.js} +6 -5
  28. package/dist/chunk-OVHBQT3Z.js.map +1 -0
  29. package/dist/{chunk-I3MTQ3CS.js → chunk-OX3NNMWG.js} +6 -6
  30. package/dist/{chunk-I3MTQ3CS.js.map → chunk-OX3NNMWG.js.map} +1 -1
  31. package/dist/{chunk-ZI3OQDET.js → chunk-R5QXMNW7.js} +297 -15
  32. package/dist/chunk-R5QXMNW7.js.map +1 -0
  33. package/dist/chunk-SJZWEBHL.js +58 -0
  34. package/dist/chunk-SJZWEBHL.js.map +1 -0
  35. package/dist/{chunk-FUKSLQ77.js → chunk-SLRTSBCJ.js} +91 -51
  36. package/dist/chunk-SLRTSBCJ.js.map +1 -0
  37. package/dist/chunk-T52LAFKG.js +1350 -0
  38. package/dist/chunk-T52LAFKG.js.map +1 -0
  39. package/dist/chunk-TYNDXMBV.js +105 -0
  40. package/dist/chunk-TYNDXMBV.js.map +1 -0
  41. package/dist/{chunk-37WOC7F7.js → chunk-UDJOIVKQ.js} +31 -113
  42. package/dist/chunk-UDJOIVKQ.js.map +1 -0
  43. package/dist/{chunk-RJEUQ7RL.js → chunk-ULCACQSA.js} +47 -90
  44. package/dist/chunk-ULCACQSA.js.map +1 -0
  45. package/dist/{chunk-HP7WUZPK.js → chunk-WIUGPZOH.js} +10 -3
  46. package/dist/chunk-WIUGPZOH.js.map +1 -0
  47. package/dist/{chunk-JTU7OBYJ.js → chunk-YL5KD5RC.js} +4 -3
  48. package/dist/chunk-YL5KD5RC.js.map +1 -0
  49. package/dist/data-grid.d.ts +25 -6
  50. package/dist/data-grid.js +180 -58
  51. package/dist/data-grid.js.map +1 -1
  52. package/dist/editor-mentions.js +4 -5
  53. package/dist/editor-mentions.js.map +1 -1
  54. package/dist/editor.js +11 -8
  55. package/dist/editor.js.map +1 -1
  56. package/dist/{feather-FNBQ74RR.js → feather-XFFEFLTV.js} +5 -3
  57. package/dist/feather-XFFEFLTV.js.map +1 -0
  58. package/dist/{heroicons-DODCSYWD.js → heroicons-L6DOHBEA.js} +5 -3
  59. package/dist/heroicons-L6DOHBEA.js.map +1 -0
  60. package/dist/icons.d.ts +1 -1
  61. package/dist/icons.js +1 -1
  62. package/dist/index.d.ts +138 -39
  63. package/dist/index.js +846 -1667
  64. package/dist/index.js.map +1 -1
  65. package/dist/kanban.d.ts +26 -8
  66. package/dist/kanban.js +204 -79
  67. package/dist/kanban.js.map +1 -1
  68. package/dist/{lucide-ZWE3EPGP.js → lucide-JOORDTO6.js} +5 -3
  69. package/dist/lucide-JOORDTO6.js.map +1 -0
  70. package/dist/{phosphor-DIHPA4AJ.js → phosphor-TKGDYNGR.js} +5 -3
  71. package/dist/phosphor-TKGDYNGR.js.map +1 -0
  72. package/dist/resizable.js +47 -16
  73. package/dist/resizable.js.map +1 -1
  74. package/dist/roots.css +12 -8
  75. package/dist/{table-utils-CxnpFHRF.d.ts → table-utils-BXkP-2Hx.d.ts} +3 -1
  76. package/dist/{tabler-D3VYTSGI.js → tabler-YGETLYRU.js} +5 -3
  77. package/dist/tabler-YGETLYRU.js.map +1 -0
  78. package/dist/tokens.css +14 -0
  79. package/dist/utils.js.map +1 -1
  80. package/dist/virtualized.d.ts +6 -1
  81. package/dist/virtualized.js +17 -13
  82. package/dist/virtualized.js.map +1 -1
  83. package/dist-static/tokens.css +14 -0
  84. package/package.json +1 -1
  85. package/dist/chunk-37WOC7F7.js.map +0 -1
  86. package/dist/chunk-4TUJXDRU.js.map +0 -1
  87. package/dist/chunk-6A5RHW2W.js.map +0 -1
  88. package/dist/chunk-FD4YED7O.js.map +0 -1
  89. package/dist/chunk-FUKSLQ77.js.map +0 -1
  90. package/dist/chunk-HP7WUZPK.js.map +0 -1
  91. package/dist/chunk-JTU7OBYJ.js.map +0 -1
  92. package/dist/chunk-MFAWJSMJ.js.map +0 -1
  93. package/dist/chunk-MKFWHWBK.js.map +0 -1
  94. package/dist/chunk-OYNUU346.js.map +0 -1
  95. package/dist/chunk-QM4SJKWV.js +0 -51
  96. package/dist/chunk-QM4SJKWV.js.map +0 -1
  97. package/dist/chunk-QNHVPE2B.js +0 -117
  98. package/dist/chunk-QNHVPE2B.js.map +0 -1
  99. package/dist/chunk-RECCCA7Z.js.map +0 -1
  100. package/dist/chunk-RJEUQ7RL.js.map +0 -1
  101. package/dist/chunk-WH2FUFAC.js +0 -15
  102. package/dist/chunk-WH2FUFAC.js.map +0 -1
  103. package/dist/chunk-ZI3OQDET.js.map +0 -1
  104. package/dist/feather-FNBQ74RR.js.map +0 -1
  105. package/dist/heroicons-DODCSYWD.js.map +0 -1
  106. package/dist/lucide-ZWE3EPGP.js.map +0 -1
  107. package/dist/phosphor-DIHPA4AJ.js.map +0 -1
  108. package/dist/tabler-D3VYTSGI.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../showcase/src/lib/initials.ts","../../../showcase/src/components/Avatar.tsx","../../../showcase/src/lib/use-active-option.ts","../../../showcase/src/lib/search-text.ts","../../../showcase/src/components/MentionList.tsx"],"names":["useRef","jsxs","jsx"],"mappings":"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","file":"chunk-6A5RHW2W.js","sourcesContent":["/**\n * Initials for an avatar. Round 21 (run 58): a builder passed each person's full name as `initials`, and the avatar\n * printed \"Amara Haddad\" across a 40 px circle on every row of the Team table. The avatar now reads what it is given:\n * up to three characters with no space are initials already and stay as they are (\"JB\", \"ABC\"); anything longer is a\n * name, and its first two words give the letters.\n */\n\n/** \"Sarah Chen\" → \"SC\"; \"Acme\" → \"A\"; \"Mary Jane Watson\" → \"MJ\". */\nexport function initialsOf(name: string): string {\n return name\n .trim()\n .split(/\\s+/)\n .filter(Boolean)\n .slice(0, 2)\n .map((word) => Array.from(word)[0] ?? \"\")\n .join(\"\")\n .toUpperCase();\n}\n\n/** What an avatar shows for an `initials` value: initials as given, or the initials of a name. */\nexport function toInitials(value: string): string {\n const s = value.trim();\n if (!s) return \"\";\n if (!/\\s/.test(s) && Array.from(s).length <= 3) return s;\n return initialsOf(s);\n}\n","import { cn } from \"../lib/utils\";\nimport { toInitials } from \"../lib/initials\";\n\nexport type AvatarStatus = \"online\" | \"away\" | \"busy\" | \"offline\";\nexport type AvatarColor = \"auto\" | \"accent\" | \"neutral\" | 1 | 2 | 3 | 4 | 5;\n\ninterface AvatarProps {\n /** One to three letters (\"JB\"). A name passed here shows its initials (\"Amara Haddad\" → \"AH\"), never the whole name. */\n initials?: string;\n src?: string;\n alt?: string;\n size?: \"sm\" | \"md\" | \"lg\";\n status?: AvatarStatus;\n /** Initials background. \"auto\" (default) derives a stable palette tint from alt/initials so groups vary; use \"accent\" sparingly. */\n color?: AvatarColor;\n className?: string;\n}\n\nconst sizeStyles = {\n sm: \"h-8 w-8 text-xs\",\n md: \"h-10 w-10 text-sm\",\n lg: \"h-12 w-12 text-base\",\n};\n\n// Fallbacks cover themes whose tokens CSS predates the decorative palette.\nconst paletteStyles = {\n 1: \"bg-[var(--ds-palette-1-bg,var(--ds-bg-muted))] text-[var(--ds-palette-1-text,var(--ds-text-secondary))]\",\n 2: \"bg-[var(--ds-palette-2-bg,var(--ds-bg-muted))] text-[var(--ds-palette-2-text,var(--ds-text-secondary))]\",\n 3: \"bg-[var(--ds-palette-3-bg,var(--ds-bg-muted))] text-[var(--ds-palette-3-text,var(--ds-text-secondary))]\",\n 4: \"bg-[var(--ds-palette-4-bg,var(--ds-bg-muted))] text-[var(--ds-palette-4-text,var(--ds-text-secondary))]\",\n 5: \"bg-[var(--ds-palette-5-bg,var(--ds-bg-muted))] text-[var(--ds-palette-5-text,var(--ds-text-secondary))]\",\n} as const;\n\nfunction paletteFor(seed: string): keyof typeof paletteStyles {\n let h = 0;\n for (const ch of seed) h = (h * 31 + ch.charCodeAt(0)) >>> 0;\n return ((h % 5) + 1) as keyof typeof paletteStyles;\n}\n\nfunction colorStyles(color: AvatarColor, seed: string): string {\n if (color === \"accent\") return \"bg-[var(--ds-accent-primary)] text-[var(--ds-text-on-primary)]\";\n if (color === \"neutral\") return \"bg-[var(--ds-bg-muted)] text-[var(--ds-text-secondary)]\";\n return paletteStyles[color === \"auto\" ? paletteFor(seed) : color];\n}\n\n/**\n * Presence as a shape as well as a colour (Sprint 25.12 A48, WCAG 1.4.1), as Fluent's presence badges do: online a filled\n * dot, away a ring, busy a dot with a bar, offline a ring with a slash. The words are in the avatar's name.\n */\nfunction PresenceMark({ status }: { status: AvatarStatus }) {\n return (\n <svg viewBox=\"0 0 10 10\" width=\"10\" height=\"10\" aria-hidden=\"true\" focusable=\"false\" data-presence={status} className=\"block\">\n {status === \"online\" && <circle cx=\"5\" cy=\"5\" r=\"5\" className=\"fill-[var(--ds-status-success)]\" />}\n {status === \"away\" && <circle cx=\"5\" cy=\"5\" r=\"4\" fill=\"none\" strokeWidth=\"2\" className=\"stroke-[var(--ds-status-warning)]\" />}\n {status === \"busy\" && (\n <>\n <circle cx=\"5\" cy=\"5\" r=\"5\" className=\"fill-[var(--ds-status-error)]\" />\n <rect x=\"2.5\" y=\"4.1\" width=\"5\" height=\"1.8\" rx=\"0.9\" className=\"fill-[var(--ds-bg-canvas)]\" />\n </>\n )}\n {status === \"offline\" && (\n <>\n <circle cx=\"5\" cy=\"5\" r=\"4\" fill=\"none\" strokeWidth=\"2\" className=\"stroke-[var(--ds-text-muted)]\" />\n <line x1=\"3.1\" y1=\"6.9\" x2=\"6.9\" y2=\"3.1\" strokeWidth=\"1.5\" strokeLinecap=\"round\" className=\"stroke-[var(--ds-text-muted)]\" />\n </>\n )}\n </svg>\n );\n}\n\nexport function Avatar({ initials, src, alt, size = \"md\", status, color = \"auto\", className }: AvatarProps) {\n // A48: presence can't show words beside a small avatar, so the avatar's own name carries it (\"Priya Nair, online\")\n const who = alt ?? initials ?? \"\";\n const named = status ? [who, status].filter(Boolean).join(\", \") : undefined;\n const base = cn(\n \"inline-flex items-center justify-center font-medium shrink-0\",\n \"rounded-[var(--ds-radius-full)]\",\n sizeStyles[size],\n className,\n );\n\n // data-avatar: the Table and DataGrid card mode stacks a cell that holds an avatar (Sprint 25.4 C-2).\n const avatarElement = src ? (\n <img\n data-avatar=\"\"\n src={src}\n alt={named ?? alt ?? initials ?? \"\"}\n className={cn(base, \"object-cover\")}\n />\n ) : (\n <div\n data-avatar=\"\"\n role={named ? \"img\" : undefined}\n aria-label={named}\n className={cn(\n base,\n colorStyles(color, alt ?? initials ?? \"\"),\n \"border-[length:var(--ds-border-width)] border-transparent\",\n )}\n >\n {/* round 21: a full name passed as initials shows its initials, not the name squeezed into the circle */}\n {initials != null ? toInitials(initials) : null}\n </div>\n );\n\n if (!status) return avatarElement;\n\n return (\n <div className=\"relative inline-flex\">\n {avatarElement}\n <span\n className={cn(\n \"absolute\",\n size === \"sm\" && \"bottom-[-2px] right-[-2px]\",\n size === \"md\" && \"bottom-[0px] right-[0px]\",\n size === \"lg\" && \"bottom-[2px] right-[2px]\",\n )}\n aria-hidden=\"true\"\n >\n {/* the canvas behind the mark fills a ring's middle and draws the 2px halo that separates it from the photo */}\n <span className=\"block rounded-[var(--ds-radius-full)] bg-[var(--ds-bg-canvas)] shadow-[0_0_0_2px_var(--ds-bg-canvas)]\">\n <PresenceMark status={status} />\n </span>\n </span>\n </div>\n );\n}\n","import { useLayoutEffect, useRef, type RefObject } from \"react\";\n\n/**\n * Keeps the active option of a list driven by aria-activedescendant in view (Sprint 25.17's review; WCAG 2.4.11): when\n * the list opens and when the active option changes, the list scrolls just enough to show it. Only the list's own box\n * scrolls, never the page: the list sits fixed over it. The option is found by its id, in the list's own document or\n * shadow root.\n *\n * Only a change brings it back into view (the second review): a render that leaves the same option active — the page\n * scrolling, the list scrolled by touch or by its scrollbar — leaves the list where the user put it.\n */\nexport function useActiveOptionInView(list: RefObject<HTMLElement | null>, activeId: string | undefined): void {\n // the option last brought into view, by its id and its text: a filtered list reuses an id for another option\n const shown = useRef<string | null>(null);\n useLayoutEffect(() => {\n const box = list.current;\n if (!box || !activeId) {\n shown.current = null;\n return;\n }\n const root = box.getRootNode() as Document | ShadowRoot;\n const option = typeof root.getElementById === \"function\" ? root.getElementById(activeId) : null;\n if (!option || !box.contains(option)) return;\n const seen = `${activeId}\\u0000${option.textContent ?? \"\"}`;\n if (seen === shown.current) return;\n shown.current = seen;\n const top = option.getBoundingClientRect().top - box.getBoundingClientRect().top + box.scrollTop;\n const bottom = top + option.offsetHeight;\n if (top < box.scrollTop) box.scrollTo({ top });\n else if (bottom > box.scrollTop + box.clientHeight) box.scrollTo({ top: bottom - box.clientHeight });\n });\n}\n","/**\n * Text as a search reads it, one way for every picker (Sprint 25.17's second review): no case, no accents, and \"_\" as a\n * space, so \"@toma\" finds Tomás, \"Sao Paulo\" and \"São Paulo\" find America/Sao_Paulo, and \"New_York\" finds New York.\n */\nexport function foldForSearch(text: string): string {\n return text.normalize(\"NFD\").replace(/\\p{M}/gu, \"\").replace(/_/g, \" \").toLowerCase();\n}\n","import { useMemo, useRef, type RefObject } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { cn } from \"../lib/utils\";\nimport { usePosition } from \"../lib/use-position\";\nimport { useLatest } from \"../lib/use-latest\";\nimport { useActiveOptionInView } from \"../lib/use-active-option\";\nimport { foldForSearch } from \"../lib/search-text\";\nimport { Avatar } from \"./Avatar\";\n\nexport interface MentionSuggestion {\n id: string;\n label: string;\n avatar?: string;\n description?: string;\n}\n\n/** Text as a search reads it: no case, no accents (\"@toma\" finds Tomás, \"@zoe\" Zoë), as every picker reads it. */\nconst fold = foldForSearch;\n\n/**\n * The suggestions a query matches, by name or by description, ignoring case and accents, best first: a name that starts with it\n * (\"@Mar\": Marcus Chen), then a name with a word that does (Tomás Martin), then a name holding it anywhere (Amara), then\n * a description that does; in their own order within each.\n */\nexport function matchMentions(items: MentionSuggestion[], query: string): MentionSuggestion[] {\n const q = fold(query);\n const rank = (s: MentionSuggestion): number => {\n const name = fold(s.label);\n if (name.startsWith(q)) return 0;\n if (name.split(/\\s+/).some((word) => word.startsWith(q))) return 1;\n if (name.includes(q)) return 2;\n return s.description && fold(s.description).includes(q) ? 3 : -1;\n };\n return items.map((s) => ({ s, r: rank(s) })).filter(({ r }) => r >= 0).sort((a, b) => a.r - b.r).map(({ s }) => s);\n}\n\n/** An option's id, for the field's aria-activedescendant. */\nexport const mentionOptionId = (listId: string, index: number) => `${listId}-option-${index}`;\n\n/**\n * The most people a list shows (Sprint 25.17's second review: two thousand drawn at once took a key a third of a second\n * to paint): the best matches, and a line saying how many more match, which typing narrows.\n */\nexport const MENTION_LIST_LIMIT = 10;\n\n/** The matches a list shows, best first, and how many more there are. */\nexport function shownMentions(found: MentionSuggestion[]): { items: MentionSuggestion[]; more: number } {\n return { items: found.slice(0, MENTION_LIST_LIMIT), more: Math.max(0, found.length - MENTION_LIST_LIMIT) };\n}\n\nexport interface MentionListProps {\n /** The listbox's id: the field's aria-controls, and the stem of its options' ids. */\n id: string;\n /** The listbox's name (\"People\", \"Suggestions\"). */\n label: string;\n /** The people shown, at most MENTION_LIST_LIMIT (shownMentions). */\n items: MentionSuggestion[];\n /** How many more match than are shown: the list says so under its people. */\n more?: number;\n activeIndex: number;\n onActiveIndexChange: (index: number) => void;\n onPick: (item: MentionSuggestion) => void;\n /** Where the mention being typed is, in the viewport: the list opens under it, above it when the screen runs out below. */\n anchorRect: () => DOMRect | null;\n /** The list's element, for the owner's checks (a click outside, focus moving into it). */\n listRef?: RefObject<HTMLDivElement | null>;\n}\n\n/**\n * The list of suggestions while a mention is typed (Sprint 25.17 A17): MentionInput's and the editor's, so a mention\n * looks and works the same in a comment box and a document. The field keeps focus and carries aria-activedescendant\n * (the field's owner wires the keys: arrows move, Enter or Tab inserts, Escape closes); the options are no Tab stops,\n * and a pointer picks one without taking focus from the field.\n */\nexport function MentionList({ id, label, items, more = 0, activeIndex, onActiveIndexChange, onPick, anchorRect, listRef }: MentionListProps) {\n const ownRef = useRef<HTMLDivElement | null>(null);\n const floatingRef = listRef ?? ownRef;\n const boxRef = useRef<HTMLDivElement | null>(null);\n const anchorRef = useLatest(anchorRect);\n // the caret as an element for usePosition, which reads only its rectangle\n const anchor = useMemo(() => ({ current: { getBoundingClientRect: () => anchorRef.current() ?? new DOMRect() } as HTMLElement }), [anchorRef]);\n const pos = usePosition(anchor, floatingRef, items.length > 0, { side: \"bottom\", align: \"start\", offset: 4 });\n // the arrows move through a list longer than its box: the active person stays in view\n useActiveOptionInView(boxRef, items.length > 0 ? mentionOptionId(id, activeIndex) : undefined);\n if (items.length === 0) return null;\n\n return createPortal(\n <div\n ref={floatingRef}\n className={cn(\n \"fixed z-[var(--ds-z-popover)] min-w-[200px] flex flex-col\",\n \"bg-[var(--ds-bg-surface-elevated)]\",\n \"[backdrop-filter:var(--ds-glass-filter)] [-webkit-backdrop-filter:var(--ds-glass-filter)]\",\n \"border-[length:var(--ds-border-width)] border-[var(--ds-border-default)]\",\n \"rounded-[var(--ds-radius-md)] shadow-[var(--ds-shadow-dropdown),var(--ds-glass-inset)]\",\n )}\n style={{ top: pos.top, left: pos.left }}\n >\n {/* rows inset in the list, rounded, as Combobox's and the menus' are (the second review: full-width square rows) */}\n <div ref={boxRef} id={id} role=\"listbox\" aria-label={label} className=\"max-h-[200px] overflow-y-auto p-ds-1\">\n {items.map((s, i) => (\n <button\n key={s.id}\n id={mentionOptionId(id, i)}\n type=\"button\"\n role=\"option\"\n tabIndex={-1}\n aria-selected={i === activeIndex}\n className={cn(\n \"flex items-center gap-ds-2.5 w-full px-ds-2 py-ds-1.5 text-left text-sm cursor-pointer rounded-[var(--ds-radius-sm)]\",\n \"transition-colors duration-[var(--ds-transition-speed)]\",\n i === activeIndex ? \"bg-[var(--ds-bg-muted)] text-[var(--ds-text-primary)]\" : \"text-[var(--ds-text-secondary)]\",\n )}\n // the field keeps focus, so the pick lands where the mention is being typed\n onMouseDown={(e) => e.preventDefault()}\n onClick={() => onPick(s)}\n onMouseEnter={() => onActiveIndexChange(i)}\n >\n {/* the name follows as text, so the picture is decoration */}\n <span aria-hidden=\"true\" className=\"inline-flex shrink-0\">\n <Avatar src={s.avatar} initials={s.label} size=\"sm\" className=\"!h-6 !w-6 !text-2xs\" />\n </span>\n <span className=\"min-w-0\">\n <span className=\"block font-medium text-[var(--ds-text-primary)] truncate\">{s.label}</span>\n {s.description && <span className=\"block text-xs text-[var(--ds-text-muted)] truncate\">{s.description}</span>}\n </span>\n </button>\n ))}\n </div>\n {more > 0 && (\n <p className=\"px-ds-3 py-ds-1.5 text-xs text-[var(--ds-text-muted)] border-t-[length:var(--ds-divider-width)] border-[var(--ds-border-subtle)]\">\n {more} more {more === 1 ? \"matches\" : \"match\"}: keep typing to narrow\n </p>\n )}\n </div>,\n document.body,\n );\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../showcase/src/lib/use-fill-height.ts","../../../showcase/src/lib/use-keyboard-scroll.ts"],"names":[],"mappings":"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","file":"chunk-FD4YED7O.js","sourcesContent":["import { createContext, useContext, useLayoutEffect, useState, type RefObject } from \"react\";\n\n/**\n * Sprint 25.16 A42 (P31): a page led by a chart, a board or a split view fills the height under its header, and its\n * content scrolls inside it; the page doesn't. SplitView (frame=\"page\"), Gantt and KanbanBoard use this one mechanism.\n *\n * The element takes the rest of the shell's <main> height (main's height less what sits above it and the padding below\n * it) when all of these hold:\n * - it leads the page: above it there is only the page's header, its chrome (notices, tabs, a toolbar, a search or\n * filters row, however tall) and short rows, so a board in a dashboard's last card keeps its own height;\n * - it is the page's last content: nothing after it, up to <main>, takes room, so nothing below it is cut off (the\n * shell's footer is not the page's: it sits below the fold, as it does under a SplitView frame=\"fill\");\n * - its height follows its content: neither its own class nor a box around it gives it one (a fixed height, a flex\n * column that already gives it the rest), and given more, the page grows;\n * - the rest is tall enough to use (a phone on its side keeps the natural height, and the page scrolls).\n * Outside the shell's <main> (AppShell marks it), or inside a view that fills (a Gantt in a SplitView's pane), it keeps\n * its own height. Returns the height in pixels, or null for the natural height.\n */\nexport function useFillHeight(ref: RefObject<HTMLElement | null>, enabled = true): number | null {\n const insideFill = useContext(FillContext);\n const active = enabled && !insideFill;\n const [height, setHeight] = useState<number | null>(null);\n useLayoutEffect(() => {\n const main = ref.current?.closest<HTMLElement>(\"main[data-shell-main]\");\n if (!active || !main || typeof ResizeObserver === \"undefined\") {\n setHeight(null);\n return;\n }\n let frame = 0;\n // the element is read on each measure: a view that changes its layout (stacked or side by side) changes its root\n const measure = () => {\n frame = 0;\n const el = ref.current;\n setHeight(el && main.contains(el) ? fillHeight(el, main) : null);\n };\n const schedule = () => {\n if (!frame) frame = requestAnimationFrame(measure);\n };\n measure();\n // main's height (the window, a phone's toolbar), and what sits above or after the element at the page's top level (a\n // header's actions wrapping, a banner or a note arriving): the boxes there now, and any that arrive\n const ro = new ResizeObserver(schedule);\n const watch = (box: Element) => {\n ro.observe(box);\n for (const child of Array.from(box.children)) ro.observe(child);\n };\n const page = main.querySelector<HTMLElement>(\"[data-shell-content]\");\n watch(main);\n if (page) watch(page);\n const mo = typeof MutationObserver === \"undefined\" ? null : new MutationObserver((records) => {\n for (const record of records) record.addedNodes.forEach((node) => { if (node instanceof Element) ro.observe(node); });\n schedule();\n });\n mo?.observe(main, { childList: true });\n if (page) mo?.observe(page, { childList: true });\n return () => {\n ro.disconnect();\n mo?.disconnect();\n if (frame) cancelAnimationFrame(frame);\n };\n }, [ref, active]);\n return active ? height : null;\n}\n\n/** Content inside a view that fills: it takes the view's height (h-full), never the page's. */\nexport const FillContext = createContext(false);\n\n/** Below this the rest of the screen is too short to scroll inside (about six rows of a chart). */\nconst MIN_FILL = 240;\n/** A row that may sit between the header and the view: tabs, a toolbar, a filters row (PageContainer's ROW_MAX). */\nconst ROW_MAX = 56;\n\nfunction fillHeight(el: HTMLElement, main: HTMLElement): number | null {\n // the page's own content: the shell's wrapper above its footer, else main\n const page = el.closest<HTMLElement>(\"[data-shell-content]\") ?? main;\n if (!leadsPage(el, page) || !isLastContent(el, page) || keepScroll(el, () => hasOwnHeight(el) || !followsContent(el, main))) return null;\n const mainBox = main.getBoundingClientRect();\n const top = el.getBoundingClientRect().top - mainBox.top - main.clientTop + main.scrollTop;\n const height = Math.floor(main.clientHeight - top - spaceBelow(el, main));\n return height >= MIN_FILL ? height : null;\n}\n\n/**\n * Runs a probe that changes the element's height for a moment, and puts back where everything inside it was scrolled:\n * at its natural height a region that scrolls inside it stops scrolling, and the browser drops its position (Sprint\n * 25.18: the week's hours opened at the working day, then the next measure sent them back to midnight).\n */\nfunction keepScroll<T>(el: HTMLElement, probe: () => T): T {\n const scrolled: Array<[HTMLElement, number, number]> = [];\n for (const node of [el, ...Array.from(el.querySelectorAll<HTMLElement>(\"*\"))]) {\n if (node.scrollTop || node.scrollLeft) scrolled.push([node, node.scrollTop, node.scrollLeft]);\n }\n try {\n return probe();\n } finally {\n for (const [node, top, left] of scrolled) {\n node.scrollTop = top;\n node.scrollLeft = left;\n }\n }\n}\n\n/** Whether a box takes room on the page: an overlay, a portal's anchor, a hidden or an empty node doesn't. */\nfunction takesRoom(box: Element): boolean {\n const style = getComputedStyle(box);\n if (style.display === \"none\" || style.position === \"absolute\" || style.position === \"fixed\") return false;\n const rect = box.getBoundingClientRect();\n return rect.height > 0 && rect.width > 0;\n}\n\n/**\n * The page's chrome, at any height: a notice (an Alert, a banner that wraps to two lines on a phone), tabs, a toolbar, a\n * search or filters row (the review of 1 October: a two-line banner turned the fill off). Content of the page's own (a\n * row of stats, cards, text) is not chrome.\n */\nconst CHROME = '[role=\"alert\"], [role=\"status\"], [role=\"tablist\"], [role=\"toolbar\"], [role=\"search\"]';\nconst isChrome = (box: Element) =>\n box.matches(CHROME) || (box.children.length > 0 && Array.from(box.children).every((child) => !takesRoom(child) || child.matches(CHROME)));\n\n/** Above the element, up to the page's root: only the page's header (its title), its chrome, and rows no taller than ROW_MAX. */\nfunction leadsPage(el: HTMLElement, page: HTMLElement): boolean {\n for (let node: HTMLElement | null = el; node && node !== page; node = node.parentElement) {\n for (let prev = node.previousElementSibling; prev; prev = prev.previousElementSibling) {\n if (!takesRoom(prev)) continue;\n if (prev.matches('[data-gs=\"page-header\"]') || prev.querySelector('[data-gs=\"page-header\"], h1')) continue;\n if (isChrome(prev)) continue;\n if (prev.getBoundingClientRect().height > ROW_MAX) return false;\n }\n }\n return true;\n}\n\n/** Nothing after the element, up to the page's root, takes room. */\nfunction isLastContent(el: HTMLElement, page: HTMLElement): boolean {\n for (let node: HTMLElement | null = el; node && node !== page; node = node.parentElement) {\n for (let next = node.nextElementSibling; next; next = next.nextElementSibling) {\n if (takesRoom(next)) return false;\n }\n }\n return true;\n}\n\n/**\n * The element's own CSS gives it a height that isn't its content's: a fixed height of its own (`h-[420px]`), or `h-full`\n * that resolves against a box which already has one. It keeps it. Read with the fill's own height set aside.\n */\nfunction hasOwnHeight(el: HTMLElement): boolean {\n const inline = el.style.height;\n el.style.height = \"\";\n const own = el.offsetHeight;\n el.style.height = \"auto\";\n const natural = el.offsetHeight;\n el.style.height = inline;\n return Math.abs(own - natural) > 1;\n}\n\n/**\n * Given more height, does the page grow? Probed once: the element is made a screen taller and main's top-level box\n * measured. A box of fixed height around it, or a flex column that already gives it its height, absorbs it.\n */\nfunction followsContent(el: HTMLElement, main: HTMLElement): boolean {\n let top: HTMLElement = el;\n while (top.parentElement && top.parentElement !== main) top = top.parentElement;\n const before = top.offsetHeight;\n const inline = el.style.height;\n el.style.height = `${el.offsetHeight + main.clientHeight}px`;\n const grows = top.offsetHeight > before;\n el.style.height = inline;\n return grows;\n}\n\n/** The padding, borders and margins under the element, up to main's own padding: they stay below it. */\nfunction spaceBelow(el: HTMLElement, main: HTMLElement): number {\n const px = (value: string) => parseFloat(value) || 0;\n let space = px(getComputedStyle(main).paddingBottom);\n for (let node: HTMLElement | null = el; node && node !== main; node = node.parentElement) {\n const style = getComputedStyle(node);\n space += px(style.marginBottom);\n if (node !== el) space += px(style.paddingBottom) + px(style.borderBottomWidth);\n }\n return space;\n}\n","import { useEffect } from \"react\";\nimport { tabStops } from \"./focus\";\nimport { useRevealFocus } from \"./reveal-focus\";\n\n/**\n * WCAG 2.1.1: a region that scrolls, with nothing inside it to Tab to, is a Tab stop of its own, named, so a keyboard\n * can scroll it (Chrome makes such a scroller focusable by itself; Safari doesn't). Sprint 25.16 A42: what fills the\n * page scrolls inside itself, so a board's column or a split view's pane can be such a region. It stops being one when\n * it no longer scrolls or something inside it takes focus — but while it has focus it stays one, until focus leaves it,\n * so a resize that makes it fit never drops the focus to the page (as Table's scroll region does; the review of\n * 1 October). Give the element a visible focus style (FOCUS_INSET). Pass the element itself (a callback ref's), so a\n * pane drawn later (a detail that opens) is read when it appears. With `nameFromHeading`, the region takes its first\n * heading's words as its name (an item's view: its title), and `label` only when it has none. What the keyboard focuses\n * inside it is scrolled into view whole (useRevealFocus, Sprint 30): give the region `scroll-p-[4px]` for the outline.\n */\nexport function useKeyboardScroll(el: HTMLElement | null, label: string, enabled = true, nameFromHeading = false): void {\n useRevealFocus(el, enabled);\n useEffect(() => {\n if (!enabled || !el || typeof ResizeObserver === \"undefined\") return;\n const name = () => {\n const heading = nameFromHeading ? el.querySelector(\"h1, h2, h3, h4, h5, h6\")?.textContent?.trim() : \"\";\n return heading || label;\n };\n const set = (on: boolean) => {\n if (on === el.hasAttribute(\"data-scroll-stop\")) {\n if (on && el.getAttribute(\"aria-label\") !== name()) el.setAttribute(\"aria-label\", name());\n return;\n }\n if (on) {\n el.setAttribute(\"data-scroll-stop\", \"\");\n el.tabIndex = 0;\n el.setAttribute(\"role\", \"region\");\n el.setAttribute(\"aria-label\", name());\n } else {\n el.removeAttribute(\"data-scroll-stop\");\n el.removeAttribute(\"tabindex\");\n el.removeAttribute(\"role\");\n el.removeAttribute(\"aria-label\");\n }\n };\n const update = () => {\n const scrolls = el.scrollHeight > el.clientHeight + 1 && tabStops(el).length === 0;\n set(scrolls || (el.hasAttribute(\"data-scroll-stop\") && document.activeElement === el));\n };\n update();\n const ro = new ResizeObserver(update);\n ro.observe(el);\n const mo = typeof MutationObserver === \"undefined\" ? null : new MutationObserver(update);\n mo?.observe(el, { childList: true, subtree: true, characterData: true });\n // focus leaving a stop that no longer scrolls ends it\n el.addEventListener(\"focusout\", update);\n return () => {\n ro.disconnect();\n mo?.disconnect();\n el.removeEventListener(\"focusout\", update);\n set(false);\n };\n }, [el, label, enabled, nameFromHeading]);\n}\n\n/** The focus style for such a region: the theme's outline, drawn inside its edge so a neighbour can't hide it (lib/utils.ts since Sprint 30). */\nexport { FOCUS_INSET } from \"./utils\";\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../showcase/src/lib/control-looks.ts","../../../showcase/src/lib/filter-row.ts","../../../showcase/src/components/Input.tsx","../../../showcase/src/components/InlineFieldError.tsx","../../../showcase/src/components/Field.tsx","../../../showcase/src/components/Dropdown.tsx","../../../showcase/src/components/NumberInput.tsx","../../../showcase/src/components/Popover.tsx","../../../showcase/src/components/Pagination.tsx","../../../showcase/src/lib/use-pagination.ts"],"names":["jsxs","jsx","createContext","useContext","useCallback","useEffect","useRef","useId","useState","createPortal"],"mappings":"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","file":"chunk-FUKSLQ77.js","sourcesContent":["/**\n * Sprint 25.14 A20: the checked and switched looks, shared by the controls (Checkbox, RadioGroup, Toggle) and the Card's\n * selection indicators, so the two never drift apart (the review of 30 September: the Card kept the old switch, the\n * accent's gradient and the accent dot after the controls moved).\n */\n\n/** A checked box's fill and a selected radio's dot: the check colour, with the theme's check gradient (by default the accent's) over it. */\nexport const CHECK_FILL = \"bg-[var(--ds-check-bg)] [background-image:var(--ds-check-gradient,var(--ds-gradient))]\";\n\n/** A switch's track when on: the check colour, as a checked box's. */\nexport const SWITCH_TRACK_ON = \"bg-[var(--ds-check-bg)] border-transparent\";\n\n/**\n * A switch's track when off: from tokens only a regenerated stylesheet has (the theme writers emit them), falling back\n * to the switch as it was, so an app that hasn't regenerated never gets an outline in its old, fainter edge colour.\n */\nexport const SWITCH_TRACK_OFF = \"bg-[var(--ds-switch-off-fill,var(--ds-bg-muted))] border-[var(--ds-switch-off-edge,var(--ds-border-default))]\";\n\n/**\n * A switch's knob when on: the surface made opaque (a glass theme's half-white surface would show the track through it),\n * as pinned table cells are (D31); a surface that is wholly transparent stays so.\n */\nexport const SWITCH_KNOB_ON = \"bg-[var(--ds-bg-surface)] supports-[color:oklch(from_red_l_c_h)]:bg-[oklch(from_var(--ds-bg-surface)_l_c_h_/_max(alpha,min(1,alpha*1000)))]\";\n\n/** A switch's knob when off: the edge colour, beside the outline (the same fallback as the track). */\nexport const SWITCH_KNOB_OFF = \"bg-[var(--ds-switch-off-knob,var(--ds-bg-surface))]\";\n\n/** The knob moves and changes colour together with its track, so it never shows before the track does. */\nexport const SWITCH_KNOB_MOTION = \"transition-[transform,background-color] duration-[var(--ds-transition-speed)]\";\n","import { createContext } from \"react\";\n\n/**\n * A row of filters (PageHeader's filters slot) tells the controls in it that they are in one, so a text field takes a\n * search field's width, the table toolbar's (280 px), instead of a line of its own (the owner's\n * look at a bold header with content overlap, 30 September 2026: the search box filled a whole line).\n */\nexport const FilterRowContext = createContext(false);\n\n/**\n * A text field's width in a filter row: the toolbar search's 280 px, never wider than the row. A set width, not a flex\n * basis: a row that hugs its controls (the strip on a bold band) sizes itself from their widths, and a basis it doesn't\n * count pushed the field onto a line of its own.\n */\nexport const FILTER_FIELD_WIDTH = \"w-[280px] max-w-full\";\n","import { useCallback, useContext, useEffect, useRef, type Ref } from \"react\";\nimport { cn, FIELD_FOCUS_RING, FIELD_HAS_FOCUS_RING, ERROR_FOCUS_RING, ERROR_HAS_FOCUS_RING, FOCUS_RING } from \"../lib/utils\";\nimport { useInputModality } from \"../lib/input-modality\";\nimport type { ReactNode, InputHTMLAttributes, TextareaHTMLAttributes, LabelHTMLAttributes } from \"react\";\nimport { ControlSizeContext } from \"./Button\";\nimport { useReportedChange } from \"../lib/form-context\";\nimport { SWITCH_KNOB_MOTION, SWITCH_KNOB_OFF, SWITCH_KNOB_ON, SWITCH_TRACK_OFF, SWITCH_TRACK_ON } from \"../lib/control-looks\";\nimport { FILTER_FIELD_WIDTH, FilterRowContext } from \"../lib/filter-row\";\n\n/** A native field's new value from its change event: `checked` for a box, `value` for the rest (Sprint 25.12 A15). */\n/** An uncontrolled field's value, which no edit equals: the field holds its value itself. */\nconst UNCONTROLLED = Symbol(\"uncontrolled\");\nconst valueOf = (e: { target: EventTarget | null }) => {\n const t = e.target as HTMLInputElement | HTMLTextAreaElement | null;\n if (!t) return undefined;\n return t instanceof HTMLInputElement && (t.type === \"checkbox\" || t.type === \"radio\") ? t.checked : t.value;\n};\n\ntype InputSize = \"sm\" | \"md\" | \"lg\";\n\n// \"prefix\" must be omitted from the inherited attributes: React's HTMLAttributes\n// declares the RDFa attribute `prefix?: string`, and intersecting it with\n// `prefix?: ReactNode` collapses the prop to string-only at use sites.\nconst INPUT_HEIGHT: Record<InputSize, string> = {\n sm: \"h-[var(--ds-control-height-sm)]\",\n md: \"h-[var(--ds-control-height-md)]\",\n lg: \"h-[var(--ds-control-height-lg)]\",\n};\n\nconst INPUT_TEXT: Record<InputSize, string> = {\n sm: \"px-ds-2 py-ds-1 text-xs\",\n md: \"px-ds-3 py-ds-2 text-sm\",\n lg: \"px-ds-4 py-ds-3 text-base\",\n};\n\nexport function Input({ className, size: sizeProp, error = false, prefix, suffix, ...props }: Omit<InputHTMLAttributes<HTMLInputElement>, \"size\" | \"prefix\"> & { size?: InputSize; error?: boolean; prefix?: ReactNode; suffix?: ReactNode }) {\n // a field: clicked into, the active look; reached with Tab, the outline (Sprint 30, lib/input-modality.ts)\n useInputModality();\n const contextSize = useContext(ControlSizeContext);\n const size = sizeProp ?? contextSize ?? \"md\";\n // in a row of filters, a search field's width rather than a line of its own (the owner, 30 September)\n const width = useContext(FilterRowContext) ? FILTER_FIELD_WIDTH : \"w-full\";\n // Sprint 25.12 A15: the user's typing marks the form's overlay (only a new value); the page's onChange runs as given.\n // Uncontrolled (defaultValue), every edit is new: clearing a prefilled field compared \"\" with no value (0.21.0).\n const onChange = useReportedChange(props.onChange, props.value === undefined ? UNCONTROLLED : props.value, valueOf);\n const borderColor = error ? \"border-[var(--ds-status-error)]\" : \"border-[var(--ds-input-border)]\";\n const hoverBorder = !error && !props.disabled && !props.readOnly ? \"hover:border-[var(--ds-input-border-hover)]\" : \"\";\n\n if (prefix || suffix) {\n return (\n <div\n className={cn(\n \"flex items-center\", width,\n INPUT_HEIGHT[size],\n \"bg-[var(--ds-input-bg)]\",\n \"border-[length:var(--ds-border-width)]\", borderColor,\n \"rounded-[var(--ds-radius-md)]\",\n \"shadow-[var(--ds-input-shadow)]\",\n hoverBorder,\n error ? ERROR_HAS_FOCUS_RING : FIELD_HAS_FOCUS_RING,\n \"transition-colors duration-[var(--ds-transition-speed)]\",\n props.disabled && \"cursor-not-allowed opacity-disabled\",\n props.readOnly && \"bg-[var(--ds-bg-muted)] cursor-default\",\n className\n )}\n >\n {prefix && <span className=\"shrink-0 pl-ds-3 text-[var(--ds-text-muted)] flex items-center\">{prefix}</span>}\n <input\n aria-invalid={error || undefined}\n className={cn(\n \"flex-1 min-w-0 bg-transparent outline-none\",\n INPUT_TEXT[size],\n \"text-[var(--ds-text-primary)]\",\n \"placeholder:text-[var(--ds-text-muted)]\",\n \"disabled:cursor-not-allowed\",\n \"read-only:text-[var(--ds-text-secondary)] read-only:cursor-default\",\n )}\n {...props}\n onChange={props.onChange || props.value === undefined ? onChange : undefined}\n />\n {suffix && <span className=\"shrink-0 pr-ds-3 text-[var(--ds-text-muted)] flex items-center\">{suffix}</span>}\n </div>\n );\n }\n\n return (\n <input\n aria-invalid={error || undefined}\n className={cn(\n \"flex\", width,\n INPUT_TEXT[size], INPUT_HEIGHT[size],\n \"bg-[var(--ds-input-bg)] text-[var(--ds-text-primary)]\",\n \"border-[length:var(--ds-border-width)]\", borderColor,\n \"rounded-[var(--ds-radius-md)]\",\n \"shadow-[var(--ds-input-shadow)]\",\n \"placeholder:text-[var(--ds-text-muted)]\",\n hoverBorder,\n error ? ERROR_FOCUS_RING : FIELD_FOCUS_RING,\n \"disabled:cursor-not-allowed disabled:opacity-disabled\",\n \"read-only:bg-[var(--ds-bg-muted)] read-only:text-[var(--ds-text-secondary)] read-only:cursor-default\",\n \"transition-colors duration-[var(--ds-transition-speed)]\",\n className\n )}\n {...props}\n onChange={props.onChange || props.value === undefined ? onChange : undefined}\n />\n );\n}\n\ninterface TextareaProps extends TextareaHTMLAttributes<HTMLTextAreaElement> {\n autoResize?: boolean;\n maxRows?: number;\n error?: boolean;\n ref?: Ref<HTMLTextAreaElement>;\n}\n\nexport function Textarea({ className, autoResize, maxRows, error = false, ref, ...props }: TextareaProps) {\n // a field, as Input (Sprint 30)\n useInputModality();\n // Sprint 25.12 A15: as Input\n const onChange = useReportedChange(props.onChange, props.value === undefined ? UNCONTROLLED : props.value, valueOf);\n const internalRef = useRef<HTMLTextAreaElement>(null);\n const textareaRef = (ref ?? internalRef) as React.RefObject<HTMLTextAreaElement>;\n\n const resize = useCallback(() => {\n const el = textareaRef.current;\n if (!el || !autoResize) return;\n el.style.height = \"auto\";\n let target = el.scrollHeight;\n if (maxRows) {\n const lineHeight = parseFloat(getComputedStyle(el).lineHeight) || 20;\n const maxHeight = lineHeight * maxRows + parseFloat(getComputedStyle(el).paddingTop) + parseFloat(getComputedStyle(el).paddingBottom);\n target = Math.min(target, maxHeight);\n }\n el.style.height = `${target}px`;\n }, [autoResize, maxRows, textareaRef]);\n\n useEffect(() => { resize(); }, [resize, props.value, props.defaultValue]);\n\n return (\n <textarea\n ref={textareaRef}\n aria-invalid={error || undefined}\n className={cn(\n \"flex min-h-[var(--ds-control-height-md)] w-full px-ds-3 py-ds-2 text-sm\",\n \"bg-[var(--ds-input-bg)] text-[var(--ds-text-primary)]\",\n \"border-[length:var(--ds-border-width)]\",\n error ? \"border-[var(--ds-status-error)]\" : \"border-[var(--ds-input-border)] hover:border-[var(--ds-input-border-hover)]\",\n \"rounded-[var(--ds-radius-md)]\",\n \"shadow-[var(--ds-input-shadow)]\",\n \"placeholder:text-[var(--ds-text-muted)]\",\n error ? ERROR_FOCUS_RING : FIELD_FOCUS_RING,\n \"disabled:cursor-not-allowed disabled:opacity-disabled disabled:hover:border-[var(--ds-input-border)]\",\n \"read-only:bg-[var(--ds-bg-muted)] read-only:text-[var(--ds-text-secondary)] read-only:cursor-default read-only:hover:border-[var(--ds-input-border)]\",\n \"transition-colors duration-[var(--ds-transition-speed)]\",\n autoResize && \"resize-none overflow-hidden\",\n className\n )}\n onInput={autoResize ? resize : undefined}\n {...props}\n onChange={props.onChange || props.value === undefined ? onChange : undefined}\n />\n );\n}\n\nexport function Label({ className, children, ...props }: LabelHTMLAttributes<HTMLLabelElement>) {\n return (\n <label\n className={cn(\n \"text-sm font-medium leading-none text-[var(--ds-text-secondary)]\",\n \"peer-disabled:cursor-not-allowed peer-disabled:opacity-disabled\",\n className\n )}\n {...props}\n >\n {children}\n </label>\n );\n}\n\nexport type ToggleLayout = \"full\" | \"compact\";\nexport type ToggleSize = \"sm\" | \"md\";\n\n// Track width/height and thumb diameter; the thumb sits 1px inside the border.\nconst TOGGLE_SIZES: Record<ToggleSize, { w: number; h: number; thumb: number }> = {\n sm: { w: 32, h: 18, thumb: 12 },\n md: { w: 44, h: 24, thumb: 16 },\n};\n\nexport function Toggle({ checked, onChange, label, disabled, error = false, layout = \"full\", size = \"md\", \"aria-labelledby\": ariaLabelledBy, ...rest }: { checked: boolean; onChange: (v: boolean) => void; label?: string; disabled?: boolean; error?: boolean; layout?: ToggleLayout; size?: ToggleSize; \"aria-labelledby\"?: string } & Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, \"onChange\">) {\n // Sprint 25.12 A15: a flip is a change, reported to the form's overlay\n const change = useReportedChange(onChange, checked);\n const dims = TOGGLE_SIZES[size];\n const travel = dims.w - dims.thumb - 3;\n const switchButton = (\n <button type=\"button\"\n role=\"switch\"\n aria-checked={checked}\n aria-label={!label && !ariaLabelledBy ? \"Toggle\" : undefined}\n aria-labelledby={ariaLabelledBy}\n aria-invalid={error || undefined}\n disabled={disabled}\n onClick={() => !disabled && change(!checked)}\n {...rest}\n className={cn(\n \"relative inline-flex shrink-0 items-center overflow-hidden\",\n \"border-[length:var(--ds-border-width)]\",\n \"rounded-[var(--ds-radius-full)]\",\n \"transition-colors duration-[var(--ds-transition-speed)]\",\n FOCUS_RING,\n disabled ? \"cursor-not-allowed\" : \"cursor-pointer\",\n // Sprint 25.14 A20: on, the checked colour, as a checkbox's; off, the outline in the edge colour (lib/control-looks.ts)\n checked ? SWITCH_TRACK_ON : SWITCH_TRACK_OFF,\n error && \"border-[var(--ds-status-error)]\"\n )}\n style={{ width: dims.w, height: dims.h }}\n >\n <span\n className={cn(\n \"pointer-events-none inline-block shrink-0\",\n // on: the surface made opaque; off: the edge colour, beside the outline\n checked ? SWITCH_KNOB_ON : SWITCH_KNOB_OFF,\n \"border-[length:var(--ds-border-width)] border-transparent\",\n \"rounded-[var(--ds-radius-full)]\",\n SWITCH_KNOB_MOTION\n )}\n style={{\n width: dims.thumb,\n height: dims.thumb,\n transform: checked\n ? `translateX(calc(${travel}px - var(--ds-border-width)))`\n : \"translateX(calc(1px + var(--ds-border-width)))\",\n }}\n />\n </button>\n );\n\n if (!label) {\n return <div className={cn(disabled && \"opacity-disabled\")}>{switchButton}</div>;\n }\n\n return (\n <label\n className={cn(\n layout === \"full\"\n ? \"flex items-center justify-between gap-ds-4\"\n : \"inline-flex items-center gap-ds-3\",\n disabled ? \"cursor-not-allowed opacity-disabled\" : \"cursor-pointer\",\n )}\n >\n <span className=\"text-sm font-medium text-[var(--ds-text-primary)]\">{label}</span>\n {switchButton}\n </label>\n );\n}\n","import { cn } from \"../lib/utils\";\nimport { Icon } from \"../lib/icons\";\n\ninterface InlineFieldErrorProps {\n message: string;\n id: string;\n className?: string;\n}\n\nexport function InlineFieldError({ message, id, className }: InlineFieldErrorProps) {\n return (\n <p\n id={id}\n role=\"alert\"\n className={cn(\n \"flex items-center gap-ds-1.5 text-xs text-[var(--ds-status-error-text)]\",\n \"mt-ds-1.5\",\n className\n )}\n >\n {/* the words take the status's words colour (Sprint 30, P10); the icon, a mark, keeps the status colour */}\n <Icon name=\"error\" size={14} className=\"shrink-0 text-[var(--ds-status-error)]\" />\n <span>{message}</span>\n </p>\n );\n}\n","import { Children, cloneElement, createContext, isValidElement, useCallback, useContext, useEffect, useId, useMemo, useRef, useState, type ReactElement, type ReactNode } from \"react\";\nimport { cn } from \"../lib/utils\";\nimport { useLatest } from \"../lib/use-latest\";\nimport { useOptionalFormContext } from \"../lib/form-context\";\nimport { Label } from \"./Input\";\nimport { InlineFieldError } from \"./InlineFieldError\";\n\nexport interface FieldControlProps {\n id: string;\n \"aria-describedby\"?: string;\n \"aria-invalid\"?: true;\n \"aria-required\"?: true;\n required?: boolean;\n /** Set on Gridsmith form components (Input, Textarea, Dropdown, DatePicker, …). */\n error?: boolean;\n}\n\n/**\n * What a control inside a Field knows about it (Sprint 25.7, C5): the label's id, for a control that `<label for>`\n * cannot name (a slider is a div with role=\"slider\") to take it with aria-labelledby, and the hint and error ids.\n */\nexport interface FieldContextValue {\n controlId: string;\n labelId: string;\n describedBy?: string;\n /** The Field shows an error. */\n invalid?: boolean;\n required?: boolean;\n}\n\nconst FieldContext = createContext<FieldContextValue | null>(null);\n\n/** The Field a control sits in, or null. */\nexport function useField(): FieldContextValue | null {\n return useContext(FieldContext);\n}\n\n/**\n * The parts of a control that has several (Sprint 25.19 R2: RecurrencePicker's custom repeat), each with a label of its\n * own: inside, no control takes the Field's id, label, description or error, which name the control's main part only.\n */\nexport function OutsideField({ children }: { children: ReactNode }) {\n return <FieldContext.Provider value={null}>{children}</FieldContext.Provider>;\n}\n\n/** The wiring a control may be given as props: by a Field's clone, or by a page that labels it itself. */\nexport interface FieldControlWiring {\n id?: string;\n \"aria-labelledby\"?: string;\n \"aria-describedby\"?: string;\n \"aria-invalid\"?: boolean | \"true\" | \"false\";\n \"aria-required\"?: boolean | \"true\" | \"false\";\n required?: boolean;\n error?: boolean;\n}\n\n/**\n * What a Gridsmith control that is not a native input takes from the Field it sits in, merged with its own props, which\n * win (round 27 review: Dropdown, DatePicker and SegmentedControl dropped the Field's id and description, so the error\n * summary read \"A field: Needs attention\" with no link, and a screen reader heard the placeholder as the name):\n * - `id`, for the Field's `<label for>`, the summary's link and the focus after a submit;\n * - `labelId`, the label that names it by aria-labelledby, which reaches a button, a group or a radiogroup alike;\n * - `describedBy`, the hint and the error, each id once;\n * - `invalid` and `required`. A role that cannot carry aria-required (a button, a group) says it in its description\n * instead: `requiredNote` is the hidden text, already in `describedBy`, for the control to render.\n * Outside a Field a control gets its own props back.\n */\nexport function useFieldControl(own: FieldControlWiring, options: { requiredInDescription?: boolean } = {}): {\n id?: string;\n labelId?: string;\n describedBy?: string;\n invalid: boolean;\n required: boolean;\n requiredNote: ReactNode;\n} {\n const field = useField();\n const id = own.id ?? field?.controlId;\n const invalid = !!own.error || own[\"aria-invalid\"] === true || own[\"aria-invalid\"] === \"true\" || !!field?.invalid;\n const required = !!own.required || own[\"aria-required\"] === true || own[\"aria-required\"] === \"true\" || !!field?.required;\n const noteId = options.requiredInDescription && required && id ? `${id}-required` : undefined;\n const ids = [own[\"aria-describedby\"], field?.describedBy, noteId].filter(Boolean).join(\" \").split(/\\s+/).filter(Boolean);\n return {\n id,\n labelId: own[\"aria-labelledby\"] ?? field?.labelId,\n describedBy: [...new Set(ids)].join(\" \") || undefined,\n invalid,\n required,\n requiredNote: noteId ? <span id={noteId} hidden>Required</span> : null,\n };\n}\n\n/**\n * A field's label: any text or element, never nothing. Sprint 25.12 A31 (R28-59): run 75 labelled only the first of its\n * repeated rows (`label={index === 0 ? … : undefined}`), and every other row's fields had no name. A label that\n * shouldn't show takes `hideLabel`; repeated rows use AddAnother, which shows each label once.\n */\nexport type FieldLabel = Exclude<ReactNode, null | undefined | boolean>;\n\n/** Set by AddAnother around each row: a hidden label shows again when the group is too narrow for its headings. */\nexport const AddAnotherRowCtx = createContext(false);\n\nexport interface FieldProps {\n label: FieldLabel;\n /**\n * The label is read out but not shown (Sprint 25.12 A31): for a field whose purpose the page shows another way, such\n * as a column heading above repeated rows. In an AddAnother group it shows again when the group stacks its rows.\n */\n hideLabel?: boolean;\n /** The single form control. Receives id, aria-describedby, aria-invalid/error and required automatically. */\n children: ReactElement | ((props: FieldControlProps) => ReactNode);\n /** Persistent help text (format requirements, why a field is disabled). Shown below the control, above any error. */\n hint?: ReactNode;\n /** Current validation error. Rendered as InlineFieldError (role=\"alert\") and linked via aria-describedby. Wins over `validate`. */\n error?: string | null | false;\n /**\n * The field's check: the message for what is wrong with its value, or nothing (`validate={(v) => v ? undefined :\n * \"Enter a title\"}`). It gets the control's `value` (or `checked`); a closure over your own state works as well.\n * Inside a FormWrapper it runs at the project's validation timing (forms.validationTiming, through the form):\n * - `onBlur`: when the field is left;\n * - `onChange`: as the value changes, once the field has been left;\n * - `onSubmit`: on submit only.\n *\n * Whatever the timing, it runs on every submit, and FormWrapper's `onSubmit` gets its message under this Field's\n * `id`, or no key at all when the value passes, so an empty `errors` means the form is valid. A message that shows is\n * checked again as the value changes, so it goes as soon as the value is right. Focus\n * moving into the control's own popup (a Dropdown's list, a DatePicker's calendar) is not leaving the field. Outside\n * a FormWrapper it runs when the field is left (round 26, R26-2).\n */\n validate?: (value: unknown) => string | undefined | null | false;\n required?: boolean;\n /** Slot to the right of the label, e.g. a \"Forgot password?\" Link. */\n labelAction?: ReactNode;\n /** Explicit id for the control; generated when omitted. */\n id?: string;\n className?: string;\n}\n\n/**\n * Label + control + hint + error, wired together. Guarantees the label is\n * associated (htmlFor/id), that hint and error are announced\n * (aria-describedby), that the control is marked invalid, and that the error\n * sits directly below the field (forms-002/006/009/010). Use one Field per\n * control; do not add a separate <Label> or a label prop on the child.\n *\n * In a SettingsLayout panel a Field keeps the narrow page's reading width however wide the page is (the panel's\n * --ds-form-max, Sprint 25.9); a `max-w-*` class of your own wins.\n */\nexport function Field({ label, children, hint, error, required, labelAction, hideLabel = false, id: idProp, validate, className }: FieldProps) {\n const inGroupRow = useContext(AddAnotherRowCtx);\n const generated = useId();\n const id = idProp ?? `field-${generated}`;\n const hintId = `${id}-hint`;\n const errorId = `${id}-error`;\n\n // ── The field's own check (round 26, R26-2) ──\n const form = useOptionalFormContext();\n // outside a form, the only moment a field can check itself is when it is left\n const mode = form?.validationMode ?? \"onBlur\";\n const [localError, setLocalError] = useState<string | undefined>(undefined);\n const [left, setLeft] = useState(false);\n const checkError = validate ? (form ? form.errors[id] : localError) : undefined;\n const child = typeof children === \"function\" ? null : Children.only(children);\n const childProps = child && isValidElement(child) ? (child.props as Record<string, unknown>) : null;\n const latest = useLatest({ validate, childProps, id, mode, left, showing: !!checkError, form });\n const check = useCallback((): string | undefined => {\n const { validate: fn, childProps: props, id: controlId } = latest.current;\n if (!fn) return undefined;\n const value = props && \"value\" in props ? props.value : props && \"checked\" in props ? props.checked : (document.getElementById(controlId) as HTMLInputElement | null)?.value;\n const message = fn(value);\n return typeof message === \"string\" && message.length > 0 ? message : undefined;\n }, [latest]);\n const show = useCallback((message: string | undefined) => {\n const { form: f, id: controlId } = latest.current;\n if (f) f.setError(controlId, message);\n else setLocalError(message);\n }, [latest]);\n // every submit runs the check, whatever the timing\n const register = form?.register;\n const checks = !!validate;\n useEffect(() => (register && checks ? register(id, check) : undefined), [register, checks, id, check]);\n // Left: focus goes out of the field's React tree and doesn't come back straight away. React carries focus events\n // through portals, so moving into the control's own popup comes back in, and cancels the check.\n const leaving = useRef<ReturnType<typeof setTimeout> | null>(null);\n useEffect(() => () => { if (leaving.current) clearTimeout(leaving.current); }, []);\n const onFocusCapture = () => {\n if (leaving.current) { clearTimeout(leaving.current); leaving.current = null; }\n };\n const onBlurCapture = () => {\n if (!validate) return;\n if (leaving.current) clearTimeout(leaving.current);\n leaving.current = setTimeout(() => {\n leaving.current = null;\n setLeft(true);\n if (latest.current.mode !== \"onSubmit\" || latest.current.showing) show(check());\n }, 0);\n };\n // Changed: checked again once the page has the new value, if the timing is onChange and the field has been left,\n // or if its message shows, so it goes as soon as the value is right\n const recheck = () => {\n if (!validate) return;\n setTimeout(() => {\n const { mode: m, left: wasLeft, showing } = latest.current;\n if ((m === \"onChange\" && wasLeft) || showing) show(check());\n }, 0);\n };\n\n const shownError = typeof error === \"string\" && error.length > 0 ? error : checkError;\n const hasError = typeof shownError === \"string\" && shownError.length > 0;\n const describedBy = [hint ? hintId : null, hasError ? errorId : null].filter(Boolean).join(\" \") || undefined;\n const labelId = `${id}-label`;\n const fieldContext = useMemo<FieldContextValue>(() => ({ controlId: id, labelId, describedBy, invalid: hasError, required: !!required }), [id, labelId, describedBy, hasError, required]);\n\n const controlProps: FieldControlProps = {\n id,\n \"aria-describedby\": describedBy,\n ...(hasError ? { \"aria-invalid\": true as const, error: true } : {}),\n ...(required ? { \"aria-required\": true as const, required: true } : {}),\n };\n\n let control: ReactNode;\n if (typeof children === \"function\") {\n control = children(controlProps);\n } else {\n if (!child || !isValidElement(child)) throw new Error(\"Field expects a single form control as its child\");\n const isNative = typeof child.type === \"string\";\n const { error: errorFlag, ...ariaOnly } = controlProps;\n // with a check, the control's own onChange is kept and the check follows it (a Gridsmith control calls onChange\n // with its value; a native one's input event reaches the wrapper too)\n const ownOnChange = childProps?.onChange as ((...args: unknown[]) => void) | undefined;\n const onChange = validate && !isNative ? { onChange: (...args: unknown[]) => { ownOnChange?.(...args); recheck(); } } : {};\n // Native elements get ARIA only (an unknown `error` attribute would warn);\n // Gridsmith components get `error` so they render their error styling.\n control = cloneElement(child as ReactElement<Record<string, unknown>>, isNative ? ariaOnly : { ...ariaOnly, ...(errorFlag ? { error: true } : {}), ...onChange });\n }\n\n const labelNode = (\n <Label id={labelId} htmlFor={id} className={cn(hideLabel && \"sr-only\", hideLabel && inGroupRow && \"@max-[30rem]:not-sr-only\")}>\n {label}\n {required && <span aria-hidden=\"true\" className=\"ml-ds-0.5 text-[var(--ds-status-error)]\">*</span>}\n </Label>\n );\n\n return (\n // In a settings panel a field keeps the narrow reading width however wide the page is (--ds-form-max, Sprint 25.9 A4)\n <div\n className={cn(\"flex flex-col gap-ds-1.5 max-w-[var(--ds-form-max,none)]\", className)}\n {...(validate ? { onFocusCapture, onBlurCapture, onInputCapture: recheck } : {})}\n >\n {/* A hidden label with no action beside it takes no row of its own, so the field keeps its height (A31); in an\n AddAnother row it shows again once the group stacks its rows and hides its headings. */}\n {hideLabel && !labelAction ? labelNode : (\n <div className=\"flex items-center justify-between gap-ds-2\">\n {labelNode}\n {labelAction}\n </div>\n )}\n <FieldContext.Provider value={fieldContext}>{control}</FieldContext.Provider>\n {hint && (\n <p id={hintId} className=\"text-xs text-[var(--ds-text-muted)]\">{hint}</p>\n )}\n {hasError && <InlineFieldError id={errorId} message={shownError} className=\"mt-0\" />}\n </div>\n );\n}\n","import { cn, ACTIVE_RING, FIELD_FOCUS_RING, ERROR_ACTIVE_RING, ERROR_FOCUS_RING, FOCUS_RING } from \"../lib/utils\";\nimport { Icon } from \"../lib/icons\";\nimport { focusAfterRemoval, usePopupFocus } from \"../lib/focus\";\nimport { useInputModality } from \"../lib/input-modality\";\nimport { useRevealFocus } from \"../lib/reveal-focus\";\nimport { AutoTooltip } from \"./Tooltip\";\nimport { useTextOverflow } from \"../lib/use-text-overflow\";\nimport { useState, useRef, useEffect, useLayoutEffect, useCallback, useContext, useId, type Ref } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { ControlSizeContext } from \"./Button\";\nimport { useFieldControl, type FieldControlWiring } from \"./Field\";\nimport { useReportedChange } from \"../lib/form-context\";\n\ninterface Option {\n id: string;\n label: string;\n group?: string;\n}\n\ntype DropdownSize = \"sm\" | \"md\" | \"lg\";\n\nconst DROPDOWN_HEIGHT: Record<DropdownSize, string> = {\n sm: \"px-ds-2 py-ds-1 text-xs h-[var(--ds-control-height-sm)]\",\n md: \"px-ds-3 py-ds-2 text-sm h-[var(--ds-control-height-md)]\",\n lg: \"px-ds-4 py-ds-3 text-base h-[var(--ds-control-height-lg)]\",\n};\n\ninterface DropdownProps extends FieldControlWiring {\n options: Option[];\n value: string | string[];\n onChange: (value: string | string[]) => void;\n label?: string;\n disabled?: boolean;\n placeholder?: string;\n multiple?: boolean;\n searchable?: boolean;\n size?: DropdownSize;\n className?: string;\n ref?: Ref<HTMLDivElement>;\n container?: Element | DocumentFragment;\n error?: boolean;\n /** When multiple, show removable chips below the trigger. Defaults to true. Set false in toolbar contexts where chips are shown elsewhere. */\n showChips?: boolean;\n /** Accessible name for the trigger, for when there is no visible `label` (e.g. in a toolbar). */\n \"aria-label\"?: string;\n}\n\nexport function Dropdown({\n options,\n value,\n onChange: onChangeProp,\n label,\n disabled,\n placeholder = \"Select...\",\n multiple,\n searchable,\n size: sizeProp,\n className,\n ref,\n container,\n error = false,\n showChips = true,\n \"aria-label\": ariaLabel,\n ...wiring\n}: DropdownProps) {\n // Sprint 25.12 A15: a choice the user makes marks the form's overlay; the list's search box doesn't (its own state)\n const onChange = useReportedChange(onChangeProp, value);\n // A field (Sprint 30, P13): from the keyboard the trigger and the list's search box show the outline; after a pointer\n // press the search box shows the active look, and while the list is open the trigger keeps it (ACTIVE_RING)\n useInputModality();\n const contextSize = useContext(ControlSizeContext);\n // Inside a Field the trigger takes the Field's id, label, hint, error and required state (round 27 review): the label\n // and then the trigger's own text name it, the list-box button pattern's \"Plan, Starter\" (APG collapsible listbox).\n const generatedId = useId();\n const control = useFieldControl({ ...wiring, error: error || undefined }, { requiredInDescription: true });\n const triggerId = control.id ?? generatedId;\n const labelSpanId = `${triggerId}-label`;\n const labelledBy = control.labelId ? `${control.labelId} ${triggerId}` : label && !ariaLabel ? `${labelSpanId} ${triggerId}` : undefined;\n const invalid = control.invalid;\n const size = sizeProp ?? contextSize ?? \"md\";\n const [open, setOpen] = useState(false);\n const [search, setSearch] = useState(\"\");\n const [positioned, setPositioned] = useState(false);\n const triggerRef = useRef<HTMLButtonElement>(null);\n // the arrows' option comes into view whole, with its outline (Sprint 30, P3): the list shows part of one at its foot\n const [listbox, setListbox] = useState<HTMLDivElement | null>(null);\n useRevealFocus(listbox);\n const menuRef = useRef<HTMLDivElement>(null);\n const searchRef = useRef<HTMLInputElement>(null);\n const [pos, setPos] = useState({ top: 0, left: 0, width: 0 });\n\n const selectedValues = Array.isArray(value) ? value : [value].filter(Boolean);\n\n const updatePos = useCallback(() => {\n if (!triggerRef.current) return;\n const rect = triggerRef.current.getBoundingClientRect();\n let top = rect.bottom + 4;\n let left = rect.left;\n const width = rect.width;\n\n if (menuRef.current) {\n const menuRect = menuRef.current.getBoundingClientRect();\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n if (left + menuRect.width > vw) left = Math.max(0, vw - menuRect.width - 8);\n if (top + menuRect.height > vh) {\n const above = rect.top - 4 - menuRect.height;\n if (above >= 0) top = above;\n else top = Math.max(0, vh - menuRect.height - 8);\n }\n }\n\n setPos({ top, left, width });\n }, []);\n\n // Opening clears the search; closing forgets the last position (render-time\n // state adjustment, so the menu never paints with stale values).\n const [prevOpen, setPrevOpen] = useState(open);\n if (open !== prevOpen) {\n setPrevOpen(open);\n if (open) setSearch(\"\");\n else setPositioned(false);\n }\n\n useEffect(() => {\n if (!open) return;\n updatePos();\n const raf = requestAnimationFrame(() => {\n updatePos();\n setPositioned(true);\n });\n const onScroll = () => updatePos();\n window.addEventListener(\"scroll\", onScroll, true);\n window.addEventListener(\"resize\", updatePos);\n return () => {\n cancelAnimationFrame(raf);\n window.removeEventListener(\"scroll\", onScroll, true);\n window.removeEventListener(\"resize\", updatePos);\n };\n }, [open, updatePos]);\n\n // Sprint 25.7: the user moved to an option since the list opened (arrows, Home/End, type-ahead). Tab then picks it (D14(a)).\n const moved = useRef(false);\n\n // Focus moves in once the panel is visible: it opens with visibility hidden until positioned, and a hidden element\n // cannot take focus (focusing it in the same frame used to leave focus on the trigger in real browsers).\n useLayoutEffect(() => {\n if (!open || !positioned) return;\n moved.current = false;\n if (searchRef.current) {\n searchRef.current.focus();\n return;\n }\n const els = Array.from(menuRef.current?.querySelectorAll<HTMLButtonElement>('[role=\"option\"]') ?? []);\n (els.find((el) => el.getAttribute(\"aria-selected\") === \"true\") ?? els[0])?.focus();\n }, [open, positioned]);\n\n useEffect(() => {\n if (!open) return;\n const handler = (e: MouseEvent) => {\n const target = e.target as Node;\n if (triggerRef.current?.contains(target) || menuRef.current?.contains(target)) return;\n setOpen(false);\n };\n document.addEventListener(\"mousedown\", handler);\n return () => document.removeEventListener(\"mousedown\", handler);\n }, [open]);\n\n // Tab while open (D14(a)): a single-select list picks the option the user moved to; opened and left, nothing changes.\n const commitMoved = () => {\n if (multiple || !moved.current) return;\n const el = document.activeElement;\n const id = el instanceof HTMLElement && menuRef.current?.contains(el) ? el.getAttribute(\"data-option-id\") : null;\n if (id) onChange(id);\n };\n // Sprint 25.7: focus hands back on close, and Tab out carries on from the trigger (lib/focus usePopupFocus).\n const { isTop: isTopLayer, returnFocus } = usePopupFocus(open, { trigger: triggerRef, panel: menuRef, close: () => setOpen(false), tabExits: \"any\", onTabOut: commitMoved });\n\n // Keyboard while open: Escape closes (focus returns to the trigger); arrows,\n // Home/End move focus through the options; typing jumps to the first option\n // starting with those letters (when there is no search box); Enter/Space\n // activate the focused option natively.\n const typeahead = useRef({ buffer: \"\", at: 0 });\n useEffect(() => {\n if (!open) return;\n const optionButtons = () => Array.from(menuRef.current?.querySelectorAll<HTMLButtonElement>('[role=\"option\"]') ?? []);\n const focusOption = (idx: number) => {\n const els = optionButtons();\n if (els.length === 0) return;\n els[((idx % els.length) + els.length) % els.length].focus();\n moved.current = true;\n };\n const onKey = (e: KeyboardEvent) => {\n const inMenu = menuRef.current?.contains(document.activeElement) || triggerRef.current === document.activeElement;\n if (!inMenu) return;\n const els = optionButtons();\n const current = els.findIndex((el) => el === document.activeElement);\n if (e.key === \"Escape\") { if (e.defaultPrevented || !isTopLayer()) return; e.preventDefault(); returnFocus(); setOpen(false); return; }\n if (e.key === \"ArrowDown\") { e.preventDefault(); focusOption(current < 0 ? 0 : current + 1); return; }\n if (e.key === \"ArrowUp\") { e.preventDefault(); focusOption(current < 0 ? els.length - 1 : current - 1); return; }\n const inSearch = document.activeElement === searchRef.current;\n if (e.key === \"Home\" && !inSearch) { e.preventDefault(); focusOption(0); return; }\n if (e.key === \"End\" && !inSearch) { e.preventDefault(); focusOption(els.length - 1); return; }\n if (!searchable && e.key.length === 1 && !e.metaKey && !e.ctrlKey && !e.altKey) {\n const now = Date.now();\n typeahead.current.buffer = now - typeahead.current.at > 700 ? e.key : typeahead.current.buffer + e.key;\n typeahead.current.at = now;\n const q = typeahead.current.buffer.toLowerCase();\n const hit = els.findIndex((el) => (el.textContent ?? \"\").trim().toLowerCase().startsWith(q));\n if (hit >= 0) { e.preventDefault(); focusOption(hit); }\n }\n };\n document.addEventListener(\"keydown\", onKey);\n return () => document.removeEventListener(\"keydown\", onKey);\n }, [open, searchable, isTopLayer, returnFocus]);\n\n const filtered = searchable && search\n ? options.filter((o) => o.label.toLowerCase().includes(search.toLowerCase()))\n : options;\n\n const groups = new Map<string, Option[]>();\n for (const opt of filtered) {\n const g = opt.group ?? \"\";\n if (!groups.has(g)) groups.set(g, []);\n groups.get(g)!.push(opt);\n }\n const hasGroups = Array.from(groups.keys()).some((k) => k !== \"\");\n\n const handleSelect = (id: string) => {\n if (multiple) {\n const arr = selectedValues.includes(id)\n ? selectedValues.filter((v) => v !== id)\n : [...selectedValues, id];\n onChange(arr);\n } else {\n // Focus back on the trigger before the consumer runs, so a dialog it opens records the trigger (Sprint 25.7).\n returnFocus();\n onChange(id);\n setOpen(false);\n }\n };\n\n // Removing a chip moves focus to the chip before it, else the one after, else the trigger (D14(c)), once the value\n // no longer holds it. The next render drops the request either way, so a removal the consumer refused never moves\n // focus later.\n const chipsRef = useRef<HTMLDivElement>(null);\n const pendingChipFocus = useRef<{ index: number; value: string } | null>(null);\n useLayoutEffect(() => {\n const pending = pendingChipFocus.current;\n if (pending === null) return;\n pendingChipFocus.current = null;\n if (selectedValues.includes(pending.value)) return;\n const chips = Array.from(chipsRef.current?.querySelectorAll<HTMLElement>(\"[data-chip-remove]\") ?? []);\n focusAfterRemoval(chips, pending.index, triggerRef.current);\n });\n\n const displayLabel = multiple\n ? selectedValues.length > 0\n ? `${selectedValues.length} selected`\n : placeholder\n : options.find((o) => o.id === selectedValues[0])?.label ?? placeholder;\n\n const { ref: overflowRef, isTruncated } = useTextOverflow({ lines: 1, content: displayLabel });\n\n return (\n <div ref={ref} className={cn(\"relative\", className)}>\n {label && (\n <span id={labelSpanId} className=\"block mb-ds-1.5 text-sm font-medium text-[var(--ds-text-secondary)]\">{label}</span>\n )}\n {control.requiredNote}\n <button\n ref={triggerRef}\n id={triggerId}\n type=\"button\"\n onClick={() => !disabled && setOpen(!open)}\n onKeyDown={(e) => {\n if (disabled || open) return;\n if (e.key === \"ArrowDown\" || e.key === \"ArrowUp\") { e.preventDefault(); setOpen(true); }\n }}\n disabled={disabled}\n aria-invalid={invalid || undefined}\n aria-haspopup=\"listbox\"\n aria-expanded={open}\n aria-label={labelledBy ? undefined : ariaLabel}\n aria-labelledby={labelledBy}\n aria-describedby={control.describedBy}\n className={cn(\n \"w-full flex items-center justify-between gap-ds-2\",\n DROPDOWN_HEIGHT[size],\n \"bg-[var(--ds-input-bg)] text-[var(--ds-text-primary)]\",\n \"border-[length:var(--ds-border-width)]\",\n invalid ? \"border-[var(--ds-status-error)]\" : \"border-[var(--ds-input-border)]\",\n \"rounded-[var(--ds-radius-md)]\",\n \"shadow-[var(--ds-input-shadow)]\",\n \"transition-colors\",\n !invalid && !disabled && !open && \"hover:border-[var(--ds-input-border-hover)]\",\n open && (invalid ? ERROR_ACTIVE_RING : ACTIVE_RING),\n invalid ? ERROR_FOCUS_RING : FIELD_FOCUS_RING,\n \"cursor-pointer disabled:cursor-not-allowed disabled:opacity-disabled\",\n !selectedValues.length && \"text-[var(--ds-text-muted)]\"\n )}\n >\n {isTruncated ? (\n <AutoTooltip content={displayLabel}><span ref={overflowRef} className=\"truncate\">{displayLabel}</span></AutoTooltip>\n ) : (\n <span ref={overflowRef} className=\"truncate\">{displayLabel}</span>\n )}\n <span className={cn(\"transition-transform\", open && \"rotate-180\")}>\n <Icon name=\"chevron-right\" size={14} className=\"rotate-90\" />\n </span>\n </button>\n\n {open && createPortal(\n <div\n ref={menuRef}\n // Safari focuses no button on a mousedown and drops focus to the body; a panel that can take focus keeps it\n // inside the control's React tree, so a Field's leave check never fires mid-choice (round 27 review)\n tabIndex={-1}\n // A choice is the list's own: its click must not also reach a clickable row or card around the Dropdown.\n onClick={(e) => e.stopPropagation()}\n className={cn(\n \"fixed z-[var(--ds-z-popover)] outline-none\",\n \"bg-[var(--ds-bg-surface-elevated)]\",\n \"[backdrop-filter:var(--ds-glass-filter)] [-webkit-backdrop-filter:var(--ds-glass-filter)]\",\n \"border-[length:var(--ds-border-width)] border-[var(--ds-border-default)]\",\n \"rounded-[var(--ds-radius-md)] overflow-hidden\",\n \"shadow-[var(--ds-shadow-dropdown),var(--ds-glass-inset)]\",\n )}\n style={{ top: pos.top, left: pos.left, minWidth: pos.width, width: \"max-content\", maxWidth: \"calc(100vw - 16px)\", visibility: positioned ? \"visible\" : \"hidden\" }}\n >\n {searchable && (\n <div className=\"border-b-[length:var(--ds-border-width)] border-[var(--ds-border-subtle)]\" style={{ padding: \"var(--ds-space-2)\" }}>\n <input\n ref={searchRef}\n type=\"text\"\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n placeholder=\"Search…\"\n // the list's own search field, its first row: no look of its own (Sprint 30, the owner's decision B)\n data-popup-search=\"\"\n className={cn(\"w-full bg-transparent text-[var(--ds-text-primary)] placeholder:text-[var(--ds-text-muted)] outline-none\", size === \"sm\" ? \"text-xs\" : \"text-sm\")}\n />\n </div>\n )}\n {/* its padding is room for the options' outline, never under its 4 px reach (Sprint 30, P3) */}\n <div ref={setListbox} role=\"listbox\" className=\"overflow-y-auto scroll-p-[4px]\" style={{ padding: \"max(var(--ds-space-1), 4px)\", maxHeight: \"var(--ds-dropdown-max-height)\" }}>\n {filtered.length === 0 ? (\n <p className={cn(\"text-[var(--ds-text-muted)] text-center py-ds-4\", size === \"sm\" ? \"text-xs\" : \"text-sm\")}>No options found</p>\n ) : hasGroups ? (\n Array.from(groups.entries()).map(([group, opts]) => (\n <div key={group}>\n {group && (\n <p className=\"text-2xs font-medium uppercase tracking-wider text-[var(--ds-text-muted)] px-ds-2 pt-ds-2 pb-ds-1\">\n {group}\n </p>\n )}\n {opts.map((opt) => (\n <OptionButton\n key={opt.id}\n opt={opt}\n isSelected={selectedValues.includes(opt.id)}\n multiple={multiple}\n onSelect={handleSelect}\n size={size}\n />\n ))}\n </div>\n ))\n ) : (\n filtered.map((opt) => (\n <OptionButton\n key={opt.id}\n opt={opt}\n isSelected={selectedValues.includes(opt.id)}\n multiple={multiple}\n onSelect={handleSelect}\n size={size}\n />\n ))\n )}\n </div>\n </div>,\n container ?? document.body\n )}\n\n {multiple && showChips && selectedValues.length > 0 && (\n <div ref={chipsRef} className=\"flex flex-wrap gap-ds-1 mt-ds-1.5\">\n {selectedValues.map((v, i) => {\n const opt = options.find((o) => o.id === v);\n return opt ? (\n <span\n key={v}\n className=\"inline-flex items-center gap-ds-1 text-xs rounded-[var(--ds-radius-sm)] bg-[var(--ds-bg-muted)] text-[var(--ds-text-secondary)] px-ds-1.5 py-ds-0.5\"\n >\n {opt.label}\n <button type=\"button\"\n data-chip-remove=\"\"\n onClick={() => { pendingChipFocus.current = { index: i, value: v }; handleSelect(v); }}\n className={cn(\"hover:text-[var(--ds-text-primary)] cursor-pointer\", FOCUS_RING)}\n aria-label={`Remove ${opt.label}`}\n >\n <Icon name=\"close\" size={10} />\n </button>\n </span>\n ) : null;\n })}\n </div>\n )}\n </div>\n );\n}\n\nfunction OptionButton({\n opt,\n isSelected,\n multiple,\n onSelect,\n size = \"md\",\n}: {\n opt: Option;\n isSelected: boolean;\n multiple?: boolean;\n onSelect: (id: string) => void;\n size?: DropdownSize;\n}) {\n return (\n <button\n type=\"button\"\n role=\"option\"\n data-option-id={opt.id}\n aria-selected={isSelected}\n tabIndex={-1}\n onClick={() => onSelect(opt.id)}\n className={cn(\n \"w-full text-left cursor-pointer rounded-[var(--ds-radius-sm)]\",\n \"transition-colors flex items-center gap-ds-2\",\n // the arrows move DOM focus here, so the option draws the outline; outside it, clear of the chosen one's fill\n FOCUS_RING,\n size === \"sm\" ? \"px-ds-2 py-ds-1 text-xs\" : \"px-ds-2 py-ds-1.5 text-sm\",\n isSelected && !multiple\n ? \"bg-[var(--ds-accent-primary)] text-[var(--ds-text-on-primary)]\"\n : \"text-[var(--ds-text-primary)] hover:bg-[var(--ds-bg-emphasis)]\"\n )}\n >\n {multiple && (\n <span\n className={cn(\n \"w-[var(--ds-icon-size-sm)] h-[var(--ds-icon-size-sm)] rounded-[var(--ds-radius-sm)] border-[length:var(--ds-border-width)] shrink-0 flex items-center justify-center\",\n isSelected\n ? \"bg-[var(--ds-accent-primary)] border-[var(--ds-accent-primary)]\"\n : \"border-[var(--ds-border-default)]\"\n )}\n >\n {isSelected && <Icon name=\"check\" size={10} className=\"text-[var(--ds-text-on-primary)]\" />}\n </span>\n )}\n <span className=\"flex-1\">{opt.label}</span>\n {isSelected && !multiple && <Icon name=\"check\" size={size === \"sm\" ? 12 : 14} />}\n </button>\n );\n}\n","import { useCallback, useContext, useRef, useState } from \"react\";\nimport { useLatest } from \"../lib/use-latest\";\nimport { cn, FIELD_FOCUS_WITHIN_RING, ERROR_FOCUS_WITHIN_RING, FOCUS_RING } from \"../lib/utils\";\nimport { useInputModality } from \"../lib/input-modality\";\nimport { ControlSizeContext } from \"./Button\";\nimport { useReportedChange } from \"../lib/form-context\";\n\ninterface NumberInputProps {\n value: number;\n onChange: (value: number) => void;\n min?: number;\n max?: number;\n step?: number;\n disabled?: boolean;\n placeholder?: string;\n prefix?: string;\n suffix?: string;\n size?: \"sm\" | \"md\" | \"lg\";\n className?: string;\n error?: boolean;\n /** Allow decimal input. Default: true when step is not an integer, false otherwise. */\n allowDecimals?: boolean;\n /** Forwarded to the inner input element so a Label htmlFor can be associated. */\n id?: string;\n}\n\n// The height is the bordered box's (box-sizing: border-box), so the control measures exactly the token beside an\n// Input or a Button; the buttons and the field stretch to it.\nconst sizes = {\n sm: { box: \"h-[var(--ds-control-height-sm)]\", input: \"text-xs self-stretch\", btn: \"w-7 text-xs\" },\n md: { box: \"h-[var(--ds-control-height-md)]\", input: \"text-sm self-stretch\", btn: \"w-9 text-sm\" },\n lg: { box: \"h-[var(--ds-control-height-lg)]\", input: \"text-base self-stretch\", btn: \"w-10 text-base\" },\n};\n\nexport function NumberInput({\n value,\n onChange: onChangeProp,\n min = -Infinity,\n max = Infinity,\n step = 1,\n disabled = false,\n placeholder = \"0\",\n prefix,\n suffix,\n size: sizeProp,\n className,\n error = false,\n allowDecimals,\n id,\n}: NumberInputProps) {\n // Sprint 25.12 A15: a new value the user gives this control marks the form's overlay; the page's onChange runs as given\n const onChange = useReportedChange(onChangeProp, value);\n // a field: clicked into, the active look; reached with Tab, the outline (Sprint 30, lib/input-modality.ts)\n useInputModality();\n const contextSize = useContext(ControlSizeContext);\n const size = sizeProp ?? contextSize ?? \"md\";\n const intervalRef = useRef<ReturnType<typeof setInterval>>(undefined);\n const timeoutRef = useRef<ReturnType<typeof setTimeout>>(undefined);\n const inputRef = useRef<HTMLInputElement>(null);\n const [focused, setFocused] = useState(false);\n const [draft, setDraft] = useState(String(value));\n\n const decimals = allowDecimals ?? (step % 1 !== 0);\n\n // While not focused the draft mirrors the controlled value; on blur it\n // re-syncs (render-time state adjustment).\n const [prevSync, setPrevSync] = useState({ value, focused });\n if (value !== prevSync.value || focused !== prevSync.focused) {\n setPrevSync({ value, focused });\n if (!focused) setDraft(String(value));\n }\n\n const clamp = useCallback(\n (v: number) => Math.min(max, Math.max(min, v)),\n [min, max],\n );\n\n // Stepping reads the latest committed value through a ref so a held button\n // (setInterval in startRepeat) keeps counting instead of re-adding one step\n // to the value captured at mousedown. useLatest syncs it to the prop in a\n // layout effect (never during render); commitValue advances it in the handler.\n const valueRef = useLatest(value);\n\n // Commit a stepped or blurred value. The draft is updated too: the input\n // shows the draft while focused, and stepping happens while focused (the\n // buttons focus the input), so without this the text never moved and the\n // stale draft was committed back over the new value on blur.\n // `own`: the control settles on a value by itself (a blur with nothing typed falls back to the minimum), which is\n // not the user's change and doesn't mark the form's overlay (Sprint 25.12 A15).\n const commitValue = useCallback((v: number, own = false) => {\n const clamped = clamp(v);\n // Advance the ref now, not on the next render: repeat ticks can land\n // before React re-renders, and each must build on the previous one.\n valueRef.current = clamped;\n setDraft(String(clamped));\n (own ? onChangeProp : onChange)(clamped);\n return clamped;\n }, [onChange, onChangeProp, clamp, valueRef]);\n\n const increment = useCallback(() => commitValue(valueRef.current + step), [commitValue, step, valueRef]);\n const decrement = useCallback(() => commitValue(valueRef.current - step), [commitValue, step, valueRef]);\n\n const startRepeat = useCallback(\n (fn: () => void) => {\n fn();\n timeoutRef.current = setTimeout(() => {\n intervalRef.current = setInterval(fn, 75);\n }, 400);\n },\n [],\n );\n\n const stopRepeat = useCallback(() => {\n clearTimeout(timeoutRef.current);\n clearInterval(intervalRef.current);\n }, []);\n\n const handleInput = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const raw = e.target.value;\n\n if (raw === \"\" || raw === \"-\") {\n setDraft(raw);\n return;\n }\n\n if (!decimals && raw.includes(\".\")) return;\n\n const validPattern = decimals ? /^-?\\d*\\.?\\d*$/ : /^-?\\d*$/;\n if (!validPattern.test(raw)) return;\n\n setDraft(raw);\n\n const parsed = parseFloat(raw);\n if (!isNaN(parsed) && isFinite(parsed)) {\n onChange(clamp(parsed));\n }\n },\n [onChange, clamp, decimals],\n );\n\n const handleBlur = useCallback(() => {\n setFocused(false);\n const parsed = parseFloat(draft);\n if (!isNaN(parsed) && isFinite(parsed)) {\n // nothing typed: a value outside min and max clamped on the way through is the control's own (0.21.0)\n const committed = commitValue(parsed, draft === String(value));\n setDraft(String(committed));\n } else {\n const fallback = isFinite(min) ? min : 0;\n const committed = commitValue(value !== undefined ? value : fallback, true);\n setDraft(String(committed));\n }\n }, [draft, commitValue, min, value]);\n\n const handleFocus = useCallback(() => {\n setFocused(true);\n }, []);\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (e.key === \"ArrowUp\") { e.preventDefault(); increment(); }\n if (e.key === \"ArrowDown\") { e.preventDefault(); decrement(); }\n },\n [increment, decrement],\n );\n\n const s = sizes[size];\n const atMin = value <= min;\n const atMax = value >= max;\n\n return (\n <div\n className={cn(\n \"flex items-center w-full\",\n s.box,\n \"border-[length:var(--ds-border-width)]\",\n error ? \"border-[var(--ds-status-error)]\" : \"border-[var(--ds-input-border)]\",\n \"rounded-[var(--ds-radius-md)]\",\n \"shadow-[var(--ds-input-shadow)]\",\n \"bg-[var(--ds-input-bg)]\",\n \"transition-colors duration-[var(--ds-transition-speed)]\",\n !error && !disabled && \"hover:border-[var(--ds-input-border-hover)]\",\n error ? ERROR_FOCUS_WITHIN_RING : FIELD_FOCUS_WITHIN_RING,\n disabled && \"opacity-disabled cursor-not-allowed\",\n className,\n )}\n >\n <button\n type=\"button\"\n tabIndex={-1}\n disabled={disabled || atMin}\n onMouseDown={(e) => { e.preventDefault(); inputRef.current?.focus(); if (!disabled && !atMin) startRepeat(decrement); }}\n onMouseUp={stopRepeat}\n onMouseLeave={stopRepeat}\n className={cn(\n \"inline-flex items-center justify-center shrink-0\",\n \"border-r-[length:var(--ds-border-width)] border-[var(--ds-border-default)]\",\n \"text-[var(--ds-text-muted)] hover:text-[var(--ds-text-primary)] hover:bg-[var(--ds-bg-muted)]\",\n \"transition-colors cursor-pointer\",\n \"rounded-l-[var(--ds-radius-md)]\",\n // kept out of the Tab order (the field's arrows step it) and never focused by a press: the outline all the same\n // if anything focuses it (Sprint 30)\n FOCUS_RING,\n s.btn, s.input,\n (disabled || atMin) && \"opacity-disabled cursor-not-allowed hover:bg-transparent hover:text-[var(--ds-text-muted)]\",\n )}\n aria-label=\"Decrease\"\n >\n −\n </button>\n\n <div className={cn(\"flex items-center flex-1 min-w-0 px-ds-2 gap-ds-1\", s.input)}>\n {prefix && <span className=\"text-[var(--ds-text-muted)] shrink-0 text-xs\">{prefix}</span>}\n <input\n ref={inputRef}\n id={id}\n type=\"text\"\n inputMode={decimals ? \"decimal\" : \"numeric\"}\n aria-invalid={error || undefined}\n value={focused ? draft : String(value)}\n onChange={handleInput}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onKeyDown={handleKeyDown}\n disabled={disabled}\n placeholder={placeholder}\n className={cn(\n \"w-full min-w-0 bg-transparent text-center outline-none\",\n \"text-[var(--ds-text-primary)]\",\n \"placeholder:text-[var(--ds-text-muted)]\",\n \"font-[family-name:var(--ds-font-mono)]\",\n s.input,\n disabled && \"cursor-not-allowed\",\n )}\n />\n {suffix && <span className=\"text-[var(--ds-text-muted)] shrink-0 text-xs\">{suffix}</span>}\n </div>\n\n <button\n type=\"button\"\n tabIndex={-1}\n disabled={disabled || atMax}\n onMouseDown={(e) => { e.preventDefault(); inputRef.current?.focus(); if (!disabled && !atMax) startRepeat(increment); }}\n onMouseUp={stopRepeat}\n onMouseLeave={stopRepeat}\n className={cn(\n \"inline-flex items-center justify-center shrink-0\",\n \"border-l-[length:var(--ds-border-width)] border-[var(--ds-border-default)]\",\n \"text-[var(--ds-text-muted)] hover:text-[var(--ds-text-primary)] hover:bg-[var(--ds-bg-muted)]\",\n \"transition-colors cursor-pointer\",\n \"rounded-r-[var(--ds-radius-md)]\",\n FOCUS_RING,\n s.btn, s.input,\n (disabled || atMax) && \"opacity-disabled cursor-not-allowed hover:bg-transparent hover:text-[var(--ds-text-muted)]\",\n )}\n aria-label=\"Increase\"\n >\n +\n </button>\n </div>\n );\n}\n","import { useRef, useEffect, type ReactNode, useState, useCallback } from \"react\";\nimport { RowsCtx } from \"../lib/surface-context\";\nimport { createPortal } from \"react-dom\";\nimport { cn, GLASS_DROPDOWN } from \"../lib/utils\";\nimport { Slot } from \"../lib/slot\";\nimport { triggerType } from \"./Button\";\nimport { usePosition, type Side, type Align } from \"../lib/use-position\";\nimport { focusInitial, usePopupFocus, usePressMarks } from \"../lib/focus\";\nimport { useLatest } from \"../lib/use-latest\";\n\ninterface PopoverProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n trigger: ReactNode;\n children: ReactNode;\n side?: Side;\n align?: Align;\n width?: \"trigger\" | \"auto\" | (string & {});\n className?: string;\n container?: Element | DocumentFragment;\n}\n\nexport function Popover({ open, onOpenChange, trigger, children, side = \"bottom\", align = \"center\", width, className, container }: PopoverProps) {\n const triggerRef = useRef<HTMLElement>(null);\n const floatingRef = useRef<HTMLDivElement>(null);\n // Measured in commit-phase code (ref callback, click handler), never read from the ref during render.\n const [triggerWidth, setTriggerWidth] = useState<number | undefined>(undefined);\n const setTriggerNode = useCallback((node: HTMLElement | null) => {\n triggerRef.current = node;\n setTriggerWidth(node?.offsetWidth);\n }, []);\n\n const pos = usePosition(triggerRef, floatingRef, open, { side, align, offset: 8, flip: true });\n // Read from the listeners below, so a new onOpenChange each render never re-registers them (an inner list's Escape\n // listener would then run first, and this popover would see itself on top after the list closed).\n const onOpenChangeRef = useLatest(onOpenChange);\n // A press in a popup the content opens elsewhere in the page (a Dropdown's list) passes through this tree first.\n const { props: pressMarks, marked } = usePressMarks();\n\n // Sprint 25.7: Tab from the panel's last control (or Shift+Tab from its first) closes it and carries on from the\n // trigger; content that closes it (an Apply button) hands focus back through the safety net.\n const { isTop: isTopLayer, returnFocus } = usePopupFocus(open, { trigger: triggerRef, panel: floatingRef, close: () => onOpenChangeRef.current(false), tabExits: \"edges\", marked });\n\n useEffect(() => {\n if (!open) return;\n\n // Bubble phase on document, after the content's own handlers: content that stops or handles Escape (a draft\n // field going back a step, a list inside closing) keeps the popover open. It acts only with focus in it, or\n // nowhere, so an Escape meant for a field elsewhere never closes it.\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key !== \"Escape\" || e.defaultPrevented || !isTopLayer()) return;\n const active = document.activeElement;\n if (active && active !== document.body && !triggerRef.current?.contains(active) && !floatingRef.current?.contains(active)) return;\n e.preventDefault();\n returnFocus();\n onOpenChangeRef.current(false);\n };\n\n // A press outside the popover's React tree closes it, whatever is open inside it (Radix's dismissable layer). A\n // press in a popup opened from it (a Dropdown's list) is inside, so its click lands.\n const onPress = (e: MouseEvent) => {\n const target = e.target as Node;\n if (marked(e) || triggerRef.current?.contains(target) || floatingRef.current?.contains(target)) return;\n onOpenChangeRef.current(false);\n };\n\n document.addEventListener(\"keydown\", onKeyDown);\n document.addEventListener(\"mousedown\", onPress);\n return () => {\n document.removeEventListener(\"keydown\", onKeyDown);\n document.removeEventListener(\"mousedown\", onPress);\n };\n }, [open, onOpenChangeRef, isTopLayer, returnFocus, marked]);\n\n useEffect(() => {\n if (open) focusInitial(floatingRef.current);\n }, [open]);\n\n return (\n <>\n <Slot\n {...triggerType(trigger)}\n ref={setTriggerNode}\n onClick={() => { setTriggerWidth(triggerRef.current?.offsetWidth); onOpenChange(!open); }}\n >\n {trigger}\n </Slot>\n {open && createPortal(\n <div\n ref={floatingRef}\n data-gs=\"popover\"\n {...pressMarks}\n // Clicks inside are the panel's own, not a click on a row or card the trigger sits in.\n onClick={(e) => e.stopPropagation()}\n className={cn(\n \"fixed z-[var(--ds-z-popover)]\",\n \"bg-[var(--ds-bg-surface-elevated)]\",\n GLASS_DROPDOWN,\n \"border-[length:var(--ds-border-width)] border-[var(--ds-border-default)]\",\n \"rounded-[var(--ds-radius-md)]\",\n className\n )}\n style={{\n top: pos.top,\n left: pos.left,\n width: width === \"trigger\" ? triggerWidth : width === \"auto\" ? undefined : width,\n }}\n >\n {/* an overlay's content is no collection's row, wherever it was opened from */}\n <RowsCtx value={false}>{children}</RowsCtx>\n </div>,\n container ?? document.body\n )}\n </>\n );\n}\n","import { useEffect, useRef, useState } from \"react\";\nimport { cn, FOCUS_RING } from \"../lib/utils\";\nimport { Icon } from \"../lib/icons\";\nimport { Dropdown } from \"./Dropdown\";\nimport { Popover } from \"./Popover\";\nimport { NumberInput } from \"./NumberInput\";\nimport { Button } from \"./Button\";\nimport { useShellPreferences } from \"../lib/preferences\";\nimport { useLatest } from \"../lib/use-latest\";\nimport { FormChangeCtx } from \"../lib/form-context\";\nimport { warnOnce } from \"../lib/dev-warn\";\n\ninterface PaginationProps {\n currentPage: number;\n totalPages: number;\n onPageChange: (page: number) => void;\n pageSize?: number;\n pageSizeOptions?: number[];\n onPageSizeChange?: (size: number) => void;\n /**\n * How the list shows more (round 22): page numbers, a Load more button, or loading as the user scrolls (with the\n * button kept for keyboard users). `usePagination` passes the project's dataDisplay.paginationStyle here in\n * `pager.props`, so `<Pagination {...pager.props} />` follows the project's style with nothing written on the page.\n */\n mode?: \"pagination\" | \"load-more\" | \"infinite-scroll\";\n /** Rows left to load (load-more and infinite-scroll). */\n hasMore?: boolean;\n /** Load the next rows (load-more and infinite-scroll). */\n onLoadMore?: () => void;\n /** The Load more button's label (default \"Load more\"). */\n loadMoreLabel?: string;\n className?: string;\n /** Set by `usePagination` in `pager.props`: which list the control belongs to (Sprint 25.13 A3). */\n pagerToken?: object;\n}\n\n/** The controls drawn for each pager: a list given the pager draws one, so a <Pagination> of the page's is a second. */\nconst controlsDrawn = new WeakMap<object, number>();\n\nexport function Pagination(props: PaginationProps) {\n const { pagerToken } = props;\n useEffect(() => {\n if (!pagerToken) return;\n const count = (controlsDrawn.get(pagerToken) ?? 0) + 1;\n controlsDrawn.set(pagerToken, count);\n if (count > 1) warnOnce(\"Pagination\", \"this list's pager already draws its control: a list given the pager (<Table pager={pager}>) draws it beneath the rows, so remove the separate <Pagination {...pager.props} />.\");\n return () => { controlsDrawn.set(pagerToken, (controlsDrawn.get(pagerToken) ?? 1) - 1); };\n }, [pagerToken]);\n if ((props.mode === \"load-more\" || props.mode === \"infinite-scroll\") && props.onLoadMore) return <LoadMore {...props} onLoadMore={props.onLoadMore} scroll={props.mode === \"infinite-scroll\"} />;\n return <PageNumbers {...props} />;\n}\n\n/**\n * The box that scrolls the marker into view: the nearest ancestor that scrolls up and down, else the page (null, the\n * viewport). A list in a fixed-height scroller loads more as that scroller moves (Sprint 25.13 A49: the trigger watched\n * the viewport, so scrolling inside the list never loaded more).\n */\nfunction scrollerOf(el: HTMLElement): HTMLElement | null {\n for (let n = el.parentElement; n && n !== document.body && n !== document.documentElement; n = n.parentElement) {\n const { overflowY } = getComputedStyle(n);\n if ((overflowY === \"auto\" || overflowY === \"scroll\") && n.scrollHeight > n.clientHeight) return n;\n }\n return null;\n}\n\n/**\n * An element's top in content coordinates: where it sits in the page, however far anything is scrolled. The window's\n * scroll is the document element's, so the walk stops below it (the review of 23 September: it was counted twice).\n */\nfunction contentTop(el: HTMLElement): number {\n let top = el.getBoundingClientRect().top + window.scrollY;\n for (let n = el.parentElement; n && n !== document.documentElement; n = n.parentElement) top += n.scrollTop;\n return top;\n}\n\n/**\n * Load more, by button or by scrolling (round 22). The scroll trigger is an observed marker above the button: when it\n * comes within 200 px of view the next rows load, and the observer is renewed after each load so a short list keeps\n * filling the window. It loads again only when the last load moved it — the list grew — or the user has scrolled since:\n * a list shown as a loading skeleton does not grow, and a Team page whose table showed one for half a second loaded\n * all 120 rows before its first row appeared. The button stays for keyboard users and for anyone who stops short.\n */\nfunction LoadMore({ hasMore, onLoadMore, loadMoreLabel, currentPage, scroll, className }: PaginationProps & { onLoadMore: () => void; scroll: boolean }) {\n const marker = useRef<HTMLDivElement>(null);\n const load = useLatest(onLoadMore);\n const loadedAt = useRef<number | null>(null);\n useEffect(() => {\n const el = marker.current;\n if (!scroll || !hasMore || !el || typeof IntersectionObserver === \"undefined\") return;\n const observer = new IntersectionObserver((entries) => {\n if (!entries.some((e) => e.isIntersecting)) return;\n const at = contentTop(el);\n if (loadedAt.current !== null && Math.abs(at - loadedAt.current) < 1) return;\n loadedAt.current = at;\n load.current();\n }, { root: scrollerOf(el), rootMargin: \"200px 0px\" });\n observer.observe(el);\n const rearm = () => { loadedAt.current = null; };\n window.addEventListener(\"scroll\", rearm, { capture: true, passive: true });\n return () => {\n observer.disconnect();\n window.removeEventListener(\"scroll\", rearm, { capture: true });\n };\n }, [scroll, hasMore, currentPage, load]);\n if (!hasMore) return null;\n return (\n <div data-ds-pager=\"\" data-pagination-mode={scroll ? \"infinite-scroll\" : \"load-more\"} className={cn(\"flex flex-col items-center\", className)}>\n {scroll && <div ref={marker} data-load-more-trigger=\"\" aria-hidden=\"true\" className=\"h-px w-full\" />}\n <Button type=\"button\" variant=\"secondary\" onClick={onLoadMore}>{loadMoreLabel ?? \"Load more\"}</Button>\n </div>\n );\n}\n\nfunction PageNumbers({ currentPage, totalPages, onPageChange, pageSize: pageSizeProp, pageSizeOptions, onPageSizeChange, className }: PaginationProps) {\n const pages = buildPageRange(currentPage, totalPages);\n // Sprint 25.6 (B9): dataDisplay.itemsPerPage reaches the selector through the shell; a prop wins. App code pages its\n // list with usePagination, which reads the same value and passes it here in `pager.props` (round 21).\n const preferences = useShellPreferences();\n const pageSize = pageSizeProp ?? preferences.itemsPerPage;\n // A list that fits on one page shows no page numbers (GOV.UK: \"Do not show pagination if there's only one page of\n // content\"; the review of 30 September found \"‹ 1 ›\" under every short list). A size choice stays, so a user who\n // picked a larger size can pick a smaller one again.\n const sizeChoice = !!(pageSizeOptions && pageSize != null && onPageSizeChange);\n if (totalPages <= 1 && !sizeChoice) return null;\n\n return (\n <nav aria-label=\"Pagination\" data-ds-pager=\"\" className={cn(\"flex flex-wrap items-center gap-ds-3\", className)}>\n {sizeChoice && pageSizeOptions && pageSize != null && onPageSizeChange && (\n <div className=\"flex items-center gap-ds-2\">\n <span className=\"text-sm text-[var(--ds-text-muted)] whitespace-nowrap\">Rows per page</span>\n {/* the page size is how the list is viewed: it never marks an overlay's form (0.21.0) */}\n <FormChangeCtx value={null}>\n {/* named by the visible label, then the size chosen (WCAG 4.1.2, 2.5.3) */}\n <Dropdown\n aria-label={`Rows per page, ${pageSize}`}\n options={pageSizeOptions.map((n) => ({ id: String(n), label: String(n) }))}\n value={String(pageSize)}\n onChange={(v) => onPageSizeChange(Number(v))}\n size=\"sm\"\n className=\"w-[4.5rem]\"\n />\n </FormChangeCtx>\n </div>\n )}\n\n {totalPages > 1 && <div className=\"flex items-center gap-ds-1\">\n <button type=\"button\"\n onClick={() => onPageChange(currentPage - 1)}\n disabled={currentPage <= 1}\n aria-label=\"Previous page\"\n className={cn(\n \"inline-flex items-center justify-center h-[var(--ds-control-height-sm)] w-[var(--ds-control-height-sm)] text-sm cursor-pointer\",\n \"rounded-[var(--ds-radius-md)]\",\n \"border-[length:var(--ds-border-width)] border-[var(--ds-border-default)]\",\n \"bg-[var(--ds-bg-surface)] text-[var(--ds-text-secondary)]\",\n \"transition-colors duration-[var(--ds-transition-speed)]\",\n \"hover:bg-[var(--ds-bg-muted)] hover:text-[var(--ds-text-primary)]\",\n \"disabled:opacity-disabled disabled:cursor-not-allowed\",\n FOCUS_RING,\n )}\n >\n <Icon name=\"chevron-right\" size={16} className=\"rotate-180\" />\n </button>\n\n {pages.map((p, i) =>\n p === \"...\" ? (\n <EllipsisJumper key={`ellipsis-${i}`} totalPages={totalPages} onPageChange={onPageChange} />\n ) : (\n <button type=\"button\"\n key={p}\n onClick={() => onPageChange(p as number)}\n aria-current={p === currentPage ? \"page\" : undefined}\n className={cn(\n \"inline-flex items-center justify-center h-[var(--ds-control-height-sm)] w-[var(--ds-control-height-sm)] text-sm font-medium cursor-pointer\",\n \"rounded-[var(--ds-radius-md)]\",\n \"border-[length:var(--ds-border-width)]\",\n \"transition-colors duration-[var(--ds-transition-speed)]\",\n FOCUS_RING,\n p === currentPage\n ? \"bg-[var(--ds-accent-primary)] [background-image:var(--ds-gradient)] text-[var(--ds-text-on-primary)] border-[var(--ds-accent-primary)]\"\n : \"bg-[var(--ds-bg-surface)] text-[var(--ds-text-secondary)] border-[var(--ds-border-default)] hover:bg-[var(--ds-bg-muted)] hover:text-[var(--ds-text-primary)]\"\n )}\n >\n {p}\n </button>\n )\n )}\n\n <button type=\"button\"\n onClick={() => onPageChange(currentPage + 1)}\n disabled={currentPage >= totalPages}\n aria-label=\"Next page\"\n className={cn(\n \"inline-flex items-center justify-center h-[var(--ds-control-height-sm)] w-[var(--ds-control-height-sm)] text-sm cursor-pointer\",\n \"rounded-[var(--ds-radius-md)]\",\n \"border-[length:var(--ds-border-width)] border-[var(--ds-border-default)]\",\n \"bg-[var(--ds-bg-surface)] text-[var(--ds-text-secondary)]\",\n \"transition-colors duration-[var(--ds-transition-speed)]\",\n \"hover:bg-[var(--ds-bg-muted)] hover:text-[var(--ds-text-primary)]\",\n \"disabled:opacity-disabled disabled:cursor-not-allowed\",\n FOCUS_RING,\n )}\n >\n <Icon name=\"chevron-right\" size={16} />\n </button>\n </div>}\n </nav>\n );\n}\n\nfunction buildPageRange(current: number, total: number): (number | \"...\")[] {\n if (total <= 7) return Array.from({ length: total }, (_, i) => i + 1);\n\n const pages: (number | \"...\")[] = [1];\n\n if (current > 3) pages.push(\"...\");\n\n const start = Math.max(2, current - 1);\n const end = Math.min(total - 1, current + 1);\n for (let i = start; i <= end; i++) pages.push(i);\n\n if (current < total - 2) pages.push(\"...\");\n\n pages.push(total);\n return pages;\n}\n\nfunction EllipsisJumper({ totalPages, onPageChange }: { totalPages: number; onPageChange: (page: number) => void }) {\n const [open, setOpen] = useState(false);\n const [jumpPage, setJumpPage] = useState(1);\n\n const handleOpenChange = (next: boolean) => {\n if (next) setJumpPage(1);\n setOpen(next);\n };\n\n const handleGo = () => {\n const clamped = Math.min(totalPages, Math.max(1, jumpPage));\n onPageChange(clamped);\n setOpen(false);\n };\n\n return (\n <Popover\n open={open}\n onOpenChange={handleOpenChange}\n trigger={\n <button\n type=\"button\"\n aria-label=\"Go to page\"\n onClick={() => handleOpenChange(true)}\n className={cn(\n \"inline-flex items-center justify-center h-[var(--ds-control-height-sm)] w-[var(--ds-control-height-sm)] text-sm cursor-pointer\",\n \"rounded-[var(--ds-radius-md)]\",\n \"text-[var(--ds-text-muted)]\",\n \"transition-colors duration-[var(--ds-transition-speed)]\",\n \"hover:bg-[var(--ds-bg-muted)] hover:text-[var(--ds-text-primary)]\",\n FOCUS_RING,\n )}\n >\n …\n </button>\n }\n >\n <div className=\"flex flex-col gap-ds-2 p-ds-3\">\n <label className=\"text-xs font-medium text-[var(--ds-text-secondary)]\">Go to page</label>\n <div className=\"flex items-center gap-ds-2\">\n <NumberInput\n value={jumpPage}\n onChange={setJumpPage}\n min={1}\n max={totalPages}\n step={1}\n size=\"sm\"\n className=\"w-[5rem]\"\n />\n <button\n type=\"button\"\n onClick={handleGo}\n className={cn(\n \"px-ds-2.5 h-[var(--ds-control-height-sm)] text-xs font-medium cursor-pointer\",\n \"rounded-[var(--ds-radius-md)]\",\n \"bg-[var(--ds-accent-primary)] text-[var(--ds-text-on-primary)]\",\n \"transition-colors duration-[var(--ds-transition-speed)]\",\n \"hover:opacity-90\",\n FOCUS_RING,\n )}\n >\n Go\n </button>\n </div>\n </div>\n </Popover>\n );\n}\n","import { useEffect, useState } from \"react\";\nimport { warnOnce } from \"./dev-warn\";\nimport { PREFERENCE_HOUSE_DEFAULTS, useShellPreferences, type PreferencePaginationStyle } from \"./preferences\";\n\n/**\n * A long list in one hook (round 21; all three list styles since round 22). The page size and the list style are the\n * project's `dataDisplay.itemsPerPage` and `dataDisplay.paginationStyle`, read from the shell, so a mid-build\n * `update_rule` on either reaches every list with no page edited. The page gets what to show, the props for\n * `<Pagination>` — page numbers, a Load more button or loading on scroll, whichever the project's style is — and the\n * numbers the count line needs (\"Showing 51–100 of 200 events\", or \"Showing 40 of 120 members\" while a list grows).\n *\n * Run 58 hand-wrote the paging; runs 59 and 60 hand-wrote load-more and scroll loading — an IntersectionObserver, a\n * visible count and a page size copied in as a constant, twice in one app — because the library had no way to.\n *\n * const rows = events.map(toRow)\n * const pager = usePagination(rows)\n * <TableToolbar resultCount={rows.length} resultNoun={[\"event\", \"events\"]} pagination={pager} />\n * <Table columns={columns} data={rows} pager={pager} />\n *\n * The list takes the whole pager (Sprint 25.13 A3): Table, DataGrid, StackedList, Timeline and VirtualizedList draw the\n * pager's part of every row and its control beneath, and a sortable Table sorts every row, not one page. For anything\n * else, draw the page's items and the control yourself: `pager.items.map(…)` then `<Pagination {...pager.props} />`.\n *\n * A long page that must mount only the rows on screen (logs, a feed) still pages: the size the user asked for goes to\n * the hook, with its override note, and the list mounts only what is on screen of each page (A49):\n *\n * // @gridsmith-override dataDisplay.itemsPerPage: <the user's words>\n * const pager = usePagination(entries, { pageSize: 100 })\n * <VirtualizedList items={entries} pager={pager} estimateSize={() => 40} renderItem={(entry) => <LogLine entry={entry} />} />\n */\nexport interface Pager<T> {\n /** The list style this list follows: the project's, unless `style` was passed. */\n style: PreferencePaginationStyle;\n /** What to show: the current page's rows, or every row loaded so far on a list that grows. */\n items: T[];\n /** The current page, from 1; on a growing list, how many pages are loaded. */\n page: number;\n pageSize: number;\n totalItems: number;\n totalPages: number;\n /** The first and last row numbers on screen, from 1 (\"Showing 51–100\"); [0, 0] for an empty list. */\n range: [number, number];\n /** How many rows are on screen. */\n shown: number;\n /** Rows left to show: a next page, or more to load. */\n hasMore: boolean;\n /** The next page, or the next `pageSize` rows on a growing list. */\n loadMore: () => void;\n setPage: (page: number) => void;\n /** A page-size selector's choice; it wins over the project's page size and starts again at page 1. */\n setPageSize: (size: number) => void;\n /**\n * Spread onto <Pagination>: it renders page numbers, a Load more button or the scroll trigger, as `style` says. A list\n * given the whole pager (`<Table pager={pager}>`, Sprint 25.13 A3) draws this control itself.\n */\n props: {\n currentPage: number; totalPages: number; onPageChange: (page: number) => void; pageSize: number; onPageSizeChange: (size: number) => void;\n mode: PreferencePaginationStyle; hasMore: boolean; onLoadMore: () => void;\n /** The page sizes the user may choose between, when the page offers the choice (`pageSizeOptions` below). */\n pageSizeOptions?: number[];\n /** Which pager the control belongs to, so a second control for the same list is caught in development (A3). */\n pagerToken: object;\n };\n}\n\nexport interface PaginationOptions {\n /** A fixed page size for this list, over the project's. Leave it out: the project's page size is the rule. */\n pageSize?: number;\n /** Values that start the list again at page 1 when they change — the sort column and direction, a search query. */\n resetOn?: unknown;\n /**\n * A list style for this list only, over the project's. Leave it out: the project's style is the rule. Passing one that\n * differs is overriding a rule in force — ask the user first, and put `// @gridsmith-override\n * dataDisplay.paginationStyle: <their reason>` above the call.\n */\n style?: PreferencePaginationStyle;\n /**\n * The page sizes the user may choose between, beside the page numbers (`[10, 25, 50]`). The choice goes with the\n * control, so a list given the pager (A3) offers it too. Leave it out for the project's page size alone.\n */\n pageSizeOptions?: number[];\n}\n\n/** What identifies a list's first item across renders: its id, or the value itself; objects without an id are not compared. */\nfunction firstKey(item: unknown): unknown {\n if (item !== null && typeof item === \"object\") return \"id\" in item ? (item as { id: unknown }).id : undefined;\n return item;\n}\n\nfunction resetKey(resetOn: unknown): string {\n try { return JSON.stringify(resetOn ?? null); } catch { return String(resetOn); }\n}\n\nfunction signature(list: readonly unknown[], resetOn: unknown): string {\n let first = \"\";\n try { first = JSON.stringify(firstKey(list[0]) ?? null); } catch { first = \"\"; }\n return `${list.length}|${first}|${resetKey(resetOn)}`;\n}\n\n/** What a list was when last seen: whether a new one is the same list with items added at either end. */\ninterface Seen { sig: string; length: number; first: unknown; reset: string }\n\n/**\n * The same list with items added at its start or its end, and the caller's resetOn unchanged: a live log's new entry,\n * a feed's newest. Its first item, which has an id or is a value, is still first, or has moved down by what was added.\n */\nfunction grewAtAnEnd(seen: Seen, list: readonly unknown[], reset: string): boolean {\n if (reset !== seen.reset || list.length <= seen.length || seen.first === undefined || seen.length === 0) return false;\n return firstKey(list[0]) === seen.first || firstKey(list[list.length - seen.length]) === seen.first;\n}\n\n/**\n * Pages a list in the project's list style (pagination, load more or infinite scroll) and page size, both from the\n * shell. It returns the pager: the rows to show now (`items`), the page and the counts, and the control's state, which a\n * Table, DataGrid, StackedList, Timeline or VirtualizedList takes as its `pager` prop to draw the rows and the control.\n * `resetOn` starts the list again at page 1 when its value changes (a sort, a search); `pageSize` and `style` set this\n * list apart from the project's.\n */\nexport function usePagination<T>(list: readonly T[], options: PaginationOptions = {}): Pager<T> {\n const shell = useShellPreferences();\n const style: PreferencePaginationStyle = options.style ?? shell.paginationStyle ?? PREFERENCE_HOUSE_DEFAULTS.paginationStyle;\n const [chosenSize, setChosenSize] = useState<number | null>(null);\n const [pagerToken] = useState(() => ({}));\n const pageSize = Math.max(1, Math.floor(chosenSize ?? options.pageSize ?? shell.itemsPerPage ?? PREFERENCE_HOUSE_DEFAULTS.itemsPerPage));\n const [page, setPageState] = useState(1);\n\n // A different list — filtered, searched, sorted another way — starts again at page 1: its length, its first item's\n // id or the caller's resetOn values changed. The same list with items added at an end keeps its page, and a growing\n // list its depth (the review of 30 September: a live log's new entry collapsed a list grown to 200 back to 100).\n // Adjusted during render, so the stale page never paints.\n const sig = signature(list, options.resetOn);\n const reset = resetKey(options.resetOn);\n const [seen, setSeen] = useState<Seen>(() => ({ sig, length: list.length, first: firstKey(list[0]), reset }));\n const changed = seen.sig !== sig;\n const startsAgain = changed && !grewAtAnEnd(seen, list, reset);\n if (changed) {\n setSeen({ sig, length: list.length, first: firstKey(list[0]), reset });\n if (startsAgain && page !== 1) setPageState(1);\n }\n\n const totalItems = list.length;\n const totalPages = Math.max(1, Math.ceil(totalItems / pageSize));\n const current = Math.min(Math.max(1, startsAgain ? 1 : page), totalPages);\n const grows = style !== \"pagination\";\n // page numbers show one page; a growing list shows every page loaded so far\n const start = grows ? 0 : (current - 1) * pageSize;\n const items = list.slice(start, current * pageSize);\n const range: [number, number] = items.length === 0 ? [0, 0] : [start + 1, start + items.length];\n const hasMore = current < totalPages;\n const setPage = (next: number) => setPageState(Math.min(Math.max(1, Math.floor(next)), totalPages));\n const loadMore = () => setPageState((p) => Math.min(p + 1, totalPages));\n const setPageSize = (size: number) => { setChosenSize(Math.max(1, Math.floor(size))); setPageState(1); };\n\n return {\n style, items, page: current, pageSize, totalItems, totalPages, range, shown: items.length, hasMore, loadMore, setPage, setPageSize,\n props: { currentPage: current, totalPages, onPageChange: setPage, pageSize, onPageSizeChange: setPageSize, mode: style, hasMore, onLoadMore: loadMore, pagerToken, ...(options.pageSizeOptions ? { pageSizeOptions: options.pageSizeOptions } : {}) },\n };\n}\n\n/**\n * The part of a whole list a pager shows (Sprint 25.13 A3): its page, or every page loaded so far on a list that grows.\n * A list given the pager draws this, then the pager's control.\n */\nexport function pagerPart<T>(list: readonly T[], pager?: Pager<unknown>): T[] {\n if (!pager) return list as T[];\n return pager.range[0] === 0 ? [] : list.slice(pager.range[0] - 1, pager.range[1]);\n}\n\n/** In development, a list handed one page with the pager: it needs every item, since it draws the pager's part itself. */\nexport function useWholeListCheck(component: string, length: number, pager?: Pager<unknown>): void {\n const total = pager?.totalItems;\n useEffect(() => {\n // the same items, either way: more than the pager counts leave the last ones where no page reaches them (the review\n // of 30 September)\n if (total !== undefined && length !== total) warnOnce(component, `the pager counts ${total} items but the list holds ${length}: give the list and usePagination the same items, every item of the list, and the list draws the pager's part (Sprint 25.13 A3).`);\n }, [component, length, total]);\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../showcase/src/lib/use-position.ts"],"names":[],"mappings":"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","file":"chunk-HP7WUZPK.js","sourcesContent":["import { useState, useCallback, useLayoutEffect, useRef, type RefObject } from \"react\";\n\nexport type Side = \"top\" | \"right\" | \"bottom\" | \"left\";\nexport type Align = \"start\" | \"center\" | \"end\";\n\ninterface PositionOptions {\n side?: Side;\n align?: Align;\n offset?: number;\n flip?: boolean;\n}\n\ninterface PositionResult {\n top: number;\n left: number;\n placement: Side;\n}\n\nconst VIEWPORT_PADDING = 8;\n\nexport function usePosition(\n triggerRef: RefObject<HTMLElement | null>,\n floatingRef: RefObject<HTMLElement | null>,\n open: boolean,\n options: PositionOptions = {}\n): PositionResult {\n const { side = \"bottom\", align = \"center\", offset = 8, flip = true } = options;\n const [pos, setPos] = useState<PositionResult>({ top: 0, left: 0, placement: side });\n const rafId = useRef(0);\n\n const compute = useCallback(() => {\n const trigger = triggerRef.current;\n const floating = floatingRef.current;\n if (!trigger || !floating) return;\n\n const tRect = trigger.getBoundingClientRect();\n const fRect = floating.getBoundingClientRect();\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n\n let placement = side;\n\n if (flip) {\n if (placement === \"bottom\" && tRect.bottom + offset + fRect.height > vh - VIEWPORT_PADDING && tRect.top - offset - fRect.height > VIEWPORT_PADDING) {\n placement = \"top\";\n } else if (placement === \"top\" && tRect.top - offset - fRect.height < VIEWPORT_PADDING && tRect.bottom + offset + fRect.height < vh - VIEWPORT_PADDING) {\n placement = \"bottom\";\n } else if (placement === \"right\" && tRect.right + offset + fRect.width > vw - VIEWPORT_PADDING && tRect.left - offset - fRect.width > VIEWPORT_PADDING) {\n placement = \"left\";\n } else if (placement === \"left\" && tRect.left - offset - fRect.width < VIEWPORT_PADDING && tRect.right + offset + fRect.width < vw - VIEWPORT_PADDING) {\n placement = \"right\";\n }\n }\n\n let top: number;\n let left: number;\n\n if (placement === \"bottom\" || placement === \"top\") {\n top = placement === \"bottom\" ? tRect.bottom + offset : tRect.top - fRect.height - offset;\n\n switch (align) {\n case \"start\":\n left = tRect.left;\n break;\n case \"end\":\n left = tRect.right - fRect.width;\n break;\n default:\n left = tRect.left + (tRect.width - fRect.width) / 2;\n }\n } else {\n left = placement === \"right\" ? tRect.right + offset : tRect.left - fRect.width - offset;\n\n switch (align) {\n case \"start\":\n top = tRect.top;\n break;\n case \"end\":\n top = tRect.bottom - fRect.height;\n break;\n default:\n top = tRect.top + (tRect.height - fRect.height) / 2;\n }\n }\n\n left = Math.max(VIEWPORT_PADDING, Math.min(left, vw - fRect.width - VIEWPORT_PADDING));\n top = Math.max(VIEWPORT_PADDING, Math.min(top, vh - fRect.height - VIEWPORT_PADDING));\n\n // the same place is no change: a scroll anywhere on the page, the popup's own list included, re-renders nothing (the\n // 25.17 second review: every scroll re-rendered an open list)\n setPos((cur) => (cur.top === top && cur.left === left && cur.placement === placement ? cur : { top, left, placement }));\n }, [triggerRef, floatingRef, side, align, offset, flip]);\n\n useLayoutEffect(() => {\n if (!open) return;\n\n compute();\n\n const onUpdate = () => {\n cancelAnimationFrame(rafId.current);\n rafId.current = requestAnimationFrame(compute);\n };\n\n window.addEventListener(\"scroll\", onUpdate, true);\n window.addEventListener(\"resize\", onUpdate);\n\n return () => {\n cancelAnimationFrame(rafId.current);\n window.removeEventListener(\"scroll\", onUpdate, true);\n window.removeEventListener(\"resize\", onUpdate);\n };\n }, [open, compute]);\n\n return pos;\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../showcase/src/lib/utils.ts"],"names":[],"mappings":";;;;;AAGO,SAAS,MAAM,MAAA,EAA8B;AAClD,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC7B;AAEO,IAAM,cAAA,GAAiB;AAEvB,IAAM,aAAA,GAAgB,GAAG,cAAc,CAAA,qDAAA;AAEvC,IAAM,aAAA,GAAgB,GAAG,cAAc,CAAA,sDAAA;AAavC,IAAM,eAAA,GAAkB;AAExB,IAAM,cAAA,GAAiB,GAAG,cAAc,CAAA,yDAAA;AAWxC,IAAM,UAAA,GAAa;AAgBnB,IAAM,eAAA,GAAkB;AAExB,IAAM,gBAAA,GAAmB;AAUzB,IAAM,WAAA,GAAc;AAOpB,IAAM,UAAA,GAAa;AAGnB,IAAM,mBAAmB,CAAC,MAAA,KAAmB,CAAA,IAAA,EAAO,MAAM,KAAK,UAAU,CAAA,GAAA;AAgBzE,IAAM,gBAAA,GAAmB;AAEzB,IAAM,uBAAA,GAA0B;AAEhC,IAAM,oBAAA,GAAuB;AAG7B,IAAM,gBAAA,GAAmB;AAEzB,IAAM,uBAAA,GAA0B;AAEhC,IAAM,oBAAA,GAAuB;AAK7B,IAAM,WAAA,GAAc;AAEpB,IAAM,iBAAA,GAAoB;AAMjC,IAAI,eAAA,GAAkB,CAAA;AACtB,IAAI,0BAAA,GAA6B,EAAA;AAE1B,SAAS,cAAA,GAAiB;AAC/B,EAAA,IAAI,oBAAoB,CAAA,EAAG;AACzB,IAAA,0BAAA,GAA6B,QAAA,CAAS,KAAK,KAAA,CAAM,QAAA;AACjD,IAAA,QAAA,CAAS,IAAA,CAAK,MAAM,QAAA,GAAW,QAAA;AAAA,EACjC;AACA,EAAA,eAAA,EAAA;AACF;AAEO,SAAS,gBAAA,GAAmB;AACjC,EAAA,IAAI,oBAAoB,CAAA,EAAG;AAC3B,EAAA,eAAA,EAAA;AACA,EAAA,IAAI,oBAAoB,CAAA,EAAG;AACzB,IAAA,QAAA,CAAS,IAAA,CAAK,MAAM,QAAA,GAAW,0BAAA;AAC/B,IAAA,0BAAA,GAA6B,EAAA;AAAA,EAC/B;AACF","file":"chunk-JTU7OBYJ.js","sourcesContent":["import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs));\n}\n\nexport const GLASS_BACKDROP = \"[backdrop-filter:var(--ds-glass-filter)] [-webkit-backdrop-filter:var(--ds-glass-filter)]\";\n\nexport const GLASS_SURFACE = `${GLASS_BACKDROP} shadow-[var(--ds-shadow-card),var(--ds-glass-inset)]`;\n\nexport const GLASS_OVERLAY = `${GLASS_BACKDROP} shadow-[var(--ds-shadow-modal),var(--ds-glass-inset)]`;\n\n/**\n * A modal surface (Dialog, Drawer, Sheet, CommandPalette, GlobalSearch): the theme's surface, never less than 85% opaque.\n * A glass theme's surface is see-through by design, which suits a card on the canvas; over an overlay's scrim the same\n * glass reads as grey mud, and the page shows through (round 27, R27-17, the owner picked 85% from a mock-up). An opaque\n * theme keeps its surface as it is: the alpha only rises, through CSS relative colour, in every mode and scope.\n *\n * The theme's surface comes first, for a browser without relative colour (Chrome before 119, Firefox before 128,\n * Safari before 16.4): a value holding var() is only found invalid once computed, which drops the background to\n * transparent rather than to an earlier declaration, so the raised one applies only where @supports says it can (the\n * round 27 review). A surface with no colour at all (fully transparent) stays so: raising it would paint it black.\n */\nexport const OVERLAY_SURFACE = \"bg-[var(--ds-bg-surface)] supports-[color:oklch(from_red_l_c_h)]:bg-[oklch(from_var(--ds-bg-surface)_l_c_h_/_max(alpha,min(1,alpha*1000)*0.85))]\";\n\nexport const GLASS_DROPDOWN = `${GLASS_BACKDROP} shadow-[var(--ds-shadow-dropdown),var(--ds-glass-inset)]`;\n\n// Keyboard focus (Sprint 30, the owner's D1 and D6): where Tab has landed. A solid outline in the theme's focus colour\n// (--ds-focus, derived to 3:1 on every ground), 2 px, with a 2 px gap between it and the element. The gap shows what the\n// element sits on, so one colour reads beside any fill, and while the outline shows, the element's own shadow steps\n// aside (D7, P12): shadow-none drops its --tw-shadow and keeps any ring. Every part is prefixed: an unprefixed\n// outline-solid draws an outline at rest. And outline-solid is required: in Tailwind 4, outline-none (which many\n// components set at rest) sets --tw-outline-style: none, which outline-2 reads, so without it no outline draws. These\n// draw no border (a button that uses one, the Launcher, gets the outline alone); a field takes FIELD_FOCUS_RING. `cn()`\n// keeps only the last of outline-none and outline-solid in one variant, so a component's own focus-visible:outline-none\n// after a utility would remove the outline: none may follow one.\nexport const FOCUS_RING = \"focus-visible:outline-2 focus-visible:outline-solid focus-visible:outline-offset-2 focus-visible:outline-[var(--ds-focus)] focus-visible:shadow-none\";\n\n/**\n * On a wrapper that shows focus for a control inside it: HAS_FOCUS_RING, from the keyboard only (`:has(:focus-visible)`).\n * FOCUS_WITHIN_RING shows it on any focus inside, a click's too, since `:focus-within` has no keyboard-only form: kept\n * for code that uses it, and a new wrapper takes HAS_FOCUS_RING (D6: keyboard focus shows only from the keyboard).\n */\nexport const FOCUS_WITHIN_RING = \"focus-within:outline-2 focus-within:outline-solid focus-within:outline-offset-2 focus-within:outline-[var(--ds-focus)] focus-within:shadow-none\";\n\nexport const HAS_FOCUS_RING = \"has-[:focus-visible]:outline-2 has-[:focus-visible]:outline-solid has-[:focus-visible]:outline-offset-2 has-[:focus-visible]:outline-[var(--ds-focus)] has-[:focus-visible]:shadow-none\";\n\n/**\n * The outline on a drawn child, where the element that takes focus is hidden or wraps it: a checkbox's box beside its\n * input (`peer`), a radio's circle inside its button, a separator's grip, a Gantt milestone's diamond (`group`). The\n * same outline, gap and shadow rule.\n */\nexport const PEER_FOCUS_RING = \"peer-focus-visible:outline-2 peer-focus-visible:outline-solid peer-focus-visible:outline-offset-2 peer-focus-visible:outline-[var(--ds-focus)] peer-focus-visible:shadow-none\";\n\nexport const GROUP_FOCUS_RING = \"group-focus-visible:outline-2 group-focus-visible:outline-solid group-focus-visible:outline-offset-2 group-focus-visible:outline-[var(--ds-focus)] group-focus-visible:shadow-none\";\n\n/**\n * The same outline drawn inside the element's edge, for edge-to-edge rows, cells and scroll regions only (the plan's\n * P3): elements that are never filled solid, since inside the edge there is no gap to keep one colour readable on a fill.\n * It sits `--ds-focus-inset` in: 5 px, deeper where the theme's corners are rounder, so it clears a table's rounded\n * corners (D8, the owner's decision A); what such an element holds keeps 1 px more clear of its edge. Anywhere else the\n * outline stays outside, with room made for it. Moved here from use-keyboard-scroll.ts (Sprint 30) so the server-safe\n * `gridsmith-ui/utils` can export it.\n */\nexport const FOCUS_INSET = \"focus-visible:outline-2 focus-visible:outline-solid focus-visible:-outline-offset-[var(--ds-focus-inset)] focus-visible:outline-[var(--ds-focus)]\";\n\n/**\n * The room FOCUS_RING's outline takes outside its element, in px: its 2 px gap and 2 px line (Sprint 30, P3). Where a\n * container clips, what sits beside its edge keeps this much clear of it: a fixed size, never a theme space. Internal,\n * as is the one below (exports/utils.ts exports by name).\n */\nexport const FOCUS_ROOM = 4;\n\n/** A theme's length that sets how far something sits from a clipping edge, never under FOCUS_ROOM (Sprint 25.27). */\nexport const atLeastFocusRoom = (length: string) => `max(${length}, ${FOCUS_ROOM}px)`;\n\n/**\n * A field (D6, P4, P13). Reached with Tab: the keyboard's outline, and its border in the focus colour, as GOV.UK turns a\n * focused input's border: it is where you type. Clicked into: the active look instead, the accent border and its soft\n * halo (`ring-2` in --ds-ring-active, laid over the field's own shadow), and no outline. A browser matches :focus-visible\n * on a text field either way, so lib/input-modality.ts notes on <html> whether a pointer moved focus last; with no note\n * yet, the outline. The field keeps its own (inset) shadow in both: no shadow-none here.\n *\n * The wrapper forms (_WITHIN_ and _HAS_, for a box round the part you type in) show it while that part has focus, and\n * not while a control of the field's own does: a button, a select, a link, a checkbox, a radio or a switch inside it (a\n * tag's remove, a picker's chevron, a composer's Send, an editor's toolbar or a task's checkbox), or anything in a popup\n * inside the box (a dialog of its own; a field that is itself in a dialog still shows it). That control shows its own outline, so there is one focus point, never\n * two (P11). _WITHIN_ reads :focus, as a click on a date's segment isn't :focus-visible; _HAS_ reads :focus-visible.\n * Either outranks the field's hover border, so hovering keeps the look.\n */\nexport const FIELD_FOCUS_RING = \"focus-visible:outline-2 focus-visible:outline-solid focus-visible:outline-offset-2 focus-visible:outline-[var(--ds-focus)] focus-visible:border-[var(--ds-focus)] [[data-input-modality=pointer]_&]:focus-visible:outline-none [[data-input-modality=pointer]_&]:focus-visible:border-[var(--ds-accent-ink)] [[data-input-modality=pointer]_&]:focus-visible:ring-2 [[data-input-modality=pointer]_&]:focus-visible:ring-[var(--ds-ring-active)]\";\n\nexport const FIELD_FOCUS_WITHIN_RING = \"has-[:focus:not(button,select,a,[role=button],input[type=checkbox],input[type=radio],[role=checkbox],[role=radio],[role=switch])]:[&:not(:has([role=dialog]_:focus))]:outline-2 has-[:focus:not(button,select,a,[role=button],input[type=checkbox],input[type=radio],[role=checkbox],[role=radio],[role=switch])]:[&:not(:has([role=dialog]_:focus))]:outline-solid has-[:focus:not(button,select,a,[role=button],input[type=checkbox],input[type=radio],[role=checkbox],[role=radio],[role=switch])]:[&:not(:has([role=dialog]_:focus))]:outline-offset-2 has-[:focus:not(button,select,a,[role=button],input[type=checkbox],input[type=radio],[role=checkbox],[role=radio],[role=switch])]:[&:not(:has([role=dialog]_:focus))]:outline-[var(--ds-focus)] has-[:focus:not(button,select,a,[role=button],input[type=checkbox],input[type=radio],[role=checkbox],[role=radio],[role=switch])]:[&:not(:has([role=dialog]_:focus))]:border-[var(--ds-focus)] [[data-input-modality=pointer]_&]:has-[:focus:not(button,select,a,[role=button],input[type=checkbox],input[type=radio],[role=checkbox],[role=radio],[role=switch])]:[&:not(:has([role=dialog]_:focus))]:outline-none [[data-input-modality=pointer]_&]:has-[:focus:not(button,select,a,[role=button],input[type=checkbox],input[type=radio],[role=checkbox],[role=radio],[role=switch])]:[&:not(:has([role=dialog]_:focus))]:border-[var(--ds-accent-ink)] [[data-input-modality=pointer]_&]:has-[:focus:not(button,select,a,[role=button],input[type=checkbox],input[type=radio],[role=checkbox],[role=radio],[role=switch])]:[&:not(:has([role=dialog]_:focus))]:ring-2 [[data-input-modality=pointer]_&]:has-[:focus:not(button,select,a,[role=button],input[type=checkbox],input[type=radio],[role=checkbox],[role=radio],[role=switch])]:[&:not(:has([role=dialog]_:focus))]:ring-[var(--ds-ring-active)]\";\n\nexport const FIELD_HAS_FOCUS_RING = \"has-[:focus-visible:not(button,select,a,[role=button],input[type=checkbox],input[type=radio],[role=checkbox],[role=radio],[role=switch])]:[&:not(:has([role=dialog]_:focus-visible))]:outline-2 has-[:focus-visible:not(button,select,a,[role=button],input[type=checkbox],input[type=radio],[role=checkbox],[role=radio],[role=switch])]:[&:not(:has([role=dialog]_:focus-visible))]:outline-solid has-[:focus-visible:not(button,select,a,[role=button],input[type=checkbox],input[type=radio],[role=checkbox],[role=radio],[role=switch])]:[&:not(:has([role=dialog]_:focus-visible))]:outline-offset-2 has-[:focus-visible:not(button,select,a,[role=button],input[type=checkbox],input[type=radio],[role=checkbox],[role=radio],[role=switch])]:[&:not(:has([role=dialog]_:focus-visible))]:outline-[var(--ds-focus)] has-[:focus-visible:not(button,select,a,[role=button],input[type=checkbox],input[type=radio],[role=checkbox],[role=radio],[role=switch])]:[&:not(:has([role=dialog]_:focus-visible))]:border-[var(--ds-focus)] [[data-input-modality=pointer]_&]:has-[:focus-visible:not(button,select,a,[role=button],input[type=checkbox],input[type=radio],[role=checkbox],[role=radio],[role=switch])]:[&:not(:has([role=dialog]_:focus-visible))]:outline-none [[data-input-modality=pointer]_&]:has-[:focus-visible:not(button,select,a,[role=button],input[type=checkbox],input[type=radio],[role=checkbox],[role=radio],[role=switch])]:[&:not(:has([role=dialog]_:focus-visible))]:border-[var(--ds-accent-ink)] [[data-input-modality=pointer]_&]:has-[:focus-visible:not(button,select,a,[role=button],input[type=checkbox],input[type=radio],[role=checkbox],[role=radio],[role=switch])]:[&:not(:has([role=dialog]_:focus-visible))]:ring-2 [[data-input-modality=pointer]_&]:has-[:focus-visible:not(button,select,a,[role=button],input[type=checkbox],input[type=radio],[role=checkbox],[role=radio],[role=switch])]:[&:not(:has([role=dialog]_:focus-visible))]:ring-[var(--ds-ring-active)]\";\n\n// A field with an error: the same, its red border kept, and the red halo when clicked into.\nexport const ERROR_FOCUS_RING = \"focus-visible:outline-2 focus-visible:outline-solid focus-visible:outline-offset-2 focus-visible:outline-[var(--ds-focus)] focus-visible:border-[var(--ds-status-error)] [[data-input-modality=pointer]_&]:focus-visible:outline-none [[data-input-modality=pointer]_&]:focus-visible:ring-2 [[data-input-modality=pointer]_&]:focus-visible:ring-[var(--ds-ring-error)]\";\n\nexport const ERROR_FOCUS_WITHIN_RING = \"has-[:focus:not(button,select,a,[role=button],input[type=checkbox],input[type=radio],[role=checkbox],[role=radio],[role=switch])]:[&:not(:has([role=dialog]_:focus))]:outline-2 has-[:focus:not(button,select,a,[role=button],input[type=checkbox],input[type=radio],[role=checkbox],[role=radio],[role=switch])]:[&:not(:has([role=dialog]_:focus))]:outline-solid has-[:focus:not(button,select,a,[role=button],input[type=checkbox],input[type=radio],[role=checkbox],[role=radio],[role=switch])]:[&:not(:has([role=dialog]_:focus))]:outline-offset-2 has-[:focus:not(button,select,a,[role=button],input[type=checkbox],input[type=radio],[role=checkbox],[role=radio],[role=switch])]:[&:not(:has([role=dialog]_:focus))]:outline-[var(--ds-focus)] has-[:focus:not(button,select,a,[role=button],input[type=checkbox],input[type=radio],[role=checkbox],[role=radio],[role=switch])]:[&:not(:has([role=dialog]_:focus))]:border-[var(--ds-status-error)] [[data-input-modality=pointer]_&]:has-[:focus:not(button,select,a,[role=button],input[type=checkbox],input[type=radio],[role=checkbox],[role=radio],[role=switch])]:[&:not(:has([role=dialog]_:focus))]:outline-none [[data-input-modality=pointer]_&]:has-[:focus:not(button,select,a,[role=button],input[type=checkbox],input[type=radio],[role=checkbox],[role=radio],[role=switch])]:[&:not(:has([role=dialog]_:focus))]:ring-2 [[data-input-modality=pointer]_&]:has-[:focus:not(button,select,a,[role=button],input[type=checkbox],input[type=radio],[role=checkbox],[role=radio],[role=switch])]:[&:not(:has([role=dialog]_:focus))]:ring-[var(--ds-ring-error)]\";\n\nexport const ERROR_HAS_FOCUS_RING = \"has-[:focus-visible:not(button,select,a,[role=button],input[type=checkbox],input[type=radio],[role=checkbox],[role=radio],[role=switch])]:[&:not(:has([role=dialog]_:focus-visible))]:outline-2 has-[:focus-visible:not(button,select,a,[role=button],input[type=checkbox],input[type=radio],[role=checkbox],[role=radio],[role=switch])]:[&:not(:has([role=dialog]_:focus-visible))]:outline-solid has-[:focus-visible:not(button,select,a,[role=button],input[type=checkbox],input[type=radio],[role=checkbox],[role=radio],[role=switch])]:[&:not(:has([role=dialog]_:focus-visible))]:outline-offset-2 has-[:focus-visible:not(button,select,a,[role=button],input[type=checkbox],input[type=radio],[role=checkbox],[role=radio],[role=switch])]:[&:not(:has([role=dialog]_:focus-visible))]:outline-[var(--ds-focus)] has-[:focus-visible:not(button,select,a,[role=button],input[type=checkbox],input[type=radio],[role=checkbox],[role=radio],[role=switch])]:[&:not(:has([role=dialog]_:focus-visible))]:border-[var(--ds-status-error)] [[data-input-modality=pointer]_&]:has-[:focus-visible:not(button,select,a,[role=button],input[type=checkbox],input[type=radio],[role=checkbox],[role=radio],[role=switch])]:[&:not(:has([role=dialog]_:focus-visible))]:outline-none [[data-input-modality=pointer]_&]:has-[:focus-visible:not(button,select,a,[role=button],input[type=checkbox],input[type=radio],[role=checkbox],[role=radio],[role=switch])]:[&:not(:has([role=dialog]_:focus-visible))]:ring-2 [[data-input-modality=pointer]_&]:has-[:focus-visible:not(button,select,a,[role=button],input[type=checkbox],input[type=radio],[role=checkbox],[role=radio],[role=switch])]:[&:not(:has([role=dialog]_:focus-visible))]:ring-[var(--ds-ring-error)]\";\n\n// Active (D6): a field clicked into, or a dropdown or picker that's open, is its accent border (--ds-accent-ink, P8) with\n// the soft halo beyond it; on a field with an error, red with the red halo. Never an outline: that is keyboard focus's.\n// Choices (a selected card, row or swatch, the Stepper's current step) draw their own selected look, not this (D2).\nexport const ACTIVE_RING = \"border-[var(--ds-accent-ink)] ring-2 ring-[var(--ds-ring-active)]\";\n\nexport const ERROR_ACTIVE_RING = \"border-[var(--ds-status-error)] ring-2 ring-[var(--ds-ring-error)]\";\n\n// Body scroll lock is reference-counted so stacked overlays (a Dialog opened\n// from a Drawer, for example) only restore scrolling when the LAST one\n// closes. The original overflow value is captured on the first lock and put\n// back on the last unlock; an unbalanced unlock is clamped at zero.\nlet scrollLockCount = 0;\nlet scrollLockPreviousOverflow = \"\";\n\nexport function lockBodyScroll() {\n if (scrollLockCount === 0) {\n scrollLockPreviousOverflow = document.body.style.overflow;\n document.body.style.overflow = \"hidden\";\n }\n scrollLockCount++;\n}\n\nexport function unlockBodyScroll() {\n if (scrollLockCount === 0) return;\n scrollLockCount--;\n if (scrollLockCount === 0) {\n document.body.style.overflow = scrollLockPreviousOverflow;\n scrollLockPreviousOverflow = \"\";\n }\n}\n\n/** Test-only: current number of active locks. */\nexport function getBodyScrollLockCount() {\n return scrollLockCount;\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../showcase/src/lib/hydrated.ts","../../../showcase/src/lib/locale.ts","../../../showcase/src/components/Skeleton.tsx","../../../showcase/src/lib/title-text.ts"],"names":[],"mappings":"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","file":"chunk-MFAWJSMJ.js","sourcesContent":["import { useSyncExternalStore } from \"react\";\n\nconst noSubscription = () => () => {};\nconst inBrowser = () => true;\nconst onServer = () => false;\n\n/**\n * Whether the browser has taken the page over (Sprint 25.20 D3): false on a server, and in the render that hydrates the\n * server's HTML (it must draw what the server drew), true straight after. A render with no server HTML (a Vite app, a\n * component mounted later) is true from its first render. What depends on the visitor's clock or time zone, which no\n * server knows, waits for it.\n */\nexport function useHydrated(): boolean {\n return useSyncExternalStore(noSubscription, inBrowser, onServer);\n}\n\n/**\n * Today on the visitor's device, once the browser has the page (null on a server and while hydrating): the day a date\n * grid marks and starts its keyboard on. Read on each render, so a grid drawn again after midnight marks the new day.\n */\nexport function useToday(): Date | null {\n return useHydrated() ? new Date() : null;\n}\n","import { createContext, useContext } from \"react\";\nimport { browserLanguages, formatLocale, localeFor, FIXED_FORM, type LocaleChoice } from \"./format-locale\";\nimport { useHydrated } from \"./hydrated\";\n\n// the choice itself needs no React, so server code can make it too (Sprint 25.22's review: requestLocale, on utils)\nexport { localeChoice, FIXED_FORM, type LocaleChoice } from \"./format-locale\";\n\nexport const LocaleContext = createContext<LocaleChoice | null>(null);\n\n/**\n * The locale a component writes its dates and numbers in (Sprint 25.20 L1). On a server, and while the browser hydrates\n * the server's HTML, the one the server chose: LocaleProvider's (the visitor's form of the page's language, from the\n * request), else \"en\", never a machine's own default, so both sides write the same. Once the page has loaded, the\n * browser's own reading (the visitor's form of the page's `lang`, as formatLocale() reads it), usually the same. A render\n * with no server HTML reads the browser's from its first render. Undefined is the browser's own language.\n */\nexport function useFormatLocale(): string | undefined {\n const choice = useContext(LocaleContext);\n const hydrated = useHydrated();\n if (!hydrated) return choice ? choice.server : FIXED_FORM;\n return choice ? localeFor(choice.lang, browserLanguages()) ?? choice.server : formatLocale();\n}\n","import { cn } from \"../lib/utils\";\n\ninterface SkeletonProps {\n variant?: \"text\" | \"avatar\" | \"card\" | \"table-row\" | \"custom\";\n lines?: number;\n width?: string;\n height?: string;\n className?: string;\n}\n\nfunction Bone({ className, style, \"data-gs\": marker }: { className?: string; style?: React.CSSProperties; \"data-gs\"?: string }) {\n return (\n <div\n data-gs={marker}\n className={cn(\"rounded-[var(--ds-radius-sm)] bg-[var(--ds-bg-emphasis)] animate-pulse\", className)}\n style={style}\n />\n );\n}\n\nexport function Skeleton({ variant = \"text\", lines = 3, width, height, className }: SkeletonProps) {\n if (variant === \"custom\") {\n return <Bone data-gs=\"skeleton\" className={className} style={{ width, height }} />;\n }\n\n if (variant === \"avatar\") {\n return <Bone data-gs=\"skeleton\" className={cn(\"h-10 w-10 rounded-[var(--ds-radius-full)]\", className)} />;\n }\n\n if (variant === \"card\") {\n return (\n <div data-gs=\"skeleton\" className={cn(\"space-y-ds-3\", className)}>\n <Bone className=\"h-32 w-full rounded-[var(--ds-radius-md)]\" />\n <Bone className=\"h-4 w-3/4\" />\n <Bone className=\"h-4 w-1/2\" />\n </div>\n );\n }\n\n if (variant === \"table-row\") {\n return (\n <div data-gs=\"skeleton\" className={cn(\"flex gap-ds-4\", className)}>\n <Bone className=\"h-4 flex-[3]\" />\n <Bone className=\"h-4 flex-[2]\" />\n <Bone className=\"h-4 flex-1\" />\n <Bone className=\"h-4 flex-1\" />\n </div>\n );\n }\n\n // text variant\n const widths = [\"w-3/4\", \"w-1/2\", \"w-5/6\", \"w-2/3\", \"w-4/5\"];\n return (\n <div data-gs=\"skeleton\" className={cn(\"space-y-ds-3\", className)}>\n {Array.from({ length: lines }, (_, i) => (\n <Bone key={i} className={cn(\"h-4\", widths[i % widths.length])} />\n ))}\n </div>\n );\n}\n","/**\n * A title's text classes: CardTitle's, which a titled Table's band and a ChartContainer's title share (Sprint 25.9, A1),\n * one definition so they cannot drift. A word or a name longer than its line breaks at the line's edge (round 27,\n * R27-16: run 70's \"primary-logo-navy.svg\" ran out of its card); break-word, not anywhere, so a title's words still\n * set its minimum and the actions beside it wrap under it before a word is broken (HEADER_LAYOUT.floor).\n */\nexport const TITLE_TEXT = \"font-[family-name:var(--ds-font-display)] text-lg font-[var(--ds-weight-heading)] text-[var(--ds-text-primary)] break-words\";\n"]}