gridsmith-ui 0.31.1 → 0.33.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/CHANGELOG.md +78 -1
  2. package/README.md +4 -2
  3. package/dist/charts.d.ts +111 -31
  4. package/dist/charts.js +288 -148
  5. package/dist/charts.js.map +1 -1
  6. package/dist/chat.js +6 -6
  7. package/dist/{chunk-EZ3ZGFGA.js → chunk-2724SJO2.js} +12 -4
  8. package/dist/chunk-2724SJO2.js.map +1 -0
  9. package/dist/{chunk-I6JJ7KKP.js → chunk-6NRLTG5W.js} +16 -11
  10. package/dist/chunk-6NRLTG5W.js.map +1 -0
  11. package/dist/{chunk-BHTAVJIG.js → chunk-6XCWKLJZ.js} +41 -6
  12. package/dist/chunk-6XCWKLJZ.js.map +1 -0
  13. package/dist/{chunk-TH272DIC.js → chunk-AB4UQ4G5.js} +125 -235
  14. package/dist/chunk-AB4UQ4G5.js.map +1 -0
  15. package/dist/{chunk-IOHGE4EW.js → chunk-AVSP6NDX.js} +8 -8
  16. package/dist/chunk-AVSP6NDX.js.map +1 -0
  17. package/dist/chunk-F2XMZOUP.js +81 -0
  18. package/dist/chunk-F2XMZOUP.js.map +1 -0
  19. package/dist/{chunk-HQFTP7Y5.js → chunk-FF57N3P7.js} +10 -8
  20. package/dist/chunk-FF57N3P7.js.map +1 -0
  21. package/dist/chunk-GIA4BMGI.js +18 -0
  22. package/dist/chunk-GIA4BMGI.js.map +1 -0
  23. package/dist/{chunk-DR6WEI3A.js → chunk-HCEHTJ5E.js} +3 -3
  24. package/dist/{chunk-DR6WEI3A.js.map → chunk-HCEHTJ5E.js.map} +1 -1
  25. package/dist/{chunk-IZW5XHKA.js → chunk-OWGF362U.js} +10 -8
  26. package/dist/chunk-OWGF362U.js.map +1 -0
  27. package/dist/chunk-P3NUUIL6.js +9 -0
  28. package/dist/chunk-P3NUUIL6.js.map +1 -0
  29. package/dist/{chunk-W3GY5ROH.js → chunk-R2IAK3J3.js} +3 -3
  30. package/dist/{chunk-W3GY5ROH.js.map → chunk-R2IAK3J3.js.map} +1 -1
  31. package/dist/chunk-R7FG4ZQ5.js +16 -0
  32. package/dist/chunk-R7FG4ZQ5.js.map +1 -0
  33. package/dist/{chunk-V73LHNRL.js → chunk-RS624TD5.js} +29 -10
  34. package/dist/chunk-RS624TD5.js.map +1 -0
  35. package/dist/{chunk-DBHVJ7Z3.js → chunk-SS3C24IJ.js} +3 -2
  36. package/dist/chunk-SS3C24IJ.js.map +1 -0
  37. package/dist/{chunk-K3NAFQ4S.js → chunk-TMPPBXX3.js} +3 -3
  38. package/dist/{chunk-K3NAFQ4S.js.map → chunk-TMPPBXX3.js.map} +1 -1
  39. package/dist/{chunk-NDL2JGQ7.js → chunk-UBLBVCQN.js} +5 -5
  40. package/dist/{chunk-NDL2JGQ7.js.map → chunk-UBLBVCQN.js.map} +1 -1
  41. package/dist/{chunk-2TCCSKL3.js → chunk-WD6T57ZJ.js} +5 -5
  42. package/dist/{chunk-2TCCSKL3.js.map → chunk-WD6T57ZJ.js.map} +1 -1
  43. package/dist/{chunk-SLGGZ3MU.js → chunk-WSKPESAX.js} +12 -10
  44. package/dist/chunk-WSKPESAX.js.map +1 -0
  45. package/dist/chunk-ZQV26NND.js +213 -0
  46. package/dist/chunk-ZQV26NND.js.map +1 -0
  47. package/dist/dashboard.d.ts +207 -0
  48. package/dist/dashboard.js +1210 -0
  49. package/dist/dashboard.js.map +1 -0
  50. package/dist/data-grid.js +11 -10
  51. package/dist/data-grid.js.map +1 -1
  52. package/dist/editor-mentions.js +2 -2
  53. package/dist/editor.js +3 -2
  54. package/dist/editor.js.map +1 -1
  55. package/dist/index.d.ts +94 -12
  56. package/dist/index.js +601 -316
  57. package/dist/index.js.map +1 -1
  58. package/dist/kanban.js +9 -9
  59. package/dist/resizable.d.ts +11 -2
  60. package/dist/resizable.js +97 -22
  61. package/dist/resizable.js.map +1 -1
  62. package/dist/roots.css +2 -2
  63. package/dist/tokens.css +6 -6
  64. package/dist/utils.d.ts +51 -1
  65. package/dist/utils.js +55 -4
  66. package/dist/utils.js.map +1 -1
  67. package/dist/virtualized.js +9 -8
  68. package/dist/virtualized.js.map +1 -1
  69. package/dist-static/tokens.css +6 -6
  70. package/package.json +6 -1
  71. package/dist/chunk-BHTAVJIG.js.map +0 -1
  72. package/dist/chunk-DBHVJ7Z3.js.map +0 -1
  73. package/dist/chunk-EZ3ZGFGA.js.map +0 -1
  74. package/dist/chunk-HQFTP7Y5.js.map +0 -1
  75. package/dist/chunk-I6JJ7KKP.js.map +0 -1
  76. package/dist/chunk-IOHGE4EW.js.map +0 -1
  77. package/dist/chunk-IZW5XHKA.js.map +0 -1
  78. package/dist/chunk-KSJTMSYA.js +0 -71
  79. package/dist/chunk-KSJTMSYA.js.map +0 -1
  80. package/dist/chunk-LJYSVZMI.js +0 -25
  81. package/dist/chunk-LJYSVZMI.js.map +0 -1
  82. package/dist/chunk-SLGGZ3MU.js.map +0 -1
  83. package/dist/chunk-TH272DIC.js.map +0 -1
  84. package/dist/chunk-V73LHNRL.js.map +0 -1
@@ -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-AVSP6NDX.js","sourcesContent":["import { useCallback, useContext, useRef, useState } from \"react\";\nimport { useLatest } from \"../lib/use-latest\";\nimport { cn, FIELD_FOCUS_WITHIN_RING, ERROR_FOCUS_WITHIN_RING, FOCUS_RING } from \"../lib/utils\";\nimport { useInputModality } from \"../lib/input-modality\";\nimport { ControlSizeContext } from \"./Button\";\nimport { useReportedChange } from \"../lib/form-context\";\n\ninterface NumberInputProps {\n value: number;\n onChange: (value: number) => void;\n min?: number;\n max?: number;\n step?: number;\n disabled?: boolean;\n placeholder?: string;\n prefix?: string;\n suffix?: string;\n size?: \"sm\" | \"md\" | \"lg\";\n className?: string;\n error?: boolean;\n /** Allow decimal input. Default: true when step is not an integer, false otherwise. */\n allowDecimals?: boolean;\n /** Forwarded to the inner input element so a Label htmlFor can be associated. */\n id?: string;\n /** The field's name where nothing on screen names it (\"Seats\"); inside a Field, the Field's label names it. */\n \"aria-label\"?: string;\n}\n\n// The height is the bordered box's (box-sizing: border-box), so the control measures exactly the token beside an\n// Input or a Button; the buttons and the field stretch to it.\nconst sizes = {\n sm: { box: \"h-[var(--ds-control-height-sm)]\", input: \"text-xs self-stretch\", btn: \"w-7 text-xs\" },\n md: { box: \"h-[var(--ds-control-height-md)]\", input: \"text-sm self-stretch\", btn: \"w-9 text-sm\" },\n lg: { box: \"h-[var(--ds-control-height-lg)]\", input: \"text-base self-stretch\", btn: \"w-10 text-base\" },\n};\n\nexport function NumberInput({\n value,\n onChange: onChangeProp,\n min = -Infinity,\n max = Infinity,\n step = 1,\n disabled = false,\n placeholder = \"0\",\n prefix,\n suffix,\n size: sizeProp,\n className,\n error = false,\n allowDecimals,\n id,\n \"aria-label\": ariaLabel,\n}: NumberInputProps) {\n // Sprint 25.12 A15: a new value the user gives this control marks the form's overlay; the page's onChange runs as given\n const onChange = useReportedChange(onChangeProp, value);\n // a field: clicked into, the active look; reached with Tab, the outline (Sprint 30, lib/input-modality.ts)\n useInputModality();\n const contextSize = useContext(ControlSizeContext);\n const size = sizeProp ?? contextSize ?? \"md\";\n const intervalRef = useRef<ReturnType<typeof setInterval>>(undefined);\n const timeoutRef = useRef<ReturnType<typeof setTimeout>>(undefined);\n const inputRef = useRef<HTMLInputElement>(null);\n const [focused, setFocused] = useState(false);\n const [draft, setDraft] = useState(String(value));\n\n const decimals = allowDecimals ?? (step % 1 !== 0);\n\n // While not focused the draft mirrors the controlled value; on blur it\n // re-syncs (render-time state adjustment).\n const [prevSync, setPrevSync] = useState({ value, focused });\n if (value !== prevSync.value || focused !== prevSync.focused) {\n setPrevSync({ value, focused });\n if (!focused) setDraft(String(value));\n }\n\n const clamp = useCallback(\n (v: number) => Math.min(max, Math.max(min, v)),\n [min, max],\n );\n\n // Stepping reads the latest committed value through a ref so a held button\n // (setInterval in startRepeat) keeps counting instead of re-adding one step\n // to the value captured at mousedown. useLatest syncs it to the prop in a\n // layout effect (never during render); commitValue advances it in the handler.\n const valueRef = useLatest(value);\n\n // Commit a stepped or blurred value. The draft is updated too: the input\n // shows the draft while focused, and stepping happens while focused (the\n // buttons focus the input), so without this the text never moved and the\n // stale draft was committed back over the new value on blur.\n // `own`: the control settles on a value by itself (a blur with nothing typed falls back to the minimum), which is\n // not the user's change and doesn't mark the form's overlay (Sprint 25.12 A15).\n const commitValue = useCallback((v: number, own = false) => {\n const clamped = clamp(v);\n // Advance the ref now, not on the next render: repeat ticks can land\n // before React re-renders, and each must build on the previous one.\n valueRef.current = clamped;\n setDraft(String(clamped));\n (own ? onChangeProp : onChange)(clamped);\n return clamped;\n }, [onChange, onChangeProp, clamp, valueRef]);\n\n const increment = useCallback(() => commitValue(valueRef.current + step), [commitValue, step, valueRef]);\n const decrement = useCallback(() => commitValue(valueRef.current - step), [commitValue, step, valueRef]);\n\n const startRepeat = useCallback(\n (fn: () => void) => {\n fn();\n timeoutRef.current = setTimeout(() => {\n intervalRef.current = setInterval(fn, 75);\n }, 400);\n },\n [],\n );\n\n const stopRepeat = useCallback(() => {\n clearTimeout(timeoutRef.current);\n clearInterval(intervalRef.current);\n }, []);\n\n const handleInput = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const raw = e.target.value;\n\n if (raw === \"\" || raw === \"-\") {\n setDraft(raw);\n return;\n }\n\n if (!decimals && raw.includes(\".\")) return;\n\n const validPattern = decimals ? /^-?\\d*\\.?\\d*$/ : /^-?\\d*$/;\n if (!validPattern.test(raw)) return;\n\n setDraft(raw);\n\n const parsed = parseFloat(raw);\n if (!isNaN(parsed) && isFinite(parsed)) {\n onChange(clamp(parsed));\n }\n },\n [onChange, clamp, decimals],\n );\n\n const handleBlur = useCallback(() => {\n setFocused(false);\n const parsed = parseFloat(draft);\n if (!isNaN(parsed) && isFinite(parsed)) {\n // nothing typed: a value outside min and max clamped on the way through is the control's own (0.21.0)\n const committed = commitValue(parsed, draft === String(value));\n setDraft(String(committed));\n } else {\n const fallback = isFinite(min) ? min : 0;\n const committed = commitValue(value !== undefined ? value : fallback, true);\n setDraft(String(committed));\n }\n }, [draft, commitValue, min, value]);\n\n const handleFocus = useCallback(() => {\n setFocused(true);\n }, []);\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (e.key === \"ArrowUp\") { e.preventDefault(); increment(); }\n if (e.key === \"ArrowDown\") { e.preventDefault(); decrement(); }\n // Sprint 25.8.7 item 24, the APG spinbutton: \"Home: If the spinbutton has a minimum value, sets the value to its\n // minimum\", and End its maximum. Without that limit, or with a modifier held (Shift+Home selects), the key is the\n // caret's: the pattern keeps the platform's text editing keys for a field that can be typed in\n const plain = !e.shiftKey && !e.ctrlKey && !e.metaKey && !e.altKey;\n if (e.key === \"Home\" && plain && Number.isFinite(min)) { e.preventDefault(); commitValue(min); }\n if (e.key === \"End\" && plain && Number.isFinite(max)) { e.preventDefault(); commitValue(max); }\n },\n [increment, decrement, commitValue, min, max],\n );\n\n const s = sizes[size];\n const atMin = value <= min;\n const atMax = value >= max;\n // Sprint 25.8.7 item 24: the value is stated while the field holds a number (\"Authors SHOULD set the aria-valuenow\n // attribute when the spinbutton has a value\", WAI-ARIA 1.2), not while it is emptied to type afresh; it is the\n // committed value, which typing keeps within the limits\n const shown = focused ? draft : String(value);\n const holdsNumber = Number.isFinite(parseFloat(shown)) && Number.isFinite(value);\n\n return (\n <div\n className={cn(\n \"flex items-center w-full\",\n s.box,\n \"border-[length:var(--ds-border-width)]\",\n error ? \"border-[var(--ds-status-error)]\" : \"border-[var(--ds-input-border)]\",\n \"rounded-[var(--ds-radius-md)]\",\n \"shadow-[var(--ds-input-shadow)]\",\n \"bg-[var(--ds-input-bg)]\",\n \"transition-colors duration-[var(--ds-transition-speed)]\",\n !error && !disabled && \"hover:border-[var(--ds-input-border-hover)]\",\n error ? ERROR_FOCUS_WITHIN_RING : FIELD_FOCUS_WITHIN_RING,\n disabled && \"opacity-disabled cursor-not-allowed\",\n className,\n )}\n >\n <button\n type=\"button\"\n tabIndex={-1}\n disabled={disabled || atMin}\n onMouseDown={(e) => { e.preventDefault(); inputRef.current?.focus(); if (!disabled && !atMin) startRepeat(decrement); }}\n onMouseUp={stopRepeat}\n onMouseLeave={stopRepeat}\n className={cn(\n \"inline-flex items-center justify-center shrink-0\",\n \"border-r-[length:var(--ds-border-width)] border-[var(--ds-border-default)]\",\n \"text-[var(--ds-text-muted)] hover:text-[var(--ds-text-primary)] hover:bg-[var(--ds-bg-muted)]\",\n \"transition-colors cursor-pointer\",\n \"rounded-l-[var(--ds-radius-md)]\",\n // kept out of the Tab order (the field's arrows step it) and never focused by a press: the outline all the same\n // if anything focuses it (Sprint 30)\n FOCUS_RING,\n s.btn, s.input,\n (disabled || atMin) && \"opacity-disabled cursor-not-allowed hover:bg-transparent hover:text-[var(--ds-text-muted)]\",\n )}\n aria-label=\"Decrease\"\n >\n −\n </button>\n\n <div className={cn(\"flex items-center flex-1 min-w-0 px-ds-2 gap-ds-1\", s.input)}>\n {prefix && <span className=\"text-[var(--ds-text-muted)] shrink-0 text-xs\">{prefix}</span>}\n <input\n ref={inputRef}\n id={id}\n type=\"text\"\n // a spinbutton that can be typed in (Sprint 25.8.7 item 24): its value, and each limit only when it exists\n role=\"spinbutton\"\n aria-label={ariaLabel}\n aria-valuenow={holdsNumber ? value : undefined}\n aria-valuemin={Number.isFinite(min) ? min : undefined}\n aria-valuemax={Number.isFinite(max) ? max : undefined}\n inputMode={decimals ? \"decimal\" : \"numeric\"}\n aria-invalid={error || undefined}\n value={shown}\n onChange={handleInput}\n onFocus={handleFocus}\n onBlur={handleBlur}\n onKeyDown={handleKeyDown}\n disabled={disabled}\n placeholder={placeholder}\n className={cn(\n \"w-full min-w-0 bg-transparent text-center outline-none\",\n \"text-[var(--ds-text-primary)]\",\n \"placeholder:text-[var(--ds-text-muted)]\",\n \"font-[family-name:var(--ds-font-mono)]\",\n s.input,\n disabled && \"cursor-not-allowed\",\n )}\n />\n {suffix && <span className=\"text-[var(--ds-text-muted)] shrink-0 text-xs\">{suffix}</span>}\n </div>\n\n <button\n type=\"button\"\n tabIndex={-1}\n disabled={disabled || atMax}\n onMouseDown={(e) => { e.preventDefault(); inputRef.current?.focus(); if (!disabled && !atMax) startRepeat(increment); }}\n onMouseUp={stopRepeat}\n onMouseLeave={stopRepeat}\n className={cn(\n \"inline-flex items-center justify-center shrink-0\",\n \"border-l-[length:var(--ds-border-width)] border-[var(--ds-border-default)]\",\n \"text-[var(--ds-text-muted)] hover:text-[var(--ds-text-primary)] hover:bg-[var(--ds-bg-muted)]\",\n \"transition-colors cursor-pointer\",\n \"rounded-r-[var(--ds-radius-md)]\",\n FOCUS_RING,\n s.btn, s.input,\n (disabled || atMax) && \"opacity-disabled cursor-not-allowed hover:bg-transparent hover:text-[var(--ds-text-muted)]\",\n )}\n aria-label=\"Increase\"\n >\n +\n </button>\n </div>\n );\n}\n","import { useRef, useEffect, type ReactNode, useState, useCallback } from \"react\";\nimport { RowsCtx, 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"]}
@@ -0,0 +1,81 @@
1
+ "use client";
2
+ import { useRevealFocus } from './chunk-HCEHTJ5E.js';
3
+ import { hasTabStop } from './chunk-2724SJO2.js';
4
+ import { useEffect } from 'react';
5
+
6
+ function useKeyboardScroll(el, label, enabled = true, nameFromHeading = false, axis = "y") {
7
+ useRevealFocus(el, enabled);
8
+ useEffect(() => {
9
+ if (!enabled || !el) return;
10
+ return keyboardScroll(el, () => nameFromHeading && el.querySelector("h1, h2, h3, h4, h5, h6")?.textContent?.trim() || label, axis)?.end;
11
+ }, [el, label, enabled, nameFromHeading, axis]);
12
+ }
13
+ function keyboardScroll(el, name, axis = "y", holdsStop = hasTabStop) {
14
+ if (typeof ResizeObserver === "undefined") return;
15
+ const own = { tabindex: el.getAttribute("tabindex"), role: el.getAttribute("role"), label: el.getAttribute("aria-label") };
16
+ const landmark = /^(MAIN|NAV|ASIDE|ARTICLE|SECTION|FORM)$/.test(el.tagName);
17
+ const keepRole = own.role !== null || landmark;
18
+ const keepName = own.label !== null || landmark;
19
+ let named = null;
20
+ const restore = (attr, value) => value === null ? el.removeAttribute(attr) : el.setAttribute(attr, value);
21
+ const rename = () => {
22
+ named = name();
23
+ if (el.getAttribute("aria-label") !== named) el.setAttribute("aria-label", named);
24
+ };
25
+ const set = (on) => {
26
+ if (on === el.hasAttribute("data-scroll-stop")) {
27
+ if (on && !keepName) rename();
28
+ return;
29
+ }
30
+ if (on) {
31
+ el.setAttribute("data-scroll-stop", "");
32
+ el.tabIndex = 0;
33
+ if (!keepRole) el.setAttribute("role", "region");
34
+ if (!keepName) rename();
35
+ } else {
36
+ el.removeAttribute("data-scroll-stop");
37
+ if (el.getAttribute("role") === (keepRole ? own.role : "region")) {
38
+ restore("tabindex", own.tabindex);
39
+ if (!keepRole) restore("role", own.role);
40
+ }
41
+ if (!keepName && el.getAttribute("aria-label") === named) restore("aria-label", own.label);
42
+ }
43
+ };
44
+ const update = () => {
45
+ if (el.closest("[inert]")) return;
46
+ if (el.hasAttribute("data-scroll-stop") && document.activeElement === el) return set(true);
47
+ if (holdsStop(el)) return set(false);
48
+ const wide = el.scrollWidth > el.clientWidth + 1, tall = el.scrollHeight > el.clientHeight + 1;
49
+ set(axis === "x" ? wide : axis === "both" ? wide || tall : tall);
50
+ };
51
+ update();
52
+ const ro = new ResizeObserver(update);
53
+ ro.observe(el);
54
+ const itsOwn = (r) => r.type === "attributes" && r.target === el && r.attributeName === "tabindex";
55
+ const mo = typeof MutationObserver === "undefined" ? null : new MutationObserver((records) => {
56
+ if (!records.every(itsOwn)) update();
57
+ });
58
+ mo?.observe(el, { childList: true, subtree: true, characterData: true, attributes: true, attributeFilter: ["inert", "disabled", "hidden", "tabindex"] });
59
+ const around = typeof MutationObserver === "undefined" ? null : new MutationObserver((records) => {
60
+ if (records.some((r) => r.target !== el && r.target instanceof Element && r.target.contains(el))) update();
61
+ });
62
+ around?.observe(el.ownerDocument.documentElement, { subtree: true, attributes: true, attributeFilter: ["inert"] });
63
+ const onFocusOut = (e) => {
64
+ if (e.target === el) update();
65
+ };
66
+ el.addEventListener("focusout", onFocusOut);
67
+ return {
68
+ update,
69
+ end: () => {
70
+ ro.disconnect();
71
+ mo?.disconnect();
72
+ around?.disconnect();
73
+ el.removeEventListener("focusout", onFocusOut);
74
+ set(false);
75
+ }
76
+ };
77
+ }
78
+
79
+ export { keyboardScroll, useKeyboardScroll };
80
+ //# sourceMappingURL=chunk-F2XMZOUP.js.map
81
+ //# sourceMappingURL=chunk-F2XMZOUP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../showcase/src/lib/use-keyboard-scroll.ts"],"names":[],"mappings":"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","file":"chunk-F2XMZOUP.js","sourcesContent":["import { useEffect } from \"react\";\nimport { hasTabStop } from \"./focus\";\nimport { useRevealFocus } from \"./reveal-focus\";\n\n/**\n * WCAG 2.1.1: a region that scrolls, with nothing inside it to Tab to, is a Tab stop of its own, named, so a keyboard\n * can scroll it (Chrome makes such a scroller focusable by itself; Safari doesn't). Sprint 25.16 A42: what fills the\n * page scrolls inside itself, so a board's column or a split view's pane can be such a region. It stops being one when\n * it no longer scrolls or something inside it takes focus — but while it has focus it stays one, until focus leaves it,\n * so a resize that makes it fit never drops the focus to the page (as Table's scroll region does; the review of\n * 1 October). Give the element a visible focus style (FOCUS_INSET). Pass the element itself (a callback ref's), so a\n * pane drawn later (a detail that opens) is read when it appears. With `nameFromHeading`, the region takes its first\n * heading's words as its name (an item's view: its title), and `label` only when it has none. What the keyboard focuses\n * inside it is scrolled into view whole (useRevealFocus, Sprint 30): give the region `scroll-p-[4px]` for the outline.\n * `axis` \"x\" for a strip that scrolls sideways (the Calendar's week of days on a phone, Sprint 25.29 item 10), \"both\"\n * for an area that scrolls either way (ScrollArea's, Sprint 25.30 item 2).\n */\nexport function useKeyboardScroll(el: HTMLElement | null, label: string, enabled = true, nameFromHeading = false, axis: \"y\" | \"x\" | \"both\" = \"y\"): void {\n useRevealFocus(el, enabled);\n useEffect(() => {\n if (!enabled || !el) return;\n return keyboardScroll(el, () => (nameFromHeading && el.querySelector(\"h1, h2, h3, h4, h5, h6\")?.textContent?.trim()) || label, axis)?.end;\n }, [el, label, enabled, nameFromHeading, axis]);\n}\n\n/**\n * useKeyboardScroll's work on an element, begun and ended by hand, for a part found in the page rather than drawn by the\n * caller (a dashboard cell's frame, Sprint 32 F10): `name` is read at each update, `update` reads again (a title changed\n * outside the element), and `end` lets go. Nothing where there's no ResizeObserver. `holdsStop` says whether anything\n * inside is a Tab stop (the library's helper by default).\n */\nexport function keyboardScroll(el: HTMLElement, name: () => string, axis: \"y\" | \"x\" | \"both\" = \"y\", holdsStop: (el: HTMLElement) => boolean = hasTabStop): { update: () => void; end: () => void } | undefined {\n if (typeof ResizeObserver === \"undefined\") return;\n // what the element has of its own, kept: a landmark's role and name (the shell's <main>), and the skip link's target's\n // tabindex -1, put back when it stops being a stop (Sprint 25.29 item 10)\n const own = { tabindex: el.getAttribute(\"tabindex\"), role: el.getAttribute(\"role\"), label: el.getAttribute(\"aria-label\") };\n const landmark = /^(MAIN|NAV|ASIDE|ARTICLE|SECTION|FORM)$/.test(el.tagName);\n const keepRole = own.role !== null || landmark;\n const keepName = own.label !== null || landmark;\n // the name last written here, so letting go takes away only that\n let named: string | null = null;\n const restore = (attr: string, value: string | null) => (value === null ? el.removeAttribute(attr) : el.setAttribute(attr, value));\n const rename = () => {\n named = name();\n if (el.getAttribute(\"aria-label\") !== named) el.setAttribute(\"aria-label\", named);\n };\n const set = (on: boolean) => {\n if (on === el.hasAttribute(\"data-scroll-stop\")) {\n if (on && !keepName) rename();\n return;\n }\n if (on) {\n el.setAttribute(\"data-scroll-stop\", \"\");\n el.tabIndex = 0;\n if (!keepRole) el.setAttribute(\"role\", \"region\");\n if (!keepName) rename();\n } else {\n el.removeAttribute(\"data-scroll-stop\");\n // a role another hand gave it meanwhile (a stat the page made a button, Sprint 32 F10) keeps its role and its\n // tabindex, which are that role's: only the name and the mark written here go\n if (el.getAttribute(\"role\") === (keepRole ? own.role : \"region\")) {\n restore(\"tabindex\", own.tabindex);\n if (!keepRole) restore(\"role\", own.role);\n }\n if (!keepName && el.getAttribute(\"aria-label\") === named) restore(\"aria-label\", own.label);\n }\n };\n const update = () => {\n // inert (the shell's phone menu over <main>), nothing in it is a stop, nor is it: what it is waits until it isn't\n // (Sprint 25.31 item 6: a clock ticking in <main> made it a stop then, and it stayed one once the menu closed)\n if (el.closest(\"[inert]\")) return;\n // a stop with focus stays one until focus leaves it\n if (el.hasAttribute(\"data-scroll-stop\") && document.activeElement === el) return set(true);\n // anything inside to Tab to, and it's no stop, with no need to measure: the first found ends the search (item 7)\n if (holdsStop(el)) return set(false);\n const wide = el.scrollWidth > el.clientWidth + 1, tall = el.scrollHeight > el.clientHeight + 1;\n set(axis === \"x\" ? wide : axis === \"both\" ? wide || tall : tall);\n };\n update();\n const ro = new ResizeObserver(update);\n ro.observe(el);\n // what's inside changing, and what decides whether it's a stop (item 6): a control enabled, shown, given a tabindex,\n // or made inert. The element's own tabindex is this hook's to write, so its change is no news.\n const itsOwn = (r: MutationRecord) => r.type === \"attributes\" && r.target === el && r.attributeName === \"tabindex\";\n const mo = typeof MutationObserver === \"undefined\" ? null : new MutationObserver((records) => { if (!records.every(itsOwn)) update(); });\n mo?.observe(el, { childList: true, subtree: true, characterData: true, attributes: true, attributeFilter: [\"inert\", \"disabled\", \"hidden\", \"tabindex\"] });\n // and a box round it made inert, or no longer inert: the page's own, or the phone menu's (item 6)\n const around = typeof MutationObserver === \"undefined\" ? null : new MutationObserver((records) => {\n if (records.some((r) => r.target !== el && r.target instanceof Element && r.target.contains(el))) update();\n });\n around?.observe(el.ownerDocument.documentElement, { subtree: true, attributes: true, attributeFilter: [\"inert\"] });\n // focus leaving a stop that no longer scrolls ends it: focus leaving the element itself, not a control inside it (item 7)\n const onFocusOut = (e: FocusEvent) => { if (e.target === el) update(); };\n el.addEventListener(\"focusout\", onFocusOut);\n return {\n update,\n end: () => {\n ro.disconnect();\n mo?.disconnect();\n around?.disconnect();\n el.removeEventListener(\"focusout\", onFocusOut);\n set(false);\n },\n };\n}\n\n/** The focus style for such a region: the theme's outline, drawn inside its edge so a neighbour can't hide it (lib/utils.ts since Sprint 30). */\nexport { FOCUS_INSET } from \"./utils\";\n"]}
@@ -1,8 +1,8 @@
1
1
  "use client";
2
2
  import { inputModality } from './chunk-7RKC5C7G.js';
3
- import { AutoTooltip, NATIVE_TITLE } from './chunk-DR6WEI3A.js';
3
+ import { AutoTooltip, NATIVE_TITLE } from './chunk-HCEHTJ5E.js';
4
4
  import { slotDraws, slotIcon } from './chunk-53F7GVBQ.js';
5
- import { cn, FOCUS_RING, pageAddress, pointOf, hasSelfRemovalWatch, focusAfterSelfRemoval, LAST_RESORT_MS } from './chunk-EZ3ZGFGA.js';
5
+ import { cn, FOCUS_RING, pageAddress, pointOf, hasSelfRemovalWatch, focusAfterSelfRemoval, LAST_RESORT_MS } from './chunk-2724SJO2.js';
6
6
  import { jsxs, jsx } from 'react/jsx-runtime';
7
7
  import { createContext, forwardRef, useContext, isValidElement } from 'react';
8
8
 
@@ -80,7 +80,7 @@ var SLOT_ICON_PX = { xs: 12, sm: 14, md: 16, lg: 18, "icon-xs": 12, "icon-sm": 1
80
80
  var HOVER_SCALE_CAP = { "--_btn-scale": "min(var(--ds-hover-scale), 1.02)" };
81
81
  var Button = forwardRef(function Button2({ variant = "default", size: sizeProp, iconLeft, iconRight, loading, className, children, disabled, style, onClick, ...props }, ref) {
82
82
  const contextSize = useContext(ControlSizeContext);
83
- const size = sizeProp ?? contextSize ?? "md";
83
+ const size = sizeProp === "icon" && contextSize && contextSize !== "md" ? `icon-${contextSize}` : sizeProp ?? contextSize ?? "md";
84
84
  const isLink = variant === "link";
85
85
  const spinnerSize = size === "lg" || size === "icon-lg" ? "md" : "sm";
86
86
  let paddingStyle;
@@ -95,7 +95,8 @@ var Button = forwardRef(function Button2({ variant = "default", size: sizeProp,
95
95
  }
96
96
  const isLoading = loading && !disabled;
97
97
  const isDisabled = !!disabled;
98
- const handleClick = isLoading ? (e) => {
98
+ const unavailable = String(props["aria-disabled"]) === "true";
99
+ const handleClick = isLoading || unavailable ? (e) => {
99
100
  e.preventDefault();
100
101
  } : (e) => {
101
102
  const button = e.currentTarget;
@@ -121,7 +122,8 @@ var Button = forwardRef(function Button2({ variant = "default", size: sizeProp,
121
122
  linkSizeStyles[size],
122
123
  "transition-colors duration-[var(--ds-transition-speed)]",
123
124
  FOCUS_RING,
124
- "cursor-pointer",
125
+ // unavailable (aria-disabled) looks it, as the other variants do: the press is ignored either way
126
+ "cursor-pointer aria-disabled:cursor-not-allowed aria-disabled:not-aria-busy:opacity-disabled",
125
127
  "active:text-[var(--ds-accent-primary-active)]"
126
128
  ) : cn(
127
129
  "border-[length:var(--ds-border-width)]",
@@ -131,7 +133,7 @@ var Button = forwardRef(function Button2({ variant = "default", size: sizeProp,
131
133
  "active:shadow-[var(--ds-shadow-button-pressed)] active:translate-x-[var(--ds-press-depth)] active:translate-y-[var(--ds-press-depth)]",
132
134
  "[transition:var(--ds-transition-interactive)]",
133
135
  FOCUS_RING,
134
- "cursor-pointer disabled:cursor-not-allowed disabled:opacity-disabled",
136
+ "cursor-pointer disabled:cursor-not-allowed disabled:opacity-disabled aria-disabled:cursor-not-allowed aria-disabled:not-aria-busy:opacity-disabled",
135
137
  sizeStyles[size]
136
138
  ),
137
139
  variantStyles[variant],
@@ -179,5 +181,5 @@ function triggerType(node) {
179
181
  }
180
182
 
181
183
  export { Button, ButtonSizeContext, ControlSizeContext, Spinner, elementType, triggerType };
182
- //# sourceMappingURL=chunk-HQFTP7Y5.js.map
183
- //# sourceMappingURL=chunk-HQFTP7Y5.js.map
184
+ //# sourceMappingURL=chunk-FF57N3P7.js.map
185
+ //# sourceMappingURL=chunk-FF57N3P7.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../showcase/src/components/Spinner.tsx","../../../showcase/src/lib/element-type.ts","../../../showcase/src/components/Button.tsx"],"names":["Button","jsx"],"mappings":"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","file":"chunk-FF57N3P7.js","sourcesContent":["import { cn } from \"../lib/utils\";\n\nconst sizes = {\n sm: \"h-4 w-4 border-[1.5px]\",\n md: \"h-6 w-6 border-2\",\n lg: \"h-8 w-8 border-[2.5px]\",\n} as const;\n\ninterface SpinnerProps {\n size?: keyof typeof sizes;\n color?: \"default\" | \"inherit\";\n label?: string;\n className?: string;\n}\n\nexport function Spinner({ size = \"md\", color = \"default\", label = \"Loading\", className }: SpinnerProps) {\n return (\n <span\n role=\"status\"\n aria-label={label}\n className={cn(\n \"inline-block rounded-[var(--ds-radius-full)] animate-spin\",\n color === \"inherit\"\n ? \"border-current/30 border-t-current\"\n : \"border-[var(--ds-bg-emphasis)] border-t-[var(--ds-accent-primary)]\",\n sizes[size],\n className\n )}\n />\n );\n}\n","/**\n * An element's own component, through a lazy reference (Sprint 25.22's fresh-eyes review). A Next.js server component\n * hands each client component among its children on as a React.lazy reference, not as the component, so a check of\n * `element.type` against a component (PageContainer's header, Card's title, EmptyState's icon) missed every one, and a\n * server page drew without its layout: no colourful band, no contained breadcrumbs, a card's badge out of place. The\n * reference is resolved as React resolves one when it renders it: its component once loaded; while it loads, its promise\n * is thrown, so the component reading it suspends until it has it. Anything else is returned as it is.\n */\nconst LAZY = Symbol.for(\"react.lazy\");\n\ninterface LazyReference {\n $$typeof: symbol;\n _payload: unknown;\n _init: (payload: unknown) => unknown;\n}\n\nconst isLazy = (type: unknown): type is LazyReference =>\n type !== null && typeof type === \"object\" && (type as LazyReference).$$typeof === LAZY && typeof (type as LazyReference)._init === \"function\";\n\nexport function elementType(type: unknown): unknown {\n let resolved = type;\n // a reference to a reference resolves in turn; a handful of steps covers any real chain\n for (let step = 0; step < 8 && isLazy(resolved); step++) resolved = resolved._init(resolved._payload);\n return resolved;\n}\n","import { cn, FOCUS_RING } from \"../lib/utils\";\n// a server component hands its client children on as lazy references (Sprint 25.22's review)\nimport { elementType } from \"../lib/element-type\";\nimport { createContext, useContext, forwardRef, isValidElement, type ButtonHTMLAttributes, type CSSProperties, type ReactNode } from \"react\";\nimport { AutoTooltip, NATIVE_TITLE } from \"./Tooltip\";\nimport { Spinner } from \"./Spinner\";\nimport { slotIcon, type IconSlot, slotDraws } from \"../lib/icons\";\nimport { focusAfterSelfRemoval, hasSelfRemovalWatch, LAST_RESORT_MS, pageAddress, pointOf } from \"../lib/focus\";\nimport { inputModality } from \"../lib/input-modality\";\n\n/** How long a Button's own handover waits once the button has gone (Sprint 25.32): past every library rule's place. */\nexport const BUTTON_HANDOVER_MS = LAST_RESORT_MS * 2;\n\ntype ButtonVariant = \"default\" | \"secondary\" | \"tertiary\" | \"outline\" | \"ghost\" | \"destructive\" | \"success\" | \"warning\" | \"link\";\ntype ButtonSize = \"xs\" | \"sm\" | \"md\" | \"lg\" | \"icon-xs\" | \"icon-sm\" | \"icon\" | \"icon-lg\";\n\nexport type ControlSize = \"sm\" | \"md\" | \"lg\";\nexport const ControlSizeContext = createContext<ControlSize | null>(null);\nexport const ButtonSizeContext = ControlSizeContext;\n\ninterface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {\n variant?: ButtonVariant;\n size?: ButtonSize;\n /** An icon name (\"clock\"), drawn as the theme's icon at the button's icon size, or an element. Not text: use children. */\n iconLeft?: IconSlot;\n /** As iconLeft, after the label. */\n iconRight?: IconSlot;\n loading?: boolean;\n children?: ReactNode;\n}\n\nconst variantStyles: Record<ButtonVariant, string> = {\n default: \"bg-[var(--ds-accent-primary)] [background-image:var(--ds-gradient)] [background-origin:border-box] text-[var(--ds-text-on-primary)] border-transparent hover:bg-[var(--ds-accent-primary-hover)] hover:brightness-110\",\n secondary: \"bg-[var(--ds-bg-surface)] text-[var(--ds-text-primary)] border-[var(--ds-border-default)] hover:bg-[var(--ds-bg-muted)]\",\n tertiary: \"bg-[var(--ds-bg-muted)] text-[var(--ds-text-primary)] border-transparent hover:brightness-95\",\n outline: \"bg-[var(--ds-input-bg)] text-[var(--ds-text-primary)] border-[var(--ds-border-default)] hover:bg-[var(--ds-bg-muted)]\",\n ghost: \"bg-transparent text-[var(--ds-text-primary)] border-transparent hover:bg-[var(--ds-bg-muted)] shadow-none\",\n destructive: \"bg-[var(--ds-status-error)] text-[var(--ds-text-on-error)] border-transparent hover:opacity-90\",\n success: \"bg-[var(--ds-status-success)] text-[var(--ds-text-on-success)] border-transparent hover:opacity-90\",\n warning: \"bg-[var(--ds-status-warning)] text-[var(--ds-text-on-warning)] border-transparent hover:opacity-90\",\n link: \"bg-transparent text-[var(--ds-accent-ink)] hover:text-[var(--ds-accent-primary-hover)] hover:underline\",\n};\n\nconst sizeStyles: Record<ButtonSize, string> = {\n // xs / icon-xs: dense tool chrome (builder toolbars, inline row actions).\n xs: \"h-ds-6 px-ds-3 py-0 text-xs\",\n sm: \"h-[var(--ds-control-height-sm)] px-ds-4 py-ds-1 text-xs\",\n md: \"h-[var(--ds-control-height-md)] px-ds-6 py-ds-2 text-sm\",\n lg: \"h-[var(--ds-control-height-lg)] px-ds-8 py-ds-3 text-base\",\n \"icon-xs\": \"h-ds-6 w-ds-6 p-0\",\n \"icon-sm\": \"h-[var(--ds-control-height-sm)] w-[var(--ds-control-height-sm)] p-0\",\n icon: \"h-[var(--ds-control-height-md)] w-[var(--ds-control-height-md)] p-0\",\n \"icon-lg\": \"h-[var(--ds-control-height-lg)] w-[var(--ds-control-height-lg)] p-0\",\n};\n\n// Link buttons have no box, so only the text size follows `size`.\nconst linkSizeStyles: Record<ButtonSize, string> = {\n xs: \"text-xs\",\n sm: \"text-xs\",\n md: \"text-sm\",\n lg: \"text-base\",\n \"icon-xs\": \"text-xs\",\n \"icon-sm\": \"text-xs\",\n icon: \"text-sm\",\n \"icon-lg\": \"text-base\",\n};\n\nconst iconPaddingReduce: Record<Exclude<ButtonSize, \"icon\" | \"icon-xs\" | \"icon-sm\" | \"icon-lg\">, number> = {\n xs: 2,\n sm: 2,\n md: 4,\n lg: 6,\n};\n\n/** The icon size each button size draws a named icon at (Sprint 25.17 A26): what the library's own buttons pass by hand. */\nconst SLOT_ICON_PX: Record<ButtonSize, number> = { xs: 12, sm: 14, md: 16, lg: 18, \"icon-xs\": 12, \"icon-sm\": 14, icon: 16, \"icon-lg\": 18 };\n\nconst HOVER_SCALE_CAP = { '--_btn-scale': 'min(var(--ds-hover-scale), 1.02)' } as CSSProperties;\n\nexport const Button = forwardRef<HTMLButtonElement, ButtonProps>(function Button({ variant = \"default\", size: sizeProp, iconLeft, iconRight, loading, className, children, disabled, style, onClick, ...props }, ref) {\n const contextSize = useContext(ControlSizeContext);\n // Sprint 32's end review (R11): an icon button follows the size round it, as a Button with no size does, so a small\n // header's ⋯ matches the buttons beside it; icon-xs, icon-sm and icon-lg are sizes of their own\n const size: ButtonSize = sizeProp === \"icon\" && contextSize && contextSize !== \"md\" ? `icon-${contextSize}` : sizeProp ?? contextSize ?? \"md\";\n const isLink = variant === \"link\";\n const spinnerSize = size === \"lg\" || size === \"icon-lg\" ? \"md\" : \"sm\";\n let paddingStyle: CSSProperties | undefined;\n const isIconSize = size === \"icon\" || size === \"icon-xs\" || size === \"icon-sm\" || size === \"icon-lg\";\n // a slot that draws nothing (text, which no icon pack names) keeps the button's even padding\n const drawsLeft = slotDraws(iconLeft);\n const drawsRight = slotDraws(iconRight);\n if (!isIconSize && !isLink && (drawsLeft || drawsRight)) {\n const reduce = iconPaddingReduce[size];\n paddingStyle = {};\n if (drawsLeft) paddingStyle.paddingLeft = `calc(${getCssPadding(size)} - ${reduce}px)`;\n if (drawsRight) paddingStyle.paddingRight = `calc(${getCssPadding(size)} - ${reduce}px)`;\n }\n\n const isLoading = loading && !disabled;\n const isDisabled = !!disabled;\n // Sprint 32's end review (R13): unavailable where focus stays (aria-disabled, which disabled isn't): drawn as a\n // disabled Button is, and its press ignored, as a busy one's is\n const unavailable = String(props[\"aria-disabled\"]) === \"true\";\n\n // Sprint 25.32 (R29-2: round 29's \"Reconnect\" was drawn only while an app was disconnected, so its own press took it\n // away and focus fell to the page): a keyboard press that takes its button away hands focus on, where the browser's\n // own Tab would go on from where the button stood (D1: the first Tab stop after a live range taken round the button\n // before its press acts, else the last before it, within the page or the dialog it was in). Only a press that isn't a\n // pointer's (the keyboard's, a screen reader's), on the button holding focus (the review of 18 October): focus moved\n // by script after a pointer's press shows no ring, so a Space meant to scroll would press whatever it landed on. Only\n // the button leaving the page counts, not its being disabled while the press is pending. Set after the page's\n // handler, so a component that knows better (Pagination's own rule) has set its watch first, and this one steps\n // aside. It waits twice the last resort's time once the button has gone, so every place the library or the page gives\n // focus goes first (a drawer's Cancel, whose drawer sends focus back where its opener's panel sat, a last resort of\n // its own at LAST_RESORT_MS), and never acts across a change of page, whose new page owns focus. The user moving on\n // ends it.\n const handleClick = isLoading || unavailable\n ? (e: React.MouseEvent<HTMLButtonElement>) => { e.preventDefault(); }\n : (e: React.MouseEvent<HTMLButtonElement>) => {\n const button = e.currentTarget;\n const watch = document.activeElement === button && inputModality() !== \"pointer\";\n // the page the press was on: a handler that navigated has a new page, which owns focus\n const page = watch ? pageAddress() : null;\n // where the button stands, taken before its press acts: the DOM keeps it once the button has gone\n const point = watch ? pointOf(button) : undefined;\n onClick?.(e);\n if (!watch || pageAddress() !== page || hasSelfRemovalWatch(button)) return;\n focusAfterSelfRemoval(button, { group: null, samePage: true, defer: BUTTON_HANDOVER_MS, removedOnly: true, point });\n };\n\n const ariaLabel = props[\"aria-label\"];\n // An icon-size Button with an aria-label draws its own tooltip from it. Round 15 (52.7): where a Tooltip the page put\n // around it shows, that one owns the label and this steps aside (AutoTooltip asks when it would show).\n const drawsTooltip = isIconSize && !!ariaLabel;\n // A title beside a tooltip is the browser's second one, a moment later (the review of 21.6 session B): a Button that\n // draws its tooltip shows the title's text in it instead (the Tooltip drops the button's own title), and a Tooltip the\n // page puts around a Button drops its title too (NATIVE_TITLE).\n const title = props.title;\n\n const btn = (\n <button\n ref={ref}\n data-variant={variant}\n className={cn(\n \"relative inline-flex items-center justify-center gap-ds-2 whitespace-nowrap font-medium\",\n isLink\n ? cn(\n \"px-0 py-ds-0.5 h-auto\",\n linkSizeStyles[size],\n \"transition-colors duration-[var(--ds-transition-speed)]\",\n FOCUS_RING,\n // unavailable (aria-disabled) looks it, as the other variants do: the press is ignored either way\n \"cursor-pointer aria-disabled:cursor-not-allowed aria-disabled:not-aria-busy:opacity-disabled\",\n \"active:text-[var(--ds-accent-primary-active)]\",\n )\n : cn(\n \"border-[length:var(--ds-border-width)]\",\n \"rounded-[var(--ds-radius-md)]\",\n \"shadow-[var(--ds-shadow-button)]\",\n \"hover:scale-[var(--_btn-scale)] hover:-translate-y-[var(--ds-hover-lift)]\",\n \"active:shadow-[var(--ds-shadow-button-pressed)] active:translate-x-[var(--ds-press-depth)] active:translate-y-[var(--ds-press-depth)]\",\n \"[transition:var(--ds-transition-interactive)]\",\n FOCUS_RING,\n \"cursor-pointer disabled:cursor-not-allowed disabled:opacity-disabled aria-disabled:cursor-not-allowed aria-disabled:not-aria-busy:opacity-disabled\",\n sizeStyles[size],\n ),\n variantStyles[variant],\n isLoading && !isLink && \"cursor-wait pointer-events-none\",\n className\n )}\n disabled={isDisabled}\n aria-busy={isLoading || undefined}\n aria-disabled={isLoading && !disabled ? true : undefined}\n onClick={handleClick}\n style={isLink ? style : { ...HOVER_SCALE_CAP, ...paddingStyle, ...style }}\n {...props}\n >\n {loading && !isLink && (\n <span className=\"absolute inset-0 flex items-center justify-center\">\n <Spinner size={spinnerSize} color=\"inherit\" />\n </span>\n )}\n <span className={cn(\"inline-flex items-center gap-ds-2 min-w-0\", loading && !isLink && \"invisible\")}>\n {slotIcon(iconLeft, SLOT_ICON_PX[size], \"Button's iconLeft\")}\n {children}\n {slotIcon(iconRight, SLOT_ICON_PX[size], \"Button's iconRight\")}\n </span>\n </button>\n );\n\n if (drawsTooltip) {\n return <AutoTooltip content={title ?? ariaLabel}>{btn}</AutoTooltip>;\n }\n\n return btn;\n});\n// a Button's title is the native attribute: a Tooltip around it drops it, as it does an element's\n(Button as unknown as Record<symbol, true>)[NATIVE_TITLE] = true;\n\nfunction getCssPadding(size: Exclude<ButtonSize, \"icon\" | \"icon-xs\" | \"icon-sm\" | \"icon-lg\">): string {\n switch (size) {\n case \"xs\": return \"var(--ds-space-3)\";\n case \"sm\": return \"var(--ds-space-4)\";\n case \"md\": return \"var(--ds-space-6)\";\n case \"lg\": return \"var(--ds-space-8)\";\n }\n}\n\n/**\n * A trigger the library wires up (a Collapsible's, a menu's, a popover's) never submits the form it sits in (0.21.0): a\n * button element or Button given no type gets type=\"button\". A page's own Button keeps HTML's default, so its submits\n * still work.\n */\nexport function triggerType(node: unknown): { type?: \"button\" } {\n if (!isValidElement(node)) return {};\n const type = elementType(node.type);\n return (type === \"button\" || type === Button) && (node.props as { type?: unknown }).type === undefined ? { type: \"button\" } : {};\n}\n"]}
@@ -0,0 +1,18 @@
1
+ "use client";
2
+ import { useSyncExternalStore } from 'react';
3
+
4
+ // ../../showcase/src/lib/hydrated.ts
5
+ var noSubscription = () => () => {
6
+ };
7
+ var inBrowser = () => true;
8
+ var onServer = () => false;
9
+ function useHydrated() {
10
+ return useSyncExternalStore(noSubscription, inBrowser, onServer);
11
+ }
12
+ function useToday() {
13
+ return useHydrated() ? /* @__PURE__ */ new Date() : null;
14
+ }
15
+
16
+ export { useHydrated, useToday };
17
+ //# sourceMappingURL=chunk-GIA4BMGI.js.map
18
+ //# sourceMappingURL=chunk-GIA4BMGI.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../showcase/src/lib/hydrated.ts"],"names":[],"mappings":";;;;AAEA,IAAM,cAAA,GAAiB,MAAM,MAAM;AAAC,CAAA;AACpC,IAAM,YAAY,MAAM,IAAA;AACxB,IAAM,WAAW,MAAM,KAAA;AAQhB,SAAS,WAAA,GAAuB;AACrC,EAAA,OAAO,oBAAA,CAAqB,cAAA,EAAgB,SAAA,EAAW,QAAQ,CAAA;AACjE;AAMO,SAAS,QAAA,GAAwB;AACtC,EAAA,OAAO,WAAA,EAAY,mBAAI,IAAI,IAAA,EAAK,GAAI,IAAA;AACtC","file":"chunk-GIA4BMGI.js","sourcesContent":["import { useSyncExternalStore } from \"react\";\n\nconst noSubscription = () => () => {};\nconst inBrowser = () => true;\nconst onServer = () => false;\n\n/**\n * Whether the browser has taken the page over (Sprint 25.20 D3): false on a server, and in the render that hydrates the\n * server's HTML (it must draw what the server drew), true straight after. A render with no server HTML (a Vite app, a\n * component mounted later) is true from its first render. What depends on the visitor's clock or time zone, which no\n * server knows, waits for it.\n */\nexport function useHydrated(): boolean {\n return useSyncExternalStore(noSubscription, inBrowser, onServer);\n}\n\n/**\n * Today on the visitor's device, once the browser has the page (null on a server and while hydrating): the day a date\n * grid marks and starts its keyboard on. Read on each render, so a grid drawn again after midnight marks the new day.\n */\nexport function useToday(): Date | null {\n return useHydrated() ? new Date() : null;\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { usePosition, useLatest, cn, GLASS_DROPDOWN } from './chunk-EZ3ZGFGA.js';
2
+ import { usePosition, useLatest, cn, GLASS_DROPDOWN } from './chunk-2724SJO2.js';
3
3
  import { version, createContext, isValidElement, cloneElement, useContext, useState, useRef, useId, useCallback, useEffect, useLayoutEffect } from 'react';
4
4
  import { createPortal } from 'react-dom';
5
5
  import { jsx, jsxs } from 'react/jsx-runtime';
@@ -237,5 +237,5 @@ function useRevealFocus(target, enabled = true) {
237
237
  }
238
238
 
239
239
  export { AutoTooltip, NATIVE_TITLE, RevealTooltip, Slot, Tooltip, mergeRefs, useRevealFocus };
240
- //# sourceMappingURL=chunk-DR6WEI3A.js.map
241
- //# sourceMappingURL=chunk-DR6WEI3A.js.map
240
+ //# sourceMappingURL=chunk-HCEHTJ5E.js.map
241
+ //# sourceMappingURL=chunk-HCEHTJ5E.js.map
@@ -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-DR6WEI3A.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-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"]}