gridsmith-ui 0.33.0 → 0.33.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/dist/charts.js +7 -7
  3. package/dist/chat.js +6 -6
  4. package/dist/{chunk-WSKPESAX.js → chunk-4FX6UCSS.js} +5 -5
  5. package/dist/{chunk-WSKPESAX.js.map → chunk-4FX6UCSS.js.map} +1 -1
  6. package/dist/{chunk-OWGF362U.js → chunk-4TQVFRKK.js} +6 -6
  7. package/dist/{chunk-OWGF362U.js.map → chunk-4TQVFRKK.js.map} +1 -1
  8. package/dist/{chunk-HCEHTJ5E.js → chunk-77X7AHFB.js} +3 -3
  9. package/dist/{chunk-HCEHTJ5E.js.map → chunk-77X7AHFB.js.map} +1 -1
  10. package/dist/{chunk-AVSP6NDX.js → chunk-BL2C35BN.js} +42 -32
  11. package/dist/chunk-BL2C35BN.js.map +1 -0
  12. package/dist/{chunk-2724SJO2.js → chunk-HDFTENVW.js} +7 -3
  13. package/dist/chunk-HDFTENVW.js.map +1 -0
  14. package/dist/{chunk-6XCWKLJZ.js → chunk-MPXE2XOP.js} +5 -5
  15. package/dist/{chunk-6XCWKLJZ.js.map → chunk-MPXE2XOP.js.map} +1 -1
  16. package/dist/{chunk-FF57N3P7.js → chunk-MW5CJOJN.js} +4 -4
  17. package/dist/{chunk-FF57N3P7.js.map → chunk-MW5CJOJN.js.map} +1 -1
  18. package/dist/{chunk-UBLBVCQN.js → chunk-N6QLEZFH.js} +5 -5
  19. package/dist/{chunk-UBLBVCQN.js.map → chunk-N6QLEZFH.js.map} +1 -1
  20. package/dist/{chunk-TMPPBXX3.js → chunk-NFVJEICH.js} +3 -3
  21. package/dist/{chunk-TMPPBXX3.js.map → chunk-NFVJEICH.js.map} +1 -1
  22. package/dist/{chunk-AB4UQ4G5.js → chunk-NJG6JQGC.js} +7 -7
  23. package/dist/{chunk-AB4UQ4G5.js.map → chunk-NJG6JQGC.js.map} +1 -1
  24. package/dist/{chunk-6NRLTG5W.js → chunk-PT4HYHI3.js} +7 -7
  25. package/dist/{chunk-6NRLTG5W.js.map → chunk-PT4HYHI3.js.map} +1 -1
  26. package/dist/{chunk-F2XMZOUP.js → chunk-T33JK3ZE.js} +4 -4
  27. package/dist/{chunk-F2XMZOUP.js.map → chunk-T33JK3ZE.js.map} +1 -1
  28. package/dist/{chunk-ZQV26NND.js → chunk-UI4BSRCQ.js} +3 -3
  29. package/dist/{chunk-ZQV26NND.js.map → chunk-UI4BSRCQ.js.map} +1 -1
  30. package/dist/{chunk-WD6T57ZJ.js → chunk-XJGFZ5CP.js} +5 -5
  31. package/dist/{chunk-WD6T57ZJ.js.map → chunk-XJGFZ5CP.js.map} +1 -1
  32. package/dist/{chunk-R2IAK3J3.js → chunk-ZTS6HJAU.js} +3 -3
  33. package/dist/{chunk-R2IAK3J3.js.map → chunk-ZTS6HJAU.js.map} +1 -1
  34. package/dist/dashboard.js +6 -6
  35. package/dist/data-grid.js +7 -7
  36. package/dist/editor-mentions.js +2 -2
  37. package/dist/editor.js +2 -2
  38. package/dist/index.d.ts +14 -2
  39. package/dist/index.js +78 -42
  40. package/dist/index.js.map +1 -1
  41. package/dist/kanban.js +7 -7
  42. package/dist/resizable.js +7 -7
  43. package/dist/utils.js.map +1 -1
  44. package/dist/virtualized.js +7 -7
  45. package/package.json +1 -1
  46. package/dist/chunk-2724SJO2.js.map +0 -1
  47. package/dist/chunk-AVSP6NDX.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../showcase/src/lib/slot.tsx","../../../showcase/src/components/Tooltip.tsx","../../../showcase/src/lib/reveal-focus.ts"],"names":["jsx","isValidElement","cloneElement","useEffect"],"mappings":"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","file":"chunk-HCEHTJ5E.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","import { useState, useRef, useCallback, useEffect, useLayoutEffect, useId, useContext, cloneElement, isValidElement, type HTMLAttributes, type ReactElement, type ReactNode, type Ref, createContext } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { cn, GLASS_DROPDOWN } from \"../lib/utils\";\nimport { Slot, mergeRefs } from \"../lib/slot\";\nimport { usePosition, type Side } from \"../lib/use-position\";\nimport { useLatest } from \"../lib/use-latest\";\n\ninterface TooltipProps extends Omit<HTMLAttributes<HTMLElement>, \"content\"> {\n content: ReactNode;\n children: ReactNode;\n side?: Side;\n delay?: number;\n className?: string;\n container?: Element | DocumentFragment;\n /**\n * Keep the Tooltip in the tree but never show it. Use this instead of rendering\n * the Tooltip only sometimes: adding or removing the wrapper remounts its child,\n * which drops focus from a field inside it (Sprint 25.7, the Combobox).\n */\n disabled?: boolean;\n /**\n * A Tooltip can itself be the child of a Slot — `<DropdownMenu trigger={<Tooltip …><Button/></Tooltip>}>` —\n * so the ref and handlers a parent merges onto it are passed through to its own trigger (14 Sep 2026).\n */\n ref?: Ref<HTMLElement>;\n}\n\n/**\n * Inside a tooltip's trigger: asks for the element that tooltip covers, or null when it can't show (disabled, in which\n * case the one around it answers). A tooltip a component draws on its own (an icon Button's from its aria-label, every\n * AutoTooltip) asks when it would show, and steps aside when the answer holds its own trigger: the outer one shows\n * whenever the pointer is in it, so both would show at once (round 15, 52.7, two tooltips on one button; every\n * component's own tooltip since the review of 21.6 session B). Asked then, not at render: a Tooltip around a component\n * that passes no props on never fires, and the component's own tooltip still shows.\n */\nexport const TooltipCtx = createContext<(() => HTMLElement | null) | null>(null);\n\n/** Marks a component whose `title` prop is the native attribute (the library's Button): a Tooltip drops it, as an element's. */\nexport const NATIVE_TITLE = Symbol(\"native title\");\n\n// 600ms: long enough that passing the pointer over a toolbar, or landing focus\n// on an icon button, does not flash a label; short enough to still feel live.\nexport function Tooltip({ content, children, side = \"top\", delay = 600, className, container, disabled = false, ref, ...slotProps }: TooltipProps) {\n return <TooltipBase content={content} side={side} delay={delay} className={className} container={container} disabled={disabled} ref={ref} {...slotProps}>{children}</TooltipBase>;\n}\n\n/**\n * The tooltip a library component draws on its own: an icon Button's label, cut-off text in full, a relative time's\n * date, an avatar's name, its own controls' labels. Where a tooltip that can show already covers its trigger (a Tooltip\n * the page put around it) it steps aside, so the control shows one (the review of 21.6 session B: a Tooltip around a\n * cut-off Badge showed two). Every component's own tooltip is one of these; `<Tooltip>` is the page's, and never steps aside.\n */\nexport function AutoTooltip(props: TooltipProps) {\n return <TooltipBase {...props} auto />;\n}\n\n/**\n * The AutoTooltip of text cut to fit (Sprint 25.8.7 item 5, lib's CutText): the tooltip is the way to the full text, so a\n * tap shows it at once and a second tap or a press elsewhere hides it, and a press or Enter never dismisses it, there\n * being nothing to activate.\n */\nexport function RevealTooltip(props: TooltipProps) {\n return <TooltipBase {...props} auto reveal />;\n}\n\n/**\n * The drawn tooltip on screen now (Sprint 25.32, round 29's double tooltips; the owner's rule, one tooltip per control,\n * and APG's one at a time): a tooltip that opens closes this one first. A focused control's label (a RelativeTime's full\n * date, shown by keyboard focus) gives way when the pointer rests on another control, so two never show at once.\n */\nlet shownTooltip: { close: () => void } | null = null;\n\nfunction TooltipBase({ content, children, side = \"top\", delay = 600, className, container, disabled = false, auto = false, reveal = false, ref: forwardedRef, ...slotProps }: TooltipProps & { auto?: boolean; reveal?: boolean }) {\n const around = useContext(TooltipCtx);\n const [open, setOpen] = useState(false);\n // Disabling while shown hides it (render-time state adjustment).\n if (disabled && open) setOpen(false);\n const triggerRef = useRef<HTMLElement>(null);\n const floatingRef = useRef<HTMLDivElement>(null);\n const timeoutRef = useRef<ReturnType<typeof setTimeout>>(undefined);\n // Set when the trigger is activated: the label must not reappear (from the\n // focus the click leaves behind, or a still-pending timer) until the pointer\n // leaves and comes back.\n const suppressedRef = useRef(false);\n const id = useId();\n\n const pos = usePosition(triggerRef, floatingRef, open, { side, offset: 6, flip: true });\n\n const cancel = useCallback(() => {\n clearTimeout(timeoutRef.current);\n timeoutRef.current = undefined;\n }, []);\n\n // What this tooltip covers, for one inside its trigger to ask: its trigger while it can show, else the answer of the\n // one around it. An automatic tooltip is covered when that answer holds its own trigger.\n const disabledRef = useLatest(disabled);\n const covers = useCallback(() => (disabledRef.current ? around?.() ?? null : triggerRef.current), [around, disabledRef]);\n const covered = useCallback(() => {\n const mine = triggerRef.current;\n const theirs = auto ? around?.() : null;\n return !!(mine && theirs && theirs.contains(mine));\n }, [auto, around]);\n\n // One pending timer at a time: hover and focus both call show(), and the\n // earlier timer used to be orphaned, firing after hide() had run and leaving\n // the tooltip up with nothing left to close it.\n const show = useCallback(() => {\n if (disabled || suppressedRef.current || covered()) return;\n cancel();\n timeoutRef.current = setTimeout(() => setOpen(true), delay);\n }, [delay, cancel, disabled, covered]);\n\n const hide = useCallback(() => {\n cancel();\n setOpen(false);\n }, [cancel]);\n\n // Pointer focus (a click) does not warrant a label; keyboard focus does. The element focused is asked, not the\n // trigger: focus that reaches the trigger from a control inside it (a card title's button) is that control's, and\n // the trigger itself never matched, so the label never showed by keyboard (the review of 30 September).\n const showOnFocus = useCallback((e: React.FocusEvent<HTMLElement>) => {\n let keyboard = true;\n const focused = e.target instanceof Element ? e.target : e.currentTarget;\n try { keyboard = focused.matches(\":focus-visible\"); } catch { /* selector unsupported: assume keyboard */ }\n if (keyboard) show();\n }, [show]);\n\n // Activating the trigger dismisses the label and keeps it away until the\n // pointer has left — what opens next (a menu, a dialog) owns the screen.\n const dismissOnActivate = useCallback(() => {\n suppressedRef.current = true;\n hide();\n }, [hide]);\n\n // Suppression lifts when the pointer leaves or focus moves on — a keyboard\n // user never produces a mouseleave, so blur must reset it too.\n const leave = useCallback(() => {\n suppressedRef.current = false;\n hide();\n }, [hide]);\n\n // Cut text's tooltip (`reveal`): a finger's tap shows it at once, and taps it away; a mouse's press leaves it as the\n // hover has it\n const revealOnPress = (e: React.PointerEvent<HTMLElement>) => {\n if (e.pointerType !== \"touch\" || disabled || covered()) return;\n if (open) { hide(); return; }\n cancel();\n suppressedRef.current = false;\n setOpen(true);\n };\n\n // Escape dismisses an open tooltip (WCAG 1.4.13); it does not stop the key\n // reaching whatever overlay is also listening. Cut text's goes with a press anywhere else too, as a tap showed it.\n useEffect(() => {\n if (!open) return;\n const onKey = (e: KeyboardEvent) => { if (e.key === \"Escape\") hide(); };\n const onPress = (e: PointerEvent) => { if (!triggerRef.current?.contains(e.target as Node)) hide(); };\n document.addEventListener(\"keydown\", onKey);\n if (reveal) document.addEventListener(\"pointerdown\", onPress, true);\n return () => {\n document.removeEventListener(\"keydown\", onKey);\n document.removeEventListener(\"pointerdown\", onPress, true);\n };\n }, [open, hide, reveal]);\n\n useEffect(() => cancel, [cancel]);\n\n // one on screen at a time: this one, once it opens, closes the one showing, before either is painted (a passive effect\n // drew both for a frame, the review of 18 October)\n useLayoutEffect(() => {\n if (!open) return;\n const mine = { close: () => { cancel(); setOpen(false); } };\n if (shownTooltip && shownTooltip !== mine) shownTooltip.close();\n shownTooltip = mine;\n return () => { if (shownTooltip === mine) shownTooltip = null; };\n }, [open, cancel]);\n\n // A native title on the trigger would be the browser's second tooltip, a moment after this one (the review of 21.6\n // session B): an element's own title goes, and the library Button's. Another component's title prop is left alone: it\n // often means something else (a Card's heading).\n const nativeTitle = isValidElement(children) && (typeof children.type === \"string\" || NATIVE_TITLE in (children.type as object));\n const trigger = nativeTitle && (children.props as { title?: unknown }).title !== undefined\n ? cloneElement(children as ReactElement<{ title?: string }>, { title: undefined })\n : children;\n\n return (\n <TooltipCtx value={covers}>\n <Slot\n {...slotProps}\n ref={mergeRefs(triggerRef, forwardedRef)}\n onMouseEnter={(e) => { slotProps.onMouseEnter?.(e); show(); }}\n onMouseLeave={(e) => { slotProps.onMouseLeave?.(e); leave(); }}\n onFocus={(e) => { slotProps.onFocus?.(e); showOnFocus(e); }}\n onBlur={(e) => { slotProps.onBlur?.(e); leave(); }}\n onPointerDown={(e) => { slotProps.onPointerDown?.(e); if (reveal) revealOnPress(e); else dismissOnActivate(); }}\n onKeyDown={(e) => { slotProps.onKeyDown?.(e); if (!reveal && (e.key === \"Enter\" || e.key === \" \")) dismissOnActivate(); }}\n aria-describedby={open ? id : undefined}\n >\n {trigger}\n </Slot>\n {open && createPortal(\n <div\n ref={floatingRef}\n id={id}\n role=\"tooltip\"\n className={cn(\n \"fixed z-[var(--ds-z-tooltip)] pointer-events-none\",\n \"px-ds-2.5 py-ds-1.5 text-xs\",\n \"max-w-[280px] break-words\",\n \"bg-[var(--ds-bg-surface-elevated)] text-[var(--ds-text-primary)]\",\n GLASS_DROPDOWN,\n \"border-[length:var(--ds-border-width)] border-[var(--ds-border-default)]\",\n \"rounded-[var(--ds-radius-sm)]\",\n className\n )}\n style={{ top: pos.top, left: pos.left }}\n >\n {content}\n </div>,\n container ?? document.body\n )}\n </TooltipCtx>\n );\n}\n\n","import { useEffect, type RefObject } from \"react\";\n\n/**\n * A scroller's focused item, shown whole with its keyboard outline (Sprint 30, P3). A browser scrolls an item into view\n * when focus reaches it only if none of it shows: one partly in view (a list's last option, a card at a board's edge, a\n * row under the fold) stays cut off, its outline with it. When a key moves focus to something inside the scroller (Tab,\n * or a component's arrows), this scrolls it into view, as little as it takes; the scroller's scroll padding\n * (`scroll-p-[4px]`, P3's room) leaves the outline its 4 px. Focus a pointer gave is left where it is, so nothing moves\n * under the mouse. Pass the element itself (a callback ref's), as useKeyboardScroll takes it, or a ref object, read when\n * focus arrives (for an element whose ref is already taken).\n */\nexport function useRevealFocus(target: HTMLElement | null | RefObject<HTMLElement | null>, enabled = true): void {\n useEffect(() => {\n if (!enabled || !target) return;\n const read = () => (\"current\" in target ? target.current : target);\n const first = read();\n const doc = first?.ownerDocument ?? (typeof document !== \"undefined\" ? document : null);\n if (!doc) return;\n // whether a key or a pointer came last: the fields' tracker counts typing as neither, and an arrow from a list's\n // search box moves focus by the keyboard all the same\n let keyed = false;\n const onKey = () => { keyed = true; };\n const onPointer = () => { keyed = false; };\n const onFocusIn = (e: FocusEvent) => {\n const el = read();\n const focused = e.target;\n // a typing surface keeps its own caret in view: scrolled \"into view\" whole, a long one would jump\n if (!keyed || !el || focused === el || !(focused instanceof Element) || !el.contains(focused) || (focused as HTMLElement).isContentEditable) return;\n focused.scrollIntoView?.({ block: \"nearest\", inline: \"nearest\" });\n };\n doc.addEventListener(\"keydown\", onKey, true);\n doc.addEventListener(\"pointerdown\", onPointer, true);\n doc.addEventListener(\"focusin\", onFocusIn);\n return () => {\n doc.removeEventListener(\"keydown\", onKey, true);\n doc.removeEventListener(\"pointerdown\", onPointer, true);\n doc.removeEventListener(\"focusin\", onFocusIn);\n };\n }, [target, enabled]);\n}\n"]}
1
+ {"version":3,"sources":["../../../showcase/src/lib/slot.tsx","../../../showcase/src/components/Tooltip.tsx","../../../showcase/src/lib/reveal-focus.ts"],"names":["jsx","isValidElement","cloneElement","useEffect"],"mappings":"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","file":"chunk-77X7AHFB.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","import { useState, useRef, useCallback, useEffect, useLayoutEffect, useId, useContext, cloneElement, isValidElement, type HTMLAttributes, type ReactElement, type ReactNode, type Ref, createContext } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { cn, GLASS_DROPDOWN } from \"../lib/utils\";\nimport { Slot, mergeRefs } from \"../lib/slot\";\nimport { usePosition, type Side } from \"../lib/use-position\";\nimport { useLatest } from \"../lib/use-latest\";\n\ninterface TooltipProps extends Omit<HTMLAttributes<HTMLElement>, \"content\"> {\n content: ReactNode;\n children: ReactNode;\n side?: Side;\n delay?: number;\n className?: string;\n container?: Element | DocumentFragment;\n /**\n * Keep the Tooltip in the tree but never show it. Use this instead of rendering\n * the Tooltip only sometimes: adding or removing the wrapper remounts its child,\n * which drops focus from a field inside it (Sprint 25.7, the Combobox).\n */\n disabled?: boolean;\n /**\n * A Tooltip can itself be the child of a Slot — `<DropdownMenu trigger={<Tooltip …><Button/></Tooltip>}>` —\n * so the ref and handlers a parent merges onto it are passed through to its own trigger (14 Sep 2026).\n */\n ref?: Ref<HTMLElement>;\n}\n\n/**\n * Inside a tooltip's trigger: asks for the element that tooltip covers, or null when it can't show (disabled, in which\n * case the one around it answers). A tooltip a component draws on its own (an icon Button's from its aria-label, every\n * AutoTooltip) asks when it would show, and steps aside when the answer holds its own trigger: the outer one shows\n * whenever the pointer is in it, so both would show at once (round 15, 52.7, two tooltips on one button; every\n * component's own tooltip since the review of 21.6 session B). Asked then, not at render: a Tooltip around a component\n * that passes no props on never fires, and the component's own tooltip still shows.\n */\nexport const TooltipCtx = createContext<(() => HTMLElement | null) | null>(null);\n\n/** Marks a component whose `title` prop is the native attribute (the library's Button): a Tooltip drops it, as an element's. */\nexport const NATIVE_TITLE = Symbol(\"native title\");\n\n// 600ms: long enough that passing the pointer over a toolbar, or landing focus\n// on an icon button, does not flash a label; short enough to still feel live.\nexport function Tooltip({ content, children, side = \"top\", delay = 600, className, container, disabled = false, ref, ...slotProps }: TooltipProps) {\n return <TooltipBase content={content} side={side} delay={delay} className={className} container={container} disabled={disabled} ref={ref} {...slotProps}>{children}</TooltipBase>;\n}\n\n/**\n * The tooltip a library component draws on its own: an icon Button's label, cut-off text in full, a relative time's\n * date, an avatar's name, its own controls' labels. Where a tooltip that can show already covers its trigger (a Tooltip\n * the page put around it) it steps aside, so the control shows one (the review of 21.6 session B: a Tooltip around a\n * cut-off Badge showed two). Every component's own tooltip is one of these; `<Tooltip>` is the page's, and never steps aside.\n */\nexport function AutoTooltip(props: TooltipProps) {\n return <TooltipBase {...props} auto />;\n}\n\n/**\n * The AutoTooltip of text cut to fit (Sprint 25.8.7 item 5, lib's CutText): the tooltip is the way to the full text, so a\n * tap shows it at once and a second tap or a press elsewhere hides it, and a press or Enter never dismisses it, there\n * being nothing to activate.\n */\nexport function RevealTooltip(props: TooltipProps) {\n return <TooltipBase {...props} auto reveal />;\n}\n\n/**\n * The drawn tooltip on screen now (Sprint 25.32, round 29's double tooltips; the owner's rule, one tooltip per control,\n * and APG's one at a time): a tooltip that opens closes this one first. A focused control's label (a RelativeTime's full\n * date, shown by keyboard focus) gives way when the pointer rests on another control, so two never show at once.\n */\nlet shownTooltip: { close: () => void } | null = null;\n\nfunction TooltipBase({ content, children, side = \"top\", delay = 600, className, container, disabled = false, auto = false, reveal = false, ref: forwardedRef, ...slotProps }: TooltipProps & { auto?: boolean; reveal?: boolean }) {\n const around = useContext(TooltipCtx);\n const [open, setOpen] = useState(false);\n // Disabling while shown hides it (render-time state adjustment).\n if (disabled && open) setOpen(false);\n const triggerRef = useRef<HTMLElement>(null);\n const floatingRef = useRef<HTMLDivElement>(null);\n const timeoutRef = useRef<ReturnType<typeof setTimeout>>(undefined);\n // Set when the trigger is activated: the label must not reappear (from the\n // focus the click leaves behind, or a still-pending timer) until the pointer\n // leaves and comes back.\n const suppressedRef = useRef(false);\n const id = useId();\n\n const pos = usePosition(triggerRef, floatingRef, open, { side, offset: 6, flip: true });\n\n const cancel = useCallback(() => {\n clearTimeout(timeoutRef.current);\n timeoutRef.current = undefined;\n }, []);\n\n // What this tooltip covers, for one inside its trigger to ask: its trigger while it can show, else the answer of the\n // one around it. An automatic tooltip is covered when that answer holds its own trigger.\n const disabledRef = useLatest(disabled);\n const covers = useCallback(() => (disabledRef.current ? around?.() ?? null : triggerRef.current), [around, disabledRef]);\n const covered = useCallback(() => {\n const mine = triggerRef.current;\n const theirs = auto ? around?.() : null;\n return !!(mine && theirs && theirs.contains(mine));\n }, [auto, around]);\n\n // One pending timer at a time: hover and focus both call show(), and the\n // earlier timer used to be orphaned, firing after hide() had run and leaving\n // the tooltip up with nothing left to close it.\n const show = useCallback(() => {\n if (disabled || suppressedRef.current || covered()) return;\n cancel();\n timeoutRef.current = setTimeout(() => setOpen(true), delay);\n }, [delay, cancel, disabled, covered]);\n\n const hide = useCallback(() => {\n cancel();\n setOpen(false);\n }, [cancel]);\n\n // Pointer focus (a click) does not warrant a label; keyboard focus does. The element focused is asked, not the\n // trigger: focus that reaches the trigger from a control inside it (a card title's button) is that control's, and\n // the trigger itself never matched, so the label never showed by keyboard (the review of 30 September).\n const showOnFocus = useCallback((e: React.FocusEvent<HTMLElement>) => {\n let keyboard = true;\n const focused = e.target instanceof Element ? e.target : e.currentTarget;\n try { keyboard = focused.matches(\":focus-visible\"); } catch { /* selector unsupported: assume keyboard */ }\n if (keyboard) show();\n }, [show]);\n\n // Activating the trigger dismisses the label and keeps it away until the\n // pointer has left — what opens next (a menu, a dialog) owns the screen.\n const dismissOnActivate = useCallback(() => {\n suppressedRef.current = true;\n hide();\n }, [hide]);\n\n // Suppression lifts when the pointer leaves or focus moves on — a keyboard\n // user never produces a mouseleave, so blur must reset it too.\n const leave = useCallback(() => {\n suppressedRef.current = false;\n hide();\n }, [hide]);\n\n // Cut text's tooltip (`reveal`): a finger's tap shows it at once, and taps it away; a mouse's press leaves it as the\n // hover has it\n const revealOnPress = (e: React.PointerEvent<HTMLElement>) => {\n if (e.pointerType !== \"touch\" || disabled || covered()) return;\n if (open) { hide(); return; }\n cancel();\n suppressedRef.current = false;\n setOpen(true);\n };\n\n // Escape dismisses an open tooltip (WCAG 1.4.13); it does not stop the key\n // reaching whatever overlay is also listening. Cut text's goes with a press anywhere else too, as a tap showed it.\n useEffect(() => {\n if (!open) return;\n const onKey = (e: KeyboardEvent) => { if (e.key === \"Escape\") hide(); };\n const onPress = (e: PointerEvent) => { if (!triggerRef.current?.contains(e.target as Node)) hide(); };\n document.addEventListener(\"keydown\", onKey);\n if (reveal) document.addEventListener(\"pointerdown\", onPress, true);\n return () => {\n document.removeEventListener(\"keydown\", onKey);\n document.removeEventListener(\"pointerdown\", onPress, true);\n };\n }, [open, hide, reveal]);\n\n useEffect(() => cancel, [cancel]);\n\n // one on screen at a time: this one, once it opens, closes the one showing, before either is painted (a passive effect\n // drew both for a frame, the review of 18 October)\n useLayoutEffect(() => {\n if (!open) return;\n const mine = { close: () => { cancel(); setOpen(false); } };\n if (shownTooltip && shownTooltip !== mine) shownTooltip.close();\n shownTooltip = mine;\n return () => { if (shownTooltip === mine) shownTooltip = null; };\n }, [open, cancel]);\n\n // A native title on the trigger would be the browser's second tooltip, a moment after this one (the review of 21.6\n // session B): an element's own title goes, and the library Button's. Another component's title prop is left alone: it\n // often means something else (a Card's heading).\n const nativeTitle = isValidElement(children) && (typeof children.type === \"string\" || NATIVE_TITLE in (children.type as object));\n const trigger = nativeTitle && (children.props as { title?: unknown }).title !== undefined\n ? cloneElement(children as ReactElement<{ title?: string }>, { title: undefined })\n : children;\n\n return (\n <TooltipCtx value={covers}>\n <Slot\n {...slotProps}\n ref={mergeRefs(triggerRef, forwardedRef)}\n onMouseEnter={(e) => { slotProps.onMouseEnter?.(e); show(); }}\n onMouseLeave={(e) => { slotProps.onMouseLeave?.(e); leave(); }}\n onFocus={(e) => { slotProps.onFocus?.(e); showOnFocus(e); }}\n onBlur={(e) => { slotProps.onBlur?.(e); leave(); }}\n onPointerDown={(e) => { slotProps.onPointerDown?.(e); if (reveal) revealOnPress(e); else dismissOnActivate(); }}\n onKeyDown={(e) => { slotProps.onKeyDown?.(e); if (!reveal && (e.key === \"Enter\" || e.key === \" \")) dismissOnActivate(); }}\n aria-describedby={open ? id : undefined}\n >\n {trigger}\n </Slot>\n {open && createPortal(\n <div\n ref={floatingRef}\n id={id}\n role=\"tooltip\"\n className={cn(\n \"fixed z-[var(--ds-z-tooltip)] pointer-events-none\",\n \"px-ds-2.5 py-ds-1.5 text-xs\",\n \"max-w-[280px] break-words\",\n \"bg-[var(--ds-bg-surface-elevated)] text-[var(--ds-text-primary)]\",\n GLASS_DROPDOWN,\n \"border-[length:var(--ds-border-width)] border-[var(--ds-border-default)]\",\n \"rounded-[var(--ds-radius-sm)]\",\n className\n )}\n style={{ top: pos.top, left: pos.left }}\n >\n {content}\n </div>,\n container ?? document.body\n )}\n </TooltipCtx>\n );\n}\n\n","import { useEffect, type RefObject } from \"react\";\n\n/**\n * A scroller's focused item, shown whole with its keyboard outline (Sprint 30, P3). A browser scrolls an item into view\n * when focus reaches it only if none of it shows: one partly in view (a list's last option, a card at a board's edge, a\n * row under the fold) stays cut off, its outline with it. When a key moves focus to something inside the scroller (Tab,\n * or a component's arrows), this scrolls it into view, as little as it takes; the scroller's scroll padding\n * (`scroll-p-[4px]`, P3's room) leaves the outline its 4 px. Focus a pointer gave is left where it is, so nothing moves\n * under the mouse. Pass the element itself (a callback ref's), as useKeyboardScroll takes it, or a ref object, read when\n * focus arrives (for an element whose ref is already taken).\n */\nexport function useRevealFocus(target: HTMLElement | null | RefObject<HTMLElement | null>, enabled = true): void {\n useEffect(() => {\n if (!enabled || !target) return;\n const read = () => (\"current\" in target ? target.current : target);\n const first = read();\n const doc = first?.ownerDocument ?? (typeof document !== \"undefined\" ? document : null);\n if (!doc) return;\n // whether a key or a pointer came last: the fields' tracker counts typing as neither, and an arrow from a list's\n // search box moves focus by the keyboard all the same\n let keyed = false;\n const onKey = () => { keyed = true; };\n const onPointer = () => { keyed = false; };\n const onFocusIn = (e: FocusEvent) => {\n const el = read();\n const focused = e.target;\n // a typing surface keeps its own caret in view: scrolled \"into view\" whole, a long one would jump\n if (!keyed || !el || focused === el || !(focused instanceof Element) || !el.contains(focused) || (focused as HTMLElement).isContentEditable) return;\n focused.scrollIntoView?.({ block: \"nearest\", inline: \"nearest\" });\n };\n doc.addEventListener(\"keydown\", onKey, true);\n doc.addEventListener(\"pointerdown\", onPointer, true);\n doc.addEventListener(\"focusin\", onFocusIn);\n return () => {\n doc.removeEventListener(\"keydown\", onKey, true);\n doc.removeEventListener(\"pointerdown\", onPointer, true);\n doc.removeEventListener(\"focusin\", onFocusIn);\n };\n }, [target, enabled]);\n}\n"]}
@@ -1,13 +1,13 @@
1
1
  "use client";
2
2
  import { useShellPreferences, PREFERENCE_HOUSE_DEFAULTS } from './chunk-QOMP4D6V.js';
3
- import { Dropdown } from './chunk-OWGF362U.js';
3
+ import { Dropdown } from './chunk-4TQVFRKK.js';
4
4
  import { RowsCtx, SplitListFramerCtx } from './chunk-RS624TD5.js';
5
5
  import { useReportedChange, FormChangeCtx } from './chunk-72SDAX54.js';
6
- import { ControlSizeContext, triggerType, Button } from './chunk-FF57N3P7.js';
6
+ import { ControlSizeContext, triggerType, Button } from './chunk-MW5CJOJN.js';
7
7
  import { useInputModality } from './chunk-7RKC5C7G.js';
8
- import { Slot, AutoTooltip } from './chunk-HCEHTJ5E.js';
8
+ import { Slot, AutoTooltip } from './chunk-77X7AHFB.js';
9
9
  import { warnOnce, Icon } from './chunk-53F7GVBQ.js';
10
- import { useLatest, cn, FOCUS_RING, ERROR_FOCUS_WITHIN_RING, FIELD_FOCUS_WITHIN_RING, usePosition, usePressMarks, usePopupFocus, focusInitial, GLASS_DROPDOWN, focusAfterSelfRemoval, tabStops, isTabStop } from './chunk-2724SJO2.js';
10
+ import { placesOf, useLatest, cn, FOCUS_RING, ERROR_FOCUS_WITHIN_RING, FIELD_FOCUS_WITHIN_RING, usePosition, usePressMarks, usePopupFocus, focusInitial, GLASS_DROPDOWN, focusAfterSelfRemoval, tabStops, isTabStop } from './chunk-HDFTENVW.js';
11
11
  import { useContext, useRef, useState, useCallback, useEffect } from 'react';
12
12
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
13
13
  import { createPortal } from 'react-dom';
@@ -30,9 +30,12 @@ function NumberInput({
30
30
  size: sizeProp,
31
31
  className,
32
32
  error = false,
33
+ decimals,
33
34
  allowDecimals,
34
35
  id,
35
- "aria-label": ariaLabel
36
+ "aria-label": ariaLabel,
37
+ "aria-describedby": describedBy,
38
+ "aria-required": ariaRequired
36
39
  }) {
37
40
  const onChange = useReportedChange(onChangeProp, value);
38
41
  useInputModality();
@@ -42,12 +45,20 @@ function NumberInput({
42
45
  const timeoutRef = useRef(void 0);
43
46
  const inputRef = useRef(null);
44
47
  const [focused, setFocused] = useState(false);
45
- const [draft, setDraft] = useState(String(value));
46
- const decimals = allowDecimals ?? step % 1 !== 0;
48
+ const stepPlaces = placesOf(step);
49
+ const exact = Math.max(stepPlaces, placesOf(min), placesOf(max));
50
+ const places = decimals !== void 0 ? Math.max(decimals, exact) : allowDecimals === false ? 0 : allowDecimals && !stepPlaces ? null : exact;
51
+ const snap = useCallback((v) => places === null ? v : Number(v.toFixed(places)), [places]);
52
+ const text = useCallback((v) => {
53
+ if (!Number.isFinite(v)) return "";
54
+ const at = snap(v);
55
+ return decimals !== void 0 ? at.toFixed(places ?? 0) : at.toFixed(Math.min(100, placesOf(at)));
56
+ }, [snap, decimals, places]);
57
+ const [draft, setDraft] = useState(() => text(value));
47
58
  const [prevSync, setPrevSync] = useState({ value, focused });
48
- if (value !== prevSync.value || focused !== prevSync.focused) {
59
+ if (!Object.is(value, prevSync.value) || focused !== prevSync.focused) {
49
60
  setPrevSync({ value, focused });
50
- if (!focused) setDraft(String(value));
61
+ if (!focused || draft === text(prevSync.value)) setDraft(text(value));
51
62
  }
52
63
  const clamp = useCallback(
53
64
  (v) => Math.min(max, Math.max(min, v)),
@@ -55,14 +66,20 @@ function NumberInput({
55
66
  );
56
67
  const valueRef = useLatest(value);
57
68
  const commitValue = useCallback((v, own = false) => {
58
- const clamped = clamp(v);
69
+ const clamped = clamp(snap(v));
59
70
  valueRef.current = clamped;
60
- setDraft(String(clamped));
71
+ setDraft(text(clamped));
61
72
  (own ? onChangeProp : onChange)(clamped);
62
73
  return clamped;
63
- }, [onChange, onChangeProp, clamp, valueRef]);
64
- const increment = useCallback(() => commitValue(valueRef.current + step), [commitValue, step, valueRef]);
65
- const decrement = useCallback(() => commitValue(valueRef.current - step), [commitValue, step, valueRef]);
74
+ }, [onChange, onChangeProp, clamp, valueRef, snap, text]);
75
+ const stepBy = useCallback((by) => {
76
+ const from = valueRef.current;
77
+ if (!Number.isFinite(from)) return commitValue(isFinite(min) ? min : 0);
78
+ const sum = from + by;
79
+ return commitValue(places === null ? Number(sum.toFixed(Math.min(100, Math.max(placesOf(from), placesOf(by))))) : sum);
80
+ }, [commitValue, valueRef, min, places]);
81
+ const increment = useCallback(() => stepBy(step), [stepBy, step]);
82
+ const decrement = useCallback(() => stepBy(-step), [stepBy, step]);
66
83
  const startRepeat = useCallback(
67
84
  (fn) => {
68
85
  fn();
@@ -83,8 +100,7 @@ function NumberInput({
83
100
  setDraft(raw);
84
101
  return;
85
102
  }
86
- if (!decimals && raw.includes(".")) return;
87
- const validPattern = decimals ? /^-?\d*\.?\d*$/ : /^-?\d*$/;
103
+ const validPattern = places === null ? /^-?\d*\.?\d*$/ : new RegExp(`^-?\\d*${places ? `(\\.\\d{0,${places}})?` : ""}$`);
88
104
  if (!validPattern.test(raw)) return;
89
105
  setDraft(raw);
90
106
  const parsed = parseFloat(raw);
@@ -92,20 +108,12 @@ function NumberInput({
92
108
  onChange(clamp(parsed));
93
109
  }
94
110
  },
95
- [onChange, clamp, decimals]
111
+ [onChange, clamp, places]
96
112
  );
97
113
  const handleBlur = useCallback(() => {
98
114
  setFocused(false);
99
- const parsed = parseFloat(draft);
100
- if (!isNaN(parsed) && isFinite(parsed)) {
101
- const committed = commitValue(parsed, draft === String(value));
102
- setDraft(String(committed));
103
- } else {
104
- const fallback = isFinite(min) ? min : 0;
105
- const committed = commitValue(value !== void 0 ? value : fallback, true);
106
- setDraft(String(committed));
107
- }
108
- }, [draft, commitValue, min, value]);
115
+ if (Number.isFinite(value) && clamp(value) !== value) commitValue(value, true);
116
+ }, [commitValue, clamp, value]);
109
117
  const handleFocus = useCallback(() => {
110
118
  setFocused(true);
111
119
  }, []);
@@ -134,7 +142,7 @@ function NumberInput({
134
142
  const s = sizes[size];
135
143
  const atMin = value <= min;
136
144
  const atMax = value >= max;
137
- const shown = focused ? draft : String(value);
145
+ const shown = focused ? draft : text(value);
138
146
  const holdsNumber = Number.isFinite(parseFloat(shown)) && Number.isFinite(value);
139
147
  return /* @__PURE__ */ jsxs(
140
148
  "div",
@@ -194,10 +202,12 @@ function NumberInput({
194
202
  type: "text",
195
203
  role: "spinbutton",
196
204
  "aria-label": ariaLabel,
197
- "aria-valuenow": holdsNumber ? value : void 0,
205
+ "aria-describedby": describedBy,
206
+ "aria-required": ariaRequired || void 0,
207
+ "aria-valuenow": holdsNumber ? snap(value) : void 0,
198
208
  "aria-valuemin": Number.isFinite(min) ? min : void 0,
199
209
  "aria-valuemax": Number.isFinite(max) ? max : void 0,
200
- inputMode: decimals ? "decimal" : "numeric",
210
+ inputMode: places === 0 ? "numeric" : "decimal",
201
211
  "aria-invalid": error || void 0,
202
212
  value: shown,
203
213
  onChange: handleInput,
@@ -751,5 +761,5 @@ function useWholeListCheck(component, length, pager) {
751
761
  }
752
762
 
753
763
  export { NumberInput, Pagination, Popover, pagerPart, usePagination, useWholeListCheck };
754
- //# sourceMappingURL=chunk-AVSP6NDX.js.map
755
- //# sourceMappingURL=chunk-AVSP6NDX.js.map
764
+ //# sourceMappingURL=chunk-BL2C35BN.js.map
765
+ //# sourceMappingURL=chunk-BL2C35BN.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../showcase/src/components/NumberInput.tsx","../../../showcase/src/components/Popover.tsx","../../../showcase/src/components/Pagination.tsx","../../../showcase/src/lib/use-pagination.ts"],"names":["useRef","useState","useCallback","jsxs","jsx","useEffect","sizes"],"mappings":"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","file":"chunk-BL2C35BN.js","sourcesContent":["import { useCallback, useContext, useRef, useState } from \"react\";\nimport { useLatest } from \"../lib/use-latest\";\nimport { cn, FIELD_FOCUS_WITHIN_RING, ERROR_FOCUS_WITHIN_RING, FOCUS_RING, placesOf } from \"../lib/utils\";\nimport { useInputModality } from \"../lib/input-modality\";\nimport { ControlSizeContext } from \"./Button\";\nimport { useReportedChange } from \"../lib/form-context\";\n\ninterface NumberInputProps {\n value: number;\n onChange: (value: number) => void;\n min?: number;\n max?: number;\n step?: number;\n disabled?: boolean;\n placeholder?: string;\n prefix?: string;\n suffix?: string;\n size?: \"sm\" | \"md\" | \"lg\";\n className?: string;\n error?: boolean;\n /**\n * The decimal places typed and shown, the value always showing them (\"12.50\"): money is `decimals={2}`, its buttons\n * moving by `step` (1 for whole pounds). Never fewer than the step's or a limit's own. Without it, a fractional step\n * gives its places (0.1: one, shown as the number is, \"2\" and \"2.5\"), and a whole step none.\n */\n decimals?: number;\n /**\n * Decimals of any length on a whole step, as typed (DataGrid's number editor); `decimals` caps them, and `false`\n * allows none. A fractional step needs neither: it gives its own places.\n */\n allowDecimals?: boolean;\n /** Forwarded to the inner input element so a Label htmlFor can be associated. */\n id?: string;\n /** The field's name where nothing on screen names it (\"Seats\"); inside a Field, the Field's label names it. */\n \"aria-label\"?: string;\n /** The hint and the error that describe it: a Field gives them. */\n \"aria-describedby\"?: string;\n \"aria-required\"?: boolean;\n}\n\n// The height is the bordered box's (box-sizing: border-box), so the control measures exactly the token beside an\n// Input or a Button; the buttons and the field stretch to it.\nconst sizes = {\n sm: { box: \"h-[var(--ds-control-height-sm)]\", input: \"text-xs self-stretch\", btn: \"w-7 text-xs\" },\n md: { box: \"h-[var(--ds-control-height-md)]\", input: \"text-sm self-stretch\", btn: \"w-9 text-sm\" },\n lg: { box: \"h-[var(--ds-control-height-lg)]\", input: \"text-base self-stretch\", btn: \"w-10 text-base\" },\n};\n\nexport function NumberInput({\n value,\n onChange: onChangeProp,\n min = -Infinity,\n max = Infinity,\n step = 1,\n disabled = false,\n placeholder = \"0\",\n prefix,\n suffix,\n size: sizeProp,\n className,\n error = false,\n decimals,\n allowDecimals,\n id,\n \"aria-label\": ariaLabel,\n \"aria-describedby\": describedBy,\n \"aria-required\": ariaRequired,\n}: NumberInputProps) {\n // Sprint 25.12 A15: a new value the user gives this control marks the form's overlay; the page's onChange runs as given\n const onChange = useReportedChange(onChangeProp, value);\n // a field: clicked into, the active look; reached with Tab, the outline (Sprint 30, lib/input-modality.ts)\n useInputModality();\n const contextSize = useContext(ControlSizeContext);\n const size = sizeProp ?? contextSize ?? \"md\";\n const intervalRef = useRef<ReturnType<typeof setInterval>>(undefined);\n const timeoutRef = useRef<ReturnType<typeof setTimeout>>(undefined);\n const inputRef = useRef<HTMLInputElement>(null);\n const [focused, setFocused] = useState(false);\n\n // The places a value keeps (Sprint 32's follow-up, L1: stepping 0.1 from 0.2 gave 0.30000000000000004): those asked\n // for, never fewer than the step's or a limit's own; else a fractional step's (or a limit's); any, with allowDecimals\n // on a whole step (null: a value keeps every digit it has); else a limit's, so the field can show its limits (none,\n // mostly)\n const stepPlaces = placesOf(step);\n const exact = Math.max(stepPlaces, placesOf(min), placesOf(max));\n const places = decimals !== undefined ? Math.max(decimals, exact) : allowDecimals === false ? 0 : allowDecimals && !stepPlaces ? null : exact;\n // a value at its places, and its text: every place when asked for (\"12.50\"), else as the number is, never with an\n // exponent (\"0.0000001\", not \"1e-7\"); empty for no number. The shown text and the text typed into come from here, so\n // they always agree (and -0.04 at one place is \"0\")\n const snap = useCallback((v: number) => (places === null ? v : Number(v.toFixed(places))), [places]);\n const text = useCallback((v: number) => {\n if (!Number.isFinite(v)) return \"\";\n const at = snap(v);\n return decimals !== undefined ? at.toFixed(places ?? 0) : at.toFixed(Math.min(100, placesOf(at)));\n }, [snap, decimals, places]);\n const [draft, setDraft] = useState(() => text(value));\n\n // While not focused the draft mirrors the controlled value; on blur it\n // re-syncs (render-time state adjustment).\n const [prevSync, setPrevSync] = useState({ value, focused });\n // Object.is: an empty field's NaN is the same NaN, where `!==` would set state on every render\n if (!Object.is(value, prevSync.value) || focused !== prevSync.focused) {\n setPrevSync({ value, focused });\n // focused, the text follows a value changed from outside (a map's radius dragged while the field kept focus) while it\n // still shows the value it had, empty or finer than the field (Sprint 32's follow-up): never over something typed\n if (!focused || draft === text(prevSync.value)) setDraft(text(value));\n }\n\n const clamp = useCallback(\n (v: number) => Math.min(max, Math.max(min, v)),\n [min, max],\n );\n\n // Stepping reads the latest committed value through a ref so a held button\n // (setInterval in startRepeat) keeps counting instead of re-adding one step\n // to the value captured at mousedown. useLatest syncs it to the prop in a\n // layout effect (never during render); commitValue advances it in the handler.\n const valueRef = useLatest(value);\n\n // Commit a stepped or blurred value. The draft is updated too: the input\n // shows the draft while focused, and stepping happens while focused (the\n // buttons focus the input), so without this the text never moved and the\n // stale draft was committed back over the new value on blur.\n // `own`: the control settles on a value by itself (a page's value past a limit, clamped as the field is left), which\n // is not the user's change and doesn't mark the form's overlay (Sprint 25.12 A15).\n const commitValue = useCallback((v: number, own = false) => {\n // rounded to the field's places, then held to its limits (a limit's own places are among them)\n const clamped = clamp(snap(v));\n // Advance the ref now, not on the next render: repeat ticks can land\n // before React re-renders, and each must build on the previous one.\n valueRef.current = clamped;\n setDraft(text(clamped));\n (own ? onChangeProp : onChange)(clamped);\n return clamped;\n }, [onChange, onChangeProp, clamp, valueRef, snap, text]);\n\n // from an empty field (no number yet) the buttons and the arrows give the minimum, or 0 without one: a step from\n // nothing was NaN (Sprint 32's follow-up: a radius not yet set). With any places a step adds in the places of what it\n // adds, so the value keeps its own digits and loses only the noise (0.125 + 1 is 1.125, and 1234567890123 + 1 exact)\n const stepBy = useCallback((by: number) => {\n const from = valueRef.current;\n if (!Number.isFinite(from)) return commitValue(isFinite(min) ? min : 0);\n const sum = from + by;\n return commitValue(places === null ? Number(sum.toFixed(Math.min(100, Math.max(placesOf(from), placesOf(by))))) : sum);\n }, [commitValue, valueRef, min, places]);\n const increment = useCallback(() => stepBy(step), [stepBy, step]);\n const decrement = useCallback(() => stepBy(-step), [stepBy, step]);\n\n const startRepeat = useCallback(\n (fn: () => void) => {\n fn();\n timeoutRef.current = setTimeout(() => {\n intervalRef.current = setInterval(fn, 75);\n }, 400);\n },\n [],\n );\n\n const stopRepeat = useCallback(() => {\n clearTimeout(timeoutRef.current);\n clearInterval(intervalRef.current);\n }, []);\n\n const handleInput = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const raw = e.target.value;\n\n if (raw === \"\" || raw === \"-\") {\n setDraft(raw);\n return;\n }\n\n // typing stops at the field's places, as it refuses a letter\n const validPattern = places === null ? /^-?\\d*\\.?\\d*$/ : new RegExp(`^-?\\\\d*${places ? `(\\\\.\\\\d{0,${places}})?` : \"\"}$`);\n if (!validPattern.test(raw)) return;\n\n setDraft(raw);\n\n const parsed = parseFloat(raw);\n if (!isNaN(parsed) && isFinite(parsed)) {\n onChange(clamp(parsed));\n }\n },\n [onChange, clamp, places],\n );\n\n // Leaving the field changes nothing: what was typed was reported as it was typed, held to the limits, and the text\n // follows the value once the field is left, so a field passed through never rewrites the page's value (a page's\n // 1.23456 shown as 1.2) nor marks its form, and one emptied, or left at \"-\", shows its value again (or stays empty with\n // none). A page's value past a limit is clamped as it's left, as the control's own (0.21.0).\n const handleBlur = useCallback(() => {\n setFocused(false);\n if (Number.isFinite(value) && clamp(value) !== value) commitValue(value, true);\n }, [commitValue, clamp, value]);\n\n const handleFocus = useCallback(() => {\n setFocused(true);\n }, []);\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (e.key === \"ArrowUp\") { e.preventDefault(); increment(); }\n if (e.key === \"ArrowDown\") { e.preventDefault(); decrement(); }\n // Sprint 25.8.7 item 24, the APG spinbutton: \"Home: If the spinbutton has a minimum value, sets the value to its\n // minimum\", and End its maximum. Without that limit, or with a modifier held (Shift+Home selects), the key is the\n // caret's: the pattern keeps the platform's text editing keys for a field that can be typed in\n const plain = !e.shiftKey && !e.ctrlKey && !e.metaKey && !e.altKey;\n if (e.key === \"Home\" && plain && Number.isFinite(min)) { e.preventDefault(); commitValue(min); }\n if (e.key === \"End\" && plain && Number.isFinite(max)) { e.preventDefault(); commitValue(max); }\n },\n [increment, decrement, commitValue, min, max],\n );\n\n const s = sizes[size];\n const atMin = value <= min;\n const atMax = value >= max;\n // Sprint 25.8.7 item 24: the value is stated while the field holds a number (\"Authors SHOULD set the aria-valuenow\n // attribute when the spinbutton has a value\", WAI-ARIA 1.2), not while it is emptied to type afresh; it is the\n // committed value, which typing keeps within the limits\n const shown = focused ? draft : text(value);\n const holdsNumber = Number.isFinite(parseFloat(shown)) && Number.isFinite(value);\n\n return (\n <div\n className={cn(\n \"flex items-center w-full\",\n s.box,\n \"border-[length:var(--ds-border-width)]\",\n error ? \"border-[var(--ds-status-error)]\" : \"border-[var(--ds-input-border)]\",\n \"rounded-[var(--ds-radius-md)]\",\n \"shadow-[var(--ds-input-shadow)]\",\n \"bg-[var(--ds-input-bg)]\",\n \"transition-colors duration-[var(--ds-transition-speed)]\",\n !error && !disabled && \"hover:border-[var(--ds-input-border-hover)]\",\n error ? ERROR_FOCUS_WITHIN_RING : FIELD_FOCUS_WITHIN_RING,\n disabled && \"opacity-disabled cursor-not-allowed\",\n className,\n )}\n >\n <button\n type=\"button\"\n tabIndex={-1}\n disabled={disabled || atMin}\n onMouseDown={(e) => { e.preventDefault(); inputRef.current?.focus(); if (!disabled && !atMin) startRepeat(decrement); }}\n onMouseUp={stopRepeat}\n onMouseLeave={stopRepeat}\n className={cn(\n \"inline-flex items-center justify-center shrink-0\",\n \"border-r-[length:var(--ds-border-width)] border-[var(--ds-border-default)]\",\n \"text-[var(--ds-text-muted)] hover:text-[var(--ds-text-primary)] hover:bg-[var(--ds-bg-muted)]\",\n \"transition-colors cursor-pointer\",\n \"rounded-l-[var(--ds-radius-md)]\",\n // kept out of the Tab order (the field's arrows step it) and never focused by a press: the outline all the same\n // if anything focuses it (Sprint 30)\n FOCUS_RING,\n s.btn, s.input,\n (disabled || atMin) && \"opacity-disabled cursor-not-allowed hover:bg-transparent hover:text-[var(--ds-text-muted)]\",\n )}\n aria-label=\"Decrease\"\n >\n −\n </button>\n\n <div className={cn(\"flex items-center flex-1 min-w-0 px-ds-2 gap-ds-1\", s.input)}>\n {prefix && <span className=\"text-[var(--ds-text-muted)] shrink-0 text-xs\">{prefix}</span>}\n <input\n ref={inputRef}\n id={id}\n type=\"text\"\n // a spinbutton that can be typed in (Sprint 25.8.7 item 24): its value, and each limit only when it exists\n role=\"spinbutton\"\n aria-label={ariaLabel}\n aria-describedby={describedBy}\n aria-required={ariaRequired || undefined}\n aria-valuenow={holdsNumber ? snap(value) : undefined}\n aria-valuemin={Number.isFinite(min) ? min : undefined}\n aria-valuemax={Number.isFinite(max) ? max : undefined}\n inputMode={places === 0 ? \"numeric\" : \"decimal\"}\n aria-invalid={error || undefined}\n value={shown}\n onChange={handleInput}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onKeyDown={handleKeyDown}\n disabled={disabled}\n placeholder={placeholder}\n className={cn(\n \"w-full min-w-0 bg-transparent text-center outline-none\",\n \"text-[var(--ds-text-primary)]\",\n \"placeholder:text-[var(--ds-text-muted)]\",\n \"font-[family-name:var(--ds-font-mono)]\",\n s.input,\n disabled && \"cursor-not-allowed\",\n )}\n />\n {suffix && <span className=\"text-[var(--ds-text-muted)] shrink-0 text-xs\">{suffix}</span>}\n </div>\n\n <button\n type=\"button\"\n tabIndex={-1}\n disabled={disabled || atMax}\n onMouseDown={(e) => { e.preventDefault(); inputRef.current?.focus(); if (!disabled && !atMax) startRepeat(increment); }}\n onMouseUp={stopRepeat}\n onMouseLeave={stopRepeat}\n className={cn(\n \"inline-flex items-center justify-center shrink-0\",\n \"border-l-[length:var(--ds-border-width)] border-[var(--ds-border-default)]\",\n \"text-[var(--ds-text-muted)] hover:text-[var(--ds-text-primary)] hover:bg-[var(--ds-bg-muted)]\",\n \"transition-colors cursor-pointer\",\n \"rounded-r-[var(--ds-radius-md)]\",\n FOCUS_RING,\n s.btn, s.input,\n (disabled || atMax) && \"opacity-disabled cursor-not-allowed hover:bg-transparent hover:text-[var(--ds-text-muted)]\",\n )}\n aria-label=\"Increase\"\n >\n +\n </button>\n </div>\n );\n}\n","import { useRef, useEffect, type ReactNode, useState, useCallback } from \"react\";\nimport { RowsCtx, SplitListFramerCtx } from \"../lib/surface-context\";\nimport { createPortal } from \"react-dom\";\nimport { cn, GLASS_DROPDOWN } from \"../lib/utils\";\nimport { Slot } from \"../lib/slot\";\nimport { triggerType } from \"./Button\";\nimport { usePosition, type Side, type Align } from \"../lib/use-position\";\nimport { focusInitial, usePopupFocus, usePressMarks } from \"../lib/focus\";\nimport { useLatest } from \"../lib/use-latest\";\n\ninterface PopoverProps {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n trigger: ReactNode;\n children: ReactNode;\n side?: Side;\n align?: Align;\n width?: \"trigger\" | \"auto\" | (string & {});\n className?: string;\n container?: Element | DocumentFragment;\n}\n\nexport function Popover({ open, onOpenChange, trigger, children, side = \"bottom\", align = \"center\", width, className, container }: PopoverProps) {\n const triggerRef = useRef<HTMLElement>(null);\n const floatingRef = useRef<HTMLDivElement>(null);\n // Measured in commit-phase code (ref callback, click handler), never read from the ref during render.\n const [triggerWidth, setTriggerWidth] = useState<number | undefined>(undefined);\n const setTriggerNode = useCallback((node: HTMLElement | null) => {\n triggerRef.current = node;\n setTriggerWidth(node?.offsetWidth);\n }, []);\n\n const pos = usePosition(triggerRef, floatingRef, open, { side, align, offset: 8, flip: true });\n // Read from the listeners below, so a new onOpenChange each render never re-registers them (an inner list's Escape\n // listener would then run first, and this popover would see itself on top after the list closed).\n const onOpenChangeRef = useLatest(onOpenChange);\n // A press in a popup the content opens elsewhere in the page (a Dropdown's list) passes through this tree first.\n const { props: pressMarks, marked } = usePressMarks();\n\n // Sprint 25.7: Tab from the panel's last control (or Shift+Tab from its first) closes it and carries on from the\n // trigger; content that closes it (an Apply button) hands focus back through the safety net.\n const { isTop: isTopLayer, returnFocus } = usePopupFocus(open, { trigger: triggerRef, panel: floatingRef, close: () => onOpenChangeRef.current(false), tabExits: \"edges\", marked });\n\n useEffect(() => {\n if (!open) return;\n\n // Bubble phase on document, after the content's own handlers: content that stops or handles Escape (a draft\n // field going back a step, a list inside closing) keeps the popover open. It acts only with focus in it, or\n // nowhere, so an Escape meant for a field elsewhere never closes it.\n const onKeyDown = (e: KeyboardEvent) => {\n if (e.key !== \"Escape\" || e.defaultPrevented || !isTopLayer()) return;\n const active = document.activeElement;\n if (active && active !== document.body && !triggerRef.current?.contains(active) && !floatingRef.current?.contains(active)) return;\n e.preventDefault();\n returnFocus();\n onOpenChangeRef.current(false);\n };\n\n // A press outside the popover's React tree closes it, whatever is open inside it (Radix's dismissable layer). A\n // press in a popup opened from it (a Dropdown's list) is inside, so its click lands.\n const onPress = (e: MouseEvent) => {\n const target = e.target as Node;\n if (marked(e) || triggerRef.current?.contains(target) || floatingRef.current?.contains(target)) return;\n onOpenChangeRef.current(false);\n };\n\n document.addEventListener(\"keydown\", onKeyDown);\n document.addEventListener(\"mousedown\", onPress);\n return () => {\n document.removeEventListener(\"keydown\", onKeyDown);\n document.removeEventListener(\"mousedown\", onPress);\n };\n }, [open, onOpenChangeRef, isTopLayer, returnFocus, marked]);\n\n useEffect(() => {\n if (open) focusInitial(floatingRef.current);\n }, [open]);\n\n return (\n <>\n <Slot\n {...triggerType(trigger)}\n ref={setTriggerNode}\n onClick={() => { setTriggerWidth(triggerRef.current?.offsetWidth); onOpenChange(!open); }}\n >\n {trigger}\n </Slot>\n {open && createPortal(\n <div\n ref={floatingRef}\n data-gs=\"popover\"\n {...pressMarks}\n // Clicks inside are the panel's own, not a click on a row or card the trigger sits in.\n onClick={(e) => e.stopPropagation()}\n className={cn(\n \"fixed z-[var(--ds-z-popover)]\",\n \"bg-[var(--ds-bg-surface-elevated)]\",\n GLASS_DROPDOWN,\n \"border-[length:var(--ds-border-width)] border-[var(--ds-border-default)]\",\n \"rounded-[var(--ds-radius-md)]\",\n className\n )}\n style={{\n top: pos.top,\n left: pos.left,\n width: width === \"trigger\" ? triggerWidth : width === \"auto\" ? undefined : width,\n }}\n >\n {/* an overlay's content is no collection's row, wherever it was opened from */}\n {/* a popup starts afresh: a list pane round it hears nothing of what it holds (the end review of 25.33's fix pass) */}\n <RowsCtx value={false}><SplitListFramerCtx value={null}>{children}</SplitListFramerCtx></RowsCtx>\n </div>,\n container ?? document.body\n )}\n </>\n );\n}\n","import { useEffect, useRef, useState } from \"react\";\nimport { cn, FOCUS_RING } from \"../lib/utils\";\nimport { focusAfterSelfRemoval, isTabStop, tabStops } from \"../lib/focus\";\nimport { Icon } from \"../lib/icons\";\nimport { Dropdown } from \"./Dropdown\";\nimport { Popover } from \"./Popover\";\nimport { NumberInput } from \"./NumberInput\";\nimport { Button } from \"./Button\";\nimport { AutoTooltip } from \"./Tooltip\";\nimport { useShellPreferences } from \"../lib/preferences\";\nimport { useLatest } from \"../lib/use-latest\";\nimport { FormChangeCtx } from \"../lib/form-context\";\nimport { warnOnce } from \"../lib/dev-warn\";\n\ninterface PaginationProps {\n currentPage: number;\n totalPages: number;\n onPageChange: (page: number) => void;\n pageSize?: number;\n pageSizeOptions?: number[];\n onPageSizeChange?: (size: number) => void;\n /**\n * How the list shows more (round 22): page numbers, a Load more button, or loading as the user scrolls (with the\n * button kept for keyboard users). `usePagination` passes the project's dataDisplay.paginationStyle here in\n * `pager.props`, so `<Pagination {...pager.props} />` follows the project's style with nothing written on the page.\n */\n mode?: \"pagination\" | \"load-more\" | \"infinite-scroll\";\n /** Rows left to load (load-more and infinite-scroll). */\n hasMore?: boolean;\n /** Load the next rows (load-more and infinite-scroll). */\n onLoadMore?: () => void;\n /** The Load more button's label (default \"Load more\"). */\n loadMoreLabel?: string;\n className?: string;\n /** Set by `usePagination` in `pager.props`: which list the control belongs to (Sprint 25.13 A3). */\n pagerToken?: object;\n}\n\n/** The controls drawn for each pager: a list given the pager draws one, so a <Pagination> of the page's is a second. */\nconst controlsDrawn = new WeakMap<object, number>();\n\nexport function Pagination(props: PaginationProps) {\n const { pagerToken } = props;\n useEffect(() => {\n if (!pagerToken) return;\n const count = (controlsDrawn.get(pagerToken) ?? 0) + 1;\n controlsDrawn.set(pagerToken, count);\n if (count > 1) warnOnce(\"Pagination\", \"this list's pager already draws its control: a list given the pager (<Table pager={pager}>) draws it beneath the rows, so remove the separate <Pagination {...pager.props} />.\");\n return () => { controlsDrawn.set(pagerToken, (controlsDrawn.get(pagerToken) ?? 1) - 1); };\n }, [pagerToken]);\n if ((props.mode === \"load-more\" || props.mode === \"infinite-scroll\") && props.onLoadMore) return <LoadMore {...props} onLoadMore={props.onLoadMore} scroll={props.mode === \"infinite-scroll\"} />;\n return <PageNumbers {...props} />;\n}\n\n/**\n * The box that scrolls the marker into view: the nearest ancestor that scrolls up and down, else the page (null, the\n * viewport). A list in a fixed-height scroller loads more as that scroller moves (Sprint 25.13 A49: the trigger watched\n * the viewport, so scrolling inside the list never loaded more).\n */\nfunction scrollerOf(el: HTMLElement): HTMLElement | null {\n for (let n = el.parentElement; n && n !== document.body && n !== document.documentElement; n = n.parentElement) {\n const { overflowY } = getComputedStyle(n);\n if ((overflowY === \"auto\" || overflowY === \"scroll\") && n.scrollHeight > n.clientHeight) return n;\n }\n return null;\n}\n\n/**\n * An element's top in content coordinates: where it sits in the page, however far anything is scrolled. The window's\n * scroll is the document element's, so the walk stops below it (the review of 23 September: it was counted twice).\n */\nfunction contentTop(el: HTMLElement): number {\n let top = el.getBoundingClientRect().top + window.scrollY;\n for (let n = el.parentElement; n && n !== document.documentElement; n = n.parentElement) top += n.scrollTop;\n return top;\n}\n\n/**\n * Load more, by button or by scrolling (round 22). The scroll trigger is an observed marker above the button: when it\n * comes within 200 px of view the next rows load, and the observer is renewed after each load so a short list keeps\n * filling the window. It loads again only when the last load moved it — the list grew — or the user has scrolled since:\n * a list shown as a loading skeleton does not grow, and a Team page whose table showed one for half a second loaded\n * all 120 rows before its first row appeared. The button stays for keyboard users and for anyone who stops short.\n * Keyboard focus on the button holds the list (Sprint 25.29 item 7): focus brought it into view, not a scroll, and each\n * load pushed it off the screen again. Enter loads, and the button is brought back into view; focus leaving looks again.\n * Only a load the keyboard's press made brings it back (Sprint 25.31 item 3): a clicked button has focus too, and bringing\n * it into view after every load scrolled, which loaded again, so one click loaded every page.\n * The last load takes the button with it, so focus goes to the first row that load brought (Sprint 25.30 item 1), in\n * whatever markup the list draws (Sprint 25.31 item 4), and the list holds no more (item 5). Only the press's own load\n * hands focus on: a load that leaves the button in place ends the press's watch.\n */\nfunction LoadMore({ hasMore, onLoadMore, loadMoreLabel, currentPage, scroll, className }: PaginationProps & { onLoadMore: () => void; scroll: boolean }) {\n const marker = useRef<HTMLDivElement>(null);\n const button = useRef<HTMLButtonElement>(null);\n const pager = useRef<HTMLDivElement>(null);\n // a press's watches: for the button going with its load (to hand focus on), and for its rows (to bring the button back)\n const watching = useRef<(() => void) | null>(null);\n const endWatch = () => {\n watching.current?.();\n watching.current = null;\n };\n // keyboard focus on the infinite list's button holds it (Sprint 25.29 item 7)\n const [held, setHeld] = useState(false);\n // a press with focus on the button: should it be the last, focus goes on to the first row it brought, the person\n // reading on where they asked to, else the last control before the pager, else the last resort round where it sat\n const press = () => {\n const b = button.current, root = pager.current;\n if (b && root && document.activeElement === b) {\n // the infinite list's: only while the keyboard holds it, since a mouse's focus shows the ring once a key is pressed,\n // and a scroll back would load again (the review of 16 October, 2). Plain Load more holds nothing, and no load\n // follows a scroll there: the keyboard's ring is enough.\n const byKey = scroll ? held : byKeyboard(b);\n const place = placeOf(root);\n const had = before(place);\n const hadRows = had.flatMap(rowsOf);\n const hadStops = had.flatMap(stopsIn);\n endWatch();\n // the watch lasts until the button goes (focus handed on), focus moves elsewhere, the next press, a load the list\n // starts by itself, or 10 s: never ended by the page number, which a page may count before its rows come (the\n // final review of 16 October, 1: the watch ended then, and the last load left focus on the page)\n const handOn = focusAfterSelfRemoval(b, {\n item: root,\n group: null,\n to: () => {\n // what the load brought, read again now it's in: the library's rows (a row with nothing in it to Tab to takes\n // focus itself, for the moment), else the Tab stops that appeared since the press, whatever the page draws\n const content = before(place);\n const fresh = appended(content.flatMap(rowsOf), hadRows);\n if (fresh) return tabStops(fresh)[0] ?? fresh;\n const stops = content.flatMap(stopsIn);\n return appended(stops, hadStops) ?? stops.at(-1);\n },\n });\n // a load by Enter: once its rows are in, above the button, with the button still here, it's brought back into view;\n // its rows, not its page number, which can come first (the final review, 1)\n const backInView = byKey ? whenRowsCome(place, hadRows, hadStops, b, () => { if (document.activeElement === b) b.scrollIntoView?.({ block: \"nearest\" }); }) : () => {};\n watching.current = () => { handOn(); backInView(); };\n }\n onLoadMore();\n };\n const load = useLatest(onLoadMore);\n const loadedAt = useRef<number | null>(null);\n // the last load takes the focused button, which fires no blur, so the list would hold for good: a filter that starts it\n // again never loaded as it scrolled (Sprint 25.31 item 5)\n if (held && !hasMore) setHeld(false);\n useEffect(() => {\n const el = marker.current;\n if (!scroll || !hasMore || !el || held || typeof IntersectionObserver === \"undefined\") return;\n const observer = new IntersectionObserver((entries) => {\n if (!entries.some((e) => e.isIntersecting)) return;\n const at = contentTop(el);\n if (loadedAt.current !== null && Math.abs(at - loadedAt.current) < 1) return;\n loadedAt.current = at;\n // a load the list starts by itself: a press's watch ends, so the list loading on as the person scrolls after a click\n // never takes focus back up to that press's rows (the reviews of 16 October, 1)\n watching.current?.();\n watching.current = null;\n load.current();\n }, { root: scrollerOf(el), rootMargin: \"200px 0px\" });\n observer.observe(el);\n const rearm = () => { loadedAt.current = null; };\n window.addEventListener(\"scroll\", rearm, { capture: true, passive: true });\n return () => {\n observer.disconnect();\n window.removeEventListener(\"scroll\", rearm, { capture: true });\n };\n }, [scroll, hasMore, currentPage, load, held]);\n if (!hasMore) return null;\n return (\n <div ref={pager} data-ds-pager=\"\" data-pagination-mode={scroll ? \"infinite-scroll\" : \"load-more\"} className={cn(\"flex flex-col items-center\", className)}>\n {scroll && <div ref={marker} data-load-more-trigger=\"\" aria-hidden=\"true\" className=\"h-px w-full\" />}\n <Button ref={button} type=\"button\" variant=\"secondary\" onClick={press}\n onFocus={(e) => setHeld(scroll && byKeyboard(e.currentTarget))} onBlur={() => setHeld(false)}>\n {loadMoreLabel ?? \"Load more\"}\n </Button>\n </div>\n );\n}\n\n/** Where a pager sits: the pager, or the nearest box round it with elements before it, its parent, and what follows it. */\ninterface PagerPlace { at: Element; parent: Element; next: Element | null }\n\n/**\n * A pager's place, read as a press begins (Sprint 25.31 item 4): the pager itself where its list comes before it (A3:\n * the list's next sibling, or the last child among the list's own items), else the nearest box round it that has\n * elements before it, as for a pager the page sets in a layout's box of its own.\n */\nfunction placeOf(el: Element): PagerPlace | null {\n for (let n: Element | null = el; n && n !== document.body; n = n.parentElement) {\n if (n.previousElementSibling && n.parentElement) return { at: n, parent: n.parentElement, next: n.nextElementSibling };\n }\n return null;\n}\n\n/**\n * What comes before that place now, its list among it: read again once a load is in, since new items can be the\n * pager's own siblings, and the last load takes the pager, whose place is then up to what followed it.\n */\nfunction before(place: PagerPlace | null): Element[] {\n if (!place) return [];\n const { at, parent, next } = place;\n const kids = Array.from(parent.children);\n const end = at.parentElement === parent ? kids.indexOf(at) : next?.parentElement === parent ? kids.indexOf(next) : kids.length;\n return kids.slice(0, end);\n}\n\n/** An element, when it matches, and what in it matches: rows and Tab stops can be the pager's own siblings. */\nconst withSelf = (el: Element, selector: string): Element[] => [...(el.matches(selector) ? [el] : []), ...el.querySelectorAll(selector)];\n\n/**\n * The rows in what a Load more follows: those the library's lists mark (the Table's rows and its cards on a phone,\n * `data-row-key` or `data-row-index`), else plain rows and items.\n */\nfunction rowsOf(list: Element): Element[] {\n const marked = withSelf(list, \"[data-row-key], [data-row-index]\");\n return marked.length ? marked : withSelf(list, 'tbody > tr, li, [role=\"row\"], [data-card]');\n}\n\n/** The Tab stops in an element, itself first. */\nconst stopsIn = (el: Element): HTMLElement[] => [...(isTabStop(el) ? [el] : []), ...tabStops(el)];\n\n/**\n * The first of `now`, in the page's order, that the press didn't see in `had`: lists append, so one after the last there\n * was, before one elsewhere, as a control the last load enabled above the list (the review of 16 October, 3).\n */\nfunction appended<T extends Element>(now: T[], had: Element[]): T | undefined {\n const seen = new Set(had);\n const fresh = now.filter((el) => !seen.has(el));\n const last = had.at(-1);\n return (last?.isConnected ? fresh.find((el) => last.compareDocumentPosition(el) & Node.DOCUMENT_POSITION_FOLLOWING) : undefined) ?? fresh[0];\n}\n\n/**\n * Calls `then` once the press's rows are in what comes before the pager, with the button still on the page (the final\n * review of 16 October, 1): a page may count the page as the press lands and draw its rows when they come. In a list the\n * library reads as rows, rows or Tab stops the press didn't see, so a spinner drawn first doesn't count; in one it can't\n * (a page's paragraphs), anything new before the pager. Ends with the button, or after 10 s. Returns what stops it.\n */\nfunction whenRowsCome(place: PagerPlace | null, hadRows: Element[], hadStops: Element[], button: HTMLElement, then: () => void): () => void {\n if (!place || typeof MutationObserver === \"undefined\") return () => {};\n const rows = new Set(hadRows), stops = new Set(hadStops);\n const observer = new MutationObserver((records) => {\n if (!button.isConnected) return stop();\n const content = before(place);\n const fresh = hadRows.length\n ? content.flatMap(rowsOf).some((r) => !rows.has(r)) || content.flatMap(stopsIn).some((s) => !stops.has(s))\n : records.some((r) => Array.from(r.addedNodes).some((n) => n instanceof Element && content.some((c) => c === n || c.contains(n))));\n if (!fresh) return;\n stop();\n then();\n });\n const timer = setTimeout(stop, 10_000);\n function stop() {\n observer.disconnect();\n clearTimeout(timer);\n }\n observer.observe(place.parent, { childList: true, subtree: true });\n return stop;\n}\n\n/** Focus the keyboard brought (`:focus-visible`), not a click; a browser without the selector counts every focus. */\nfunction byKeyboard(el: Element): boolean {\n try { return el.matches(\":focus-visible\"); } catch { return true; }\n}\n\nfunction PageNumbers({ currentPage, totalPages, onPageChange, pageSize: pageSizeProp, pageSizeOptions, onPageSizeChange, className }: PaginationProps) {\n const pages = buildPageRange(currentPage, totalPages);\n // Sprint 25.6 (B9): dataDisplay.itemsPerPage reaches the selector through the shell; a prop wins. App code pages its\n // list with usePagination, which reads the same value and passes it here in `pager.props` (round 21).\n const preferences = useShellPreferences();\n const pageSize = pageSizeProp ?? preferences.itemsPerPage;\n // A list that fits on one page shows no page numbers (GOV.UK: \"Do not show pagination if there's only one page of\n // content\"; the review of 30 September found \"‹ 1 ›\" under every short list). A size choice stays, so a user who\n // picked a larger size can pick a smaller one again.\n const sizeChoice = !!(pageSizeOptions && pageSize != null && onPageSizeChange);\n if (totalPages <= 1 && !sizeChoice) return null;\n // the size in force is always among the choices: a project's size the options lack joins them (the review of 16 October,\n // 5: 20 against 10, 25 and 50 showed and read \"Select...\"), at its place in the page's own order (the final review, 4)\n const sizes = pageSizeOptions && pageSize != null ? withSize(pageSizeOptions, pageSize) : pageSizeOptions;\n\n return (\n <nav aria-label=\"Pagination\" data-ds-pager=\"\" className={cn(\"flex flex-wrap items-center gap-ds-3\", className)}>\n {sizeChoice && pageSizeOptions && pageSize != null && onPageSizeChange && (\n <div className=\"flex items-center gap-ds-2\">\n <span className=\"text-sm text-[var(--ds-text-muted)] whitespace-nowrap\">Rows per page</span>\n {/* the page size is how the list is viewed: it never marks an overlay's form (0.21.0) */}\n <FormChangeCtx value={null}>\n {/* named by the visible label's words, then the size chosen, which the Dropdown adds itself (WCAG 4.1.2, 2.5.3;\n Sprint 25.31 item 1): \"Rows per page, 10\" */}\n <Dropdown\n aria-label=\"Rows per page\"\n options={(sizes ?? pageSizeOptions).map((n) => ({ id: String(n), label: String(n) }))}\n value={String(pageSize)}\n onChange={(v) => onPageSizeChange(Number(v))}\n size=\"sm\"\n className=\"w-[4.5rem]\"\n />\n </FormChangeCtx>\n </div>\n )}\n\n {totalPages > 1 && <div className=\"flex items-center gap-ds-1\">\n {/* an icon button's one tooltip, its name (Sprint 25.29 item 18, accessibility#10) */}\n <AutoTooltip content=\"Previous page\">\n <button type=\"button\"\n // a Previous on the first page turns disabled, which drops its focus: it hands focus on (Sprint 25.29 item 2)\n onClick={(e) => { focusAfterSelfRemoval(e.currentTarget); onPageChange(currentPage - 1); }}\n disabled={currentPage <= 1}\n aria-label=\"Previous page\"\n className={cn(\n \"inline-flex items-center justify-center h-[var(--ds-control-height-sm)] w-[var(--ds-control-height-sm)] text-sm cursor-pointer\",\n \"rounded-[var(--ds-radius-md)]\",\n \"border-[length:var(--ds-border-width)] border-[var(--ds-border-default)]\",\n \"bg-[var(--ds-bg-surface)] text-[var(--ds-text-secondary)]\",\n \"transition-colors duration-[var(--ds-transition-speed)]\",\n \"hover:bg-[var(--ds-bg-muted)] hover:text-[var(--ds-text-primary)]\",\n \"disabled:opacity-disabled disabled:cursor-not-allowed\",\n FOCUS_RING,\n )}\n >\n <Icon name=\"chevron-right\" size={16} className=\"rotate-180\" />\n </button>\n </AutoTooltip>\n\n {pages.map((p, i) =>\n p === \"...\" ? (\n <EllipsisJumper key={`ellipsis-${i}`} totalPages={totalPages} onPageChange={onPageChange} />\n ) : (\n <button type=\"button\"\n key={p}\n onClick={() => onPageChange(p as number)}\n aria-current={p === currentPage ? \"page\" : undefined}\n className={cn(\n \"inline-flex items-center justify-center h-[var(--ds-control-height-sm)] w-[var(--ds-control-height-sm)] text-sm font-medium cursor-pointer\",\n \"rounded-[var(--ds-radius-md)]\",\n \"border-[length:var(--ds-border-width)]\",\n \"transition-colors duration-[var(--ds-transition-speed)]\",\n FOCUS_RING,\n p === currentPage\n ? \"bg-[var(--ds-accent-primary)] [background-image:var(--ds-gradient)] text-[var(--ds-text-on-primary)] border-[var(--ds-accent-primary)]\"\n : \"bg-[var(--ds-bg-surface)] text-[var(--ds-text-secondary)] border-[var(--ds-border-default)] hover:bg-[var(--ds-bg-muted)] hover:text-[var(--ds-text-primary)]\"\n )}\n >\n {p}\n </button>\n )\n )}\n\n <AutoTooltip content=\"Next page\">\n <button type=\"button\"\n // likewise a Next on the last page (Sprint 26's sweep; Sprint 25.29 item 2)\n onClick={(e) => { focusAfterSelfRemoval(e.currentTarget); onPageChange(currentPage + 1); }}\n disabled={currentPage >= totalPages}\n aria-label=\"Next page\"\n className={cn(\n \"inline-flex items-center justify-center h-[var(--ds-control-height-sm)] w-[var(--ds-control-height-sm)] text-sm cursor-pointer\",\n \"rounded-[var(--ds-radius-md)]\",\n \"border-[length:var(--ds-border-width)] border-[var(--ds-border-default)]\",\n \"bg-[var(--ds-bg-surface)] text-[var(--ds-text-secondary)]\",\n \"transition-colors duration-[var(--ds-transition-speed)]\",\n \"hover:bg-[var(--ds-bg-muted)] hover:text-[var(--ds-text-primary)]\",\n \"disabled:opacity-disabled disabled:cursor-not-allowed\",\n FOCUS_RING,\n )}\n >\n <Icon name=\"chevron-right\" size={16} />\n </button>\n </AutoTooltip>\n </div>}\n </nav>\n );\n}\n\n/** `size` among `options`, at its place in their own order: largest first stays largest first. */\nfunction withSize(options: number[], size: number): number[] {\n if (options.includes(size)) return options;\n const descending = options.length > 1 && options.every((n, i) => i === 0 || options[i - 1] >= n);\n const at = options.findIndex((n) => (descending ? n < size : n > size));\n return at < 0 ? [...options, size] : [...options.slice(0, at), size, ...options.slice(at)];\n}\n\nfunction buildPageRange(current: number, total: number): (number | \"...\")[] {\n if (total <= 7) return Array.from({ length: total }, (_, i) => i + 1);\n\n const pages: (number | \"...\")[] = [1];\n\n if (current > 3) pages.push(\"...\");\n\n const start = Math.max(2, current - 1);\n const end = Math.min(total - 1, current + 1);\n for (let i = start; i <= end; i++) pages.push(i);\n\n if (current < total - 2) pages.push(\"...\");\n\n pages.push(total);\n return pages;\n}\n\nfunction EllipsisJumper({ totalPages, onPageChange }: { totalPages: number; onPageChange: (page: number) => void }) {\n const [open, setOpen] = useState(false);\n const [jumpPage, setJumpPage] = useState(1);\n\n const handleOpenChange = (next: boolean) => {\n if (next) setJumpPage(1);\n setOpen(next);\n };\n\n const handleGo = () => {\n const clamped = Math.min(totalPages, Math.max(1, jumpPage));\n onPageChange(clamped);\n setOpen(false);\n };\n\n return (\n <Popover\n open={open}\n onOpenChange={handleOpenChange}\n trigger={\n <button\n type=\"button\"\n aria-label=\"Go to page\"\n onClick={() => handleOpenChange(true)}\n className={cn(\n \"inline-flex items-center justify-center h-[var(--ds-control-height-sm)] w-[var(--ds-control-height-sm)] text-sm cursor-pointer\",\n \"rounded-[var(--ds-radius-md)]\",\n \"text-[var(--ds-text-muted)]\",\n \"transition-colors duration-[var(--ds-transition-speed)]\",\n \"hover:bg-[var(--ds-bg-muted)] hover:text-[var(--ds-text-primary)]\",\n FOCUS_RING,\n )}\n >\n …\n </button>\n }\n >\n <div className=\"flex flex-col gap-ds-2 p-ds-3\">\n <label className=\"text-xs font-medium text-[var(--ds-text-secondary)]\">Go to page</label>\n <div className=\"flex items-center gap-ds-2\">\n <NumberInput\n value={jumpPage}\n onChange={setJumpPage}\n min={1}\n max={totalPages}\n step={1}\n size=\"sm\"\n className=\"w-[5rem]\"\n />\n <button\n type=\"button\"\n onClick={handleGo}\n className={cn(\n \"px-ds-2.5 h-[var(--ds-control-height-sm)] text-xs font-medium cursor-pointer\",\n \"rounded-[var(--ds-radius-md)]\",\n \"bg-[var(--ds-accent-primary)] text-[var(--ds-text-on-primary)]\",\n \"transition-colors duration-[var(--ds-transition-speed)]\",\n \"hover:opacity-90\",\n FOCUS_RING,\n )}\n >\n Go\n </button>\n </div>\n </div>\n </Popover>\n );\n}\n","import { useEffect, useState } from \"react\";\nimport { warnOnce } from \"./dev-warn\";\nimport { PREFERENCE_HOUSE_DEFAULTS, useShellPreferences, type PreferencePaginationStyle } from \"./preferences\";\n\n/**\n * A long list in one hook (round 21; all three list styles since round 22). The page size and the list style are the\n * project's `dataDisplay.itemsPerPage` and `dataDisplay.paginationStyle`, read from the shell, so a mid-build\n * `update_rule` on either reaches every list with no page edited. The page gets what to show, the props for\n * `<Pagination>` — page numbers, a Load more button or loading on scroll, whichever the project's style is — and the\n * numbers the count line needs (\"Showing 51–100 of 200 events\", or \"Showing 40 of 120 members\" while a list grows).\n *\n * Run 58 hand-wrote the paging; runs 59 and 60 hand-wrote load-more and scroll loading — an IntersectionObserver, a\n * visible count and a page size copied in as a constant, twice in one app — because the library had no way to.\n *\n * const rows = events.map(toRow)\n * const pager = usePagination(rows)\n * <TableToolbar resultCount={rows.length} resultNoun={[\"event\", \"events\"]} pagination={pager} />\n * <Table columns={columns} data={rows} pager={pager} />\n *\n * The list takes the whole pager (Sprint 25.13 A3): Table, DataGrid, StackedList, Timeline and VirtualizedList draw the\n * pager's part of every row and its control beneath, and a sortable Table sorts every row, not one page. For anything\n * else, draw the page's items and the control yourself: `pager.items.map(…)` then `<Pagination {...pager.props} />`.\n *\n * A long page that must mount only the rows on screen (logs, a feed) still pages: the size the user asked for goes to\n * the hook, with its override note, and the list mounts only what is on screen of each page (A49):\n *\n * // @gridsmith-override dataDisplay.itemsPerPage: <the user's words>\n * const pager = usePagination(entries, { pageSize: 100 })\n * <VirtualizedList items={entries} pager={pager} estimateSize={() => 40} renderItem={(entry) => <LogLine entry={entry} />} />\n */\nexport interface Pager<T> {\n /** The list style this list follows: the project's, unless `style` was passed. */\n style: PreferencePaginationStyle;\n /** What to show: the current page's rows, or every row loaded so far on a list that grows. */\n items: T[];\n /** The current page, from 1; on a growing list, how many pages are loaded. */\n page: number;\n pageSize: number;\n totalItems: number;\n totalPages: number;\n /** The first and last row numbers on screen, from 1 (\"Showing 51–100\"); [0, 0] for an empty list. */\n range: [number, number];\n /** How many rows are on screen. */\n shown: number;\n /** Rows left to show: a next page, or more to load. */\n hasMore: boolean;\n /** The next page, or the next `pageSize` rows on a growing list. */\n loadMore: () => void;\n setPage: (page: number) => void;\n /** A page-size selector's choice; it wins over the project's page size and starts again at page 1. */\n setPageSize: (size: number) => void;\n /**\n * Spread onto <Pagination>: it renders page numbers, a Load more button or the scroll trigger, as `style` says. A list\n * given the whole pager (`<Table pager={pager}>`, Sprint 25.13 A3) draws this control itself.\n */\n props: {\n currentPage: number; totalPages: number; onPageChange: (page: number) => void; pageSize: number; onPageSizeChange: (size: number) => void;\n mode: PreferencePaginationStyle; hasMore: boolean; onLoadMore: () => void;\n /** The page sizes the user may choose between, when the page offers the choice (`pageSizeOptions` below). */\n pageSizeOptions?: number[];\n /** Which pager the control belongs to, so a second control for the same list is caught in development (A3). */\n pagerToken: object;\n };\n}\n\nexport interface PaginationOptions {\n /** A fixed page size for this list, over the project's. Leave it out: the project's page size is the rule. */\n pageSize?: number;\n /** Values that start the list again at page 1 when they change — the sort column and direction, a search query. */\n resetOn?: unknown;\n /**\n * A list style for this list only, over the project's. Leave it out: the project's style is the rule. Passing one that\n * differs is overriding a rule in force — ask the user first, and put `// @gridsmith-override\n * dataDisplay.paginationStyle: <their reason>` above the call.\n */\n style?: PreferencePaginationStyle;\n /**\n * The page sizes the user may choose between, beside the page numbers (`[10, 25, 50]`). The choice goes with the\n * control, so a list given the pager (A3) offers it too. Leave it out for the project's page size alone.\n */\n pageSizeOptions?: number[];\n}\n\n/** What identifies a list's first item across renders: its id, or the value itself; objects without an id are not compared. */\nfunction firstKey(item: unknown): unknown {\n if (item !== null && typeof item === \"object\") return \"id\" in item ? (item as { id: unknown }).id : undefined;\n return item;\n}\n\nfunction resetKey(resetOn: unknown): string {\n try { return JSON.stringify(resetOn ?? null); } catch { return String(resetOn); }\n}\n\nfunction signature(list: readonly unknown[], resetOn: unknown): string {\n let first = \"\";\n try { first = JSON.stringify(firstKey(list[0]) ?? null); } catch { first = \"\"; }\n return `${list.length}|${first}|${resetKey(resetOn)}`;\n}\n\n/** What a list was when last seen: whether a new one is the same list with items added at either end. */\ninterface Seen { sig: string; length: number; first: unknown; reset: string }\n\n/**\n * The same list with items added at its start or its end, and the caller's resetOn unchanged: a live log's new entry,\n * a feed's newest. Its first item, which has an id or is a value, is still first, or has moved down by what was added.\n */\nfunction grewAtAnEnd(seen: Seen, list: readonly unknown[], reset: string): boolean {\n if (reset !== seen.reset || list.length <= seen.length || seen.first === undefined || seen.length === 0) return false;\n return firstKey(list[0]) === seen.first || firstKey(list[list.length - seen.length]) === seen.first;\n}\n\n/**\n * Pages a list in the project's list style (pagination, load more or infinite scroll) and page size, both from the\n * shell. It returns the pager: the rows to show now (`items`), the page and the counts, and the control's state, which a\n * Table, DataGrid, StackedList, Timeline or VirtualizedList takes as its `pager` prop to draw the rows and the control.\n * `resetOn` starts the list again at page 1 when its value changes (a sort, a search); `pageSize` and `style` set this\n * list apart from the project's.\n */\nexport function usePagination<T>(list: readonly T[], options: PaginationOptions = {}): Pager<T> {\n const shell = useShellPreferences();\n const style: PreferencePaginationStyle = options.style ?? shell.paginationStyle ?? PREFERENCE_HOUSE_DEFAULTS.paginationStyle;\n const [chosenSize, setChosenSize] = useState<number | null>(null);\n const [pagerToken] = useState(() => ({}));\n const pageSize = Math.max(1, Math.floor(chosenSize ?? options.pageSize ?? shell.itemsPerPage ?? PREFERENCE_HOUSE_DEFAULTS.itemsPerPage));\n const [page, setPageState] = useState(1);\n\n // A different list — filtered, searched, sorted another way — starts again at page 1: its length, its first item's\n // id or the caller's resetOn values changed. The same list with items added at an end keeps its page, and a growing\n // list its depth (the review of 30 September: a live log's new entry collapsed a list grown to 200 back to 100).\n // Adjusted during render, so the stale page never paints.\n const sig = signature(list, options.resetOn);\n const reset = resetKey(options.resetOn);\n const [seen, setSeen] = useState<Seen>(() => ({ sig, length: list.length, first: firstKey(list[0]), reset }));\n const changed = seen.sig !== sig;\n const startsAgain = changed && !grewAtAnEnd(seen, list, reset);\n if (changed) {\n setSeen({ sig, length: list.length, first: firstKey(list[0]), reset });\n if (startsAgain && page !== 1) setPageState(1);\n }\n\n const totalItems = list.length;\n const totalPages = Math.max(1, Math.ceil(totalItems / pageSize));\n const current = Math.min(Math.max(1, startsAgain ? 1 : page), totalPages);\n const grows = style !== \"pagination\";\n // page numbers show one page; a growing list shows every page loaded so far\n const start = grows ? 0 : (current - 1) * pageSize;\n const items = list.slice(start, current * pageSize);\n const range: [number, number] = items.length === 0 ? [0, 0] : [start + 1, start + items.length];\n const hasMore = current < totalPages;\n const setPage = (next: number) => setPageState(Math.min(Math.max(1, Math.floor(next)), totalPages));\n const loadMore = () => setPageState((p) => Math.min(p + 1, totalPages));\n const setPageSize = (size: number) => { setChosenSize(Math.max(1, Math.floor(size))); setPageState(1); };\n\n return {\n style, items, page: current, pageSize, totalItems, totalPages, range, shown: items.length, hasMore, loadMore, setPage, setPageSize,\n props: { currentPage: current, totalPages, onPageChange: setPage, pageSize, onPageSizeChange: setPageSize, mode: style, hasMore, onLoadMore: loadMore, pagerToken, ...(options.pageSizeOptions ? { pageSizeOptions: options.pageSizeOptions } : {}) },\n };\n}\n\n/**\n * The part of a whole list a pager shows (Sprint 25.13 A3): its page, or every page loaded so far on a list that grows.\n * A list given the pager draws this, then the pager's control.\n */\nexport function pagerPart<T>(list: readonly T[], pager?: Pager<unknown>): T[] {\n if (!pager) return list as T[];\n return pager.range[0] === 0 ? [] : list.slice(pager.range[0] - 1, pager.range[1]);\n}\n\n/** In development, a list handed one page with the pager: it needs every item, since it draws the pager's part itself. */\nexport function useWholeListCheck(component: string, length: number, pager?: Pager<unknown>): void {\n const total = pager?.totalItems;\n useEffect(() => {\n // the same items, either way: more than the pager counts leave the last ones where no page reaches them (the review\n // of 30 September)\n if (total !== undefined && length !== total) warnOnce(component, `the pager counts ${total} items but the list holds ${length}: give the list and usePagination the same items, every item of the list, and the list draws the pager's part (Sprint 25.13 A3).`);\n }, [component, length, total]);\n}\n"]}
@@ -916,6 +916,10 @@ function useNonModalDialog(root, active, onClose, isTop = ALWAYS_TOP) {
916
916
  function cn(...inputs) {
917
917
  return twMerge(clsx(inputs));
918
918
  }
919
+ function placesOf2(n) {
920
+ const [digits, exponent = "0"] = String(n).split("e");
921
+ return Math.max(0, (digits.split(".")[1]?.length ?? 0) - Number(exponent));
922
+ }
919
923
  var GLASS_BACKDROP = "[backdrop-filter:var(--ds-glass-filter)] [-webkit-backdrop-filter:var(--ds-glass-filter)]";
920
924
  var GLASS_SURFACE = `${GLASS_BACKDROP} shadow-[var(--ds-shadow-card),var(--ds-glass-inset)]`;
921
925
  var GLASS_OVERLAY = `${GLASS_BACKDROP} shadow-[var(--ds-shadow-modal),var(--ds-glass-inset)]`;
@@ -1027,6 +1031,6 @@ function usePosition(triggerRef, floatingRef, open, options = {}) {
1027
1031
  return pos;
1028
1032
  }
1029
1033
 
1030
- export { ACTIVE_RING, CONTROL_ANCESTOR, ERROR_ACTIVE_RING, ERROR_FOCUS_RING, ERROR_FOCUS_WITHIN_RING, ERROR_HAS_FOCUS_RING, FIELD, FIELD_FOCUS_RING, FIELD_FOCUS_WITHIN_RING, FIELD_HAS_FOCUS_RING, FOCUSABLE, FOCUS_INSET, FOCUS_INSET_WHILE_STOP, FOCUS_RING, FOCUS_ROOM, GLASS_BACKDROP, GLASS_DROPDOWN, GLASS_OVERLAY, GLASS_SURFACE, GROUP_FOCUS_RING, LAST_RESORT_MS, OPEN_TO_FOCUS, OVERLAY_CLOSE_ATTR, OVERLAY_SURFACE, PEER_FOCUS_RING, ZOOM_KEYS, atLeastFocusRoom, cn, focusAfterRemoval, focusAfterSelfRemoval, focusInitial, focusOutOf, hasSelfRemovalWatch, hasTabStop, inertOutside, isTabStop, lockBodyScroll, onMovingOn, openToFocus, pageAddress, pointOf, registerOpenerRoot, rememberFocus, rememberOpener, rovingTabStop, tabStops, unlockBodyScroll, useCloseOnFocusOut, useFocusBeforeOpen, useFocusKeptInList, useFocusLeave, useFocusTrap, useGridKeyboard, useLatest, useNonModalDialog, useOverlayLayer, usePopupFocus, usePosition, usePressMarks, useReturnFocus };
1031
- //# sourceMappingURL=chunk-2724SJO2.js.map
1032
- //# sourceMappingURL=chunk-2724SJO2.js.map
1034
+ export { ACTIVE_RING, CONTROL_ANCESTOR, ERROR_ACTIVE_RING, ERROR_FOCUS_RING, ERROR_FOCUS_WITHIN_RING, ERROR_HAS_FOCUS_RING, FIELD, FIELD_FOCUS_RING, FIELD_FOCUS_WITHIN_RING, FIELD_HAS_FOCUS_RING, FOCUSABLE, FOCUS_INSET, FOCUS_INSET_WHILE_STOP, FOCUS_RING, FOCUS_ROOM, GLASS_BACKDROP, GLASS_DROPDOWN, GLASS_OVERLAY, GLASS_SURFACE, GROUP_FOCUS_RING, LAST_RESORT_MS, OPEN_TO_FOCUS, OVERLAY_CLOSE_ATTR, OVERLAY_SURFACE, PEER_FOCUS_RING, ZOOM_KEYS, atLeastFocusRoom, cn, focusAfterRemoval, focusAfterSelfRemoval, focusInitial, focusOutOf, hasSelfRemovalWatch, hasTabStop, inertOutside, isTabStop, lockBodyScroll, onMovingOn, openToFocus, pageAddress, placesOf2 as placesOf, pointOf, registerOpenerRoot, rememberFocus, rememberOpener, rovingTabStop, tabStops, unlockBodyScroll, useCloseOnFocusOut, useFocusBeforeOpen, useFocusKeptInList, useFocusLeave, useFocusTrap, useGridKeyboard, useLatest, useNonModalDialog, useOverlayLayer, usePopupFocus, usePosition, usePressMarks, useReturnFocus };
1035
+ //# sourceMappingURL=chunk-HDFTENVW.js.map
1036
+ //# sourceMappingURL=chunk-HDFTENVW.js.map