gridsmith-ui 0.30.2 → 0.31.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 +53 -1
- package/dist/charts.d.ts +114 -1
- package/dist/charts.js +1113 -206
- package/dist/charts.js.map +1 -1
- package/dist/chat.js +20 -12
- package/dist/chat.js.map +1 -1
- package/dist/{chunk-MIUSSYVE.js → chunk-2Q4HOGEI.js} +16 -51
- package/dist/chunk-2Q4HOGEI.js.map +1 -0
- package/dist/{chunk-SIWERRP2.js → chunk-3J67NISC.js} +13 -14
- package/dist/chunk-3J67NISC.js.map +1 -0
- package/dist/{chunk-L6HWACK7.js → chunk-53F7GVBQ.js} +6 -3
- package/dist/chunk-53F7GVBQ.js.map +1 -0
- package/dist/{chunk-USHW523V.js → chunk-BKYWKMUN.js} +73 -699
- package/dist/chunk-BKYWKMUN.js.map +1 -0
- package/dist/{chunk-K6IDOCGE.js → chunk-EKWXPSTI.js} +10 -10
- package/dist/{chunk-K6IDOCGE.js.map → chunk-EKWXPSTI.js.map} +1 -1
- package/dist/{chunk-ACLKDE5W.js → chunk-GP2COVJC.js} +23 -11
- package/dist/chunk-GP2COVJC.js.map +1 -0
- package/dist/{chunk-BZRZENBS.js → chunk-GT6M74IZ.js} +6 -6
- package/dist/{chunk-BZRZENBS.js.map → chunk-GT6M74IZ.js.map} +1 -1
- package/dist/{chunk-ZCDA74RQ.js → chunk-HUNEJIKV.js} +3 -3
- package/dist/{chunk-ZCDA74RQ.js.map → chunk-HUNEJIKV.js.map} +1 -1
- package/dist/{chunk-ZASGFL5D.js → chunk-LE72KHIE.js} +3 -4
- package/dist/chunk-LE72KHIE.js.map +1 -0
- package/dist/{chunk-SQHKC4HA.js → chunk-OFACAHRV.js} +8 -7
- package/dist/chunk-OFACAHRV.js.map +1 -0
- package/dist/{chunk-4HJDOZ2M.js → chunk-OWQ7M6R7.js} +75 -15
- package/dist/chunk-OWQ7M6R7.js.map +1 -0
- package/dist/{chunk-TYNDXMBV.js → chunk-QOMP4D6V.js} +3 -3
- package/dist/{chunk-TYNDXMBV.js.map → chunk-QOMP4D6V.js.map} +1 -1
- package/dist/chunk-U7WBI4AV.js +285 -0
- package/dist/chunk-U7WBI4AV.js.map +1 -0
- package/dist/chunk-V2ARGHJN.js +755 -0
- package/dist/chunk-V2ARGHJN.js.map +1 -0
- package/dist/chunk-V73LHNRL.js +51 -0
- package/dist/chunk-V73LHNRL.js.map +1 -0
- package/dist/{chunk-WWN6CQKI.js → chunk-XSQD3UGY.js} +47 -7
- package/dist/chunk-XSQD3UGY.js.map +1 -0
- package/dist/{chunk-HVGHGBKV.js → chunk-YFHTREH5.js} +6 -7
- package/dist/chunk-YFHTREH5.js.map +1 -0
- package/dist/data-grid.js +10 -11
- package/dist/data-grid.js.map +1 -1
- package/dist/editor-mentions.js +2 -3
- package/dist/editor-mentions.js.map +1 -1
- package/dist/editor.js +3 -5
- package/dist/editor.js.map +1 -1
- package/dist/icons.js +1 -1
- package/dist/index.d.ts +91 -16
- package/dist/index.js +1055 -640
- package/dist/index.js.map +1 -1
- package/dist/kanban.js +9 -11
- package/dist/kanban.js.map +1 -1
- package/dist/resizable.js +9 -11
- package/dist/resizable.js.map +1 -1
- package/dist/virtualized.js +10 -11
- package/dist/virtualized.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-4HJDOZ2M.js.map +0 -1
- package/dist/chunk-6C2IUMY7.js +0 -46
- package/dist/chunk-6C2IUMY7.js.map +0 -1
- package/dist/chunk-7Q46JXSK.js +0 -51
- package/dist/chunk-7Q46JXSK.js.map +0 -1
- package/dist/chunk-ACLKDE5W.js.map +0 -1
- package/dist/chunk-HVGHGBKV.js.map +0 -1
- package/dist/chunk-L6HWACK7.js.map +0 -1
- package/dist/chunk-MIUSSYVE.js.map +0 -1
- package/dist/chunk-NKUCS67T.js +0 -13
- package/dist/chunk-NKUCS67T.js.map +0 -1
- package/dist/chunk-SIWERRP2.js.map +0 -1
- package/dist/chunk-SQHKC4HA.js.map +0 -1
- package/dist/chunk-USHW523V.js.map +0 -1
- package/dist/chunk-WWN6CQKI.js.map +0 -1
- package/dist/chunk-YL5KD5RC.js +0 -49
- package/dist/chunk-YL5KD5RC.js.map +0 -1
- package/dist/chunk-ZASGFL5D.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/use-position.ts"],"names":["useRef","useLayoutEffect","active","useState","useCallback"],"mappings":"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","file":"chunk-4HJDOZ2M.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/** 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/** 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 /** As RememberedFocus's; else, with the overlay the opener sat in closed, that overlay's own opener. */\n restore(fallback?: HTMLElement | null): 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 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() {\n setTimeout(() => {\n if (typeof document === \"undefined\") return;\n const now = document.activeElement;\n if ((now && now !== document.body && now.isConnected && !root.contains(now)) || (location.pathname !== pathname && !pathAbove(location.pathname, pathname))) return;\n landLastResort(places, root);\n }, LAST_RESORT_MS);\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();\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 /** What the item sits in, whose controls are its neighbours. Default: the item's parent. */\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 const landOnGroup = () => {\n if (!within?.isConnected) return false;\n // a group that takes no focus is given it for the moment, as an error summary is (focus by script, never by Tab)\n if (!within.hasAttribute(\"tabindex\") && within.tabIndex < 0) within.setAttribute(\"tabindex\", \"-1\");\n within.focus();\n return document.activeElement === within;\n };\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) || landOnGroup();\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 { 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"]}
|
package/dist/chunk-6C2IUMY7.js
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { cn } from './chunk-YL5KD5RC.js';
|
|
3
|
-
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
4
|
-
|
|
5
|
-
function Bone({ className, style, "data-gs": marker }) {
|
|
6
|
-
return /* @__PURE__ */ jsx(
|
|
7
|
-
"div",
|
|
8
|
-
{
|
|
9
|
-
"data-gs": marker,
|
|
10
|
-
className: cn("rounded-[var(--ds-radius-sm)] bg-[var(--ds-bg-emphasis)] animate-pulse", className),
|
|
11
|
-
style
|
|
12
|
-
}
|
|
13
|
-
);
|
|
14
|
-
}
|
|
15
|
-
function Skeleton({ variant = "text", lines = 3, width, height, className }) {
|
|
16
|
-
if (variant === "custom") {
|
|
17
|
-
return /* @__PURE__ */ jsx(Bone, { "data-gs": "skeleton", className, style: { width, height } });
|
|
18
|
-
}
|
|
19
|
-
if (variant === "avatar") {
|
|
20
|
-
return /* @__PURE__ */ jsx(Bone, { "data-gs": "skeleton", className: cn("h-10 w-10 rounded-[var(--ds-radius-full)]", className) });
|
|
21
|
-
}
|
|
22
|
-
if (variant === "card") {
|
|
23
|
-
return /* @__PURE__ */ jsxs("div", { "data-gs": "skeleton", className: cn("space-y-ds-3", className), children: [
|
|
24
|
-
/* @__PURE__ */ jsx(Bone, { className: "h-32 w-full rounded-[var(--ds-radius-md)]" }),
|
|
25
|
-
/* @__PURE__ */ jsx(Bone, { className: "h-4 w-3/4" }),
|
|
26
|
-
/* @__PURE__ */ jsx(Bone, { className: "h-4 w-1/2" })
|
|
27
|
-
] });
|
|
28
|
-
}
|
|
29
|
-
if (variant === "table-row") {
|
|
30
|
-
return /* @__PURE__ */ jsxs("div", { "data-gs": "skeleton", className: cn("flex gap-ds-4", className), children: [
|
|
31
|
-
/* @__PURE__ */ jsx(Bone, { className: "h-4 flex-[3]" }),
|
|
32
|
-
/* @__PURE__ */ jsx(Bone, { className: "h-4 flex-[2]" }),
|
|
33
|
-
/* @__PURE__ */ jsx(Bone, { className: "h-4 flex-1" }),
|
|
34
|
-
/* @__PURE__ */ jsx(Bone, { className: "h-4 flex-1" })
|
|
35
|
-
] });
|
|
36
|
-
}
|
|
37
|
-
const widths = ["w-3/4", "w-1/2", "w-5/6", "w-2/3", "w-4/5"];
|
|
38
|
-
return /* @__PURE__ */ jsx("div", { "data-gs": "skeleton", className: cn("space-y-ds-3", className), children: Array.from({ length: lines }, (_, i) => /* @__PURE__ */ jsx(Bone, { className: cn("h-4", widths[i % widths.length]) }, i)) });
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// ../../showcase/src/lib/title-text.ts
|
|
42
|
-
var TITLE_TEXT = "font-[family-name:var(--ds-font-display)] text-lg font-[var(--ds-weight-heading)] text-[var(--ds-text-primary)] break-words";
|
|
43
|
-
|
|
44
|
-
export { Skeleton, TITLE_TEXT };
|
|
45
|
-
//# sourceMappingURL=chunk-6C2IUMY7.js.map
|
|
46
|
-
//# sourceMappingURL=chunk-6C2IUMY7.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../showcase/src/components/Skeleton.tsx","../../../showcase/src/lib/title-text.ts"],"names":[],"mappings":";;;;AAUA,SAAS,KAAK,EAAE,SAAA,EAAW,KAAA,EAAO,SAAA,EAAW,QAAO,EAA4E;AAC9H,EAAA,uBACE,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,SAAA,EAAS,MAAA;AAAA,MACT,SAAA,EAAW,EAAA,CAAG,wEAAA,EAA0E,SAAS,CAAA;AAAA,MACjG;AAAA;AAAA,GACF;AAEJ;AAEO,SAAS,QAAA,CAAS,EAAE,OAAA,GAAU,MAAA,EAAQ,QAAQ,CAAA,EAAG,KAAA,EAAO,MAAA,EAAQ,SAAA,EAAU,EAAkB;AACjG,EAAA,IAAI,YAAY,QAAA,EAAU;AACxB,IAAA,uBAAO,GAAA,CAAC,QAAK,SAAA,EAAQ,UAAA,EAAW,WAAsB,KAAA,EAAO,EAAE,KAAA,EAAO,MAAA,EAAO,EAAG,CAAA;AAAA,EAClF;AAEA,EAAA,IAAI,YAAY,QAAA,EAAU;AACxB,IAAA,uBAAO,GAAA,CAAC,QAAK,SAAA,EAAQ,UAAA,EAAW,WAAW,EAAA,CAAG,2CAAA,EAA6C,SAAS,CAAA,EAAG,CAAA;AAAA,EACzG;AAEA,EAAA,IAAI,YAAY,MAAA,EAAQ;AACtB,IAAA,uBACE,IAAA,CAAC,SAAI,SAAA,EAAQ,UAAA,EAAW,WAAW,EAAA,CAAG,cAAA,EAAgB,SAAS,CAAA,EAC7D,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,IAAA,EAAA,EAAK,WAAU,2CAAA,EAA4C,CAAA;AAAA,sBAC5D,GAAA,CAAC,IAAA,EAAA,EAAK,SAAA,EAAU,WAAA,EAAY,CAAA;AAAA,sBAC5B,GAAA,CAAC,IAAA,EAAA,EAAK,SAAA,EAAU,WAAA,EAAY;AAAA,KAAA,EAC9B,CAAA;AAAA,EAEJ;AAEA,EAAA,IAAI,YAAY,WAAA,EAAa;AAC3B,IAAA,uBACE,IAAA,CAAC,SAAI,SAAA,EAAQ,UAAA,EAAW,WAAW,EAAA,CAAG,eAAA,EAAiB,SAAS,CAAA,EAC9D,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,IAAA,EAAA,EAAK,WAAU,cAAA,EAAe,CAAA;AAAA,sBAC/B,GAAA,CAAC,IAAA,EAAA,EAAK,SAAA,EAAU,cAAA,EAAe,CAAA;AAAA,sBAC/B,GAAA,CAAC,IAAA,EAAA,EAAK,SAAA,EAAU,YAAA,EAAa,CAAA;AAAA,sBAC7B,GAAA,CAAC,IAAA,EAAA,EAAK,SAAA,EAAU,YAAA,EAAa;AAAA,KAAA,EAC/B,CAAA;AAAA,EAEJ;AAGA,EAAA,MAAM,SAAS,CAAC,OAAA,EAAS,OAAA,EAAS,OAAA,EAAS,SAAS,OAAO,CAAA;AAC3D,EAAA,uBACE,GAAA,CAAC,KAAA,EAAA,EAAI,SAAA,EAAQ,UAAA,EAAW,SAAA,EAAW,EAAA,CAAG,cAAA,EAAgB,SAAS,CAAA,EAC5D,QAAA,EAAA,KAAA,CAAM,IAAA,CAAK,EAAE,QAAQ,KAAA,EAAM,EAAG,CAAC,CAAA,EAAG,CAAA,qBACjC,GAAA,CAAC,IAAA,EAAA,EAAa,SAAA,EAAW,GAAG,KAAA,EAAO,MAAA,CAAO,CAAA,GAAI,MAAA,CAAO,MAAM,CAAC,CAAA,EAAA,EAAjD,CAAoD,CAChE,CAAA,EACH,CAAA;AAEJ;;;ACrDO,IAAM,UAAA,GAAa","file":"chunk-6C2IUMY7.js","sourcesContent":["import { cn } from \"../lib/utils\";\n\ninterface SkeletonProps {\n variant?: \"text\" | \"avatar\" | \"card\" | \"table-row\" | \"custom\";\n lines?: number;\n width?: string;\n height?: string;\n className?: string;\n}\n\nfunction Bone({ className, style, \"data-gs\": marker }: { className?: string; style?: React.CSSProperties; \"data-gs\"?: string }) {\n return (\n <div\n data-gs={marker}\n className={cn(\"rounded-[var(--ds-radius-sm)] bg-[var(--ds-bg-emphasis)] animate-pulse\", className)}\n style={style}\n />\n );\n}\n\nexport function Skeleton({ variant = \"text\", lines = 3, width, height, className }: SkeletonProps) {\n if (variant === \"custom\") {\n return <Bone data-gs=\"skeleton\" className={className} style={{ width, height }} />;\n }\n\n if (variant === \"avatar\") {\n return <Bone data-gs=\"skeleton\" className={cn(\"h-10 w-10 rounded-[var(--ds-radius-full)]\", className)} />;\n }\n\n if (variant === \"card\") {\n return (\n <div data-gs=\"skeleton\" className={cn(\"space-y-ds-3\", className)}>\n <Bone className=\"h-32 w-full rounded-[var(--ds-radius-md)]\" />\n <Bone className=\"h-4 w-3/4\" />\n <Bone className=\"h-4 w-1/2\" />\n </div>\n );\n }\n\n if (variant === \"table-row\") {\n return (\n <div data-gs=\"skeleton\" className={cn(\"flex gap-ds-4\", className)}>\n <Bone className=\"h-4 flex-[3]\" />\n <Bone className=\"h-4 flex-[2]\" />\n <Bone className=\"h-4 flex-1\" />\n <Bone className=\"h-4 flex-1\" />\n </div>\n );\n }\n\n // text variant\n const widths = [\"w-3/4\", \"w-1/2\", \"w-5/6\", \"w-2/3\", \"w-4/5\"];\n return (\n <div data-gs=\"skeleton\" className={cn(\"space-y-ds-3\", className)}>\n {Array.from({ length: lines }, (_, i) => (\n <Bone key={i} className={cn(\"h-4\", widths[i % widths.length])} />\n ))}\n </div>\n );\n}\n","/**\n * A title's text classes: CardTitle's, which a titled Table's band and a ChartContainer's title share (Sprint 25.9, A1),\n * one definition so they cannot drift. A word or a name longer than its line breaks at the line's edge (round 27,\n * R27-16: run 70's \"primary-logo-navy.svg\" ran out of its card); break-word, not anywhere, so a title's words still\n * set its minimum and the actions beside it wrap under it before a word is broken (HEADER_LAYOUT.floor).\n */\nexport const TITLE_TEXT = \"font-[family-name:var(--ds-font-display)] text-lg font-[var(--ds-weight-heading)] text-[var(--ds-text-primary)] break-words\";\n"]}
|
package/dist/chunk-7Q46JXSK.js
DELETED
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
import { version, isValidElement, cloneElement } from 'react';
|
|
3
|
-
import 'react/jsx-runtime';
|
|
4
|
-
|
|
5
|
-
// ../../showcase/src/lib/slot.tsx
|
|
6
|
-
var REACT_18 = version.startsWith("18.");
|
|
7
|
-
function mergeRefs(...refs) {
|
|
8
|
-
const filtered = refs.filter(Boolean);
|
|
9
|
-
if (filtered.length === 0) return void 0;
|
|
10
|
-
if (filtered.length === 1) return filtered[0];
|
|
11
|
-
return (node) => {
|
|
12
|
-
for (const ref of filtered) {
|
|
13
|
-
if (typeof ref === "function") ref(node);
|
|
14
|
-
else if (ref && typeof ref === "object") ref.current = node;
|
|
15
|
-
}
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
function Slot({ children, ref, ...slotProps }) {
|
|
19
|
-
if (!isValidElement(children)) {
|
|
20
|
-
console.warn("Slot: expected a single React element child.");
|
|
21
|
-
return null;
|
|
22
|
-
}
|
|
23
|
-
const childProps = children.props;
|
|
24
|
-
const slotRecord = slotProps;
|
|
25
|
-
const mergedProps = { ...slotProps };
|
|
26
|
-
for (const key of Object.keys(childProps)) {
|
|
27
|
-
if (key === "style") {
|
|
28
|
-
mergedProps.style = { ...slotProps.style ?? {}, ...childProps.style };
|
|
29
|
-
} else if (key === "className") {
|
|
30
|
-
mergedProps.className = [slotProps.className, childProps.className].filter(Boolean).join(" ");
|
|
31
|
-
} else if (key.startsWith("on") && typeof slotRecord[key] === "function") {
|
|
32
|
-
const slotHandler = slotRecord[key];
|
|
33
|
-
const childHandler = childProps[key];
|
|
34
|
-
mergedProps[key] = (...args) => {
|
|
35
|
-
childHandler?.(...args);
|
|
36
|
-
slotHandler?.(...args);
|
|
37
|
-
};
|
|
38
|
-
} else {
|
|
39
|
-
mergedProps[key] = childProps[key] ?? slotRecord[key];
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
if (ref) {
|
|
43
|
-
const childRef = childProps.ref ?? (REACT_18 ? children.ref : void 0);
|
|
44
|
-
mergedProps.ref = mergeRefs(ref, childRef);
|
|
45
|
-
}
|
|
46
|
-
return cloneElement(children, mergedProps);
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export { Slot, mergeRefs };
|
|
50
|
-
//# sourceMappingURL=chunk-7Q46JXSK.js.map
|
|
51
|
-
//# sourceMappingURL=chunk-7Q46JXSK.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../showcase/src/lib/slot.tsx"],"names":[],"mappings":";;;;;AAYA,IAAM,QAAA,GAAW,OAAA,CAAQ,UAAA,CAAW,KAAK,CAAA;AAOlC,SAAS,aAAa,IAAA,EAAsE;AACjG,EAAA,MAAM,QAAA,GAAW,IAAA,CAAK,MAAA,CAAO,OAAO,CAAA;AACpC,EAAA,IAAI,QAAA,CAAS,MAAA,KAAW,CAAA,EAAG,OAAO,MAAA;AAClC,EAAA,IAAI,QAAA,CAAS,MAAA,KAAW,CAAA,EAAG,OAAO,SAAS,CAAC,CAAA;AAC5C,EAAA,OAAO,CAAC,IAAA,KAA6B;AACnC,IAAA,KAAA,MAAW,OAAO,QAAA,EAAU;AAC1B,MAAA,IAAI,OAAO,GAAA,KAAQ,UAAA,EAAY,GAAA,CAAI,IAAI,CAAA;AAAA,WAAA,IAC9B,OAAO,OAAO,GAAA,KAAQ,QAAA,EAAW,IAAwC,OAAA,GAAU,IAAA;AAAA,IAC9F;AAAA,EACF,CAAA;AACF;AAUO,SAAS,KAAK,EAAE,QAAA,EAAU,GAAA,EAAK,GAAG,WAAU,EAAc;AAC/D,EAAA,IAAI,CAAC,cAAA,CAAe,QAAQ,CAAA,EAAG;AAC7B,IAAA,OAAA,CAAQ,KAAK,8CAA8C,CAAA;AAC3D,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,aAAa,QAAA,CAAS,KAAA;AAC5B,EAAA,MAAM,UAAA,GAAa,SAAA;AAEnB,EAAA,MAAM,WAAA,GAAuC,EAAE,GAAG,SAAA,EAAU;AAC5D,EAAA,KAAA,MAAW,GAAA,IAAO,MAAA,CAAO,IAAA,CAAK,UAAU,CAAA,EAAG;AACzC,IAAA,IAAI,QAAQ,OAAA,EAAS;AACnB,MAAA,WAAA,CAAY,KAAA,GAAQ,EAAE,GAAI,SAAA,CAAU,SAAS,EAAC,EAAI,GAAI,UAAA,CAAW,KAAA,EAAiB;AAAA,IACpF,CAAA,MAAA,IAAW,QAAQ,WAAA,EAAa;AAC9B,MAAA,WAAA,CAAY,SAAA,GAAY,CAAC,SAAA,CAAU,SAAA,EAAW,UAAA,CAAW,SAAS,CAAA,CAAE,MAAA,CAAO,OAAO,CAAA,CAAE,IAAA,CAAK,GAAG,CAAA;AAAA,IAC9F,CAAA,MAAA,IAAW,IAAI,UAAA,CAAW,IAAI,KAAK,OAAO,UAAA,CAAW,GAAG,CAAA,KAAM,UAAA,EAAY;AACxE,MAAA,MAAM,WAAA,GAAc,WAAW,GAAG,CAAA;AAClC,MAAA,MAAM,YAAA,GAAe,WAAW,GAAG,CAAA;AACnC,MAAA,WAAA,CAAY,GAAG,CAAA,GAAI,CAAA,GAAI,IAAA,KAAoB;AACzC,QAAA,YAAA,GAAe,GAAG,IAAI,CAAA;AACtB,QAAA,WAAA,GAAc,GAAG,IAAI,CAAA;AAAA,MACvB,CAAA;AAAA,IACF,CAAA,MAAO;AACL,MAAA,WAAA,CAAY,GAAG,CAAA,GAAI,UAAA,CAAW,GAAG,CAAA,IAAK,WAAW,GAAG,CAAA;AAAA,IACtD;AAAA,EACF;AAEA,EAAA,IAAI,GAAA,EAAK;AAEP,IAAA,MAAM,QAAA,GAAY,UAAA,CAAW,GAAA,KACvB,QAAA,GAAY,SAAuD,GAAA,GAAM,MAAA,CAAA;AAC/E,IAAA,WAAA,CAAY,GAAA,GAAM,SAAA,CAAU,GAAA,EAAK,QAAQ,CAAA;AAAA,EAC3C;AAEA,EAAA,OAAO,YAAA,CAAa,UAA0B,WAAW,CAAA;AAC3D","file":"chunk-7Q46JXSK.js","sourcesContent":["import {\n type ReactNode,\n type ReactElement,\n type HTMLAttributes,\n type Ref,\n isValidElement,\n cloneElement,\n createElement,\n Children,\n version,\n} from \"react\";\n\nconst REACT_18 = version.startsWith(\"18.\");\n\ntype SlotProps = HTMLAttributes<HTMLElement> & {\n children?: ReactNode;\n ref?: Ref<HTMLElement>;\n};\n\nexport function mergeRefs(...refs: (Ref<HTMLElement> | undefined)[]): Ref<HTMLElement> | undefined {\n const filtered = refs.filter(Boolean) as Ref<HTMLElement>[];\n if (filtered.length === 0) return undefined;\n if (filtered.length === 1) return filtered[0];\n return (node: HTMLElement | null) => {\n for (const ref of filtered) {\n if (typeof ref === \"function\") ref(node);\n else if (ref && typeof ref === \"object\") (ref as { current: HTMLElement | null }).current = node;\n }\n };\n}\n\n/**\n * Merges its own props onto its single React element child instead of\n * rendering a wrapper DOM node. Used by trigger-based components\n * (Tooltip, HoverCard, Popover, DropdownMenu) via the `asChild` prop\n * to let consumers control the rendered element.\n *\n * Follows the same contract as Radix UI's Slot / `asChild` pattern.\n */\nexport function Slot({ children, ref, ...slotProps }: SlotProps) {\n if (!isValidElement(children)) {\n console.warn(\"Slot: expected a single React element child.\");\n return null;\n }\n\n const childProps = children.props as Record<string, unknown>;\n const slotRecord = slotProps as Record<string, unknown>;\n\n const mergedProps: Record<string, unknown> = { ...slotProps };\n for (const key of Object.keys(childProps)) {\n if (key === \"style\") {\n mergedProps.style = { ...(slotProps.style ?? {}), ...(childProps.style as object) };\n } else if (key === \"className\") {\n mergedProps.className = [slotProps.className, childProps.className].filter(Boolean).join(\" \");\n } else if (key.startsWith(\"on\") && typeof slotRecord[key] === \"function\") {\n const slotHandler = slotRecord[key] as (...args: unknown[]) => void;\n const childHandler = childProps[key] as (...args: unknown[]) => void;\n mergedProps[key] = (...args: unknown[]) => {\n childHandler?.(...args);\n slotHandler?.(...args);\n };\n } else {\n mergedProps[key] = childProps[key] ?? slotRecord[key];\n }\n }\n\n if (ref) {\n // React 19 passes ref as a prop and warns on element.ref; React 18 keeps it on the element.\n const childRef = (childProps.ref as Ref<HTMLElement> | undefined)\n ?? (REACT_18 ? (children as ReactElement & { ref?: Ref<HTMLElement> }).ref : undefined);\n mergedProps.ref = mergeRefs(ref, childRef);\n }\n\n return cloneElement(children as ReactElement, mergedProps);\n}\n\n/**\n * Renders either a Slot (when `asChild` is true — merging props onto\n * the consumer's child element) or the given `fallback` tag (default\n * behaviour, rendering a wrapper element with the given props).\n */\nexport function Slottable({\n asChild,\n fallback: Tag = \"span\",\n children,\n ref,\n ...rest\n}: {\n asChild?: boolean;\n fallback?: keyof HTMLElementTagNameMap;\n children?: ReactNode;\n ref?: Ref<HTMLElement>;\n} & HTMLAttributes<HTMLElement>) {\n if (asChild) {\n const child = Children.only(children);\n return <Slot ref={ref} {...rest}>{child}</Slot>;\n }\n // `ref` is a forwarded prop being passed on, not a ref object being read.\n // eslint-disable-next-line react-hooks/refs -- forwarding, not dereferencing\n return createElement(Tag, { ref, ...rest } as Record<string, unknown>, children);\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../showcase/src/lib/use-keyboard-scroll.ts"],"names":[],"mappings":"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","file":"chunk-ACLKDE5W.js","sourcesContent":["import { useEffect } from \"react\";\nimport { tabStops } from \"./focus\";\nimport { useRevealFocus } from \"./reveal-focus\";\n\n/**\n * WCAG 2.1.1: a region that scrolls, with nothing inside it to Tab to, is a Tab stop of its own, named, so a keyboard\n * can scroll it (Chrome makes such a scroller focusable by itself; Safari doesn't). Sprint 25.16 A42: what fills the\n * page scrolls inside itself, so a board's column or a split view's pane can be such a region. It stops being one when\n * it no longer scrolls or something inside it takes focus — but while it has focus it stays one, until focus leaves it,\n * so a resize that makes it fit never drops the focus to the page (as Table's scroll region does; the review of\n * 1 October). Give the element a visible focus style (FOCUS_INSET). Pass the element itself (a callback ref's), so a\n * pane drawn later (a detail that opens) is read when it appears. With `nameFromHeading`, the region takes its first\n * heading's words as its name (an item's view: its title), and `label` only when it has none. What the keyboard focuses\n * inside it is scrolled into view whole (useRevealFocus, Sprint 30): give the region `scroll-p-[4px]` for the outline.\n * `axis` \"x\" for a strip that scrolls sideways (the Calendar's week of days on a phone, Sprint 25.29 item 10), \"both\"\n * for an area that scrolls either way (ScrollArea's, Sprint 25.30 item 2).\n */\nexport function useKeyboardScroll(el: HTMLElement | null, label: string, enabled = true, nameFromHeading = false, axis: \"y\" | \"x\" | \"both\" = \"y\"): void {\n useRevealFocus(el, enabled);\n useEffect(() => {\n if (!enabled || !el || typeof ResizeObserver === \"undefined\") return;\n const name = () => {\n const heading = nameFromHeading ? el.querySelector(\"h1, h2, h3, h4, h5, h6\")?.textContent?.trim() : \"\";\n return heading || label;\n };\n // what the element has of its own, kept: a landmark's role and name (the shell's <main>), and the skip link's target's\n // tabindex -1, put back when it stops being a stop (Sprint 25.29 item 10)\n const own = { tabindex: el.getAttribute(\"tabindex\"), role: el.getAttribute(\"role\"), label: el.getAttribute(\"aria-label\") };\n const landmark = /^(MAIN|NAV|ASIDE|ARTICLE|SECTION|FORM)$/.test(el.tagName);\n const keepRole = own.role !== null || landmark;\n const keepName = own.label !== null || landmark;\n const restore = (attr: string, value: string | null) => (value === null ? el.removeAttribute(attr) : el.setAttribute(attr, value));\n const set = (on: boolean) => {\n if (on === el.hasAttribute(\"data-scroll-stop\")) {\n if (on && !keepName && el.getAttribute(\"aria-label\") !== name()) el.setAttribute(\"aria-label\", name());\n return;\n }\n if (on) {\n el.setAttribute(\"data-scroll-stop\", \"\");\n el.tabIndex = 0;\n if (!keepRole) el.setAttribute(\"role\", \"region\");\n if (!keepName) el.setAttribute(\"aria-label\", name());\n } else {\n el.removeAttribute(\"data-scroll-stop\");\n restore(\"tabindex\", own.tabindex);\n if (!keepRole) restore(\"role\", own.role);\n if (!keepName) restore(\"aria-label\", own.label);\n }\n };\n const update = () => {\n const wide = el.scrollWidth > el.clientWidth + 1, tall = el.scrollHeight > el.clientHeight + 1;\n const overflows = axis === \"x\" ? wide : axis === \"both\" ? wide || tall : tall;\n const scrolls = overflows && tabStops(el).length === 0;\n set(scrolls || (el.hasAttribute(\"data-scroll-stop\") && document.activeElement === el));\n };\n update();\n const ro = new ResizeObserver(update);\n ro.observe(el);\n const mo = typeof MutationObserver === \"undefined\" ? null : new MutationObserver(update);\n mo?.observe(el, { childList: true, subtree: true, characterData: true });\n // focus leaving a stop that no longer scrolls ends it\n el.addEventListener(\"focusout\", update);\n return () => {\n ro.disconnect();\n mo?.disconnect();\n el.removeEventListener(\"focusout\", update);\n set(false);\n };\n }, [el, label, enabled, nameFromHeading, axis]);\n}\n\n/** The focus style for such a region: the theme's outline, drawn inside its edge so a neighbour can't hide it (lib/utils.ts since Sprint 30). */\nexport { FOCUS_INSET } from \"./utils\";\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../showcase/src/components/DropdownMenu.tsx"],"names":[],"mappings":"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","file":"chunk-HVGHGBKV.js","sourcesContent":["import { useRef, useEffect, useLayoutEffect, useState, type ReactNode, type KeyboardEvent as ReactKeyboardEvent } from \"react\";\nimport { useBreakpoint } from \"../lib/use-breakpoint\";\nimport { createPortal } from \"react-dom\";\nimport { cn, FOCUS_RING, GLASS_DROPDOWN } from \"../lib/utils\";\nimport { Icon, type IconName } from \"../lib/icons\";\nimport { Slot } from \"../lib/slot\";\nimport { triggerType } from \"./Button\";\nimport { usePosition, type Align } from \"../lib/use-position\";\nimport { usePopupFocus } from \"../lib/focus\";\n\nexport interface DropdownMenuItem {\n label: string;\n icon?: IconName;\n onClick: () => void;\n variant?: \"default\" | \"destructive\";\n disabled?: boolean;\n}\n\nexport interface DropdownMenuDivider {\n type: \"divider\";\n}\n\n/**\n * An entry that opens a submenu of its own (Sprint 25.8.7's look check: a card's Move among its other actions), one\n * level deep. On a desktop it opens beside the menu: → or Enter opens it, its first item focused; ← or Escape closes it,\n * focus back on this entry; a hover opens it too. On a phone its items take the menu's place, under a Back item.\n */\nexport interface DropdownMenuSubmenu {\n label: string;\n icon?: IconName;\n items: (DropdownMenuItem | DropdownMenuDivider)[];\n disabled?: boolean;\n}\n\nexport type DropdownMenuEntry = DropdownMenuItem | DropdownMenuDivider | DropdownMenuSubmenu;\n\nfunction isDivider(entry: DropdownMenuEntry): entry is DropdownMenuDivider {\n return \"type\" in entry && entry.type === \"divider\";\n}\nfunction isSubmenu(entry: DropdownMenuEntry): entry is DropdownMenuSubmenu {\n return \"items\" in entry;\n}\n/** The indices of a list's items the arrows stop at: no divider, nothing unavailable. */\nconst stopsOf = (entries: DropdownMenuEntry[]): number[] => entries.reduce<number[]>((acc, e, i) => {\n if (!isDivider(e) && !isUnavailable(e)) acc.push(i);\n return acc;\n}, []);\n/** An entry that can't be chosen: disabled, or a submenu with nothing in it to choose, which never opens empty. */\nfunction isUnavailable(entry: DropdownMenuItem | DropdownMenuSubmenu): boolean {\n return !!entry.disabled || (isSubmenu(entry) && stopsOf(entry.items).length === 0);\n}\n/**\n * How long a hover on another entry waits before it closes the open submenu (or opens the other's): a pointer on its way\n * to the submenu crosses the entries below its own, and reaching the submenu in that time keeps it open.\n */\nconst SUBMENU_GRACE_MS = 300;\n\nconst ITEM = \"flex items-center gap-ds-2 w-full text-left px-ds-3 py-ds-2 text-sm cursor-pointer transition-colors rounded-[var(--ds-radius-sm)]\";\nconst itemLook = (entry: DropdownMenuItem | DropdownMenuSubmenu, open = false) => cn(\n ITEM,\n FOCUS_RING,\n isUnavailable(entry)\n ? \"opacity-disabled cursor-not-allowed\"\n : \"variant\" in entry && entry.variant === \"destructive\"\n ? \"text-[var(--ds-status-error-text)] hover:bg-[var(--ds-status-error-bg)] focus-visible:bg-[var(--ds-status-error-bg)]\"\n : cn(\"text-[var(--ds-text-primary)] hover:bg-[var(--ds-bg-emphasis)] focus-visible:bg-[var(--ds-bg-emphasis)]\", open && \"bg-[var(--ds-bg-emphasis)]\"),\n);\nconst PANEL = cn(\n // the items' outline has its 4 px of room at any density (Sprint 30, P3)\n \"fixed z-[var(--ds-z-popover)] min-w-[180px] p-[max(var(--ds-space-1),4px)]\",\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)] overflow-hidden\",\n);\nconst Divider = () => <div role=\"separator\" className=\"my-ds-1 h-px bg-[var(--ds-border-default)]\" />;\n\ninterface DropdownMenuProps {\n trigger: ReactNode;\n items: DropdownMenuEntry[];\n align?: Align;\n className?: string;\n container?: Element | DocumentFragment;\n}\n\nexport function DropdownMenu({ trigger, items, align = \"end\", className, container }: DropdownMenuProps) {\n const [open, setOpen] = useState(false);\n const [focusedIdx, setFocusedIdx] = useState(-1);\n // the submenu open, by its entry's index, and the focus inside it\n const [sub, setSub] = useState<number | null>(null);\n const [subFocusedIdx, setSubFocusedIdx] = useState(-1);\n const triggerRef = useRef<HTMLElement>(null);\n // both panels, the menu and its submenu, sit in one box (display: contents) that is the popup's for focus and presses\n const panelsRef = useRef<HTMLDivElement>(null);\n const menuRef = useRef<HTMLDivElement>(null);\n const subRef = useRef<HTMLDivElement>(null);\n const subItemRef = useRef<HTMLElement>(null);\n const isPhone = useBreakpoint(\"sm\");\n // a hover elsewhere, waiting before it closes the open submenu (SUBMENU_GRACE_MS)\n const graceTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n const cancelGrace = () => {\n if (graceTimer.current) { clearTimeout(graceTimer.current); graceTimer.current = null; }\n };\n const afterGrace = (then: () => void) => {\n cancelGrace();\n graceTimer.current = setTimeout(() => { graceTimer.current = null; then(); }, SUBMENU_GRACE_MS);\n };\n // closing the menu, or leaving the page, drops a hover's wait\n useEffect(() => { if (!open) cancelGrace(); }, [open]);\n useEffect(() => cancelGrace, []);\n\n const pos = usePosition(triggerRef, menuRef, open, { side: \"bottom\", align, offset: 4, flip: true });\n // beside the menu, 4 px from its edge, its first item level with its entry; on the other side where the screen has no\n // room, and inside the screen (measured against the menu, not the entry: the menu's padding and edge sit between them)\n const [subPos, setSubPos] = useState({ top: 0, left: 0 });\n useLayoutEffect(() => {\n if (!open || sub === null || isPhone) return;\n const place = () => {\n const menu = menuRef.current;\n const entry = subItemRef.current;\n const panel = subRef.current;\n if (!menu || !entry || !panel) return;\n const m = menu.getBoundingClientRect();\n const e = entry.getBoundingClientRect();\n const p = panel.getBoundingClientRect();\n const first = panel.querySelector(\"[data-sub-index]\")?.getBoundingClientRect();\n let left = m.right + 4;\n if (left + p.width > window.innerWidth - 8) left = Math.max(8, m.left - 4 - p.width);\n const top = Math.max(8, Math.min(e.top - (first ? first.top - p.top : 0), window.innerHeight - p.height - 8));\n setSubPos((cur) => (cur.top === top && cur.left === left ? cur : { top, left }));\n };\n place();\n window.addEventListener(\"resize\", place);\n window.addEventListener(\"scroll\", place, true);\n return () => {\n window.removeEventListener(\"resize\", place);\n window.removeEventListener(\"scroll\", place, true);\n };\n }, [open, sub, isPhone]);\n\n const enabledIndices = stopsOf(items);\n const subEntry = sub !== null && isSubmenu(items[sub]) ? (items[sub] as DropdownMenuSubmenu) : null;\n const subIndices = subEntry ? stopsOf(subEntry.items) : [];\n\n // Closing clears the keyboard focus index and the submenu (render-time state adjustment).\n const [prevOpen, setPrevOpen] = useState(open);\n if (open !== prevOpen) {\n setPrevOpen(open);\n if (!open) { setFocusedIdx(-1); setSub(null); setSubFocusedIdx(-1); }\n }\n\n // Sprint 25.7: focus hands back on close, and Tab out carries on from the trigger (lib/focus usePopupFocus).\n const { isTop: isTopLayer, returnFocus } = usePopupFocus(open, { trigger: triggerRef, panel: panelsRef, close: () => setOpen(false), tabExits: \"any\" });\n\n /** The submenu closes, and focus goes back to the entry that opened it. */\n const closeSub = () => {\n if (sub === null) return;\n setFocusedIdx(sub);\n setSub(null);\n setSubFocusedIdx(-1);\n };\n const openSub = (i: number, focusFirst: boolean) => {\n const entry = items[i];\n if (!isSubmenu(entry) || isUnavailable(entry)) return;\n cancelGrace();\n setSub(i);\n setFocusedIdx(i);\n setSubFocusedIdx(focusFirst ? stopsOf(entry.items)[0] ?? -1 : -1);\n };\n\n useEffect(() => {\n if (!open) return;\n\n // An Escape a control inside already handled is its own; the one this acts on is marked for overlays around it.\n // In a submenu it closes the submenu alone.\n const onKeyDown = (e: globalThis.KeyboardEvent) => {\n if (e.key !== \"Escape\" || e.defaultPrevented || !isTopLayer()) return;\n e.preventDefault();\n if (sub !== null) { closeSub(); return; }\n returnFocus();\n setOpen(false);\n };\n\n const onClick = (e: MouseEvent) => {\n const target = e.target as Node;\n if (triggerRef.current?.contains(target) || panelsRef.current?.contains(target)) return;\n setOpen(false);\n };\n\n document.addEventListener(\"keydown\", onKeyDown);\n document.addEventListener(\"mousedown\", onClick);\n return () => {\n document.removeEventListener(\"keydown\", onKeyDown);\n document.removeEventListener(\"mousedown\", onClick);\n };\n });\n\n useEffect(() => {\n if (!open) return;\n // By the item's own index: items and dividers share one numbering, so indexing the buttons alone left every\n // item after a divider unreachable by the arrows (the shell's user menu: Settings, divider, Log out).\n if (sub !== null && subFocusedIdx >= 0) panelsRef.current?.querySelector<HTMLElement>(`[data-sub-index=\"${subFocusedIdx}\"]`)?.focus();\n else if (sub !== null && isPhone) panelsRef.current?.querySelector<HTMLElement>(\"[data-sub-back]\")?.focus();\n else if (focusedIdx >= 0) menuRef.current?.querySelector<HTMLElement>(`[data-index=\"${focusedIdx}\"]`)?.focus();\n }, [open, focusedIdx, sub, subFocusedIdx, isPhone]);\n\n const step = (stops: number[], at: number, by: number) => stops[((stops.indexOf(at) + by) % stops.length + stops.length) % stops.length];\n function handleMenuKeyDown(e: ReactKeyboardEvent) {\n const inSub = sub !== null;\n const stops = inSub ? subIndices : enabledIndices;\n const at = inSub ? subFocusedIdx : focusedIdx;\n const go = (i: number | undefined) => { if (i === undefined) return; if (inSub) setSubFocusedIdx(i); else setFocusedIdx(i); };\n if (e.key === \"ArrowDown\") { e.preventDefault(); go(at < 0 ? stops[0] : step(stops, at, 1)); }\n else if (e.key === \"ArrowUp\") { e.preventDefault(); go(at < 0 ? stops[stops.length - 1] : step(stops, at, -1)); }\n else if (e.key === \"Home\") { e.preventDefault(); go(stops[0]); }\n else if (e.key === \"End\") { e.preventDefault(); go(stops[stops.length - 1]); }\n else if (e.key === \"ArrowRight\" && !inSub && focusedIdx >= 0 && isSubmenu(items[focusedIdx])) { e.preventDefault(); openSub(focusedIdx, true); }\n else if (e.key === \"ArrowLeft\" && inSub) { e.preventDefault(); closeSub(); }\n }\n\n /** A choice: focus back on the trigger first, so a dialog the item opens returns there (Sprint 25.7). */\n const choose = (item: DropdownMenuItem) => {\n if (item.disabled) return;\n returnFocus();\n item.onClick();\n setOpen(false);\n };\n\n const subItems = (entries: (DropdownMenuItem | DropdownMenuDivider)[]) => entries.map((item, i) => (isDivider(item) ? <Divider key={i} /> : (\n <button type=\"button\" key={i} data-sub-index={i} role=\"menuitem\" disabled={item.disabled} tabIndex={subFocusedIdx === i ? 0 : -1} onFocus={() => setSubFocusedIdx(i)} onClick={() => choose(item)} className={itemLook(item)}>\n {item.icon && <Icon name={item.icon} size={16} className=\"shrink-0\" />}\n <span>{item.label}</span>\n </button>\n )));\n\n return (\n <>\n <Slot\n {...triggerType(trigger)}\n // the APG's menu button: the trigger says it opens a menu, and whether it is open\n aria-haspopup=\"menu\"\n aria-expanded={open}\n ref={triggerRef}\n onClick={() => {\n setOpen(!open);\n if (!open && enabledIndices.length) setFocusedIdx(enabledIndices[0]);\n }}\n >\n {trigger}\n </Slot>\n {open && createPortal(\n <div ref={panelsRef} className=\"contents\">\n <div\n ref={menuRef}\n role=\"menu\"\n data-gs=\"menu\"\n aria-label={isPhone && subEntry ? subEntry.label : undefined}\n onKeyDown={handleMenuKeyDown}\n className={cn(PANEL, className)}\n style={{ top: pos.top, left: pos.left }}\n // A choice is the menu's own: the click must not also reach a clickable row or card the menu sits in\n // (React carries events from a portal to its React parents).\n onClick={(e) => e.stopPropagation()}\n >\n {isPhone && subEntry ? (\n // on a phone the submenu takes the menu's place: Back first, its entry's name on it\n <>\n <button type=\"button\" data-sub-back=\"\" role=\"menuitem\" aria-label={`Back from ${subEntry.label}`} tabIndex={-1} onClick={closeSub} className={cn(itemLook(subEntry), \"text-[var(--ds-text-secondary)] font-[var(--ds-weight-heading)]\")}>\n <Icon name=\"chevron-left\" size={16} className=\"shrink-0\" />\n <span>{subEntry.label}</span>\n </button>\n <Divider />\n {subItems(subEntry.items)}\n </>\n ) : items.map((item, i) => {\n if (isDivider(item)) return <Divider key={i} />;\n if (isSubmenu(item)) {\n const isOpen = sub === i;\n return (\n <button type=\"button\"\n key={i}\n ref={isOpen ? (el) => { subItemRef.current = el; } : undefined}\n data-index={i}\n role=\"menuitem\"\n aria-haspopup=\"menu\"\n aria-expanded={isOpen}\n disabled={isUnavailable(item)}\n tabIndex={focusedIdx === i ? 0 : -1}\n // the arrows go on from wherever focus is, however it got there (a click, a screen reader's command)\n onFocus={() => setFocusedIdx(i)}\n // Enter (its click) or a press goes into the submenu, its first item focused, whether a hover had\n // opened it or not (the APG's menu: Enter opens it and focuses its first item); ←, Escape or Back\n // closes it\n onClick={() => openSub(i, true)}\n // a hover opens it at once where no other is open; with another open it waits, as the pointer may be\n // on its way to that one (SUBMENU_GRACE_MS); back on its own entry, the wait for a close is dropped\n onMouseEnter={(e) => {\n if (isPhone || e.buttons !== 0) return;\n if (isOpen) cancelGrace();\n else if (sub === null) openSub(i, false);\n else afterGrace(() => openSub(i, false));\n }}\n className={itemLook(item, isOpen)}\n >\n {item.icon && <Icon name={item.icon} size={16} className=\"shrink-0\" />}\n <span className=\"flex-1\">{item.label}</span>\n <Icon name=\"chevron-right\" size={14} className=\"shrink-0 text-[var(--ds-text-muted)]\" />\n </button>\n );\n }\n return (\n <button type=\"button\"\n key={i}\n data-index={i}\n role=\"menuitem\"\n disabled={item.disabled}\n tabIndex={focusedIdx === i ? 0 : -1}\n onFocus={() => setFocusedIdx(i)}\n onClick={() => choose(item)}\n // a hover on another entry closes an open submenu, as moving on from it does, after a moment: the\n // pointer may only be crossing it on its way to the submenu (SUBMENU_GRACE_MS)\n onMouseEnter={() => { if (!isPhone && sub !== null) afterGrace(() => { setSub(null); setSubFocusedIdx(-1); }); }}\n className={itemLook(item)}\n >\n {item.icon && <Icon name={item.icon} size={16} className=\"shrink-0\" />}\n <span>{item.label}</span>\n </button>\n );\n })}\n </div>\n {!isPhone && subEntry && (\n <div\n ref={subRef}\n role=\"menu\"\n aria-label={subEntry.label}\n onKeyDown={handleMenuKeyDown}\n className={PANEL}\n style={{ top: subPos.top, left: subPos.left }}\n onClick={(e) => e.stopPropagation()}\n // the pointer has reached the submenu: a hover it crossed on the way closes nothing\n onMouseEnter={cancelGrace}\n >\n {subItems(subEntry.items)}\n </div>\n )}\n </div>,\n container ?? document.body\n )}\n </>\n );\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../showcase/src/lib/dev-warn.ts","../../../showcase/src/lib/icon-pack-imports.ts","../../../showcase/src/lib/icons.tsx"],"names":[],"mappings":"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","file":"chunk-L6HWACK7.js","sourcesContent":["// Bundlers set process.env.NODE_ENV. Where none did (a page with no build step), reading it throws and warnings stay off.\ndeclare const process: { env: { NODE_ENV?: string } };\nconst warned = new Set<string>();\n\n/** A mistake in a component's props, told to the developer once a page, in a development build. */\nexport function warnOnce(component: string, message: string): void {\n let dev = false;\n try {\n dev = process.env.NODE_ENV !== \"production\";\n } catch {\n dev = false;\n }\n const text = `${component}: ${message}`;\n if (!dev || warned.has(text)) return;\n warned.add(text);\n console.warn(text);\n}\n","/**\n * The import each icon pack takes, as an app writes it when it registers its theme's pack (Sprint 25.21 P1:\n * `registerIconPack('feather', () => import('react-icons/fi'))`). One table for the library's warning, the shells\n * `get_app_shell` writes and the engine's fix. Lucide is the library's own: every app installs it, as the fallback.\n * No React here, so the platform reads it as it reads the other showcase modules.\n */\nexport const ICON_PACK_IMPORTS = {\n feather: \"react-icons/fi\",\n heroicons: \"@heroicons/react/24/outline\",\n phosphor: \"@phosphor-icons/react\",\n tabler: \"@tabler/icons-react\",\n} as const;\n\n/** A pack an app registers: every pack but Lucide. */\nexport type RegisteredIconPack = keyof typeof ICON_PACK_IMPORTS;\n\n/** The two lines that register a pack, at the top of an app's shell, before any preloadPack. */\nexport function iconPackRegistration(pack: RegisteredIconPack): { importLine: string; call: string } {\n return {\n importLine: \"import { registerIconPack } from 'gridsmith-ui/icons'\",\n call: `registerIconPack('${pack}', () => import('${ICON_PACK_IMPORTS[pack]}'))`,\n };\n}\n","import { createContext, useContext, useEffect, useSyncExternalStore, type ReactElement, type ReactNode, type ComponentType } from \"react\";\nimport { warnOnce } from \"./dev-warn\";\nimport { iconPackRegistration, type RegisteredIconPack } from \"./icon-pack-imports\";\nimport type { PackLoad } from \"./icon-packs/types\";\n\n/* ── Types ────────────────────────────────────────────────────── */\n\n/**\n * Runtime list of curated icon names. The CuratedIconName type derives from\n * this array, so adding a name here extends autocomplete automatically.\n * Every name must have an alias (or auto-kebab match) in ALL five packs —\n * icon-completeness.test.tsx enforces this.\n */\nexport const CURATED_ICON_NAMES = [\n \"home\", \"folder\", \"chart\", \"settings\",\n \"chevron-right\", \"close\", \"plus\", \"search\",\n \"bell\", \"user\", \"check\", \"warning\", \"info\", \"error\",\n \"clock\", \"calendar\",\n \"bold\", \"italic\", \"underline\", \"strikethrough\",\n \"align-left\", \"align-center\", \"align-right\",\n \"list\", \"list-ordered\", \"list-checks\",\n \"link\", \"image\", \"table\", \"code\", \"quote\", \"minus\",\n \"superscript\", \"subscript\", \"highlight\", \"type\",\n \"chevron-up\", \"chevron-down\", \"chevron-left\", \"trash\",\n \"undo\", \"redo\",\n \"arrow-left\", \"grip-vertical\",\n \"mic\", \"paperclip\", \"send\",\n \"log-out\", \"edit\", \"menu\", \"more-horizontal\",\n \"star\", \"bookmark\", \"download\", \"upload\", \"sparkles\",\n \"file\", \"file-text\", \"eye\", \"eye-off\", \"copy\", \"external-link\", \"filter\", \"lock\",\n \"map-pin\", \"play\", \"pause\",\n] as const;\n\ntype CuratedIconName = (typeof CURATED_ICON_NAMES)[number];\n\n/**\n * Curated names provide autocomplete and work identically across all 5 packs.\n * Any kebab-case string is also accepted — it resolves directly against the\n * active pack's native exports (e.g. \"clipboard-copy\" → Lucide's ClipboardCopy).\n */\nexport type IconName = CuratedIconName | (string & {});\n\nexport type IconPack = \"lucide\" | \"phosphor\" | \"heroicons\" | \"tabler\" | \"feather\";\n\ntype IconComponent = ComponentType<Record<string, unknown>>;\ntype IconMap = Record<string, IconComponent>;\n\n/* ── External store ──────────────────────────────────────────── */\n\ntype Subscriber = () => void;\nconst subscribers = new Set<Subscriber>();\nfunction notifySubscribers() {\n subscribers.forEach((fn) => fn());\n}\nfunction subscribe(cb: Subscriber): () => void {\n subscribers.add(cb);\n return () => { subscribers.delete(cb); };\n}\n\nconst curatedCache = new Map<IconPack, IconMap>();\nconst extendedCache = new Map<IconPack, IconMap>();\n\nfunction useCuratedMap(pack: IconPack): IconMap | null {\n return useSyncExternalStore(\n subscribe,\n () => curatedCache.get(pack) ?? null,\n () => null,\n );\n}\n\nfunction useExtendedMap(pack: IconPack): IconMap | null {\n return useSyncExternalStore(\n subscribe,\n () => extendedCache.get(pack) ?? null,\n () => null,\n );\n}\n\n/* ── Pack loading ────────────────────────────────────────────────\n Each pack is isolated in its own file under ./icon-packs/, and reads\n its package through an import handed to it: the app's own for its\n theme's pack (registerIconPack, Sprint 25.21 P1), the library's own\n for Lucide. No file the library publishes names a pack the app may\n not have installed, so no bundler looks for one: Next.js's webpack\n resolved every pack the library named, and failed the build.\n\n Loading is two-phase:\n 1. Curated map (50 static named imports) — available as soon as\n the pack chunk loads, cached and notified immediately.\n 2. Extended map (full barrel import + kebab-case iteration) —\n loaded in the background, cached and notified when ready. */\n\nconst loadingPacks = new Set<IconPack>();\nconst failedPacks = new Set<IconPack>();\n\ntype PackModule = {\n loadCurated(load: PackLoad): Promise<IconMap>;\n loadExtended(load: PackLoad): Promise<IconMap>;\n};\n\n/** Each pack's import: Lucide's is the library's own (every app installs it); the others are the app's, registered. */\nconst packImports = new Map<IconPack, PackLoad>([[\"lucide\", () => import(\"lucide-react\")]]);\n\n/**\n * The theme's icon pack, as the app's own import (Sprint 25.21 P1): `registerIconPack('feather', () =>\n * import('react-icons/fi'))` at the top of the shell, before any preloadPack. The library names no pack itself, so an\n * app's bundler only ever meets the pack the app installed. A pack drawn before it is registered draws Lucide's icons,\n * and draws its own once registered. Lucide needs no line.\n */\nexport function registerIconPack(pack: RegisteredIconPack, load: PackLoad): void {\n packImports.set(pack, load);\n // a draw that met the pack unregistered loads it now: its icons redraw once the pack's map arrives (a notice alone\n // changes no snapshot, so nothing would redraw to ask)\n if (failedPacks.delete(pack)) void loadPack(pack);\n}\n\n/** The npm package each pack needs — named in the error when a pack is missing. */\nconst PEER_PACKAGE: Record<IconPack, string> = {\n lucide: \"lucide-react\",\n phosphor: \"@phosphor-icons/react\",\n heroicons: \"@heroicons/react\",\n tabler: \"@tabler/icons-react\",\n feather: \"react-icons\",\n};\n\nasync function loadPack(pack: IconPack): Promise<void> {\n if (curatedCache.has(pack) || loadingPacks.has(pack) || failedPacks.has(pack)) return;\n loadingPacks.add(pack);\n\n // Each pack module reaches its package only through the import handed to it\n // (see icon-packs/*.ts), so the chunk import below always succeeds and it is\n // loadCurated() that rejects when the package is not installed.\n const load = packImports.get(pack);\n if (!load) {\n // not registered: Lucide's icons stand in (Icon's third tier), and the developer is told the line to add\n failedPacks.add(pack);\n loadingPacks.delete(pack);\n const lines = iconPackRegistration(pack as RegisteredIconPack);\n warnOnce(\"IconProvider\", `the ${pack} icon pack isn't registered, so its icons are drawn from Lucide. At the top of the shell, before any preloadPack: ${lines.importLine}; ${lines.call}`);\n return;\n }\n let mod: PackModule;\n let curated: IconMap;\n try {\n switch (pack) {\n case \"lucide\": mod = await import(\"./icon-packs/lucide\"); break;\n case \"phosphor\": mod = await import(\"./icon-packs/phosphor\"); break;\n case \"heroicons\": mod = await import(\"./icon-packs/heroicons\"); break;\n case \"tabler\": mod = await import(\"./icon-packs/tabler\"); break;\n case \"feather\": mod = await import(\"./icon-packs/feather\"); break;\n }\n curated = await mod!.loadCurated(load);\n } catch {\n loadingPacks.delete(pack);\n failedPacks.add(pack);\n console.error(`gridsmith-ui: ${PEER_PACKAGE[pack]} is not installed. Run: npm install ${PEER_PACKAGE[pack]}`);\n return;\n }\n\n curatedCache.set(pack, curated);\n notifySubscribers();\n\n mod!.loadExtended(load).then((extended) => {\n extendedCache.set(pack, extended);\n notifySubscribers();\n }).catch(() => {\n // Extended map failed (e.g. network error loading the full barrel).\n // Curated icons still work; extended names will not resolve.\n });\n}\n\n/** A pack's registered import, for the tests that load the packs directly; they register them first. */\nfunction importOf(pack: IconPack): PackLoad {\n const load = packImports.get(pack);\n if (!load) throw new Error(`gridsmith-ui: register the ${pack} icon pack first (registerIconPack)`);\n return load;\n}\n\n/** Exported for the icon-completeness test — not part of the public API. */\nexport const packLoaders: Record<IconPack, {\n curated: () => Promise<IconMap>;\n extended: () => Promise<IconMap>;\n}> = {\n lucide: { curated: () => import(\"./icon-packs/lucide\").then((m) => m.loadCurated(importOf(\"lucide\"))), extended: () => import(\"./icon-packs/lucide\").then((m) => m.loadExtended(importOf(\"lucide\"))) },\n phosphor: { curated: () => import(\"./icon-packs/phosphor\").then((m) => m.loadCurated(importOf(\"phosphor\"))), extended: () => import(\"./icon-packs/phosphor\").then((m) => m.loadExtended(importOf(\"phosphor\"))) },\n heroicons: { curated: () => import(\"./icon-packs/heroicons\").then((m) => m.loadCurated(importOf(\"heroicons\"))), extended: () => import(\"./icon-packs/heroicons\").then((m) => m.loadExtended(importOf(\"heroicons\"))) },\n tabler: { curated: () => import(\"./icon-packs/tabler\").then((m) => m.loadCurated(importOf(\"tabler\"))), extended: () => import(\"./icon-packs/tabler\").then((m) => m.loadExtended(importOf(\"tabler\"))) },\n feather: { curated: () => import(\"./icon-packs/feather\").then((m) => m.loadCurated(importOf(\"feather\"))), extended: () => import(\"./icon-packs/feather\").then((m) => m.loadExtended(importOf(\"feather\"))) },\n};\n\n/* ── Context ──────────────────────────────────────────────────── */\n\ninterface IconContextValue {\n pack: IconPack;\n weight: number;\n}\n\nconst IconCtx = createContext<IconContextValue>({ pack: \"lucide\", weight: 1.5 });\n\n/**\n * Sets the icon pack and stroke weight for every Icon inside it, and starts loading the pack. The app shell's generated\n * code puts it around the app with the theme's pack, so a page doesn't add its own.\n */\nexport function IconProvider({ pack, weight, children }: { pack: IconPack; weight: number; children: ReactNode }) {\n useEffect(() => {\n loadPack(pack);\n if (pack !== \"lucide\") loadPack(\"lucide\");\n }, [pack]);\n\n return <IconCtx.Provider value={{ pack, weight }}>{children}</IconCtx.Provider>;\n}\n\n/**\n * Start loading a pack's icon chunk before React mounts. Call this in your\n * app's entry point or shell for the fastest possible cold start, after the\n * pack is registered (every pack but Lucide, Sprint 25.21 P1):\n *\n * import { preloadPack, registerIconPack } from 'gridsmith-ui/icons'\n * registerIconPack('feather', () => import('react-icons/fi'))\n * preloadPack('feather')\n */\nexport function preloadPack(pack: IconPack): void {\n loadPack(pack);\n}\n\n/* ── Phosphor weight mapping ──────────────────────────────────── */\n\n/**\n * A stroke weight maps to a stroke weight only. `fill` and `duotone` change the\n * glyph itself (Phosphor's filled Check is a check inside a filled square), so\n * a theme's heaviest stroke must never reach them — the Sprint 22 bench found\n * every tick on a 2.5-weight theme rendered as a filled box (14 Sep 2026).\n */\nexport function getPhosphorWeight(numericWeight: number): \"thin\" | \"light\" | \"regular\" | \"bold\" {\n if (numericWeight <= 0.75) return \"thin\";\n if (numericWeight <= 1.25) return \"light\";\n if (numericWeight <= 1.75) return \"regular\";\n return \"bold\";\n}\n\n/* ── Icon component ───────────────────────────────────────────── */\n\n/**\n * `from`: the component slot that drew the icon (\"Button's iconLeft\"), named in the development warning when the theme's\n * pack has no icon by that name. A name no pack has draws nothing (Sprint 25.17 A26: an arrow or a word passed as an\n * icon was printed as text before slots took names).\n */\n/**\n * Whether a map holds an icon of its own by this name, never one its prototype lends: a slot now takes any string, and\n * \"constructor\", \"toString\" or \"__proto__\" read off a plain object drew junk or threw (Sprint 25.17's review). The icon\n * is then read off the map itself, so the compiler sees a component the map holds, not one made while rendering.\n */\nfunction owns(map: Record<string, IconComponent> | null | undefined, name: string): map is Record<string, IconComponent> {\n return !!map && Object.prototype.hasOwnProperty.call(map, name);\n}\n\n/**\n * An icon by name, drawn from the pack the IconProvider around it sets (the theme's, through the app shell), with Lucide\n * as the fallback when the pack lacks the name; `size` in pixels, 16 by default. A name neither has draws nothing and\n * warns once in development, where `from` names the caller.\n */\nexport function Icon({ name, size = 16, className, from }: { name: IconName; size?: number; className?: string; from?: string }) {\n const { pack, weight } = useContext(IconCtx);\n\n const curatedMap = useCuratedMap(pack);\n const extendedMap = useExtendedMap(pack);\n const lucideCurated = useCuratedMap(\"lucide\");\n const lucideExtended = useExtendedMap(\"lucide\");\n\n // Ensure the active pack is loading (covers cases where Icon mounts\n // before IconProvider's useEffect fires, e.g. during SSR hydration)\n if (!curatedCache.has(pack) && !loadingPacks.has(pack)) {\n loadPack(pack);\n }\n\n let Comp: IconComponent | undefined | null = null;\n let renderPack: IconPack = pack;\n\n // Tier 1: curated map (available once pack chunk has loaded)\n if (owns(curatedMap, name)) {\n Comp = curatedMap[name];\n }\n\n // Tier 2: extended map (available after barrel import completes)\n if (!Comp && owns(extendedMap, name)) {\n Comp = extendedMap[name];\n }\n\n // Tier 3: lucide fallback (curated first, then extended)\n if (!Comp && pack !== \"lucide\") {\n const fallback = owns(lucideCurated, name) ? lucideCurated[name] : owns(lucideExtended, name) ? lucideExtended[name] : undefined;\n if (fallback) {\n Comp = fallback;\n renderPack = \"lucide\";\n }\n }\n\n const allMapsLoaded = !!(curatedMap && extendedMap && (pack === \"lucide\" || (lucideCurated && lucideExtended)));\n const missing = !Comp && allMapsLoaded;\n useEffect(() => {\n if (missing) warnOnce(\"Icon\", `\"${name}\" is not an icon name in the ${pack} pack${pack === \"lucide\" ? \"\" : \" or Lucide\"}, so ${from ?? \"it\"} draws nothing. Pass an icon name, or an element.`);\n }, [missing, name, pack, from]);\n\n if (!Comp) {\n if (allMapsLoaded) return null;\n return <span style={{ display: \"inline-block\", width: size, height: size }} className={className} />;\n }\n\n if (renderPack === \"phosphor\") {\n return <Comp size={size} weight={getPhosphorWeight(weight)} className={className} />;\n }\n\n if (renderPack === \"heroicons\") {\n return <Comp className={className} style={{ width: size, height: size, strokeWidth: weight }} />;\n }\n\n if (renderPack === \"tabler\") {\n return <Comp size={size} stroke={weight} className={className} />;\n }\n\n if (renderPack === \"feather\") {\n return <Comp size={size} className={className} strokeWidth={weight} />;\n }\n\n return <Comp size={size} strokeWidth={weight} className={className} />;\n}\n\n/* ── Icon slots ───────────────────────────────────────────────── */\n\n/**\n * What an icon slot takes (Sprint 25.17 A26): an icon name, drawn as the theme's icon at the slot's size, or an element,\n * drawn as given. `IconName` accepts any string, so text type-checks: in development a name the theme's pack lacks warns,\n * naming the slot, and draws nothing; the engine flags a literal that is no icon name (gs:icon-slot-not-an-icon).\n */\nexport type IconSlot = IconName | ReactElement | false | null | undefined;\n\n/** What an icon slot holds, drawn: a name as the theme's icon at `size`, anything else as given. */\nexport function slotIcon(icon: IconSlot | ReactNode, size: number, from: string): ReactNode {\n if (typeof icon === \"string\") {\n // \"\" is no icon (`saved ? \"check\" : \"\"`): nothing drawn, nothing warned\n if (!icon) return null;\n return ICON_NAME_SHAPE.test(icon) ? <Icon name={icon} size={size} from={from} /> : <NotAnIcon text={icon} from={from} />;\n }\n return icon;\n}\n\n/** The shape of an icon name: kebab case, as every pack's names are written (\"arrow-right\", \"file-text\"). */\nconst ICON_NAME_SHAPE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;\n\n/**\n * Whether a slot draws something: an element, or a string shaped as an icon name. Text (\"→\", \"Save\") draws nothing, so\n * a button keeps its even padding for it (Sprint 25.17's review); a name the pack lacks still warns, once its maps load.\n */\nexport function slotDraws(icon: IconSlot | ReactNode): boolean {\n if (typeof icon === \"string\") return ICON_NAME_SHAPE.test(icon);\n return icon != null && icon !== false && icon !== true;\n}\n\n/** Text given to an icon slot: it draws nothing, and says so in development, naming the slot. */\nfunction NotAnIcon({ text, from }: { text: string; from: string }) {\n useEffect(() => {\n warnOnce(\"Icon\", `\"${text}\" is not an icon name, so ${from} draws nothing. Words go in the label; pass an icon name, or an element.`);\n }, [text, from]);\n return null;\n}\n"]}
|