gridsmith-ui 0.31.0 → 0.32.0
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.
- package/CHANGELOG.md +64 -1
- package/dist/charts.d.ts +101 -30
- package/dist/charts.js +181 -106
- package/dist/charts.js.map +1 -1
- package/dist/chat.js +6 -6
- package/dist/{chunk-OWQ7M6R7.js → chunk-2724SJO2.js} +141 -24
- package/dist/chunk-2724SJO2.js.map +1 -0
- package/dist/{chunk-BKYWKMUN.js → chunk-DO6DLTFK.js} +11 -9
- package/dist/chunk-DO6DLTFK.js.map +1 -0
- package/dist/{chunk-GP2COVJC.js → chunk-H732QL56.js} +4 -4
- package/dist/{chunk-GP2COVJC.js.map → chunk-H732QL56.js.map} +1 -1
- package/dist/{chunk-XSQD3UGY.js → chunk-HCEHTJ5E.js} +17 -4
- package/dist/chunk-HCEHTJ5E.js.map +1 -0
- package/dist/{chunk-YFHTREH5.js → chunk-HUVZQOU4.js} +5 -5
- package/dist/{chunk-YFHTREH5.js.map → chunk-HUVZQOU4.js.map} +1 -1
- package/dist/{chunk-EKWXPSTI.js → chunk-JHZ22HQP.js} +75 -24
- package/dist/chunk-JHZ22HQP.js.map +1 -0
- package/dist/{chunk-3J67NISC.js → chunk-NGZJK57C.js} +15 -11
- package/dist/chunk-NGZJK57C.js.map +1 -0
- package/dist/{chunk-U7WBI4AV.js → chunk-OVHM55JF.js} +5 -5
- package/dist/{chunk-U7WBI4AV.js.map → chunk-OVHM55JF.js.map} +1 -1
- package/dist/{chunk-OFACAHRV.js → chunk-QY2RA2HO.js} +5 -5
- package/dist/{chunk-OFACAHRV.js.map → chunk-QY2RA2HO.js.map} +1 -1
- package/dist/{chunk-HUNEJIKV.js → chunk-R2IAK3J3.js} +3 -3
- package/dist/{chunk-HUNEJIKV.js.map → chunk-R2IAK3J3.js.map} +1 -1
- package/dist/{chunk-V73LHNRL.js → chunk-RS624TD5.js} +29 -10
- package/dist/chunk-RS624TD5.js.map +1 -0
- package/dist/{chunk-V2ARGHJN.js → chunk-SIEU4H3H.js} +9 -9
- package/dist/chunk-SIEU4H3H.js.map +1 -0
- package/dist/{chunk-DBHVJ7Z3.js → chunk-SS3C24IJ.js} +3 -2
- package/dist/chunk-SS3C24IJ.js.map +1 -0
- package/dist/{chunk-LE72KHIE.js → chunk-TMPPBXX3.js} +3 -3
- package/dist/{chunk-LE72KHIE.js.map → chunk-TMPPBXX3.js.map} +1 -1
- package/dist/{chunk-GT6M74IZ.js → chunk-WSKPESAX.js} +12 -10
- package/dist/chunk-WSKPESAX.js.map +1 -0
- package/dist/{chunk-2Q4HOGEI.js → chunk-XBVZIN26.js} +15 -5
- package/dist/chunk-XBVZIN26.js.map +1 -0
- package/dist/data-grid.js +10 -10
- package/dist/data-grid.js.map +1 -1
- package/dist/editor-mentions.js +2 -2
- package/dist/editor.js +4 -3
- package/dist/editor.js.map +1 -1
- package/dist/index.d.ts +53 -6
- package/dist/index.js +557 -232
- package/dist/index.js.map +1 -1
- package/dist/kanban.js +10 -9
- package/dist/kanban.js.map +1 -1
- package/dist/resizable.d.ts +11 -2
- package/dist/resizable.js +97 -22
- package/dist/resizable.js.map +1 -1
- package/dist/roots.css +2 -2
- package/dist/tokens.css +6 -6
- package/dist/virtualized.js +10 -9
- package/dist/virtualized.js.map +1 -1
- package/dist-static/tokens.css +6 -6
- package/package.json +1 -1
- package/dist/chunk-2Q4HOGEI.js.map +0 -1
- package/dist/chunk-3J67NISC.js.map +0 -1
- package/dist/chunk-BKYWKMUN.js.map +0 -1
- package/dist/chunk-DBHVJ7Z3.js.map +0 -1
- package/dist/chunk-EKWXPSTI.js.map +0 -1
- package/dist/chunk-GT6M74IZ.js.map +0 -1
- package/dist/chunk-OWQ7M6R7.js.map +0 -1
- package/dist/chunk-V2ARGHJN.js.map +0 -1
- package/dist/chunk-V73LHNRL.js.map +0 -1
- package/dist/chunk-XSQD3UGY.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../showcase/src/lib/use-latest.ts","../../../showcase/src/lib/focus.ts","../../../showcase/src/lib/utils.ts","../../../showcase/src/lib/use-position.ts"],"names":["useRef","useLayoutEffect","active","useState","useCallback"],"mappings":"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","file":"chunk-OWQ7M6R7.js","sourcesContent":["import { useLayoutEffect, useRef, type RefObject } from \"react\";\n\n/**\n * A ref that always holds the latest value of `value`, updated in a layout\n * effect (before paint, before any event can fire) rather than during render.\n *\n * Use it for callbacks read from long-lived listeners — `onClose` inside a\n * document keydown handler, `onDismiss` inside a timer — so the listener need\n * not be re-attached every render and never calls a stale closure.\n *\n * The write happens in a commit-phase effect, which is the React-sanctioned\n * place to touch refs (the React Compiler's `refs` rule rejects writes during\n * render).\n */\nexport function useLatest<T>(value: T): RefObject<T> {\n const ref = useRef(value);\n useLayoutEffect(() => {\n ref.current = value;\n });\n return ref;\n}\n","import { useCallback, useEffect, useInsertionEffect, useLayoutEffect, useMemo, useRef, useState, type KeyboardEvent as ReactKeyboardEvent, type RefObject } from \"react\";\nimport { flushSync } from \"react-dom\";\nimport { useLatest } from \"./use-latest\";\n\n/**\n * Everything a keyboard user might land on: the candidates. Whether one is a\n * Tab stop right now is `isTabStop`'s call (a roving item with tabindex=\"-1\", a\n * hidden input or a disabled field matches this selector but is not a stop).\n */\nexport const FOCUSABLE =\n 'a[href], button:not(:disabled), input:not(:disabled), select:not(:disabled), textarea:not(:disabled), [tabindex]:not([tabindex=\"-1\"]), [contenteditable]:not([contenteditable=\"false\"])';\n\n/** A field that takes typing: keys pressed in one are its own (a grid's arrows, a time view's zoom keys leave them). */\nexport const FIELD = \"input, select, textarea, [contenteditable='true']\";\n\n/**\n * A control a library element with a Tab stop of its own can sit in (a RelativeTime, cut text): a Card or a board's card\n * that is a button, a link, a button, a row or an option the app built. Inside one the element takes no Tab stop: a stop\n * nested in a button, and a Card holding one stops being a button (the 25.17 second review: a time took an action\n * card's keyboard access away).\n */\nexport const CONTROL_ANCESTOR = 'a[href], button, summary, label, [role=\"button\"], [role=\"link\"], [role=\"option\"], [role=\"menuitem\"], [role=\"menuitemcheckbox\"], [role=\"menuitemradio\"], [role=\"tab\"], [role=\"treeitem\"], [role=\"row\"], [role=\"gridcell\"], [role=\"checkbox\"], [role=\"radio\"], [role=\"switch\"]';\nconst SAFE_BUTTON = 'button:not([data-variant=\"destructive\"])';\n\n/** Mark an overlay's own close/dismiss button so initial focus skips it. */\nexport const OVERLAY_CLOSE_ATTR = \"data-overlay-close\";\n\n// ─── Tab stops ───────────────────────────────────────────────────────────────\n\n/** Rendered and not hidden. Real browsers answer with checkVisibility; with no layout (jsdom) the tree is walked. */\nfunction isRendered(el: HTMLElement): boolean {\n if (typeof el.checkVisibility === \"function\") return el.checkVisibility({ checkVisibilityCSS: true });\n for (let n: Element | null = el; n; n = n.parentElement) {\n if (n instanceof HTMLElement && n.hidden) return false;\n const style = getComputedStyle(n);\n if (style.display === \"none\") return false;\n if (n === el && style.visibility === \"hidden\") return false;\n }\n return true;\n}\n\n/** A native radio is a Tab stop when it is its group's checked radio, or the first when none is checked. */\nfunction isRadioStop(el: HTMLInputElement): boolean {\n if (!el.name) return true;\n const scope: ParentNode = el.form ?? el.ownerDocument;\n const group = Array.from(scope.querySelectorAll<HTMLInputElement>('input[type=\"radio\"]'))\n .filter((r) => r.name === el.name && !r.disabled && r.form === el.form);\n const checked = group.find((r) => r.checked);\n return (checked ?? group[0]) === el;\n}\n\n/**\n * Could the browser's own Tab land here? A focusable element with a\n * non-negative tabIndex, not disabled, not a hidden input, not inside an inert\n * subtree, rendered, and for a native radio the group's one stop (Sprint 25.7).\n */\nexport function isTabStop(el: Element): el is HTMLElement {\n if (!(el instanceof HTMLElement) || el.tabIndex < 0) return false;\n if ((el instanceof HTMLButtonElement || el instanceof HTMLInputElement || el instanceof HTMLSelectElement || el instanceof HTMLTextAreaElement) && el.disabled) return false;\n if (el instanceof HTMLInputElement && (el.type === \"hidden\" || (el.type === \"radio\" && !isRadioStop(el)))) return false;\n if (el.closest(\"[inert]\")) return false;\n return isRendered(el);\n}\n\n/**\n * Whether `root` holds a Tab stop at all: the first one found ends the search, with no order to sort (Sprint 25.31 item 7:\n * the shell's `<main>` asked it of the whole page on every change).\n */\nexport function hasTabStop(root: ParentNode): boolean {\n for (const el of root.querySelectorAll(FOCUSABLE)) if (isTabStop(el)) return true;\n return false;\n}\n\n/** The Tab stops inside `root`, in document order. */\nexport function tabStops(root: ParentNode): HTMLElement[] {\n // sorted: a selector list can come back grouped by selector (jsdom's does), which put a trap's first or last stop, or a\n // card's first action, on the wrong element in a test (the review of 2 October)\n return Array.from(root.querySelectorAll<HTMLElement>(FOCUSABLE))\n .filter(isTabStop)\n .sort((a, b) => (a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1));\n}\n\n/**\n * Move initial focus into an overlay the way users expect: the first visible\n * form field if there is one, otherwise the first focusable element that is\n * not the overlay's own close button.\n *\n * For destructive confirmations (`destructive: true`) the corpus rule applies\n * instead: focus the non-destructive action so Enter can't confirm by\n * accident. That is the first button not rendered with the destructive\n * variant, regardless of footer order; a lone destructive button falls back to\n * the general rule.\n *\n * React's `autoFocus` prop is not reflected as a DOM attribute, so a\n * field-first rule is the reliable general behaviour.\n */\nexport function focusInitial(root: HTMLElement | null | undefined, opts: { destructive?: boolean } = {}): boolean {\n if (!root) return false;\n const all = tabStops(root);\n if (!all.length) return false;\n const candidates = all.filter((el) => !el.hasAttribute(OVERLAY_CLOSE_ATTR));\n\n // Round 18 (the owner, 55.5; round 17 F-9): a destructive dialog that holds a field is a type-to-confirm dialog — its\n // confirm stays disabled until the text matches, so the field is the safe target. Cancel is the target only when the\n // dialog is buttons-only.\n const field = candidates.find((el) => el.matches(FIELD));\n if (opts.destructive && !field) {\n const safe = candidates.find((el) => el.matches(SAFE_BUTTON));\n if (safe) {\n safe.focus();\n return true;\n }\n }\n\n const target = candidates.find((el) => el.matches(FIELD)) ?? candidates[0] ?? all[0];\n target.focus();\n return true;\n}\n\n// ─── Remembering where focus was ─────────────────────────────────────────────\n\n/**\n * The element that had focus when `open` turned true, read before this commit's children can move it. An `autoFocus`\n * field inside a dialog takes focus while React commits (the layout phase), so an effect that reads\n * document.activeElement afterwards sees that field, not the opener (run 57's type-to-confirm dialog, Sprint 25.7).\n * Insertion effects run earlier in the commit, before any of that.\n */\nexport function useFocusBeforeOpen(open: boolean): RefObject<Element | null> {\n const before = useRef<Element | null>(null);\n useInsertionEffect(() => {\n trackFocus();\n if (!open) return;\n // focus fell to the page in this same commit, its element removed before this overlay looked: that element (Sprint\n // 25.29 item 4: a preview dialog's \"Edit details\", gone with the preview as the edit drawer opens)\n const active = document.activeElement;\n before.current = !active || active === document.body ? (justLost() ?? active) : active;\n }, [open]);\n return before;\n}\n\n/** The element that last took focus, kept once it has left the page, and when; and when the person last acted. */\nlet lastFocused: Element | null = null;\nlet lastFocusedAt = 0;\nlet lastActedAt = 0;\nlet tracking = false;\nfunction trackFocus() {\n if (tracking || typeof document === \"undefined\") return;\n tracking = true;\n document.addEventListener(\"focusin\", (e) => {\n lastFocused = e.target instanceof Element ? e.target : null;\n lastFocusedAt = performance.now();\n }, true);\n const acted = () => { lastActedAt = performance.now(); };\n for (const type of [\"keydown\", \"pointerdown\", \"click\"]) document.addEventListener(type, acted, true);\n}\n\n/**\n * The element focus fell from in what the person just did: it left the page with focus on it, and they had acted since\n * it took focus, within the second. Never one gone long ago, or with a page that has moved on since (a panel open from\n * the start on the next page).\n */\nfunction justLost(): Element | null {\n const recent = lastActedAt >= lastFocusedAt && performance.now() - lastActedAt < 1000;\n return lastFocused && !lastFocused.isConnected && recent ? lastFocused : null;\n}\n// from the start, so a press made before any overlay mounted counts (an edit drawer drawn only once its address is open)\ntrackFocus();\n\n/** `to` is a path above `from`: /calendar above /calendar/events/7; the site's root above /events/7 (a home page's own\n * overlay, the second review). */\nfunction pathAbove(to: string, from: string): boolean {\n const up = to.replace(/\\/+$/, \"\");\n return from.startsWith(`${up}/`) && from.replace(/\\/+$/, \"\") !== up;\n}\n\n/** What counts as \"the row\" an opener sits in, for a row that is deleted while its menu or dialog is open. */\nconst ROW = 'tr, li, [role=\"row\"], [data-card], [data-row]';\n\n/**\n * The index of the one row a deletion took out, when the rows now read as the old rows with that one removed: every\n * row after it moved up by one. A list keyed by position (the library Table, `key={i}`) keeps a deleted row's\n * elements for the next item, and a paged list keeps its length by bringing a new item into its last row. Else -1:\n * an edit (even one that makes a row read like another) or a re-sort.\n */\nfunction deletedRow(before: readonly string[], now: readonly string[]): number {\n const refilled = now.length === before.length;\n if (!refilled && now.length !== before.length - 1) return -1;\n let k = 0;\n while (k < now.length && now[k] === before[k]) k++;\n const last = now.length - 1;\n // a refilled last row shows an item the list did not show\n if (refilled && (k >= last || before.includes(now[last]))) return -1;\n for (let j = k; j < (refilled ? last : now.length); j++) if (now[j] !== before[j + 1]) return -1;\n return k;\n}\n\n/**\n * Focus by script on an element that takes none, a heading or a container (Sprint 25.29 item 3): it takes `tabindex=\"-1\"`\n * while it holds focus, never a Tab stop, and the library's ring when the keyboard brought it there. True when it took\n * focus.\n */\nexport function focusForTheMoment(el: HTMLElement): boolean {\n const own = el.getAttribute(\"tabindex\");\n if (own === null) el.setAttribute(\"tabindex\", \"-1\");\n el.focus();\n if (document.activeElement !== el) {\n if (own === null) el.removeAttribute(\"tabindex\");\n return false;\n }\n let ring = false;\n try { ring = el.matches(\":focus-visible\"); } catch { /* a browser without :focus-visible draws its own */ }\n const { outline, outlineOffset } = el.style;\n if (ring) {\n // FOCUS_RING's outline, which a class added now might not find in a stylesheet built without it\n el.style.outline = \"2px solid var(--ds-focus)\";\n el.style.outlineOffset = \"2px\";\n }\n el.addEventListener(\"blur\", () => {\n if (own === null) el.removeAttribute(\"tabindex\");\n if (ring) Object.assign(el.style, { outline, outlineOffset });\n }, { once: true });\n return true;\n}\n\nconst HEADING = 'h1, h2, h3, h4, h5, h6, [role=\"heading\"]';\n\n/**\n * How long `rememberFocus`'s last resort waits (Sprint 25.29 item 3): past every library component's own place for focus\n * after a removal, so the most particular place goes first. The Calendar's is the slowest: its card's frame, then a\n * check 120 ms on (the event's day).\n */\nexport const LAST_RESORT_MS = 200;\n\n/** Each container round an element, nearest first, with what stood just before and after it there. The app's root and\n * the body are the page itself, never a place for focus. */\ninterface Place { box: HTMLElement; prev: Element | null; next: Element | null }\nfunction placesOf(el: Element): Place[] {\n const places: Place[] = [];\n for (let c: Element = el, box = el.parentElement; box && box !== document.body && box.parentElement && box.parentElement !== document.body; c = box, box = box.parentElement) {\n places.push({ box, prev: c.previousElementSibling, next: c.nextElementSibling });\n }\n return places;\n}\n\n/**\n * The last resort's place (item 3): in the nearest container still on the page, what now stands where the element was,\n * then the container, then each one round it, each its first Tab stop, else its first heading, focused for the moment.\n * Nothing inside `closing` counts (an overlay still on its way out). Last, the page's `<main>` (Sprint 25.30 item 4): an\n * overlay in a portal leaves no place of its own once it has gone, so focus goes where the skip link's jump goes, its\n * first Tab stop, else its first heading, else `<main>` itself. True when focus landed.\n */\nfunction landLastResort(places: Place[], closing?: Element | null): boolean {\n const counts = (el: Element) => !closing?.contains(el);\n const areas: Element[][] = [];\n const at = places.findIndex((p) => p.box.isConnected);\n if (at >= 0) {\n const { box, prev, next } = places[at];\n const kids = Array.from(box.children);\n const from = prev?.parentElement === box ? kids.indexOf(prev) + 1 : 0;\n const to = next?.parentElement === box ? kids.indexOf(next) : kids.length;\n areas.push(kids.slice(from, Math.max(from, to)), ...places.slice(at).map((p) => [p.box]));\n }\n const main = document.querySelector<HTMLElement>('main, [role=\"main\"]');\n const mainCounts = !!main && counts(main) && isRendered(main);\n if (mainCounts) areas.push([main]);\n for (const area of areas) {\n const stop = area.flatMap((a) => [...(isTabStop(a) ? [a] : []), ...tabStops(a)]).find(counts);\n if (stop) {\n stop.focus();\n if (document.activeElement === stop) return true;\n }\n const heading = area.flatMap((a) => [...(a.matches(HEADING) ? [a] : []), ...a.querySelectorAll(HEADING)])\n .find((h): h is HTMLElement => h instanceof HTMLElement && isRendered(h) && counts(h));\n if (heading && focusForTheMoment(heading)) return true;\n }\n return mainCounts && focusForTheMoment(main!);\n}\n\nexport interface RememberFocusOptions {\n /** The element's page outlives a change of path (a list beside a pane whose selection is in the URL): give focus back even then. */\n ignoreRoute?: boolean;\n}\n\nexport interface RememberedFocus {\n readonly el: HTMLElement;\n /**\n * Put focus back (Sprint 25.7). Nothing happens once the page has changed — a new path, or a new URL that took the\n * element with it — since the new page owns focus (D14(d)); a new query or hash alone (a filter, a page number) is\n * no page change, nor is a path above (an overlay's own address closing back to its page, Sprint 25.18). Otherwise the element itself; if its row was deleted, the same control in the row before, else\n * the row after, else the first Tab stop of the list (D14(c), MOJ \"Add another\" order); else `fallback`. True when\n * focus landed. With all of that gone (Sprint 25.29 item 3: a row's \"Restore\" that empties its list, swapped for its\n * empty state), the last resort, `LAST_RESORT_MS` later and only with focus still on nothing: the nearest container\n * still on the page, what now stands where the element was, then the container, each its first Tab stop, else its\n * first heading, focused for the moment (`focusForTheMoment`). Never the page itself.\n *\n * Rows carrying `data-row-key` are told apart by it. Without one, a list keyed by position (the library Table,\n * `key={i}`) keeps a deleted row's elements for the next item, so the rows' text decides: focus follows this item\n * to the one row that now shows it, and when the rows read as the old ones with one taken out, this row's item was\n * deleted or moved up. An edit keeps focus, even one that makes the row read like another.\n *\n * When focus lands back on the element in a row, the list is watched for 10 s: a row deleted a moment later (a\n * server round trip) that takes focus with it sends focus to its neighbour the same way.\n */\n restore(fallback?: HTMLElement | null): boolean;\n}\n\nexport function rememberFocus(el: HTMLElement, { ignoreRoute = false }: RememberFocusOptions = {}): RememberedFocus {\n const { href, pathname } = location;\n const row = el.closest<HTMLElement>(ROW);\n const before = row?.previousElementSibling ?? null;\n const after = row?.nextElementSibling ?? null;\n const list = row?.parentElement ?? null;\n const index = row ? tabStops(row).indexOf(el) : -1;\n const rows = list ? Array.from(list.children) : [];\n const at = row ? rows.indexOf(row) : -1;\n const texts = rows.map((r) => r.textContent ?? \"\");\n const keyOf = (r: Element | null) => r?.getAttribute(\"data-row-key\") ?? null;\n const key = keyOf(row);\n // where it sat, for the last resort\n const places = placesOf(el);\n const pageChanged = () => {\n if (ignoreRoute) return false;\n // back up to a path above: an overlay or a pane with an address of its own closing (/calendar/events/7 back to\n // /calendar, navigation#29), the same page (Sprint 25.18). A page that replaced it keeps nothing focus could land on.\n if (location.pathname !== pathname) return !pathAbove(location.pathname, pathname);\n return location.href !== href && !el.isConnected;\n };\n const land = (target: HTMLElement | null | undefined) => {\n if (!target || !target.isConnected) return false;\n target.focus();\n return document.activeElement === target;\n };\n const inRow = (r: Element | null | undefined) => {\n if (!r || !r.isConnected) return false;\n const stops = tabStops(r);\n return land(stops[Math.max(0, Math.min(index, stops.length - 1))]);\n };\n const byKey = (k: string | null) => (k !== null && list?.isConnected ? list.querySelector(`:scope > [data-row-key=\"${CSS.escape(k)}\"]`) : null);\n /** The row this item is in now, when the list moved under it; undefined when it did not. */\n const moved = (): Element | undefined => {\n if (!list?.isConnected || at < 0) return undefined;\n if (key !== null) {\n const same = byKey(key);\n return same === row ? undefined : same ?? byKey(keyOf(before)) ?? byKey(keyOf(after)) ?? undefined;\n }\n const now = Array.from(list.children, (r) => r.textContent ?? \"\");\n const text = texts[at];\n if (texts.indexOf(text) === texts.lastIndexOf(text)) {\n const found = now.flatMap((t, i) => (t === text ? [i] : []));\n if (found.length === 1) return list.children[found[0]] === row ? undefined : list.children[found[0]];\n }\n const k = deletedRow(texts, now);\n return k >= 0 && k <= at ? list.children[Math.max(0, at - 1)] ?? undefined : undefined;\n };\n const neighbour = () => inRow(byKey(keyOf(before)) ?? before) || inRow(byKey(keyOf(after)) ?? after) || (!!list?.isConnected && land(tabStops(list)[0]));\n // a moment later, and only with focus still on nothing: a component with a place of its own for focus goes first\n const lastResort = () => {\n setTimeout(() => {\n // a page torn down in the meantime (a test's) has nowhere to land\n if (typeof document === \"undefined\") return;\n const active = document.activeElement;\n if ((active && active !== document.body && active.isConnected) || pageChanged()) return;\n landLastResort(places);\n }, LAST_RESORT_MS);\n return false;\n };\n let unwatch: (() => void) | null = null;\n const watch = () => {\n unwatch?.();\n if (!list || typeof MutationObserver === \"undefined\") return;\n const observer = new MutationObserver((changes) => {\n if (el.isConnected) return;\n const active = document.activeElement;\n const dropped = !active || active === document.body || !active.isConnected;\n stop();\n if (!dropped || pageChanged()) return;\n // its row taken from the list: the neighbour (D14(c)); gone any other way, the list with it, the last resort\n const fromList = changes.some((c) => c.target === list || c.target === list.parentNode);\n if (!(fromList && neighbour())) lastResort();\n });\n const onFocusIn = (e: FocusEvent) => { if (e.target !== el) stop(); };\n const timer = setTimeout(() => stop(), 10_000);\n function stop() {\n observer.disconnect();\n clearTimeout(timer);\n // its timer can outlive the page (a test's)\n if (typeof document !== \"undefined\") document.removeEventListener(\"focusin\", onFocusIn, true);\n unwatch = null;\n }\n observer.observe(list, { childList: true });\n if (list.parentNode) observer.observe(list.parentNode, { childList: true });\n // and every container round it: a page that swaps the whole list for its empty state removes it from higher up\n // (Sprint 25.29 item 3)\n for (const { box } of places) observer.observe(box, { childList: true });\n document.addEventListener(\"focusin\", onFocusIn, true);\n unwatch = stop;\n };\n return {\n el,\n restore(fallback) {\n if (pageChanged()) return false;\n if (inRow(moved())) return true;\n if (land(el)) {\n if (row) watch();\n return true;\n }\n if (row && !row.isConnected && neighbour()) return true;\n return land(fallback) || lastResort();\n },\n };\n}\n\n/**\n * A list whose item holding focus the page takes away (Sprint 25.29 item 5: run 81's \"Acknowledge\" filtered its alert out\n * of a StackedList, and focus fell to the page): focus goes on by `rememberFocus`'s rule, the same control in the item\n * before, else in the item after, else the list's first, else the last resort. Watched while focus is in the list;\n * focus moved anywhere else, or let go on the page by a click, forgets it, so a removal the user didn't make (a data\n * refresh) never pulls focus back. A removed element fires no focusout, or one with the element gone, so a removal keeps it.\n */\nexport function useFocusKeptInList(listRef: RefObject<HTMLElement | null>) {\n useEffect(() => {\n if (typeof MutationObserver === \"undefined\") return;\n let held: RememberedFocus | null = null;\n let observer: MutationObserver | null = null;\n const forget = () => {\n held = null;\n observer?.disconnect();\n observer = null;\n };\n const onFocusIn = (e: FocusEvent) => {\n const list = listRef.current;\n const t = e.target;\n if (!list || !(t instanceof HTMLElement) || !list.contains(t)) {\n if (held) forget();\n return;\n }\n held = rememberFocus(t);\n if (observer) return;\n observer = new MutationObserver(() => {\n const h = held;\n if (!h || h.el.isConnected) return;\n const active = document.activeElement;\n forget();\n if (!active || active === document.body || !active.isConnected) h.restore();\n });\n observer.observe(list, { childList: true, subtree: true });\n };\n const onFocusOut = (e: FocusEvent) => {\n if (!held || e.target !== held.el) return;\n queueMicrotask(() => { if (held?.el.isConnected && !listRef.current?.contains(document.activeElement)) forget(); });\n };\n document.addEventListener(\"focusin\", onFocusIn, true);\n document.addEventListener(\"focusout\", onFocusOut, true);\n return () => {\n document.removeEventListener(\"focusin\", onFocusIn, true);\n document.removeEventListener(\"focusout\", onFocusOut, true);\n const h = held;\n forget();\n // the list itself taken away with focus in it (its last item gone, an empty state drawn instead), before the\n // watch heard of it: the last resort (item 3)\n const active = document.activeElement;\n if (h && !h.el.isConnected && (!active || active === document.body || !active.isConnected)) h.restore();\n };\n }, [listRef]);\n}\n\n// ─── An overlay's way back ───────────────────────────────────────────────────\n\n/**\n * Each overlay's opener, by the overlay's element (Sprint 25.29 item 4). An overlay opened from inside another that\n * closed as it opened (run 79: a preview dialog's \"Edit details\" moves the address to the edit drawer's, closing the\n * preview) has an opener that went with it, so it falls back to that overlay's own opener, still on the page (the asset\n * card). Kept by element, not with the layers: the outer overlay has left the layers by the time the inner one opens.\n */\nconst openers = new WeakMap<Element, RememberedFocus>();\n\n/**\n * Each overlay's last resort still waiting, by the overlay's element, with what stops it (Sprint 25.31 item 2). The overlay\n * opening again stops it: StrictMode's rehearsal unmounts an overlay open from the start and mounts it again, which armed\n * its way back while it stayed open, and 200 ms on that took focus from inside it to the page behind it. So does a remount\n * or a quick reopen.\n */\nconst waiting = new WeakMap<Element, () => void>();\n\n/** How long a way back watches for the overlay it came from to go (Sprint 25.31 item 2), as the removal watches do. */\nconst WATCH_MS = 10_000;\n\n/** What an overlay gives focus back to, read as it opened. */\nexport interface OverlayOpener {\n /** What had focus as it opened, while that was on the page; null when it had gone. */\n readonly el: HTMLElement | null;\n /**\n * As RememberedFocus's; else, with the overlay the opener sat in closed, that overlay's own opener. With nothing to go\n * back to, the last resort round where the overlay sat. `closed`: the overlay's open state turned false, so it's on\n * its way out and focus left inside it is lost at once (Sprint 25.29 item 6). Without it, the overlay unmounted, which\n * StrictMode rehearses with the overlay still open, so focus inside it is lost only once it has left the page or is\n * hidden (Sprint 25.31 item 2).\n */\n restore(fallback?: HTMLElement | null, closed?: boolean): boolean;\n}\n\n/**\n * Remember an overlay's opener as it opens: `active`, what had focus then, and `root`, the overlay's element, which\n * keeps it for an overlay opened from inside this one. Null when nothing is left to give focus back to.\n */\nexport function rememberOpener(active: Element | null, root?: Element | null): OverlayOpener | null {\n // open again: the last resort its last close left waiting has nothing to do\n if (root) waiting.get(root)?.();\n let own = active instanceof HTMLElement && active !== document.body && active.isConnected ? rememberFocus(active) : null;\n // nothing on the page had focus (an overlay open from the start), or what had it has gone: the control that controls\n // it, which names it in aria-controls (Sprint 25.29 item 6: a CornerPanel open on load, closed by Escape, gives focus\n // to its Launcher)\n const controller = !own && root?.id ? document.querySelector<HTMLElement>(`[aria-controls~=\"${CSS.escape(root.id)}\"]`) : null;\n if (controller) own = rememberFocus(controller);\n // the overlay the opener sat in, on the page or not: a closed overlay's element keeps its children\n let around: { root: Element; opener: RememberedFocus } | null = null;\n for (let n = active; n && !around; n = n.parentElement) {\n const opener = openers.get(n);\n if (opener) around = { root: n, opener };\n }\n const back = own ?? around?.opener;\n if (!back) {\n if (!root) return null;\n // nothing to go back to at all: the last resort round where the overlay sits, once it has gone (item 3). A path\n // above is the same page, as for rememberFocus (an overlay's own address closing back to its page, Sprint 25.30\n // item 4: run 79's edit drawer, opened from a preview that was open as the page loaded)\n const places = placesOf(root);\n const { pathname } = location;\n return {\n el: null,\n restore(_fallback, closed = false) {\n const since = performance.now();\n let timer: ReturnType<typeof setTimeout> | undefined;\n const stop = () => {\n clearTimeout(timer);\n if (waiting.get(root) === stop) waiting.delete(root);\n };\n const look = () => {\n // a page torn down in the meantime (a test's) has nowhere to land\n if (typeof document === \"undefined\") return;\n const now = document.activeElement;\n const real = !!now && now !== document.body && now.isConnected;\n if ((real && !root.contains(now)) || (location.pathname !== pathname && !pathAbove(location.pathname, pathname))) return stop();\n // unmounted, not closed: focus inside the overlay is lost only once the overlay has left the page or is hidden\n // (Sprint 25.31 item 2), since StrictMode's rehearsal leaves it open; until then, look again shortly. Closed, it's\n // on its way out, and nothing inside it is a place for focus (Sprint 25.29 item 6).\n if (real && !closed && root instanceof HTMLElement && isRendered(root)) {\n if (performance.now() - since < WATCH_MS) timer = setTimeout(look, 50);\n else stop();\n return;\n }\n stop();\n landLastResort(places, root);\n };\n timer = setTimeout(look, LAST_RESORT_MS);\n waiting.set(root, stop);\n return false;\n },\n };\n }\n if (root) openers.set(root, back);\n return {\n el: own?.el ?? null,\n restore(fallback) {\n if (own?.restore(fallback)) return true;\n return !!around && !around.root.isConnected && around.opener.restore();\n },\n };\n}\n\n/**\n * Remember what had focus when a modal overlay opened and give it back on\n * close (corpus: \"After an overlay closes, return focus to the element that\n * triggered it\"). With `root`, focus is given back only when it was lost or is\n * still inside the closing overlay, so a focus move the consumer made on close\n * wins. Returns `returnFocus()` for a command that must hand focus back before\n * it runs (CommandPalette: a command that opens a Dialog).\n */\nexport function useReturnFocus(open: boolean, root?: RefObject<HTMLElement | null>) {\n const remembered = useRef<OverlayOpener | null>(null);\n const before = useFocusBeforeOpen(open);\n useEffect(() => {\n if (open) {\n remembered.current = rememberOpener(before.current, root?.current);\n return;\n }\n const r = remembered.current;\n remembered.current = null;\n if (!r) return;\n const active = document.activeElement;\n const lost = !active || active === document.body || !active.isConnected;\n if (!root || lost || (active instanceof Node && !!root.current?.contains(active))) r.restore(undefined, true);\n }, [open, root, before]);\n // Unmounted while open, as Dialog gives focus back (Sprint 25.18: run 72 keys its form by the event's address, so\n // closing it unmounted an open Drawer, which gave none back; a page that renders an overlay only while open does the\n // same). Its panel is gone, so focus is lost, unless the page moved it.\n useEffect(() => () => {\n const r = remembered.current;\n remembered.current = null;\n const now = document.activeElement;\n if (r && (!now || now === document.body || !now.isConnected)) r.restore();\n }, []);\n return useCallback(() => { remembered.current?.restore(); }, []);\n}\n\n/**\n * Index of the single Tab stop in a radio-style group (APG radio pattern):\n * the checked item, else the first enabled item so a group with no selection\n * is still reachable. −1 when every item is disabled.\n */\nexport function rovingTabStop<T>(items: T[], isChecked: (item: T) => boolean, isDisabled: (item: T) => boolean = () => false): number {\n const checked = items.findIndex((item) => isChecked(item) && !isDisabled(item));\n return checked >= 0 ? checked : items.findIndex((item) => !isDisabled(item));\n}\n\n/**\n * Rule 4 (D14(c), MOJ \"Add another\" order): after the item at `index` was\n * removed, focus the item before it, else the one now in its place, else\n * `fallback`. `items` is the list as it is after the removal.\n */\nexport function focusAfterRemoval(items: ArrayLike<HTMLElement>, index: number, fallback?: HTMLElement | null) {\n (items[index - 1] ?? items[index] ?? fallback)?.focus();\n}\n\n/** The Tab stops in `root`, and the controls disabled now that a press may enable, in document order. */\nfunction mayStop(root: ParentNode): HTMLElement[] {\n const disabled = (el: Element) => (el instanceof HTMLButtonElement || el instanceof HTMLInputElement || el instanceof HTMLSelectElement || el instanceof HTMLTextAreaElement) && el.disabled;\n return Array.from(root.querySelectorAll<HTMLElement>(`${FOCUSABLE}, button:disabled, input:disabled, select:disabled, textarea:disabled`))\n .filter((el) => (disabled(el) ? !(el instanceof HTMLInputElement && el.type === \"hidden\") : isTabStop(el)))\n .sort((a, b) => (a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1));\n}\n\nexport interface SelfRemovalOptions {\n /** What goes: the alert, the tag. Nothing inside it is a place for focus. Default: the control itself. */\n item?: HTMLElement | null;\n /**\n * What the item sits in, whose controls are its neighbours. Default: the item's parent. Null for an item in no group of\n * its own (Load more's pager, which may sit in a layout's empty box, Sprint 25.31 item 4): with nowhere else, the last\n * resort round where it sat.\n */\n group?: HTMLElement | null;\n /**\n * Where focus belongs next, when it's on the page then (Sprint 25.29 item 2: a chat's suggestion, gone once its message\n * is sent, hands focus to the message field); else the rule above. Read when focus moves, so a control drawn by then\n * counts. One that isn't a Tab stop (a row with nothing in it to Tab to: the first a last Load more brought, Sprint\n * 25.30 item 1) takes focus for the moment.\n */\n to?: HTMLElement | null | (() => HTMLElement | null | undefined);\n}\n\n/**\n * The library's rule for a control that removes itself, or the item it belongs to (Sprint 25.8.7 item 33, D72): Sprint\n * 26 found focus falling to the page after an Alert's Dismiss and a Tag's remove. Focus goes to the item's neighbour in\n * its group, in rule 4's order (D14(c), as `focusAfterRemoval` orders a list): the same control in the item before (else\n * the nearest control before it that takes focus then), else in the item after (else the nearest after), else the group\n * itself. A control disabled as the press began counts, once the press has enabled it (Sprint 25.29 item 2: TransferList's\n * \"Move all left\", once everything has moved right). Call it as the control acts, before the removal: it reads the\n * group's controls now, while the item is in the page, and moves focus once the control has gone (left the page, or been disabled) with focus\n * lost, within 10 s, so a page that removes the item after a server round trip is served too, and focus the page moved\n * itself stays where the page put it. Returns a function that stops the watch.\n */\nexport function focusAfterSelfRemoval(control: HTMLElement, { item, group, to }: SelfRemovalOptions = {}): () => void {\n const goes = item ?? control;\n const within = group === undefined ? goes.parentElement : group;\n const stops = within ? mayStop(within).filter((el) => !goes.contains(el)) : [];\n const before = stops.filter((el) => goes.compareDocumentPosition(el) & Node.DOCUMENT_POSITION_PRECEDING).reverse();\n const after = stops.filter((el) => goes.compareDocumentPosition(el) & Node.DOCUMENT_POSITION_FOLLOWING);\n // the same control in the neighbouring item, as rememberFocus finds it in a row: the next tag's remove button after a\n // remove, so the keyboard can go on removing\n const stopsOf = (el: Element) => [...(isTabStop(el) ? [el] : []), ...tabStops(el)];\n const index = stopsOf(goes).indexOf(control);\n const neighbour = (step: \"previousElementSibling\" | \"nextElementSibling\") => {\n for (let el = goes[step]; el; el = el[step]) {\n const own = stopsOf(el);\n if (own.length) return own[Math.max(0, Math.min(index, own.length - 1))];\n }\n return null;\n };\n const sameBefore = neighbour(\"previousElementSibling\");\n const sameAfter = neighbour(\"nextElementSibling\");\n const gone = () => !control.isConnected || (control instanceof HTMLButtonElement && control.disabled);\n const lost = () => {\n const active = document.activeElement;\n return !active || active === document.body || !active.isConnected || active === control;\n };\n const land = (el: HTMLElement | null | undefined) => {\n if (!el || !el.isConnected || !isTabStop(el)) return false;\n el.focus();\n return document.activeElement === el;\n };\n // a group that takes no focus is given it for the moment, as an error summary is (focus by script, never by Tab); its\n // tabindex comes off as focus leaves it (focusForTheMoment, Sprint 25.31 item 4: it stayed, on a box left empty)\n const landOnGroup = () => !!within?.isConnected && focusForTheMoment(within);\n // no group: where the item sat, read now while it's in the page\n const places = within ? [] : placesOf(goes);\n const landTo = (el: HTMLElement | null | undefined) => land(el) || (!!el && el.isConnected && !isTabStop(el) && isRendered(el) && focusForTheMoment(el));\n const place = () => landTo(typeof to === \"function\" ? to() : to) || land(sameBefore) || before.some(land) || land(sameAfter) || after.some(land) || (within ? landOnGroup() : landLastResort(places));\n if (typeof MutationObserver === \"undefined\") return () => {};\n const observer = new MutationObserver(() => {\n if (!gone()) return;\n stop();\n if (lost()) place();\n });\n const onFocusIn = (e: FocusEvent) => { if (e.target !== control) stop(); };\n const timer = setTimeout(() => stop(), 10_000);\n function stop() {\n observer.disconnect();\n clearTimeout(timer);\n // its timer can outlive the page (a test's)\n if (typeof document !== \"undefined\") document.removeEventListener(\"focusin\", onFocusIn, true);\n }\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: [\"disabled\"] });\n document.addEventListener(\"focusin\", onFocusIn, true);\n return stop;\n}\n\n// ─── Overlay layers ──────────────────────────────────────────────────────────\n// Every overlay that closes on Escape listens on `document`, so a Dropdown open\n// inside a Drawer used to close both with one key press. Open overlays register\n// here in the order they opened; only the topmost one acts on a global key.\n// (Two overlays opening in the same commit register child-first; in practice\n// overlays open one user action at a time.)\n\nconst layers: symbol[] = [];\n\n/**\n * Register this overlay as a layer while `open`. Returns a stable predicate\n * that is true when this overlay is the topmost open one — check it before\n * acting on Escape or trapping Tab.\n */\nexport function useOverlayLayer(open: boolean): () => boolean {\n const [id] = useState(() => Symbol(\"overlay-layer\"));\n useEffect(() => {\n if (!open) return;\n layers.push(id);\n return () => {\n const i = layers.indexOf(id);\n if (i >= 0) layers.splice(i, 1);\n };\n }, [open, id]);\n return useCallback(() => layers[layers.length - 1] === id, [id]);\n}\n\n/** Number of registered overlay layers (test seam). */\nexport function getOverlayLayerCount(): number {\n return layers.length;\n}\n\n// ─── Close on focus-out ──────────────────────────────────────────────────────\n\n/**\n * Close a non-modal popover (menu, picker, panel) when keyboard focus leaves\n * both its trigger and its panel — Tab and Shift+Tab out, or focus leaving the\n * document. Nested overlays (a Dropdown inside a Popover) register a layer on\n * top, so focus moving into them does not count as leaving. A pointer-down on\n * a non-focusable spot inside the panel briefly sends focus to body; that is\n * ignored so clicking panel chrome never closes it.\n */\nexport function useCloseOnFocusOut(\n open: boolean,\n triggerRef: RefObject<HTMLElement | null>,\n panelRef: RefObject<HTMLElement | null>,\n onClose: () => void,\n isTop: () => boolean = ALWAYS_TOP,\n) {\n // Latest-value ref written in a layout effect, not during render (React Compiler `refs` rule).\n const onCloseRef = useLatest(onClose);\n useEffect(() => {\n if (!open) return;\n let pointerInside = false;\n const inside = (n: EventTarget | Node | null) =>\n n instanceof Node && (!!triggerRef.current?.contains(n) || !!panelRef.current?.contains(n));\n const onPointerDown = (e: PointerEvent) => { pointerInside = inside(e.target); };\n const onFocusOut = (e: FocusEvent) => {\n if (!inside(e.target)) return;\n if (e.relatedTarget) {\n if (!inside(e.relatedTarget) && isTop()) onCloseRef.current();\n return;\n }\n setTimeout(() => {\n if (pointerInside) { pointerInside = false; return; }\n if (!inside(document.activeElement) && isTop()) onCloseRef.current();\n }, 0);\n };\n document.addEventListener(\"pointerdown\", onPointerDown, true);\n document.addEventListener(\"focusout\", onFocusOut, true);\n return () => {\n document.removeEventListener(\"pointerdown\", onPointerDown, true);\n document.removeEventListener(\"focusout\", onFocusOut, true);\n };\n }, [open, triggerRef, panelRef, isTop, onCloseRef]);\n}\n\n// ─── Close on a press outside ───────────────────────────────────────────────\n\n/**\n * Marks the presses that pass through a component's React tree, so a document\n * listener can tell a press inside it from one outside (Sprint 25.7; Radix's\n * dismissable layer). A popup that content inside it renders elsewhere in the\n * page — a Dropdown's list, a DatePicker's calendar, a Dialog — is outside its\n * element tree, but React carries the press through its own tree first. Spread\n * `props` on the tree's outer element; `marked(e)` is true for a pointer or\n * mouse press that went through it.\n */\nexport function usePressMarks() {\n const [marks] = useState(() => new WeakSet<Event>());\n return useMemo(() => {\n const mark = (e: { nativeEvent: Event }) => { marks.add(e.nativeEvent); };\n return { props: { onPointerDownCapture: mark, onMouseDownCapture: mark }, marked: (e: Event) => marks.has(e) };\n }, [marks]);\n}\n\n/**\n * Call `onOutside` for a pointer press outside `ref`'s element and its React\n * tree (Sprint 25.7): spread the returned handler on the element. For a\n * container that is not an overlay layer (the builder's floating toolbar).\n */\nexport function usePressOutside(enabled: boolean, ref: RefObject<HTMLElement | null>, onOutside: (e: PointerEvent) => void) {\n const onOutsideRef = useLatest(onOutside);\n const { props, marked } = usePressMarks();\n useEffect(() => {\n if (!enabled) return;\n const onPointerDown = (e: PointerEvent) => {\n if (marked(e) || (e.target instanceof Node && ref.current?.contains(e.target))) return;\n onOutsideRef.current(e);\n };\n document.addEventListener(\"pointerdown\", onPointerDown);\n return () => document.removeEventListener(\"pointerdown\", onPointerDown);\n }, [enabled, ref, onOutsideRef, marked]);\n return { onPointerDownCapture: props.onPointerDownCapture };\n}\n\n// ─── Leaving a component ─────────────────────────────────────────────────────\n\n/**\n * Focus leaving a component: a blur that no focus inside its React tree follows straight away (round 26's Field check,\n * shared with DataGrid's cell editor in Sprint 25.8.7 item 19). React carries focus events through portals, so focus\n * moving into the component's own popup (a Dropdown's list, a DatePicker's calendar) comes back in and is not leaving.\n * Spread the handlers on the component's outer element; `onLeave` runs a task after the blur, once focus has gone.\n */\nexport function useFocusLeave(onLeave: () => void): { onFocusCapture: () => void; onBlurCapture: () => void } {\n const onLeaveRef = useLatest(onLeave);\n const leaving = useRef<ReturnType<typeof setTimeout> | null>(null);\n useEffect(() => () => { if (leaving.current) clearTimeout(leaving.current); }, []);\n return useMemo(() => ({\n onFocusCapture: () => {\n if (leaving.current) { clearTimeout(leaving.current); leaving.current = null; }\n },\n onBlurCapture: () => {\n if (leaving.current) clearTimeout(leaving.current);\n leaving.current = setTimeout(() => {\n leaving.current = null;\n onLeaveRef.current();\n }, 0);\n },\n }), [onLeaveRef]);\n}\n\n// ─── Popup focus (Sprint 25.7) ───────────────────────────────────────────────\n// Every non-modal popup — a list, a menu, a picker, a panel — renders in a portal\n// at the end of <body>. Without help, a choice removes the focused option and\n// focus falls to the page, and Tab out of the panel moves on from the end of the\n// document. usePopupFocus hands focus back and makes Tab carry on from the\n// control that opened the popup, in the browser's own order.\n\nexport type PopupTabExits = \"any\" | \"edges\" | \"none\";\n\ninterface OpenPopup {\n panel: RefObject<HTMLElement | null>;\n tabExits: PopupTabExits;\n leave: (e: KeyboardEvent) => void;\n}\n\n/** Open popups, so a popup inside another popup's panel can hand a Tab exit on to it. */\nconst openPopups = new Map<symbol, OpenPopup>();\n\nexport interface PopupFocusOptions {\n trigger: RefObject<HTMLElement | null>;\n panel: RefObject<HTMLElement | null>;\n /** Closes the popup (sets its open state false). */\n close: () => void;\n /**\n * How Tab leaves the panel. \"any\": every Tab leaves (single-stop lists and\n * menus). \"edges\": Tab leaves from the panel's last Tab stop and Shift+Tab\n * from its first (panels with several stops). \"none\": focus never enters the\n * panel (a combobox keeps it in its input), so the browser's Tab is left alone.\n */\n tabExits: PopupTabExits;\n /** Runs first when Tab leaves, before the popup closes — a list commits the option the user moved to (D14(a)). */\n onTabOut?: (e: KeyboardEvent) => void;\n /**\n * True for a press that went through the popup's React tree (`usePressMarks`), so a press in a list its content\n * opened elsewhere in the page is not a press outside it.\n */\n marked?: (e: Event) => boolean;\n}\n\n/**\n * Focus for a non-modal popup (Sprint 25.7, P10):\n * - records the opener when the popup opens (the trigger when focus was on the page);\n * - closes on focus-out, and registers the overlay layer (`isTop`);\n * - Tab out of the panel closes it and carries on from the opener: Shift+Tab lands\n * on the opener; Tab puts focus on the opener and lets the browser's own Tab run,\n * except that inside a modal the opener's being its last stop wraps to its first,\n * and inside another popup's panel that popup's own exit rule then applies;\n * - on close, when focus was lost (the focused option went with the panel), puts it\n * back — unless the close followed a press outside the popup and its React tree\n * (`marked`), or the page changed; inside a modal, a press outside that left focus\n * on nothing gives it back too, so focus never drops out of the modal;\n * - returns `returnFocus()`, which a select handler calls before the consumer's\n * callback so a dialog that callback opens records the opener, and any focus\n * move the consumer makes wins.\n */\nexport function usePopupFocus(open: boolean, { trigger, panel, close, tabExits, onTabOut, marked }: PopupFocusOptions) {\n const isTop = useOverlayLayer(open);\n const [id] = useState(() => Symbol(\"popup\"));\n const closeRef = useLatest(close);\n const onTabOutRef = useLatest(onTabOut);\n const markedRef = useLatest(marked);\n const remembered = useRef<RememberedFocus | null>(null);\n // The last press while open, and whether it was in the trigger or panel; a key press since clears it.\n const lastPress = useRef<{ e: Event; inside: boolean } | null>(null);\n const wasOpen = useRef(false);\n\n useCloseOnFocusOut(open, trigger, panel, close, isTop);\n\n // The opener, as it was before this commit (content with autoFocus moves focus in during it).\n const before = useFocusBeforeOpen(open);\n useLayoutEffect(() => {\n if (!open) return;\n const active = before.current;\n const inPanel = active instanceof Node && !!panel.current?.contains(active);\n const opener = active instanceof HTMLElement && active !== document.body && !inPanel ? active : trigger.current;\n remembered.current = opener ? rememberFocus(opener) : null;\n // kept by the panel, for an overlay opened from inside it that outlives it (Sprint 25.29 item 4)\n if (panel.current && remembered.current) openers.set(panel.current, remembered.current);\n lastPress.current = null;\n }, [open, trigger, panel, before]);\n\n useEffect(() => {\n if (!open) return;\n const onPointerDown = (e: PointerEvent) => {\n const t = e.target;\n lastPress.current = { e, inside: t instanceof Node && (!!trigger.current?.contains(t) || !!panel.current?.contains(t)) };\n };\n const onKeyPress = () => { lastPress.current = null; };\n const leave = (e: KeyboardEvent) => {\n onTabOutRef.current?.(e);\n const r = remembered.current;\n const opener = r && r.el.isConnected ? r.el : trigger.current;\n // Focus the opener, then close now, so the panel is gone before the browser moves focus on.\n opener?.focus();\n flushSync(() => closeRef.current());\n if (!opener || !opener.isConnected) return;\n if (e.shiftKey) {\n e.preventDefault();\n return;\n }\n const modal = opener.closest<HTMLElement>('[aria-modal=\"true\"]');\n if (modal) {\n const stops = tabStops(modal);\n if (stops.length && stops[stops.length - 1] === opener) {\n e.preventDefault();\n stops[0].focus();\n return;\n }\n }\n for (const [otherId, other] of openPopups) {\n const outer = other.panel.current;\n if (otherId === id || !outer?.contains(opener)) continue;\n const stops = tabStops(outer);\n if (other.tabExits === \"any\" || stops[stops.length - 1] === opener) {\n other.leave(e);\n return;\n }\n break;\n }\n // The browser's own Tab carries on from the opener.\n };\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key !== \"Tab\" || e.defaultPrevented || tabExits === \"none\" || !isTop()) return;\n const p = panel.current;\n const active = document.activeElement;\n if (!p || !(active instanceof Node) || !p.contains(active)) return;\n if (tabExits === \"edges\") {\n const stops = tabStops(p);\n if (stops.length && active !== (e.shiftKey ? stops[0] : stops[stops.length - 1])) return;\n }\n leave(e);\n };\n openPopups.set(id, { panel, tabExits, leave });\n document.addEventListener(\"pointerdown\", onPointerDown, true);\n document.addEventListener(\"keydown\", onKeyPress, true);\n document.addEventListener(\"keydown\", onKeyDown);\n return () => {\n openPopups.delete(id);\n document.removeEventListener(\"pointerdown\", onPointerDown, true);\n document.removeEventListener(\"keydown\", onKeyPress, true);\n document.removeEventListener(\"keydown\", onKeyDown);\n };\n }, [open, tabExits, isTop, id, trigger, panel, closeRef, onTabOutRef]);\n\n // The safety net: a close the component could not see (content that closes it,\n // a choice that removed the focused option) puts focus back when it was lost.\n useLayoutEffect(() => {\n if (open) {\n wasOpen.current = true;\n return;\n }\n if (!wasOpen.current) return;\n wasOpen.current = false;\n const r = remembered.current;\n remembered.current = null;\n // A close that followed a press outside the popup (and outside its React tree) leaves focus to that press.\n const press = lastPress.current;\n if (!r) return;\n if (press && !press.inside && !markedRef.current?.(press.e)) {\n // Inside a modal, a press on nothing that takes focus (its text, its padding) would drop focus out of the modal\n // onto the page, so the control that opened the popup takes it back, once the press has done its own focusing\n // (Sprint 25.8.7 item 35: a date picker in a phone's sheet, closed by a tap beside it). On the page itself, focus\n // on nothing after a press on nothing is the browser's own, and stays.\n const modal = r.el.closest('[aria-modal=\"true\"]');\n const target = press.e.target;\n if (modal && target instanceof Node && modal.contains(target)) {\n setTimeout(() => {\n const active = document.activeElement;\n if (active && active !== document.body && active.isConnected) return;\n if (modal.isConnected) r.restore(trigger.current);\n }, 0);\n }\n return;\n }\n // Focus that is somewhere real stays there: the user or the consumer put it there. Focus on the opener is\n // checked again, because the choice may have deleted the opener's row in this commit (see rememberFocus).\n const active = document.activeElement;\n if (active !== r.el && active && active !== document.body && active.isConnected) return;\n r.restore(trigger.current);\n }, [open, trigger, markedRef]);\n\n // Removed while open with focus in it (a row menu whose Delete removed its own row): give focus back once the DOM\n // has settled. The panel is still in the page while this runs. A popup focus never went into (a flyout opened by\n // hover) leaves focus where it is.\n useLayoutEffect(() => () => {\n if (!wasOpen.current) return;\n const active = document.activeElement;\n if (!(active instanceof Node) || !(panel.current?.contains(active) || trigger.current?.contains(active))) return;\n const r = remembered.current;\n queueMicrotask(() => {\n const now = document.activeElement;\n if (now && now !== document.body && now.isConnected) return;\n r?.restore();\n });\n }, [panel, trigger]);\n\n const returnFocus = useCallback(() => {\n remembered.current?.restore(trigger.current);\n }, [trigger]);\n\n return { isTop, returnFocus };\n}\n\n// ─── Grid keyboard (Sprint 25.7, P11) ────────────────────────────────────────\n\nexport interface GridKeyboardOptions<K> {\n /** Holds the items, which carry `data-grid-key={keyOf(item)}`. */\n container: RefObject<HTMLElement | null>;\n /** The item that is the Tab stop. Keep it in step with focus (setActive from the item's onFocus). */\n active: K;\n setActive: (item: K) => void;\n keyOf: (item: K) => string;\n /** Where a key moves focus from `from` (arrows, Home, End: the caller's geometry), or null for a key it leaves alone. */\n move: (from: K, e: ReactKeyboardEvent) => K | null;\n /** Enter and Space on an item. */\n onActivate?: (item: K, e: ReactKeyboardEvent) => void;\n /**\n * Printable keys go to the next item whose label starts with what was typed in the last 500 ms (the same letter\n * again cycles). Never the zoom keys (+, = and −), never with Ctrl, ⌘ or Alt.\n */\n typeahead?: { items: readonly K[]; labelOf: (item: K) => string };\n /** Runs after focus moves to an item, in place of the browser's own scrolling (a time view keeps the item clear of its pinned column). */\n scrollIntoView?: (key: string, el: HTMLElement) => void;\n /**\n * Keys held with Ctrl, ⌘ or Alt go to `move` too: an APG grid's Ctrl+Home and Ctrl+End. Typeahead and activation\n * still ignore them. Off by default, so the browser keeps its own (Alt+Left is Back).\n */\n modifierKeys?: boolean;\n}\n\nexport interface GridKeyboard<K> {\n /** On the container. */\n onKeyDown: (e: ReactKeyboardEvent) => void;\n tabIndexOf: (item: K) => 0 | -1;\n /** Focus the active item (after the next render when it is not in the DOM yet). */\n focusActive: () => void;\n /** Focus an item, as a key would (after the next render when it is not in the DOM yet); keep `active` in step. */\n focus: (item: K) => void;\n}\n\nconst TYPEAHEAD_MS = 500;\n/** The keys a time view zooms with (TimeViewport), in and out; typeahead leaves them to it. U+2212 is the minus sign. */\nexport const ZOOM_KEYS: { readonly in: readonly string[]; readonly out: readonly string[] } = { in: [\"+\", \"=\"], out: [\"-\", \"\\u2212\"] };\nconst isZoomKey = (key: string) => ZOOM_KEYS.in.includes(key) || ZOOM_KEYS.out.includes(key);\n\nfunction focusGridKey(root: HTMLElement | null, key: string, scrollIntoView?: (key: string, el: HTMLElement) => void): boolean {\n const el = root?.querySelector<HTMLElement>(`[data-grid-key=\"${CSS.escape(key)}\"]`);\n if (!el) return false;\n el.focus(scrollIntoView ? { preventScroll: true } : undefined);\n scrollIntoView?.(key, el);\n return true;\n}\n\n/** The next item whose label starts with `text`: a new search (one letter, or one letter repeated) starts after `from`. */\nfunction typeaheadMatch<K>(items: readonly K[], labelOf: (item: K) => string, keyOf: (item: K) => string, fromKey: string, text: string): K | null {\n const chars = [...text];\n const query = chars.every((c) => c === chars[0]) ? chars[0] : text;\n const at = items.findIndex((item) => keyOf(item) === fromKey);\n const first = at < 0 ? 0 : at + (query.length === 1 ? 1 : 0);\n for (let k = 0; k < items.length; k++) {\n const item = items[(first + k) % items.length];\n if (labelOf(item).trim().toLocaleLowerCase().startsWith(query)) return item;\n }\n return null;\n}\n\n/**\n * One Tab stop over a grid or rows of items (APG grid and tree patterns): the caller says where each key moves\n * (`move`), and the hook keeps the roving tabindex and puts focus on the new item — after the next render when the\n * item is not in the DOM yet (a date grid moving into the next month). Enter and Space activate, typeahead jumps by\n * label, and `scrollIntoView` places the item. It works by key, not DOM position, so a virtualised list can use it.\n * Keys typed in a field inside the container are left alone. Built for the date pickers, extended in Part D for\n * time-axis rows (it is Sprint 2X.3's `useGridNavigation`).\n */\nexport function useGridKeyboard<K>({ container, active, setActive, keyOf, move, onActivate, typeahead, scrollIntoView, modifierKeys = false }: GridKeyboardOptions<K>): GridKeyboard<K> {\n const pending = useRef<string | null>(null);\n const typed = useRef({ text: \"\", at: 0 });\n // One try, on the render the move caused: a key that never renders is dropped, so a later render cannot steal focus.\n useLayoutEffect(() => {\n const key = pending.current;\n if (key === null) return;\n pending.current = null;\n focusGridKey(container.current, key, scrollIntoView);\n });\n const activeKey = keyOf(active);\n const go = (next: K) => {\n const key = keyOf(next);\n setActive(next);\n if (!focusGridKey(container.current, key, scrollIntoView)) pending.current = key;\n };\n const onKeyDown = (e: ReactKeyboardEvent) => {\n const modified = e.altKey || e.ctrlKey || e.metaKey;\n if (e.defaultPrevented || (modified && !modifierKeys)) return;\n // React passes on keys from a portal opened inside an item (a dialog, a menu): they are that popup's own\n if (!(e.currentTarget as Node).contains(e.target as Node)) return;\n const target = e.target instanceof HTMLElement ? e.target : null;\n if (target?.closest(FIELD)) return;\n const next = move(active, e);\n if (next !== null) {\n e.preventDefault();\n go(next);\n return;\n }\n // Activation and typeahead act on the item itself, not a control inside it, and never with a modifier held.\n if (modified || target?.getAttribute(\"data-grid-key\") !== activeKey) return;\n const buffered = typed.current.text !== \"\" && Date.now() - typed.current.at <= TYPEAHEAD_MS;\n if (onActivate && (e.key === \"Enter\" || (e.key === \" \" && !buffered))) {\n e.preventDefault();\n onActivate(active, e);\n return;\n }\n if (!typeahead || [...e.key].length !== 1 || isZoomKey(e.key) || (e.key === \" \" && !buffered)) return;\n const text = (buffered ? typed.current.text : \"\") + e.key.toLocaleLowerCase();\n typed.current = { text, at: Date.now() };\n const match = typeaheadMatch(typeahead.items, typeahead.labelOf, keyOf, activeKey, text);\n if (match === null) return;\n e.preventDefault();\n if (keyOf(match) !== activeKey) go(match);\n };\n const focus = (item: K) => {\n const key = keyOf(item);\n if (!focusGridKey(container.current, key, scrollIntoView)) pending.current = key;\n };\n const focusActive = () => focus(active);\n const tabIndexOf = (item: K): 0 | -1 => (keyOf(item) === activeKey ? 0 : -1);\n return { onKeyDown, tabIndexOf, focusActive, focus };\n}\n\n// ─── Focus trap ──────────────────────────────────────────────────────────────\n\nconst ALWAYS_TOP = () => true;\n\n/**\n * Keep Tab and Shift+Tab inside `root` while `active` (corpus: a modal\n * overlay owns keyboard focus until it closes). Focus that has escaped the\n * root — a portalled menu that just closed, or the body — is pulled back in on\n * the next Tab. Pass the predicate from `useOverlayLayer` so a nested overlay\n * on top of this one keeps its own keyboard handling.\n */\nexport function useFocusTrap(root: RefObject<HTMLElement | null>, active: boolean, isTop: () => boolean = ALWAYS_TOP, also?: RefObject<HTMLElement | null> | null) {\n useEffect(() => {\n if (!active) return;\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key !== \"Tab\" || e.defaultPrevented || !root.current || !isTop()) return;\n // the trap's scope: the overlay, and what stays in it outside the overlay (the shell's navbar above its phone menu,\n // Sprint 25.29 item 9), in the page's order\n const scope = [root.current, also?.current].filter((el): el is HTMLElement => !!el);\n const focusable = scope.flatMap((el) => tabStops(el))\n .sort((a, b) => (a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1));\n if (focusable.length === 0) {\n e.preventDefault();\n return;\n }\n const first = focusable[0];\n const last = focusable[focusable.length - 1];\n const current = document.activeElement;\n const inside = current instanceof Node && scope.some((el) => el.contains(current));\n if (e.shiftKey) {\n if (!inside || current === first) {\n e.preventDefault();\n last.focus();\n }\n } else if (!inside || current === last) {\n e.preventDefault();\n first.focus();\n }\n };\n document.addEventListener(\"keydown\", onKeyDown);\n return () => document.removeEventListener(\"keydown\", onKeyDown);\n }, [root, active, isTop, also]);\n}\n\n/**\n * Everything in `within` made inert but what `keep` holds (Sprint 25.29 item 9: the shell's phone menu is modal with the\n * navbar in its scope): the highest elements that hold none of it. Returns a function that undoes it; an element already\n * inert stays as the page made it.\n */\nexport function inertOutside(keep: Element[], within: Element): () => void {\n const made: Element[] = [];\n const visit = (el: Element) => {\n for (const child of Array.from(el.children)) {\n if (keep.includes(child)) continue;\n if (keep.some((k) => child.contains(k))) visit(child);\n else if (!child.hasAttribute(\"inert\")) {\n child.setAttribute(\"inert\", \"\");\n made.push(child);\n }\n }\n };\n visit(within);\n return () => { for (const el of made) el.removeAttribute(\"inert\"); };\n}\n\n// ─── Non-modal dialog ────────────────────────────────────────────────────────\n\n/**\n * The lifecycle of a persistent, non-modal dialog — an assistant panel the\n * user works alongside (Drawer with modal={false}, CornerPanel). Unlike a\n * popover it does not close when focus leaves; unlike a modal it never traps.\n *\n * While `active`: remembers the opener and gives focus back on close when focus\n * was lost or inside the panel, never from where the user moved it; moves focus\n * into the panel on open (first field, else first non-close control); closes on\n * Escape only while focus is inside the panel, it is the topmost layer and\n * nothing inside handled the key, so Escape elsewhere is untouched. Outside\n * clicks do nothing. Tab out of the panel is allowed — the panel is portalled to the end\n * of the document, so the last Tab reaches the browser chrome; a Launcher\n * shortcut is the way back in.\n */\nexport function useNonModalDialog(\n root: RefObject<HTMLElement | null>,\n active: boolean,\n onClose: () => void,\n isTop: () => boolean = ALWAYS_TOP,\n) {\n const onCloseRef = useLatest(onClose);\n useReturnFocus(active, root);\n useEffect(() => {\n if (!active) return;\n const raf = requestAnimationFrame(() => focusInitial(root.current));\n return () => cancelAnimationFrame(raf);\n }, [active, root]);\n useEffect(() => {\n if (!active) return;\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key !== \"Escape\" || e.defaultPrevented || !isTop()) return;\n const el = root.current;\n if (!el || !el.contains(document.activeElement)) return;\n e.preventDefault();\n onCloseRef.current();\n };\n document.addEventListener(\"keydown\", onKeyDown);\n return () => document.removeEventListener(\"keydown\", onKeyDown);\n }, [active, root, isTop, onCloseRef]);\n}\n","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 * FOCUS_INSET only while the element is a scroll region's Tab stop (useKeyboardScroll's `data-scroll-stop`), for one that\n * takes focus by script for another reason and shows no ring for it: the shell's <main>, the skip link's target (Sprint\n * 25.29 item 10).\n */\nexport const FOCUS_INSET_WHILE_STOP = \"data-[scroll-stop]:focus-visible:outline-2 data-[scroll-stop]:focus-visible:outline-solid data-[scroll-stop]:focus-visible:-outline-offset-[var(--ds-focus-inset)] data-[scroll-stop]: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","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/components/NumberInput.tsx","../../../showcase/src/components/Popover.tsx","../../../showcase/src/components/Pagination.tsx","../../../showcase/src/lib/use-pagination.ts"],"names":["useRef","useState","useCallback","jsxs","jsx","useEffect","sizes"],"mappings":"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","file":"chunk-V2ARGHJN.js","sourcesContent":["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 /** The field's name where nothing on screen names it (\"Seats\"); inside a Field, the Field's label names it. */\n \"aria-label\"?: 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 \"aria-label\": ariaLabel,\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 // Sprint 25.8.7 item 24, the APG spinbutton: \"Home: If the spinbutton has a minimum value, sets the value to its\n // minimum\", and End its maximum. Without that limit, or with a modifier held (Shift+Home selects), the key is the\n // caret's: the pattern keeps the platform's text editing keys for a field that can be typed in\n const plain = !e.shiftKey && !e.ctrlKey && !e.metaKey && !e.altKey;\n if (e.key === \"Home\" && plain && Number.isFinite(min)) { e.preventDefault(); commitValue(min); }\n if (e.key === \"End\" && plain && Number.isFinite(max)) { e.preventDefault(); commitValue(max); }\n },\n [increment, decrement, commitValue, min, max],\n );\n\n const s = sizes[size];\n const atMin = value <= min;\n const atMax = value >= max;\n // Sprint 25.8.7 item 24: the value is stated while the field holds a number (\"Authors SHOULD set the aria-valuenow\n // attribute when the spinbutton has a value\", WAI-ARIA 1.2), not while it is emptied to type afresh; it is the\n // committed value, which typing keeps within the limits\n const shown = focused ? draft : String(value);\n const holdsNumber = Number.isFinite(parseFloat(shown)) && Number.isFinite(value);\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 // a spinbutton that can be typed in (Sprint 25.8.7 item 24): its value, and each limit only when it exists\n role=\"spinbutton\"\n aria-label={ariaLabel}\n aria-valuenow={holdsNumber ? value : undefined}\n aria-valuemin={Number.isFinite(min) ? min : undefined}\n aria-valuemax={Number.isFinite(max) ? max : undefined}\n inputMode={decimals ? \"decimal\" : \"numeric\"}\n aria-invalid={error || undefined}\n value={shown}\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 { focusAfterSelfRemoval, isTabStop, tabStops } from \"../lib/focus\";\nimport { Icon } from \"../lib/icons\";\nimport { Dropdown } from \"./Dropdown\";\nimport { Popover } from \"./Popover\";\nimport { NumberInput } from \"./NumberInput\";\nimport { Button } from \"./Button\";\nimport { AutoTooltip } from \"./Tooltip\";\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 * Keyboard focus on the button holds the list (Sprint 25.29 item 7): focus brought it into view, not a scroll, and each\n * load pushed it off the screen again. Enter loads, and the button is brought back into view; focus leaving looks again.\n * Only a load the keyboard's press made brings it back (Sprint 25.31 item 3): a clicked button has focus too, and bringing\n * it into view after every load scrolled, which loaded again, so one click loaded every page.\n * The last load takes the button with it, so focus goes to the first row that load brought (Sprint 25.30 item 1), in\n * whatever markup the list draws (Sprint 25.31 item 4), and the list holds no more (item 5). Only the press's own load\n * hands focus on: a load that leaves the button in place ends the press's watch.\n */\nfunction LoadMore({ hasMore, onLoadMore, loadMoreLabel, currentPage, scroll, className }: PaginationProps & { onLoadMore: () => void; scroll: boolean }) {\n const marker = useRef<HTMLDivElement>(null);\n const button = useRef<HTMLButtonElement>(null);\n const pager = useRef<HTMLDivElement>(null);\n // a press's watches: for the button going with its load (to hand focus on), and for its rows (to bring the button back)\n const watching = useRef<(() => void) | null>(null);\n const endWatch = () => {\n watching.current?.();\n watching.current = null;\n };\n // keyboard focus on the infinite list's button holds it (Sprint 25.29 item 7)\n const [held, setHeld] = useState(false);\n // a press with focus on the button: should it be the last, focus goes on to the first row it brought, the person\n // reading on where they asked to, else the last control before the pager, else the last resort round where it sat\n const press = () => {\n const b = button.current, root = pager.current;\n if (b && root && document.activeElement === b) {\n // the infinite list's: only while the keyboard holds it, since a mouse's focus shows the ring once a key is pressed,\n // and a scroll back would load again (the review of 16 October, 2). Plain Load more holds nothing, and no load\n // follows a scroll there: the keyboard's ring is enough.\n const byKey = scroll ? held : byKeyboard(b);\n const place = placeOf(root);\n const had = before(place);\n const hadRows = had.flatMap(rowsOf);\n const hadStops = had.flatMap(stopsIn);\n endWatch();\n // the watch lasts until the button goes (focus handed on), focus moves elsewhere, the next press, a load the list\n // starts by itself, or 10 s: never ended by the page number, which a page may count before its rows come (the\n // final review of 16 October, 1: the watch ended then, and the last load left focus on the page)\n const handOn = focusAfterSelfRemoval(b, {\n item: root,\n group: null,\n to: () => {\n // what the load brought, read again now it's in: the library's rows (a row with nothing in it to Tab to takes\n // focus itself, for the moment), else the Tab stops that appeared since the press, whatever the page draws\n const content = before(place);\n const fresh = appended(content.flatMap(rowsOf), hadRows);\n if (fresh) return tabStops(fresh)[0] ?? fresh;\n const stops = content.flatMap(stopsIn);\n return appended(stops, hadStops) ?? stops.at(-1);\n },\n });\n // a load by Enter: once its rows are in, above the button, with the button still here, it's brought back into view;\n // its rows, not its page number, which can come first (the final review, 1)\n const backInView = byKey ? whenRowsCome(place, hadRows, hadStops, b, () => { if (document.activeElement === b) b.scrollIntoView?.({ block: \"nearest\" }); }) : () => {};\n watching.current = () => { handOn(); backInView(); };\n }\n onLoadMore();\n };\n const load = useLatest(onLoadMore);\n const loadedAt = useRef<number | null>(null);\n // the last load takes the focused button, which fires no blur, so the list would hold for good: a filter that starts it\n // again never loaded as it scrolled (Sprint 25.31 item 5)\n if (held && !hasMore) setHeld(false);\n useEffect(() => {\n const el = marker.current;\n if (!scroll || !hasMore || !el || held || 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 // a load the list starts by itself: a press's watch ends, so the list loading on as the person scrolls after a click\n // never takes focus back up to that press's rows (the reviews of 16 October, 1)\n watching.current?.();\n watching.current = null;\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, held]);\n if (!hasMore) return null;\n return (\n <div ref={pager} 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 ref={button} type=\"button\" variant=\"secondary\" onClick={press}\n onFocus={(e) => setHeld(scroll && byKeyboard(e.currentTarget))} onBlur={() => setHeld(false)}>\n {loadMoreLabel ?? \"Load more\"}\n </Button>\n </div>\n );\n}\n\n/** Where a pager sits: the pager, or the nearest box round it with elements before it, its parent, and what follows it. */\ninterface PagerPlace { at: Element; parent: Element; next: Element | null }\n\n/**\n * A pager's place, read as a press begins (Sprint 25.31 item 4): the pager itself where its list comes before it (A3:\n * the list's next sibling, or the last child among the list's own items), else the nearest box round it that has\n * elements before it, as for a pager the page sets in a layout's box of its own.\n */\nfunction placeOf(el: Element): PagerPlace | null {\n for (let n: Element | null = el; n && n !== document.body; n = n.parentElement) {\n if (n.previousElementSibling && n.parentElement) return { at: n, parent: n.parentElement, next: n.nextElementSibling };\n }\n return null;\n}\n\n/**\n * What comes before that place now, its list among it: read again once a load is in, since new items can be the\n * pager's own siblings, and the last load takes the pager, whose place is then up to what followed it.\n */\nfunction before(place: PagerPlace | null): Element[] {\n if (!place) return [];\n const { at, parent, next } = place;\n const kids = Array.from(parent.children);\n const end = at.parentElement === parent ? kids.indexOf(at) : next?.parentElement === parent ? kids.indexOf(next) : kids.length;\n return kids.slice(0, end);\n}\n\n/** An element, when it matches, and what in it matches: rows and Tab stops can be the pager's own siblings. */\nconst withSelf = (el: Element, selector: string): Element[] => [...(el.matches(selector) ? [el] : []), ...el.querySelectorAll(selector)];\n\n/**\n * The rows in what a Load more follows: those the library's lists mark (the Table's rows and its cards on a phone,\n * `data-row-key` or `data-row-index`), else plain rows and items.\n */\nfunction rowsOf(list: Element): Element[] {\n const marked = withSelf(list, \"[data-row-key], [data-row-index]\");\n return marked.length ? marked : withSelf(list, 'tbody > tr, li, [role=\"row\"], [data-card]');\n}\n\n/** The Tab stops in an element, itself first. */\nconst stopsIn = (el: Element): HTMLElement[] => [...(isTabStop(el) ? [el] : []), ...tabStops(el)];\n\n/**\n * The first of `now`, in the page's order, that the press didn't see in `had`: lists append, so one after the last there\n * was, before one elsewhere, as a control the last load enabled above the list (the review of 16 October, 3).\n */\nfunction appended<T extends Element>(now: T[], had: Element[]): T | undefined {\n const seen = new Set(had);\n const fresh = now.filter((el) => !seen.has(el));\n const last = had.at(-1);\n return (last?.isConnected ? fresh.find((el) => last.compareDocumentPosition(el) & Node.DOCUMENT_POSITION_FOLLOWING) : undefined) ?? fresh[0];\n}\n\n/**\n * Calls `then` once the press's rows are in what comes before the pager, with the button still on the page (the final\n * review of 16 October, 1): a page may count the page as the press lands and draw its rows when they come. In a list the\n * library reads as rows, rows or Tab stops the press didn't see, so a spinner drawn first doesn't count; in one it can't\n * (a page's paragraphs), anything new before the pager. Ends with the button, or after 10 s. Returns what stops it.\n */\nfunction whenRowsCome(place: PagerPlace | null, hadRows: Element[], hadStops: Element[], button: HTMLElement, then: () => void): () => void {\n if (!place || typeof MutationObserver === \"undefined\") return () => {};\n const rows = new Set(hadRows), stops = new Set(hadStops);\n const observer = new MutationObserver((records) => {\n if (!button.isConnected) return stop();\n const content = before(place);\n const fresh = hadRows.length\n ? content.flatMap(rowsOf).some((r) => !rows.has(r)) || content.flatMap(stopsIn).some((s) => !stops.has(s))\n : records.some((r) => Array.from(r.addedNodes).some((n) => n instanceof Element && content.some((c) => c === n || c.contains(n))));\n if (!fresh) return;\n stop();\n then();\n });\n const timer = setTimeout(stop, 10_000);\n function stop() {\n observer.disconnect();\n clearTimeout(timer);\n }\n observer.observe(place.parent, { childList: true, subtree: true });\n return stop;\n}\n\n/** Focus the keyboard brought (`:focus-visible`), not a click; a browser without the selector counts every focus. */\nfunction byKeyboard(el: Element): boolean {\n try { return el.matches(\":focus-visible\"); } catch { return true; }\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 // the size in force is always among the choices: a project's size the options lack joins them (the review of 16 October,\n // 5: 20 against 10, 25 and 50 showed and read \"Select...\"), at its place in the page's own order (the final review, 4)\n const sizes = pageSizeOptions && pageSize != null ? withSize(pageSizeOptions, pageSize) : pageSizeOptions;\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's words, then the size chosen, which the Dropdown adds itself (WCAG 4.1.2, 2.5.3;\n Sprint 25.31 item 1): \"Rows per page, 10\" */}\n <Dropdown\n aria-label=\"Rows per page\"\n options={(sizes ?? 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 {/* an icon button's one tooltip, its name (Sprint 25.29 item 18, accessibility#10) */}\n <AutoTooltip content=\"Previous page\">\n <button type=\"button\"\n // a Previous on the first page turns disabled, which drops its focus: it hands focus on (Sprint 25.29 item 2)\n onClick={(e) => { focusAfterSelfRemoval(e.currentTarget); 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 </AutoTooltip>\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 <AutoTooltip content=\"Next page\">\n <button type=\"button\"\n // likewise a Next on the last page (Sprint 26's sweep; Sprint 25.29 item 2)\n onClick={(e) => { focusAfterSelfRemoval(e.currentTarget); 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 </AutoTooltip>\n </div>}\n </nav>\n );\n}\n\n/** `size` among `options`, at its place in their own order: largest first stays largest first. */\nfunction withSize(options: number[], size: number): number[] {\n if (options.includes(size)) return options;\n const descending = options.length > 1 && options.every((n, i) => i === 0 || options[i - 1] >= n);\n const at = options.findIndex((n) => (descending ? n < size : n > size));\n return at < 0 ? [...options, size] : [...options.slice(0, at), size, ...options.slice(at)];\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/page-actions.ts","../../../showcase/src/lib/surface-context.ts"],"names":["createContext"],"mappings":";;;;AAwBO,IAAM,cAAA,GAAiB,cAAsC,IAAI;AClBjE,IAAM,cAAA,GAAiBA,cAAc,KAAK;AAS1C,IAAM,YAAA,GAAeA,cAA6B,KAAK;AAOvD,IAAM,YAAA,GAAeA,cAAc,KAAK;AAUxC,IAAM,OAAA,GAAUA,cAAc,KAAK;AAWnC,IAAM,kBAAA,GAAqBA,cAAsC,IAAI,CAAA;AAE5E,SAAS,gBAAgB,IAAA,EAA4B;AACnD,EAAA,MAAM,MAAA,GAAS,WAAW,kBAAkB,CAAA;AAC5C,EAAA,eAAA,CAAgB,MAAM;AACpB,IAAA,IAAI,CAAC,MAAA,EAAQ;AACb,IAAA,MAAA,CAAO,MAAM,IAAI,CAAA;AACjB,IAAA,OAAO,MAAM,MAAA,CAAO,IAAA,EAAM,KAAK,CAAA;AAAA,EACjC,CAAA,EAAG,CAAC,MAAA,EAAQ,IAAI,CAAC,CAAA;AACnB;AAGO,SAAS,eAAA,GAAkB;AAChC,EAAA,eAAA,CAAgB,QAAQ,CAAA;AAC1B;AAGO,SAAS,gBAAA,GAAmB;AACjC,EAAA,eAAA,CAAgB,SAAS,CAAA;AAC3B;AASO,SAAS,gBAAgB,EAAE,QAAA,EAAU,OAAO,KAAA,EAAO,MAAA,GAAS,MAAK,EAAmF;AAGzJ,EAAA,OAAO,aAAA;AAAA,IAAc,cAAA;AAAA,IAAgB,EAAE,OAAO,KAAA,EAAM;AAAA,IAClD,aAAA;AAAA,MAAc,YAAA;AAAA,MAAc,EAAE,OAAO,IAAA,EAAK;AAAA,MACxC,aAAA;AAAA,QAAc,YAAA;AAAA,QAAc,EAAE,OAAO,KAAA,EAAM;AAAA,QACzC,aAAA;AAAA,UAAc,OAAA;AAAA,UAAS,EAAE,OAAO,KAAA,EAAM;AAAA,UACpC,aAAA;AAAA,YAAc,cAAA;AAAA,YAAgB,EAAE,OAAO,IAAA,EAAK;AAAA,YAC1C,cAAc,kBAAA,EAAoB,EAAE,KAAA,EAAO,MAAA,IAAU,QAAQ;AAAA;AAAC;AAAC;AAAC;AAAC,GAAC;AAC9E","file":"chunk-V73LHNRL.js","sourcesContent":["import { createContext } from \"react\";\nimport type { ControlSize } from \"../components/Button\";\n\n/**\n * Sprint 25.16 A4 (R28-7): the slot in a page's own PageHeader for its actions (PageActions). PageContainer provides it,\n * its header draws it while a page asks, and the page's PageActions render into it. The review of 1 October:\n * - content that starts afresh (an overlay's body, a SplitView's pane: SurfaceBoundary) has no slot, so a header there\n * (a message's own header, a drawer's) never takes the page's actions;\n * - the page's header is the first slot in the page, so a second header that comes and goes hands nothing on;\n * - a container with no header of its own (a page that wraps itself in one under an area layout) passes its page's\n * actions to the container around it;\n * - the actions take the header's control size (a minimal or snapping header draws its own actions small).\n */\nexport interface PageActionsSlot {\n /** A page below asks for the slot: a PageActions is drawn. */\n wanted: boolean;\n /** Where the actions go: the slot of the page's header, at the size its controls are drawn. */\n target: { el: HTMLElement; size: ControlSize | null } | null;\n /** A header's slot, while drawn, with its controls' size; returns its release. */\n register: (el: HTMLElement, size: ControlSize | null) => () => void;\n /** A PageActions asks for the slot while drawn; returns its release. */\n add: () => () => void;\n}\n\nexport const PageActionsCtx = createContext<PageActionsSlot | null>(null);\n","import { createContext, createElement, useContext, useLayoutEffect, type ReactNode } from \"react\";\nimport { PageActionsCtx } from \"./page-actions\";\n\n/**\n * True inside a Card's surface. A StackedList reads it to inset its rows to the card's header (px-ds-5).\n */\nexport const CardSurfaceCtx = createContext(false);\n\n/**\n * The SplitView pane content sits in (\"list\", \"detail\", \"aside\"), false outside one. A StackedList reads it to take its\n * inset from the pane (Sprint 25.4 C-5): rows keep their padding so the selection rail sits at the pane's edge and never\n * touches content. A pane header (SectionHeading variant=\"pane\") in the detail insets at the page's gutter, as the item's\n * path above it does, and in the list at its rows' inset (the owner's review of 1 October).\n */\nexport type SplitPaneKind = false | \"list\" | \"detail\" | \"aside\";\nexport const SplitPaneCtx = createContext<SplitPaneKind>(false);\n\n/**\n * True inside a Table or DataGrid card (the phone layout below mobileBreakpoint). An EntityCell reads it to keep\n * the avatar beside the text and align to the value column (Sprint 25.4, round 7: the stacked cell made the card\n * three lines taller than it needed to be).\n */\nexport const TableCardCtx = createContext(false);\n\n/**\n * True among a collection's rows: a Table's or a DataGrid's rows and their phone cards, a StackedList's rows, a Timeline's\n * items, a NotificationCenter's rows. Something\n * with a Tab stop of its own adds a stop to every row there, which makes the collection hard to cross: a RelativeTime\n * drops its own, its full timestamp in its name and on hover (Sprint 25.17 A29). A DataList is one record's fields, not\n * rows, so it doesn't set it (the second review). Inside a control (a card or a row that is a button, a link) the time\n * finds that for itself, from the page. Overlays reset it: SurfaceBoundary, a Popover, a HoverCard.\n */\nexport const RowsCtx = createContext(false);\n\n/**\n * Sprint 25.14 A44: what a SplitView's list pane holds, as its content reports it while mounted. \"framed\": content that\n * draws its own frame or cards (a KanbanBoard, a CardGrid, a Table, a DataGrid). \"scrolls\": content with no frame of its\n * own that scrolls inside the pane (a StackedList, a Gantt, a VirtualizedList), which the view's hairline frames. The\n * view drops its frame and surface when the pane holds framed content and nothing that scrolls (P32: no frame around\n * what frames itself; a hairline around what scrolls inside). Here, not in SplitView, so a board or a card grid never\n * imports the resizable panels. Null outside a list pane: overlays and the view's other panes reset it (SurfaceBoundary).\n */\nexport type SplitListReport = (kind: \"framed\" | \"scrolls\", present: boolean) => void;\nexport const SplitListFramerCtx = createContext<SplitListReport | null>(null);\n\nfunction useReportToList(kind: \"framed\" | \"scrolls\") {\n const report = useContext(SplitListFramerCtx);\n useLayoutEffect(() => {\n if (!report) return;\n report(kind, true);\n return () => report(kind, false);\n }, [report, kind]);\n}\n\n/** Tell a SplitView whose list pane this sits in that it draws its own frame or cards (A44). */\nexport function useFramesItself() {\n useReportToList(\"framed\");\n}\n\n/** Tell a SplitView whose list pane this sits in that it scrolls inside the pane with no frame of its own (A44). */\nexport function useScrollsInside() {\n useReportToList(\"scrolls\");\n}\n\n/**\n * Where content starts afresh: an overlay's body, an opened table row's panel, a SplitView's pane. What a Card, a pane\n * or a table card told the content around it stops here (the review of 30 September: a StackedList in a Drawer opened\n * from a Card took the card's inset, and one in a Dialog declared in a list pane the pane's, so neither lined up with\n * the overlay's gutter), and so does the page's actions slot. A pane passes `pane` (which pane its content is in) and\n * the list pane its `framer`.\n */\nexport function SurfaceBoundary({ children, pane = false, framer = null }: { children: ReactNode; pane?: SplitPaneKind; framer?: SplitListReport | null }) {\n // the page's actions belong to the page's own header (Sprint 25.16's review): a header in a pane or an overlay never\n // takes them, and PageActions there renders nothing\n return createElement(CardSurfaceCtx, { value: false },\n createElement(SplitPaneCtx, { value: pane },\n createElement(TableCardCtx, { value: false },\n createElement(RowsCtx, { value: false },\n createElement(PageActionsCtx, { value: null },\n createElement(SplitListFramerCtx, { value: framer }, children))))));\n}\n"]}
|