From f8dc22c6900b7344c2a493fa8c302e85b4838917 Mon Sep 17 00:00:00 2001 From: BigSimmo <87357024+BigSimmo@users.noreply.github.com> Date: Sun, 16 Aug 2026 20:31:44 +0800 Subject: [PATCH 1/9] fix(guide): pin guide chrome controls to shared scroll-hide behavior --- .../clinical-dashboard/guide-dialog.tsx | 131 +++++++++++------- src/components/ui/sheet.tsx | 18 ++- tests/guide-centre.dom.test.tsx | 28 ++-- tests/ui-smoke.spec.ts | 14 +- 4 files changed, 130 insertions(+), 61 deletions(-) diff --git a/src/components/clinical-dashboard/guide-dialog.tsx b/src/components/clinical-dashboard/guide-dialog.tsx index f13df3d1f1..42283897c4 100644 --- a/src/components/clinical-dashboard/guide-dialog.tsx +++ b/src/components/clinical-dashboard/guide-dialog.tsx @@ -23,7 +23,7 @@ import { X, type LucideIcon, } from "lucide-react"; -import { useMemo, useRef, useState, useSyncExternalStore, type UIEvent } from "react"; +import { useMemo, useRef, useState, type RefObject, type UIEvent } from "react"; import { guideQuickTasks, @@ -44,6 +44,7 @@ import { saveGuideProgress, type GuideProgress, } from "@/components/clinical-dashboard/guide-progress"; +import { readChromeCollapseMetrics, useScrollHideReporter } from "@/components/clinical-dashboard/use-hide-on-scroll"; import { Sheet } from "@/components/ui/sheet"; import { chatComposerIconButton, @@ -57,23 +58,6 @@ import { } from "@/components/ui-primitives"; const guideAccessibleNameId = "clinical-kb-guide-accessible-name"; -const phoneMediaQuery = "(max-width: 639px)"; - -function subscribeToPhoneMedia(callback: () => void) { - if (typeof window === "undefined" || typeof window.matchMedia !== "function") return () => undefined; - const media = window.matchMedia(phoneMediaQuery); - media.addEventListener("change", callback); - return () => media.removeEventListener("change", callback); -} - -function getPhoneMediaSnapshot() { - if (typeof window === "undefined" || typeof window.matchMedia !== "function") return false; - return window.matchMedia(phoneMediaQuery).matches; -} - -function usePhoneViewport() { - return useSyncExternalStore(subscribeToPhoneMedia, getPhoneMediaSnapshot, () => false); -} const topicIcons: Record = { "getting-started": BookOpen, @@ -88,12 +72,23 @@ const topicIcons: Record = { const quickTaskIcons: readonly LucideIcon[] = [HelpCircle, SlidersHorizontal, ShieldCheck, LockKeyhole]; -function GuideSearch({ query, onQueryChange }: { query: string; onQueryChange: (query: string) => void }) { +function GuideSearch({ + query, + inputRef, + onFocusChange, + onQueryChange, +}: { + query: string; + inputRef: RefObject; + onFocusChange: (focused: boolean) => void; + onQueryChange: (query: string) => void; +}) { return (
event.preventDefault()} + data-guide-universal-search className="mx-auto w-full max-w-3xl" >
Search the guide onQueryChange(event.target.value)} + onFocus={() => onFocusChange(true)} + onBlur={() => onFocusChange(false)} placeholder="Search the guide" className={cn(chatComposerInput, "answer-footer-search-input w-full min-w-0")} autoComplete="off" @@ -139,7 +137,10 @@ function GuideTopNavigation({ view, onNavigate }: { view: GuideView; onNavigate: { view: "topics", label: "All topics", icon: Grid2X2 }, ]; return ( - } + > +

Body

+ , + ); + + header = dialog.querySelector('[data-sheet-header="true"]'); + expect(header).not.toBeNull(); + expect(header).not.toHaveClass("pt-[max(1rem,var(--safe-area-top))]"); + expect(header).toHaveAttribute("aria-hidden", "true"); + expect(header).toHaveAttribute("inert", ""); +}); From f2387eaf248dd70da1b181b3e2619f8a31386af4 Mon Sep 17 00:00:00 2001 From: BigSimmo <87357024+BigSimmo@users.noreply.github.com> Date: Sun, 16 Aug 2026 21:23:12 +0800 Subject: [PATCH 4/9] Format Sheet safe-area guard --- src/components/ui/sheet.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/ui/sheet.tsx b/src/components/ui/sheet.tsx index ad53faa1ad..a5a06044fe 100644 --- a/src/components/ui/sheet.tsx +++ b/src/components/ui/sheet.tsx @@ -473,8 +473,12 @@ export function Sheet({ "flex items-center justify-between gap-x-3 border-b border-[color:var(--border)] p-4 sm:p-5", Boolean(headerBottom) && "flex-wrap", headerClassName, - !headerHidden && resolvedMobileHeaderSafeArea === "padding" && "pt-[max(1rem,var(--safe-area-top))] sm:pt-5", - !headerHidden && resolvedMobileHeaderSafeArea === "offset" && "top-[max(0.75rem,var(--safe-area-top))] sm:top-4", + !headerHidden && + resolvedMobileHeaderSafeArea === "padding" && + "pt-[max(1rem,var(--safe-area-top))] sm:pt-5", + !headerHidden && + resolvedMobileHeaderSafeArea === "offset" && + "top-[max(0.75rem,var(--safe-area-top))] sm:top-4", )} >
From 1ccdf61456fde43285c360126f3ed9dfa9939cc2 Mon Sep 17 00:00:00 2001 From: BigSimmo <87357024+BigSimmo@users.noreply.github.com> Date: Sun, 16 Aug 2026 21:38:43 +0800 Subject: [PATCH 5/9] Fix Guide design-system contract violations --- ...e8bdb42e2083e6630c223f07f7a5e795dcf70c163c119aac.record.md | 1 + src/components/clinical-dashboard/guide-dialog.tsx | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) create mode 100644 docs/branch-review-records/5a9658946b353e47e8bdb42e2083e6630c223f07f7a5e795dcf70c163c119aac.record.md diff --git a/docs/branch-review-records/5a9658946b353e47e8bdb42e2083e6630c223f07f7a5e795dcf70c163c119aac.record.md b/docs/branch-review-records/5a9658946b353e47e8bdb42e2083e6630c223f07f7a5e795dcf70c163c119aac.record.md new file mode 100644 index 0000000000..b08d6833d7 --- /dev/null +++ b/docs/branch-review-records/5a9658946b353e47e8bdb42e2083e6630c223f07f7a5e795dcf70c163c119aac.record.md @@ -0,0 +1 @@ +| 2026-08-16 | PR #2007 / codex/guide-search-chrome-20260815 | 0874f3f7faa9539b6db30a58cee360adff4bf7a1 | design-system CI repair | Replaced the retired elevated shadow alias and removed two layout-transition exceptions from Guide chrome | Design-system contract diagnosis from exact-head CI; targeted source verification; exact-head CI re-run | diff --git a/src/components/clinical-dashboard/guide-dialog.tsx b/src/components/clinical-dashboard/guide-dialog.tsx index 42283897c4..51450c45e1 100644 --- a/src/components/clinical-dashboard/guide-dialog.tsx +++ b/src/components/clinical-dashboard/guide-dialog.tsx @@ -888,14 +888,14 @@ function GuideDialogSession({ onClose }: { onClose: () => void }) { headerHidden={chromeHidden} headerBottom={} headerClassName={cn( - "guide-centre-header max-h-48 overflow-hidden pt-[max(1rem,env(safe-area-inset-top))] transition-[max-height,padding,border-color,opacity] duration-[var(--duration-moderate)] motion-reduce:transition-none sm:pt-5", + "guide-centre-header max-h-48 overflow-hidden pt-[max(1rem,env(safe-area-inset-top))] transition-[border-color,opacity] duration-[var(--duration-moderate)] motion-reduce:transition-none sm:pt-5", chromeHidden && "max-h-0 border-transparent p-0 opacity-0 sm:max-h-48 sm:border-[color:var(--border)] sm:p-5 sm:opacity-100", )} mobilePlacement="fullscreen" footer={footer} footerClassName={cn( - "absolute inset-x-0 bottom-0 z-30 border-t border-[color:var(--border)] bg-[color:var(--surface-raised)] pl-[max(0.75rem,env(safe-area-inset-left))] pr-[max(0.75rem,env(safe-area-inset-right))] pb-[max(0.75rem,env(safe-area-inset-bottom))] pt-3 shadow-[var(--shadow-elevated)] transition-[transform,opacity] duration-[var(--duration-moderate)] motion-reduce:transition-none sm:static sm:p-4 sm:shadow-none", + "absolute inset-x-0 bottom-0 z-30 border-t border-[color:var(--border)] bg-[color:var(--surface-raised)] pl-[max(0.75rem,env(safe-area-inset-left))] pr-[max(0.75rem,env(safe-area-inset-right))] pb-[max(0.75rem,env(safe-area-inset-bottom))] pt-3 shadow-[var(--e4)] transition-[transform,opacity] duration-[var(--duration-moderate)] motion-reduce:transition-none sm:static sm:p-4 sm:shadow-none", chromeHidden && "pointer-events-none translate-y-full opacity-0 sm:pointer-events-auto sm:translate-y-0 sm:opacity-100", )} From 6666613662921734181d12ea9a51d9cb972e2171 Mon Sep 17 00:00:00 2001 From: BigSimmo <87357024+BigSimmo@users.noreply.github.com> Date: Sun, 16 Aug 2026 21:42:29 +0800 Subject: [PATCH 6/9] Correct Guide review record and lock design tokens --- ...d5ed4615778a6e59fa3c4e010706922.record.md} | 0 .../guide-centre-design-contract.dom.test.tsx | 27 +++++++++++++++++++ 2 files changed, 27 insertions(+) rename docs/branch-review-records/{5a9658946b353e47e8bdb42e2083e6630c223f07f7a5e795dcf70c163c119aac.record.md => 6cdaa052c37673355af42b196c2bb613fd5ed4615778a6e59fa3c4e010706922.record.md} (100%) create mode 100644 tests/guide-centre-design-contract.dom.test.tsx diff --git a/docs/branch-review-records/5a9658946b353e47e8bdb42e2083e6630c223f07f7a5e795dcf70c163c119aac.record.md b/docs/branch-review-records/6cdaa052c37673355af42b196c2bb613fd5ed4615778a6e59fa3c4e010706922.record.md similarity index 100% rename from docs/branch-review-records/5a9658946b353e47e8bdb42e2083e6630c223f07f7a5e795dcf70c163c119aac.record.md rename to docs/branch-review-records/6cdaa052c37673355af42b196c2bb613fd5ed4615778a6e59fa3c4e010706922.record.md diff --git a/tests/guide-centre-design-contract.dom.test.tsx b/tests/guide-centre-design-contract.dom.test.tsx new file mode 100644 index 0000000000..09258d48c3 --- /dev/null +++ b/tests/guide-centre-design-contract.dom.test.tsx @@ -0,0 +1,27 @@ +import { cleanup, render, screen } from "@testing-library/react"; +import { afterEach, expect, it, vi } from "vitest"; + +import { GuideDialog } from "@/components/clinical-dashboard/guide-dialog"; + +afterEach(async () => { + cleanup(); + await new Promise((resolve) => { + window.requestAnimationFrame(() => window.setTimeout(resolve, 60)); + }); +}); + +it("keeps Guide chrome on approved elevation and non-layout transitions", () => { + render(); + + const dialog = screen.getByRole("dialog", { name: "Clinical KB guide" }); + const header = dialog.querySelector(".guide-centre-header"); + const footer = dialog.querySelector("[data-guide-mobile-footer]")?.parentElement; + + expect(header).not.toBeNull(); + expect(footer).not.toBeNull(); + expect(header).toHaveClass("transition-[border-color,opacity]"); + expect(header).not.toHaveClass("transition-[max-height,padding,border-color,opacity]"); + expect(footer).toHaveClass("shadow-[var(--e4)]"); + expect(footer).not.toHaveClass("shadow-[var(--shadow-elevated)]"); + expect(footer).toHaveClass("transition-[transform,opacity]"); +}); From 5af71dc435245f4c2391fb02834754e844d83d14 Mon Sep 17 00:00:00 2001 From: BigSimmo <87357024+BigSimmo@users.noreply.github.com> Date: Sun, 16 Aug 2026 21:55:22 +0800 Subject: [PATCH 7/9] Consolidate Guide safe-area regression coverage --- tests/guide-centre.dom.test.tsx | 5 ++- tests/sheet-header-safe-area.dom.test.tsx | 48 ----------------------- 2 files changed, 4 insertions(+), 49 deletions(-) delete mode 100644 tests/sheet-header-safe-area.dom.test.tsx diff --git a/tests/guide-centre.dom.test.tsx b/tests/guide-centre.dom.test.tsx index 59a3ba74fe..93c318c10d 100644 --- a/tests/guide-centre.dom.test.tsx +++ b/tests/guide-centre.dom.test.tsx @@ -68,6 +68,7 @@ describe("Clinical KB Guide Centre", () => { expect(content).not.toBeNull(); expect(footer?.querySelector("[data-guide-universal-search]")).not.toBeNull(); expect(footer?.querySelector("[data-guide-tour-action-row]")).not.toBeNull(); + expect(header).toHaveClass("pt-[max(1rem,var(--safe-area-top))]"); Object.defineProperty(scrollBody, "scrollHeight", { configurable: true, value: 1_600 }); Object.defineProperty(scrollBody, "clientHeight", { configurable: true, value: 600 }); @@ -75,6 +76,7 @@ describe("Clinical KB Guide Centre", () => { fireEvent.scroll(scrollBody!); await waitFor(() => expect(footerLayer).toHaveClass("translate-y-full")); expect(header).toHaveClass("max-h-0"); + expect(header).not.toHaveClass("pt-[max(1rem,var(--safe-area-top))]"); expect(header).toHaveAttribute("aria-hidden", "true"); expect(header).toHaveAttribute("inert", ""); expect(footer).toHaveAttribute("aria-hidden", "true"); @@ -87,6 +89,7 @@ describe("Clinical KB Guide Centre", () => { fireEvent.scroll(scrollBody!); await waitFor(() => expect(footerLayer).not.toHaveClass("translate-y-full")); expect(header).not.toHaveClass("max-h-0"); + expect(header).toHaveClass("pt-[max(1rem,var(--safe-area-top))]"); expect(header).toHaveAttribute("aria-hidden", "false"); expect(header).not.toHaveAttribute("inert"); expect(footer).toHaveAttribute("aria-hidden", "false"); @@ -244,4 +247,4 @@ describe("Clinical KB Guide Centre", () => { fireEvent.click(within(dialog).getByRole("button", { name: "Close guide" })); expect(onClose).toHaveBeenCalledTimes(1); }); -}); +}); \ No newline at end of file diff --git a/tests/sheet-header-safe-area.dom.test.tsx b/tests/sheet-header-safe-area.dom.test.tsx deleted file mode 100644 index 3481133447..0000000000 --- a/tests/sheet-header-safe-area.dom.test.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import { render, screen } from "@testing-library/react"; -import { expect, it, vi } from "vitest"; - -import { Sheet } from "@/components/ui/sheet"; - -it("releases Sheet-owned phone safe-area utilities while the header is hidden", () => { - const onClose = vi.fn(); - const visible = ( - Views} - > -

Body

-
- ); - const { rerender } = render(visible); - - const dialog = screen.getByRole("dialog"); - let header = dialog.querySelector('[data-sheet-header="true"]'); - expect(header).not.toBeNull(); - expect(header).toHaveClass("pt-[max(1rem,var(--safe-area-top))]"); - expect(header).toHaveAttribute("aria-hidden", "false"); - expect(header).not.toHaveAttribute("inert"); - - rerender( - Views} - > -

Body

-
, - ); - - header = dialog.querySelector('[data-sheet-header="true"]'); - expect(header).not.toBeNull(); - expect(header).not.toHaveClass("pt-[max(1rem,var(--safe-area-top))]"); - expect(header).toHaveAttribute("aria-hidden", "true"); - expect(header).toHaveAttribute("inert", ""); -}); From 6fcf0066a5706a0c05db38c56ad509690340f67d Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 17 Aug 2026 08:35:25 +0000 Subject: [PATCH 8/9] fix(guide): resolve CI failures blocking PR merge Static PR checks: format tests/guide-centre.dom.test.tsx (missing trailing newline). Unit coverage (design-sync-contract, design-sync-visual-exports): regenerate .design-sync/config.json - Sheet gained headerBottom, headerHidden, and headerRef props that were never synced. Unit coverage (guide-centre.dom.test.tsx): the shared useScrollHideReporter hook schedules an rAF-deferred hide-state reset on mount. A synchronous test scroll immediately after render could race that reset and silently revert the hide state between the footer and header assertions. Flush the pending frame before the first scroll, matching the pattern this file's own afterEach already uses. Production UI (ui-smoke.spec.ts): the pre-existing (PR-untouched) guide accessibility test scrolled 80px, clearing the old footer-only hide threshold but not the shared hook's 72px + 24px activation threshold now governing both header and footer. Bumped to 140px to match the PR's own new tests, and: - the tab-order check previously started from "Close guide", which now lives inside the header and is unfocusable while it's inert - swapped to a content control, matching the PR's own new guide-centre-chrome.spec.ts. - moving the guided-tour "Continue" action out of the scrollable body and into the fixed footer means the scroll body can render with no focusable descendant on some tour steps, tripping axe's scrollable-region-focusable rule. Added an opt-in bodyTabIndex prop to Sheet (default off, so no other Sheet consumer is affected) and set it for the guide dialog's scroll body. Note for follow-up (not blocking this PR): tests/guide-centre-chrome.spec.ts, also added by this PR, isn't matched by playwright.config.ts's testMatch allowlist and therefore never runs in CI. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01HR7cnmJRWZyg2Q9MFV1SCs --- .design-sync/config.json | 2 +- src/components/clinical-dashboard/guide-dialog.tsx | 1 + src/components/ui/sheet.tsx | 9 +++++++++ tests/guide-centre.dom.test.tsx | 6 +++++- tests/ui-smoke.spec.ts | 12 +++++++++--- 5 files changed, 25 insertions(+), 5 deletions(-) diff --git a/.design-sync/config.json b/.design-sync/config.json index 46df2b8d8a..a9e5b32b3b 100644 --- a/.design-sync/config.json +++ b/.design-sync/config.json @@ -59,7 +59,7 @@ "SearchField": "about?: string; accept?: string; accessKey?: string; alt?: string; \"aria-activedescendant\"?: string; \"aria-atomic\"?: (boolean | \"true\" | \"false\"); \"aria-autocomplete\"?: \"none\" | \"list\" | \"inline\" | \"both\"; \"aria-braillelabel\"?: string; \"aria-brailleroledescription\"?: string; \"aria-busy\"?: (boolean | \"true\" | \"false\"); \"aria-checked\"?: boolean | \"true\" | \"false\" | \"mixed\"; \"aria-colcount\"?: number; \"aria-colindex\"?: number; \"aria-colindextext\"?: string; \"aria-colspan\"?: number; \"aria-controls\"?: string; \"aria-current\"?: boolean | \"true\" | \"false\" | \"page\" | \"step\" | \"location\" | \"date\" | \"time\"; \"aria-describedby\"?: string; \"aria-description\"?: string; \"aria-details\"?: string; \"aria-disabled\"?: (boolean | \"true\" | \"false\"); \"aria-dropeffect\"?: \"none\" | \"link\" | \"copy\" | \"execute\" | \"move\" | \"popup\"; \"aria-errormessage\"?: string; \"aria-expanded\"?: (boolean | \"true\" | \"false\"); \"aria-flowto\"?: string; \"aria-grabbed\"?: (boolean | \"true\" | \"false\"); \"aria-haspopup\"?: boolean | \"true\" | \"false\" | \"dialog\" | \"grid\" | \"listbox\" | \"menu\" | \"tree\"; \"aria-hidden\"?: (boolean | \"true\" | \"false\"); \"aria-invalid\"?: boolean | \"true\" | \"false\" | \"grammar\" | \"spelling\"; \"aria-keyshortcuts\"?: string; \"aria-label\"?: string; \"aria-labelledby\"?: string; \"aria-level\"?: number; \"aria-live\"?: \"off\" | \"assertive\" | \"polite\"; \"aria-modal\"?: (boolean | \"true\" | \"false\"); \"aria-multiline\"?: (boolean | \"true\" | \"false\"); \"aria-multiselectable\"?: (boolean | \"true\" | \"false\"); \"aria-orientation\"?: \"horizontal\" | \"vertical\"; \"aria-owns\"?: string; \"aria-placeholder\"?: string; \"aria-posinset\"?: number; \"aria-pressed\"?: boolean | \"true\" | \"false\" | \"mixed\"; \"aria-readonly\"?: (boolean | \"true\" | \"false\"); \"aria-relevant\"?: \"text\" | \"additions\" | \"additions removals\" | \"additions text\" | \"all\" | \"removals\" | \"removals additions\" | \"removals text\" | \"text additions\" | \"text removals\"; \"aria-required\"?: (boolean | \"true\" | \"false\"); \"aria-roledescription\"?: string; \"aria-rowcount\"?: number; \"aria-rowindex\"?: number; \"aria-rowindextext\"?: string; \"aria-rowspan\"?: number; \"aria-selected\"?: (boolean | \"true\" | \"false\"); \"aria-setsize\"?: number; \"aria-sort\"?: \"none\" | \"ascending\" | \"descending\" | \"other\"; \"aria-valuemax\"?: number; \"aria-valuemin\"?: number; \"aria-valuenow\"?: number; \"aria-valuetext\"?: string; autoCapitalize?: \"off\" | \"none\" | \"on\" | \"sentences\" | \"words\" | \"characters\" | (string & {}); autoComplete?: import(\"react\").HTMLInputAutoCompleteAttribute; autoCorrect?: string; autoFocus?: boolean; autoSave?: string; capture?: boolean | \"user\" | \"environment\"; checked?: boolean; children?: import(\"react\").ReactNode; className?: string; clearLabel?: string; color?: string; content?: string; contentEditable?: (boolean | \"true\" | \"false\") | \"inherit\" | \"plaintext-only\"; contextMenu?: string; dangerouslySetInnerHTML?: { __html: string | TrustedHTML; }; datatype?: string; defaultChecked?: boolean; defaultValue?: string | number | readonly string[]; dir?: string; disabled?: boolean; draggable?: (boolean | \"true\" | \"false\"); enterKeyHint?: \"enter\" | \"done\" | \"go\" | \"next\" | \"previous\" | \"search\" | \"send\"; error?: string; exportparts?: string; fieldClassName?: string; form?: string; formAction?: string | ((formData: FormData) => void | Promise); formEncType?: string; formMethod?: string; formNoValidate?: boolean; formTarget?: string; height?: string | number; hidden?: boolean; hideLabel?: boolean; hint?: string; id?: string; inert?: boolean; inlist?: any; inputMode?: \"none\" | \"search\" | \"text\" | \"tel\" | \"url\" | \"email\" | \"numeric\" | \"decimal\"; is?: string; itemID?: string; itemProp?: string; itemRef?: string; itemScope?: boolean; itemType?: string; label: string; lang?: string; list?: string; max?: string | number; maxLength?: number; min?: string | number; minLength?: number; multiple?: boolean; name?: string; nonce?: string; onAbort?: import(\"react\").ReactEventHandler; onAbortCapture?: import(\"react\").ReactEventHandler; onAnimationEnd?: import(\"react\").AnimationEventHandler; onAnimationEndCapture?: import(\"react\").AnimationEventHandler; onAnimationIteration?: import(\"react\").AnimationEventHandler; onAnimationIterationCapture?: import(\"react\").AnimationEventHandler; onAnimationStart?: import(\"react\").AnimationEventHandler; onAnimationStartCapture?: import(\"react\").AnimationEventHandler; onAuxClick?: import(\"react\").MouseEventHandler; onAuxClickCapture?: import(\"react\").MouseEventHandler; onBeforeInput?: import(\"react\").InputEventHandler; onBeforeInputCapture?: import(\"react\").InputEventHandler; onBeforeToggle?: import(\"react\").ToggleEventHandler; onBlur?: import(\"react\").FocusEventHandler; onBlurCapture?: import(\"react\").FocusEventHandler; onCanPlay?: import(\"react\").ReactEventHandler; onCanPlayCapture?: import(\"react\").ReactEventHandler; onCanPlayThrough?: import(\"react\").ReactEventHandler; onCanPlayThroughCapture?: import(\"react\").ReactEventHandler; onChange?: import(\"react\").ChangeEventHandler; onChangeCapture?: import(\"react\").ChangeEventHandler; onClear?: (() => void); onClick?: import(\"react\").MouseEventHandler; onClickCapture?: import(\"react\").MouseEventHandler; onCompositionEnd?: import(\"react\").CompositionEventHandler; onCompositionEndCapture?: import(\"react\").CompositionEventHandler; onCompositionStart?: import(\"react\").CompositionEventHandler; onCompositionStartCapture?: import(\"react\").CompositionEventHandler; onCompositionUpdate?: import(\"react\").CompositionEventHandler; onCompositionUpdateCapture?: import(\"react\").CompositionEventHandler; onContextMenu?: import(\"react\").MouseEventHandler; onContextMenuCapture?: import(\"react\").MouseEventHandler; onCopy?: import(\"react\").ClipboardEventHandler; onCopyCapture?: import(\"react\").ClipboardEventHandler; onCut?: import(\"react\").ClipboardEventHandler; onCutCapture?: import(\"react\").ClipboardEventHandler; onDoubleClick?: import(\"react\").MouseEventHandler; onDoubleClickCapture?: import(\"react\").MouseEventHandler; onDrag?: import(\"react\").DragEventHandler; onDragCapture?: import(\"react\").DragEventHandler; onDragEnd?: import(\"react\").DragEventHandler; onDragEndCapture?: import(\"react\").DragEventHandler; onDragEnter?: import(\"react\").DragEventHandler; onDragEnterCapture?: import(\"react\").DragEventHandler; onDragExit?: import(\"react\").DragEventHandler; onDragExitCapture?: import(\"react\").DragEventHandler; onDragLeave?: import(\"react\").DragEventHandler; onDragLeaveCapture?: import(\"react\").DragEventHandler; onDragOver?: import(\"react\").DragEventHandler; onDragOverCapture?: import(\"react\").DragEventHandler; onDragStart?: import(\"react\").DragEventHandler; onDragStartCapture?: import(\"react\").DragEventHandler; onDrop?: import(\"react\").DragEventHandler; onDropCapture?: import(\"react\").DragEventHandler; onDurationChange?: import(\"react\").ReactEventHandler; onDurationChangeCapture?: import(\"react\").ReactEventHandler; onEmptied?: import(\"react\").ReactEventHandler; onEmptiedCapture?: import(\"react\").ReactEventHandler; onEncrypted?: import(\"react\").ReactEventHandler; onEncryptedCapture?: import(\"react\").ReactEventHandler; onEnded?: import(\"react\").ReactEventHandler; onEndedCapture?: import(\"react\").ReactEventHandler; onError?: import(\"react\").ReactEventHandler; onErrorCapture?: import(\"react\").ReactEventHandler; onFocus?: import(\"react\").FocusEventHandler; onFocusCapture?: import(\"react\").FocusEventHandler; onGotPointerCapture?: import(\"react\").PointerEventHandler; onGotPointerCaptureCapture?: import(\"react\").PointerEventHandler; onInput?: import(\"react\").InputEventHandler; onInputCapture?: import(\"react\").InputEventHandler; onInvalid?: import(\"react\").ReactEventHandler; onInvalidCapture?: import(\"react\").ReactEventHandler; onKeyDown?: import(\"react\").KeyboardEventHandler; onKeyDownCapture?: import(\"react\").KeyboardEventHandler; onKeyPress?: import(\"react\").KeyboardEventHandler; onKeyPressCapture?: import(\"react\").KeyboardEventHandler; onKeyUp?: import(\"react\").KeyboardEventHandler; onKeyUpCapture?: import(\"react\").KeyboardEventHandler; onLoad?: import(\"react\").ReactEventHandler; onLoadCapture?: import(\"react\").ReactEventHandler; onLoadedData?: import(\"react\").ReactEventHandler; onLoadedDataCapture?: import(\"react\").ReactEventHandler; onLoadedMetadata?: import(\"react\").ReactEventHandler; onLoadedMetadataCapture?: import(\"react\").ReactEventHandler; onLoadStart?: import(\"react\").ReactEventHandler; onLoadStartCapture?: import(\"react\").ReactEventHandler; onLostPointerCapture?: import(\"react\").PointerEventHandler; onLostPointerCaptureCapture?: import(\"react\").PointerEventHandler; onMouseDown?: import(\"react\").MouseEventHandler; onMouseDownCapture?: import(\"react\").MouseEventHandler; onMouseEnter?: import(\"react\").MouseEventHandler; onMouseLeave?: import(\"react\").MouseEventHandler; onMouseMove?: import(\"react\").MouseEventHandler; onMouseMoveCapture?: import(\"react\").MouseEventHandler; onMouseOut?: import(\"react\").MouseEventHandler; onMouseOutCapture?: import(\"react\").MouseEventHandler; onMouseOver?: import(\"react\").MouseEventHandler; onMouseOverCapture?: import(\"react\").MouseEventHandler; onMouseUp?: import(\"react\").MouseEventHandler; onMouseUpCapture?: import(\"react\").MouseEventHandler; onPaste?: import(\"react\").ClipboardEventHandler; onPasteCapture?: import(\"react\").ClipboardEventHandler; onPause?: import(\"react\").ReactEventHandler; onPauseCapture?: import(\"react\").ReactEventHandler; onPlay?: import(\"react\").ReactEventHandler; onPlayCapture?: import(\"react\").ReactEventHandler; onPlaying?: import(\"react\").ReactEventHandler; onPlayingCapture?: import(\"react\").ReactEventHandler; onPointerCancel?: import(\"react\").PointerEventHandler; onPointerCancelCapture?: import(\"react\").PointerEventHandler; onPointerDown?: import(\"react\").PointerEventHandler; onPointerDownCapture?: import(\"react\").PointerEventHandler; onPointerEnter?: import(\"react\").PointerEventHandler; onPointerLeave?: import(\"react\").PointerEventHandler; onPointerMove?: import(\"react\").PointerEventHandler; onPointerMoveCapture?: import(\"react\").PointerEventHandler; onPointerOut?: import(\"react\").PointerEventHandler; onPointerOutCapture?: import(\"react\").PointerEventHandler; onPointerOver?: import(\"react\").PointerEventHandler; onPointerOverCapture?: import(\"react\").PointerEventHandler; onPointerUp?: import(\"react\").PointerEventHandler; onPointerUpCapture?: import(\"react\").PointerEventHandler; onProgress?: import(\"react\").ReactEventHandler; onProgressCapture?: import(\"react\").ReactEventHandler; onRateChange?: import(\"react\").ReactEventHandler; onRateChangeCapture?: import(\"react\").ReactEventHandler; onReset?: import(\"react\").ReactEventHandler; onResetCapture?: import(\"react\").ReactEventHandler; onScroll?: import(\"react\").UIEventHandler; onScrollCapture?: import(\"react\").UIEventHandler; onScrollEnd?: import(\"react\").UIEventHandler; onScrollEndCapture?: import(\"react\").UIEventHandler; onSeeked?: import(\"react\").ReactEventHandler; onSeekedCapture?: import(\"react\").ReactEventHandler; onSeeking?: import(\"react\").ReactEventHandler; onSeekingCapture?: import(\"react\").ReactEventHandler; onSelect?: import(\"react\").ReactEventHandler; onSelectCapture?: import(\"react\").ReactEventHandler; onStalled?: import(\"react\").ReactEventHandler; onStalledCapture?: import(\"react\").ReactEventHandler; onSubmit?: import(\"react\").SubmitEventHandler; onSubmitCapture?: import(\"react\").SubmitEventHandler; onSuspend?: import(\"react\").ReactEventHandler; onSuspendCapture?: import(\"react\").ReactEventHandler; onTimeUpdate?: import(\"react\").ReactEventHandler; onTimeUpdateCapture?: import(\"react\").ReactEventHandler; onToggle?: import(\"react\").ToggleEventHandler; onTouchCancel?: import(\"react\").TouchEventHandler; onTouchCancelCapture?: import(\"react\").TouchEventHandler; onTouchEnd?: import(\"react\").TouchEventHandler; onTouchEndCapture?: import(\"react\").TouchEventHandler; onTouchMove?: import(\"react\").TouchEventHandler; onTouchMoveCapture?: import(\"react\").TouchEventHandler; onTouchStart?: import(\"react\").TouchEventHandler; onTouchStartCapture?: import(\"react\").TouchEventHandler; onTransitionCancel?: import(\"react\").TransitionEventHandler; onTransitionCancelCapture?: import(\"react\").TransitionEventHandler; onTransitionEnd?: import(\"react\").TransitionEventHandler; onTransitionEndCapture?: import(\"react\").TransitionEventHandler; onTransitionRun?: import(\"react\").TransitionEventHandler; onTransitionRunCapture?: import(\"react\").TransitionEventHandler; onTransitionStart?: import(\"react\").TransitionEventHandler; onTransitionStartCapture?: import(\"react\").TransitionEventHandler; onVolumeChange?: import(\"react\").ReactEventHandler; onVolumeChangeCapture?: import(\"react\").ReactEventHandler; onWaiting?: import(\"react\").ReactEventHandler; onWaitingCapture?: import(\"react\").ReactEventHandler; onWheel?: import(\"react\").WheelEventHandler; onWheelCapture?: import(\"react\").WheelEventHandler; part?: string; pattern?: string; placeholder?: string; popover?: \"\" | \"auto\" | \"manual\" | \"hint\"; popoverTarget?: string; popoverTargetAction?: \"toggle\" | \"show\" | \"hide\"; prefix?: string; property?: string; radioGroup?: string; readOnly?: boolean; ref?: Ref; rel?: string; required?: boolean; resource?: string; results?: number; rev?: string; role?: import(\"react\").AriaRole; security?: string; size?: number; slot?: string; spellCheck?: (boolean | \"true\" | \"false\"); src?: string; step?: string | number; style?: import(\"react\").CSSProperties; suppressContentEditableWarning?: boolean; suppressHydrationWarning?: boolean; tabIndex?: number; title?: string; translate?: \"yes\" | \"no\"; typeof?: string; unselectable?: \"off\" | \"on\"; value?: string | number | readonly string[]; vocab?: string; width?: string | number;", "SegmentedControl": "ariaControls?: string; ariaDescribedBy?: string; ariaLabelledBy?: string; className?: string; label?: string; layout?: \"fit\" | \"equal\"; onChange: (value: string) => void; options: readonly SegmentedControlOption[]; value: string;", "Select": "about?: string; accessKey?: string; \"aria-activedescendant\"?: string; \"aria-atomic\"?: (boolean | \"true\" | \"false\"); \"aria-autocomplete\"?: \"none\" | \"list\" | \"inline\" | \"both\"; \"aria-braillelabel\"?: string; \"aria-brailleroledescription\"?: string; \"aria-busy\"?: (boolean | \"true\" | \"false\"); \"aria-checked\"?: boolean | \"true\" | \"false\" | \"mixed\"; \"aria-colcount\"?: number; \"aria-colindex\"?: number; \"aria-colindextext\"?: string; \"aria-colspan\"?: number; \"aria-controls\"?: string; \"aria-current\"?: boolean | \"true\" | \"false\" | \"page\" | \"step\" | \"location\" | \"date\" | \"time\"; \"aria-describedby\"?: string; \"aria-description\"?: string; \"aria-details\"?: string; \"aria-disabled\"?: (boolean | \"true\" | \"false\"); \"aria-dropeffect\"?: \"none\" | \"link\" | \"copy\" | \"execute\" | \"move\" | \"popup\"; \"aria-errormessage\"?: string; \"aria-expanded\"?: (boolean | \"true\" | \"false\"); \"aria-flowto\"?: string; \"aria-grabbed\"?: (boolean | \"true\" | \"false\"); \"aria-haspopup\"?: boolean | \"true\" | \"false\" | \"dialog\" | \"grid\" | \"listbox\" | \"menu\" | \"tree\"; \"aria-hidden\"?: (boolean | \"true\" | \"false\"); \"aria-invalid\"?: boolean | \"true\" | \"false\" | \"grammar\" | \"spelling\"; \"aria-keyshortcuts\"?: string; \"aria-label\"?: string; \"aria-labelledby\"?: string; \"aria-level\"?: number; \"aria-live\"?: \"off\" | \"assertive\" | \"polite\"; \"aria-modal\"?: (boolean | \"true\" | \"false\"); \"aria-multiline\"?: (boolean | \"true\" | \"false\"); \"aria-multiselectable\"?: (boolean | \"true\" | \"false\"); \"aria-orientation\"?: \"horizontal\" | \"vertical\"; \"aria-owns\"?: string; \"aria-placeholder\"?: string; \"aria-posinset\"?: number; \"aria-pressed\"?: boolean | \"true\" | \"false\" | \"mixed\"; \"aria-readonly\"?: (boolean | \"true\" | \"false\"); \"aria-relevant\"?: \"text\" | \"additions\" | \"additions removals\" | \"additions text\" | \"all\" | \"removals\" | \"removals additions\" | \"removals text\" | \"text additions\" | \"text removals\"; \"aria-required\"?: (boolean | \"true\" | \"false\"); \"aria-roledescription\"?: string; \"aria-rowcount\"?: number; \"aria-rowindex\"?: number; \"aria-rowindextext\"?: string; \"aria-rowspan\"?: number; \"aria-selected\"?: (boolean | \"true\" | \"false\"); \"aria-setsize\"?: number; \"aria-sort\"?: \"none\" | \"ascending\" | \"descending\" | \"other\"; \"aria-valuemax\"?: number; \"aria-valuemin\"?: number; \"aria-valuenow\"?: number; \"aria-valuetext\"?: string; autoCapitalize?: \"off\" | \"none\" | \"on\" | \"sentences\" | \"words\" | \"characters\" | (string & {}); autoComplete?: string; autoCorrect?: string; autoFocus?: boolean; autoSave?: string; className?: string; color?: string; content?: string; contentEditable?: (boolean | \"true\" | \"false\") | \"inherit\" | \"plaintext-only\"; contextMenu?: string; dangerouslySetInnerHTML?: { __html: string | TrustedHTML; }; datatype?: string; defaultChecked?: boolean; defaultValue?: string | number | readonly string[]; dir?: string; disabled?: boolean; draggable?: (boolean | \"true\" | \"false\"); enterKeyHint?: \"enter\" | \"done\" | \"go\" | \"next\" | \"previous\" | \"search\" | \"send\"; error?: string; exportparts?: string; fieldClassName?: string; form?: string; hidden?: boolean; hideLabel?: boolean; hint?: string; id?: string; inert?: boolean; inlist?: any; inputMode?: \"none\" | \"search\" | \"text\" | \"tel\" | \"url\" | \"email\" | \"numeric\" | \"decimal\"; is?: string; itemID?: string; itemProp?: string; itemRef?: string; itemScope?: boolean; itemType?: string; label: string; lang?: string; multiple?: boolean; name?: string; nonce?: string; onAbort?: import(\"react\").ReactEventHandler; onAbortCapture?: import(\"react\").ReactEventHandler; onAnimationEnd?: import(\"react\").AnimationEventHandler; onAnimationEndCapture?: import(\"react\").AnimationEventHandler; onAnimationIteration?: import(\"react\").AnimationEventHandler; onAnimationIterationCapture?: import(\"react\").AnimationEventHandler; onAnimationStart?: import(\"react\").AnimationEventHandler; onAnimationStartCapture?: import(\"react\").AnimationEventHandler; onAuxClick?: import(\"react\").MouseEventHandler; onAuxClickCapture?: import(\"react\").MouseEventHandler; onBeforeInput?: import(\"react\").InputEventHandler; onBeforeInputCapture?: import(\"react\").InputEventHandler; onBeforeToggle?: import(\"react\").ToggleEventHandler; onBlur?: import(\"react\").FocusEventHandler; onBlurCapture?: import(\"react\").FocusEventHandler; onCanPlay?: import(\"react\").ReactEventHandler; onCanPlayCapture?: import(\"react\").ReactEventHandler; onCanPlayThrough?: import(\"react\").ReactEventHandler; onCanPlayThroughCapture?: import(\"react\").ReactEventHandler; onChange?: import(\"react\").ChangeEventHandler; onChangeCapture?: import(\"react\").ChangeEventHandler; onClick?: import(\"react\").MouseEventHandler; onClickCapture?: import(\"react\").MouseEventHandler; onCompositionEnd?: import(\"react\").CompositionEventHandler; onCompositionEndCapture?: import(\"react\").CompositionEventHandler; onCompositionStart?: import(\"react\").CompositionEventHandler; onCompositionStartCapture?: import(\"react\").CompositionEventHandler; onCompositionUpdate?: import(\"react\").CompositionEventHandler; onCompositionUpdateCapture?: import(\"react\").CompositionEventHandler; onContextMenu?: import(\"react\").MouseEventHandler; onContextMenuCapture?: import(\"react\").MouseEventHandler; onCopy?: import(\"react\").ClipboardEventHandler; onCopyCapture?: import(\"react\").ClipboardEventHandler; onCut?: import(\"react\").ClipboardEventHandler; onCutCapture?: import(\"react\").ClipboardEventHandler; onDoubleClick?: import(\"react\").MouseEventHandler; onDoubleClickCapture?: import(\"react\").MouseEventHandler; onDrag?: import(\"react\").DragEventHandler; onDragCapture?: import(\"react\").DragEventHandler; onDragEnd?: import(\"react\").DragEventHandler; onDragEndCapture?: import(\"react\").DragEventHandler; onDragEnter?: import(\"react\").DragEventHandler; onDragEnterCapture?: import(\"react\").DragEventHandler; onDragExit?: import(\"react\").DragEventHandler; onDragExitCapture?: import(\"react\").DragEventHandler; onDragLeave?: import(\"react\").DragEventHandler; onDragLeaveCapture?: import(\"react\").DragEventHandler; onDragOver?: import(\"react\").DragEventHandler; onDragOverCapture?: import(\"react\").DragEventHandler; onDragStart?: import(\"react\").DragEventHandler; onDragStartCapture?: import(\"react\").DragEventHandler; onDrop?: import(\"react\").DragEventHandler; onDropCapture?: import(\"react\").DragEventHandler; onDurationChange?: import(\"react\").ReactEventHandler; onDurationChangeCapture?: import(\"react\").ReactEventHandler; onEmptied?: import(\"react\").ReactEventHandler; onEmptiedCapture?: import(\"react\").ReactEventHandler; onEncrypted?: import(\"react\").ReactEventHandler; onEncryptedCapture?: import(\"react\").ReactEventHandler; onEnded?: import(\"react\").ReactEventHandler; onEndedCapture?: import(\"react\").ReactEventHandler; onError?: import(\"react\").ReactEventHandler; onErrorCapture?: import(\"react\").ReactEventHandler; onFocus?: import(\"react\").FocusEventHandler; onFocusCapture?: import(\"react\").FocusEventHandler; onGotPointerCapture?: import(\"react\").PointerEventHandler; onGotPointerCaptureCapture?: import(\"react\").PointerEventHandler; onInput?: import(\"react\").InputEventHandler; onInputCapture?: import(\"react\").InputEventHandler; onInvalid?: import(\"react\").ReactEventHandler; onInvalidCapture?: import(\"react\").ReactEventHandler; onKeyDown?: import(\"react\").KeyboardEventHandler; onKeyDownCapture?: import(\"react\").KeyboardEventHandler; onKeyPress?: import(\"react\").KeyboardEventHandler; onKeyPressCapture?: import(\"react\").KeyboardEventHandler; onKeyUp?: import(\"react\").KeyboardEventHandler; onKeyUpCapture?: import(\"react\").KeyboardEventHandler; onLoad?: import(\"react\").ReactEventHandler; onLoadCapture?: import(\"react\").ReactEventHandler; onLoadedData?: import(\"react\").ReactEventHandler; onLoadedDataCapture?: import(\"react\").ReactEventHandler; onLoadedMetadata?: import(\"react\").ReactEventHandler; onLoadedMetadataCapture?: import(\"react\").ReactEventHandler; onLoadStart?: import(\"react\").ReactEventHandler; onLoadStartCapture?: import(\"react\").ReactEventHandler; onLostPointerCapture?: import(\"react\").PointerEventHandler; onLostPointerCaptureCapture?: import(\"react\").PointerEventHandler; onMouseDown?: import(\"react\").MouseEventHandler; onMouseDownCapture?: import(\"react\").MouseEventHandler; onMouseEnter?: import(\"react\").MouseEventHandler; onMouseLeave?: import(\"react\").MouseEventHandler; onMouseMove?: import(\"react\").MouseEventHandler; onMouseMoveCapture?: import(\"react\").MouseEventHandler; onMouseOut?: import(\"react\").MouseEventHandler; onMouseOutCapture?: import(\"react\").MouseEventHandler; onMouseOver?: import(\"react\").MouseEventHandler; onMouseOverCapture?: import(\"react\").MouseEventHandler; onMouseUp?: import(\"react\").MouseEventHandler; onMouseUpCapture?: import(\"react\").MouseEventHandler; onPaste?: import(\"react\").ClipboardEventHandler; onPasteCapture?: import(\"react\").ClipboardEventHandler; onPause?: import(\"react\").ReactEventHandler; onPauseCapture?: import(\"react\").ReactEventHandler; onPlay?: import(\"react\").ReactEventHandler; onPlayCapture?: import(\"react\").ReactEventHandler; onPlaying?: import(\"react\").ReactEventHandler; onPlayingCapture?: import(\"react\").ReactEventHandler; onPointerCancel?: import(\"react\").PointerEventHandler; onPointerCancelCapture?: import(\"react\").PointerEventHandler; onPointerDown?: import(\"react\").PointerEventHandler; onPointerDownCapture?: import(\"react\").PointerEventHandler; onPointerEnter?: import(\"react\").PointerEventHandler; onPointerLeave?: import(\"react\").PointerEventHandler; onPointerMove?: import(\"react\").PointerEventHandler; onPointerMoveCapture?: import(\"react\").PointerEventHandler; onPointerOut?: import(\"react\").PointerEventHandler; onPointerOutCapture?: import(\"react\").PointerEventHandler; onPointerOver?: import(\"react\").PointerEventHandler; onPointerOverCapture?: import(\"react\").PointerEventHandler; onPointerUp?: import(\"react\").PointerEventHandler; onPointerUpCapture?: import(\"react\").PointerEventHandler; onProgress?: import(\"react\").ReactEventHandler; onProgressCapture?: import(\"react\").ReactEventHandler; onRateChange?: import(\"react\").ReactEventHandler; onRateChangeCapture?: import(\"react\").ReactEventHandler; onReset?: import(\"react\").ReactEventHandler; onResetCapture?: import(\"react\").ReactEventHandler; onScroll?: import(\"react\").UIEventHandler; onScrollCapture?: import(\"react\").UIEventHandler; onScrollEnd?: import(\"react\").UIEventHandler; onScrollEndCapture?: import(\"react\").UIEventHandler; onSeeked?: import(\"react\").ReactEventHandler; onSeekedCapture?: import(\"react\").ReactEventHandler; onSeeking?: import(\"react\").ReactEventHandler; onSeekingCapture?: import(\"react\").ReactEventHandler; onSelect?: import(\"react\").ReactEventHandler; onSelectCapture?: import(\"react\").ReactEventHandler; onStalled?: import(\"react\").ReactEventHandler; onStalledCapture?: import(\"react\").ReactEventHandler; onSubmit?: import(\"react\").SubmitEventHandler; onSubmitCapture?: import(\"react\").SubmitEventHandler; onSuspend?: import(\"react\").ReactEventHandler; onSuspendCapture?: import(\"react\").ReactEventHandler; onTimeUpdate?: import(\"react\").ReactEventHandler; onTimeUpdateCapture?: import(\"react\").ReactEventHandler; onToggle?: import(\"react\").ToggleEventHandler; onTouchCancel?: import(\"react\").TouchEventHandler; onTouchCancelCapture?: import(\"react\").TouchEventHandler; onTouchEnd?: import(\"react\").TouchEventHandler; onTouchEndCapture?: import(\"react\").TouchEventHandler; onTouchMove?: import(\"react\").TouchEventHandler; onTouchMoveCapture?: import(\"react\").TouchEventHandler; onTouchStart?: import(\"react\").TouchEventHandler; onTouchStartCapture?: import(\"react\").TouchEventHandler; onTransitionCancel?: import(\"react\").TransitionEventHandler; onTransitionCancelCapture?: import(\"react\").TransitionEventHandler; onTransitionEnd?: import(\"react\").TransitionEventHandler; onTransitionEndCapture?: import(\"react\").TransitionEventHandler; onTransitionRun?: import(\"react\").TransitionEventHandler; onTransitionRunCapture?: import(\"react\").TransitionEventHandler; onTransitionStart?: import(\"react\").TransitionEventHandler; onTransitionStartCapture?: import(\"react\").TransitionEventHandler; onVolumeChange?: import(\"react\").ReactEventHandler; onVolumeChangeCapture?: import(\"react\").ReactEventHandler; onWaiting?: import(\"react\").ReactEventHandler; onWaitingCapture?: import(\"react\").ReactEventHandler; onWheel?: import(\"react\").WheelEventHandler; onWheelCapture?: import(\"react\").WheelEventHandler; options: SelectOption[]; part?: string; placeholder?: string; popover?: \"\" | \"auto\" | \"manual\" | \"hint\"; popoverTarget?: string; popoverTargetAction?: \"toggle\" | \"show\" | \"hide\"; prefix?: string; property?: string; radioGroup?: string; ref?: Ref; rel?: string; required?: boolean; resource?: string; results?: number; rev?: string; role?: import(\"react\").AriaRole; security?: string; size?: number; slot?: string; spellCheck?: (boolean | \"true\" | \"false\"); style?: import(\"react\").CSSProperties; suppressContentEditableWarning?: boolean; suppressHydrationWarning?: boolean; tabIndex?: number; title?: string; translate?: \"yes\" | \"no\"; typeof?: string; unselectable?: \"off\" | \"on\"; value?: string | number | readonly string[]; vocab?: string;", - "Sheet": "ariaLabel?: string; bodyClassName?: string; bodyRef?: RefObject; children: ReactNode; closeButtonClassName?: string; closeLabel?: string; contentClassName?: string; contentStyle?: CSSProperties; description?: string; descriptionContent?: ReactNode; desktopBackdropClassName?: string; footer?: ReactNode; footerClassName?: string; headerActions?: ReactNode; headerClassName?: string; headerLeading?: ReactNode; id?: string; initialFocusRef?: RefObject; labelledBy?: string; mobileHeaderSafeArea?: SheetMobileHeaderSafeArea; mobilePlacement?: \"bottom\" | \"top\" | \"fullscreen\"; mobileSize?: SheetMobileSize; onBodyScroll?: UIEventHandler; onClose: () => void; open: boolean; placement?: \"default\" | \"left\"; portal?: boolean; resolveReturnFocusTarget?: (() => HTMLElement | null); returnFocusRef?: RefObject; testId?: string; title?: string; titleAccessory?: ReactNode; titleClassName?: string;", + "Sheet": "ariaLabel?: string; bodyClassName?: string; bodyRef?: RefObject; bodyTabIndex?: number; children: ReactNode; closeButtonClassName?: string; closeLabel?: string; contentClassName?: string; contentStyle?: CSSProperties; description?: string; descriptionContent?: ReactNode; desktopBackdropClassName?: string; footer?: ReactNode; footerClassName?: string; headerActions?: ReactNode; headerBottom?: ReactNode; headerClassName?: string; headerHidden?: boolean; headerLeading?: ReactNode; headerRef?: RefObject; id?: string; initialFocusRef?: RefObject; labelledBy?: string; mobileHeaderSafeArea?: SheetMobileHeaderSafeArea; mobilePlacement?: \"bottom\" | \"top\" | \"fullscreen\"; mobileSize?: SheetMobileSize; onBodyScroll?: UIEventHandler; onClose: () => void; open: boolean; placement?: \"default\" | \"left\"; portal?: boolean; resolveReturnFocusTarget?: (() => HTMLElement | null); returnFocusRef?: RefObject; testId?: string; title?: string; titleAccessory?: ReactNode; titleClassName?: string;", "Skeleton": "about?: string; accessKey?: string; animationDelay?: string; \"aria-activedescendant\"?: string; \"aria-atomic\"?: (boolean | \"true\" | \"false\"); \"aria-autocomplete\"?: \"none\" | \"list\" | \"inline\" | \"both\"; \"aria-braillelabel\"?: string; \"aria-brailleroledescription\"?: string; \"aria-busy\"?: (boolean | \"true\" | \"false\"); \"aria-checked\"?: boolean | \"true\" | \"false\" | \"mixed\"; \"aria-colcount\"?: number; \"aria-colindex\"?: number; \"aria-colindextext\"?: string; \"aria-colspan\"?: number; \"aria-controls\"?: string; \"aria-current\"?: boolean | \"true\" | \"false\" | \"page\" | \"step\" | \"location\" | \"date\" | \"time\"; \"aria-describedby\"?: string; \"aria-description\"?: string; \"aria-details\"?: string; \"aria-disabled\"?: (boolean | \"true\" | \"false\"); \"aria-dropeffect\"?: \"none\" | \"link\" | \"copy\" | \"execute\" | \"move\" | \"popup\"; \"aria-errormessage\"?: string; \"aria-expanded\"?: (boolean | \"true\" | \"false\"); \"aria-flowto\"?: string; \"aria-grabbed\"?: (boolean | \"true\" | \"false\"); \"aria-haspopup\"?: boolean | \"true\" | \"false\" | \"dialog\" | \"grid\" | \"listbox\" | \"menu\" | \"tree\"; \"aria-hidden\"?: (boolean | \"true\" | \"false\"); \"aria-invalid\"?: boolean | \"true\" | \"false\" | \"grammar\" | \"spelling\"; \"aria-keyshortcuts\"?: string; \"aria-label\"?: string; \"aria-labelledby\"?: string; \"aria-level\"?: number; \"aria-live\"?: \"off\" | \"assertive\" | \"polite\"; \"aria-modal\"?: (boolean | \"true\" | \"false\"); \"aria-multiline\"?: (boolean | \"true\" | \"false\"); \"aria-multiselectable\"?: (boolean | \"true\" | \"false\"); \"aria-orientation\"?: \"horizontal\" | \"vertical\"; \"aria-owns\"?: string; \"aria-placeholder\"?: string; \"aria-posinset\"?: number; \"aria-pressed\"?: boolean | \"true\" | \"false\" | \"mixed\"; \"aria-readonly\"?: (boolean | \"true\" | \"false\"); \"aria-relevant\"?: \"text\" | \"additions\" | \"additions removals\" | \"additions text\" | \"all\" | \"removals\" | \"removals additions\" | \"removals text\" | \"text additions\" | \"text removals\"; \"aria-required\"?: (boolean | \"true\" | \"false\"); \"aria-roledescription\"?: string; \"aria-rowcount\"?: number; \"aria-rowindex\"?: number; \"aria-rowindextext\"?: string; \"aria-rowspan\"?: number; \"aria-selected\"?: (boolean | \"true\" | \"false\"); \"aria-setsize\"?: number; \"aria-sort\"?: \"none\" | \"ascending\" | \"descending\" | \"other\"; \"aria-valuemax\"?: number; \"aria-valuemin\"?: number; \"aria-valuenow\"?: number; \"aria-valuetext\"?: string; autoCapitalize?: \"off\" | \"none\" | \"on\" | \"sentences\" | \"words\" | \"characters\" | (string & {}); autoCorrect?: string; autoFocus?: boolean; autoSave?: string; children?: ReactNode; className?: string; color?: string; content?: string; contentEditable?: (boolean | \"true\" | \"false\") | \"inherit\" | \"plaintext-only\"; contextMenu?: string; dangerouslySetInnerHTML?: { __html: string | TrustedHTML; }; datatype?: string; defaultChecked?: boolean; defaultValue?: string | number | readonly string[]; dir?: string; draggable?: (boolean | \"true\" | \"false\"); enterKeyHint?: \"enter\" | \"done\" | \"go\" | \"next\" | \"previous\" | \"search\" | \"send\"; exportparts?: string; hidden?: boolean; id?: string; inert?: boolean; inlist?: any; inputMode?: \"none\" | \"search\" | \"text\" | \"tel\" | \"url\" | \"email\" | \"numeric\" | \"decimal\"; is?: string; itemID?: string; itemProp?: string; itemRef?: string; itemScope?: boolean; itemType?: string; lang?: string; nonce?: string; onAbort?: import(\"react\").ReactEventHandler; onAbortCapture?: import(\"react\").ReactEventHandler; onAnimationEnd?: import(\"react\").AnimationEventHandler; onAnimationEndCapture?: import(\"react\").AnimationEventHandler; onAnimationIteration?: import(\"react\").AnimationEventHandler; onAnimationIterationCapture?: import(\"react\").AnimationEventHandler; onAnimationStart?: import(\"react\").AnimationEventHandler; onAnimationStartCapture?: import(\"react\").AnimationEventHandler; onAuxClick?: import(\"react\").MouseEventHandler; onAuxClickCapture?: import(\"react\").MouseEventHandler; onBeforeInput?: import(\"react\").InputEventHandler; onBeforeInputCapture?: import(\"react\").InputEventHandler; onBeforeToggle?: import(\"react\").ToggleEventHandler; onBlur?: import(\"react\").FocusEventHandler; onBlurCapture?: import(\"react\").FocusEventHandler; onCanPlay?: import(\"react\").ReactEventHandler; onCanPlayCapture?: import(\"react\").ReactEventHandler; onCanPlayThrough?: import(\"react\").ReactEventHandler; onCanPlayThroughCapture?: import(\"react\").ReactEventHandler; onChange?: import(\"react\").ChangeEventHandler; onChangeCapture?: import(\"react\").ChangeEventHandler; onClick?: import(\"react\").MouseEventHandler; onClickCapture?: import(\"react\").MouseEventHandler; onCompositionEnd?: import(\"react\").CompositionEventHandler; onCompositionEndCapture?: import(\"react\").CompositionEventHandler; onCompositionStart?: import(\"react\").CompositionEventHandler; onCompositionStartCapture?: import(\"react\").CompositionEventHandler; onCompositionUpdate?: import(\"react\").CompositionEventHandler; onCompositionUpdateCapture?: import(\"react\").CompositionEventHandler; onContextMenu?: import(\"react\").MouseEventHandler; onContextMenuCapture?: import(\"react\").MouseEventHandler; onCopy?: import(\"react\").ClipboardEventHandler; onCopyCapture?: import(\"react\").ClipboardEventHandler; onCut?: import(\"react\").ClipboardEventHandler; onCutCapture?: import(\"react\").ClipboardEventHandler; onDoubleClick?: import(\"react\").MouseEventHandler; onDoubleClickCapture?: import(\"react\").MouseEventHandler; onDrag?: import(\"react\").DragEventHandler; onDragCapture?: import(\"react\").DragEventHandler; onDragEnd?: import(\"react\").DragEventHandler; onDragEndCapture?: import(\"react\").DragEventHandler; onDragEnter?: import(\"react\").DragEventHandler; onDragEnterCapture?: import(\"react\").DragEventHandler; onDragExit?: import(\"react\").DragEventHandler; onDragExitCapture?: import(\"react\").DragEventHandler; onDragLeave?: import(\"react\").DragEventHandler; onDragLeaveCapture?: import(\"react\").DragEventHandler; onDragOver?: import(\"react\").DragEventHandler; onDragOverCapture?: import(\"react\").DragEventHandler; onDragStart?: import(\"react\").DragEventHandler; onDragStartCapture?: import(\"react\").DragEventHandler; onDrop?: import(\"react\").DragEventHandler; onDropCapture?: import(\"react\").DragEventHandler; onDurationChange?: import(\"react\").ReactEventHandler; onDurationChangeCapture?: import(\"react\").ReactEventHandler; onEmptied?: import(\"react\").ReactEventHandler; onEmptiedCapture?: import(\"react\").ReactEventHandler; onEncrypted?: import(\"react\").ReactEventHandler; onEncryptedCapture?: import(\"react\").ReactEventHandler; onEnded?: import(\"react\").ReactEventHandler; onEndedCapture?: import(\"react\").ReactEventHandler; onError?: import(\"react\").ReactEventHandler; onErrorCapture?: import(\"react\").ReactEventHandler; onFocus?: import(\"react\").FocusEventHandler; onFocusCapture?: import(\"react\").FocusEventHandler; onGotPointerCapture?: import(\"react\").PointerEventHandler; onGotPointerCaptureCapture?: import(\"react\").PointerEventHandler; onInput?: import(\"react\").InputEventHandler; onInputCapture?: import(\"react\").InputEventHandler; onInvalid?: import(\"react\").ReactEventHandler; onInvalidCapture?: import(\"react\").ReactEventHandler; onKeyDown?: import(\"react\").KeyboardEventHandler; onKeyDownCapture?: import(\"react\").KeyboardEventHandler; onKeyPress?: import(\"react\").KeyboardEventHandler; onKeyPressCapture?: import(\"react\").KeyboardEventHandler; onKeyUp?: import(\"react\").KeyboardEventHandler; onKeyUpCapture?: import(\"react\").KeyboardEventHandler; onLoad?: import(\"react\").ReactEventHandler; onLoadCapture?: import(\"react\").ReactEventHandler; onLoadedData?: import(\"react\").ReactEventHandler; onLoadedDataCapture?: import(\"react\").ReactEventHandler; onLoadedMetadata?: import(\"react\").ReactEventHandler; onLoadedMetadataCapture?: import(\"react\").ReactEventHandler; onLoadStart?: import(\"react\").ReactEventHandler; onLoadStartCapture?: import(\"react\").ReactEventHandler; onLostPointerCapture?: import(\"react\").PointerEventHandler; onLostPointerCaptureCapture?: import(\"react\").PointerEventHandler; onMouseDown?: import(\"react\").MouseEventHandler; onMouseDownCapture?: import(\"react\").MouseEventHandler; onMouseEnter?: import(\"react\").MouseEventHandler; onMouseLeave?: import(\"react\").MouseEventHandler; onMouseMove?: import(\"react\").MouseEventHandler; onMouseMoveCapture?: import(\"react\").MouseEventHandler; onMouseOut?: import(\"react\").MouseEventHandler; onMouseOutCapture?: import(\"react\").MouseEventHandler; onMouseOver?: import(\"react\").MouseEventHandler; onMouseOverCapture?: import(\"react\").MouseEventHandler; onMouseUp?: import(\"react\").MouseEventHandler; onMouseUpCapture?: import(\"react\").MouseEventHandler; onPaste?: import(\"react\").ClipboardEventHandler; onPasteCapture?: import(\"react\").ClipboardEventHandler; onPause?: import(\"react\").ReactEventHandler; onPauseCapture?: import(\"react\").ReactEventHandler; onPlay?: import(\"react\").ReactEventHandler; onPlayCapture?: import(\"react\").ReactEventHandler; onPlaying?: import(\"react\").ReactEventHandler; onPlayingCapture?: import(\"react\").ReactEventHandler; onPointerCancel?: import(\"react\").PointerEventHandler; onPointerCancelCapture?: import(\"react\").PointerEventHandler; onPointerDown?: import(\"react\").PointerEventHandler; onPointerDownCapture?: import(\"react\").PointerEventHandler; onPointerEnter?: import(\"react\").PointerEventHandler; onPointerLeave?: import(\"react\").PointerEventHandler; onPointerMove?: import(\"react\").PointerEventHandler; onPointerMoveCapture?: import(\"react\").PointerEventHandler; onPointerOut?: import(\"react\").PointerEventHandler; onPointerOutCapture?: import(\"react\").PointerEventHandler; onPointerOver?: import(\"react\").PointerEventHandler; onPointerOverCapture?: import(\"react\").PointerEventHandler; onPointerUp?: import(\"react\").PointerEventHandler; onPointerUpCapture?: import(\"react\").PointerEventHandler; onProgress?: import(\"react\").ReactEventHandler; onProgressCapture?: import(\"react\").ReactEventHandler; onRateChange?: import(\"react\").ReactEventHandler; onRateChangeCapture?: import(\"react\").ReactEventHandler; onReset?: import(\"react\").ReactEventHandler; onResetCapture?: import(\"react\").ReactEventHandler; onScroll?: import(\"react\").UIEventHandler; onScrollCapture?: import(\"react\").UIEventHandler; onScrollEnd?: import(\"react\").UIEventHandler; onScrollEndCapture?: import(\"react\").UIEventHandler; onSeeked?: import(\"react\").ReactEventHandler; onSeekedCapture?: import(\"react\").ReactEventHandler; onSeeking?: import(\"react\").ReactEventHandler; onSeekingCapture?: import(\"react\").ReactEventHandler; onSelect?: import(\"react\").ReactEventHandler; onSelectCapture?: import(\"react\").ReactEventHandler; onStalled?: import(\"react\").ReactEventHandler; onStalledCapture?: import(\"react\").ReactEventHandler; onSubmit?: import(\"react\").SubmitEventHandler; onSubmitCapture?: import(\"react\").SubmitEventHandler; onSuspend?: import(\"react\").ReactEventHandler; onSuspendCapture?: import(\"react\").ReactEventHandler; onTimeUpdate?: import(\"react\").ReactEventHandler; onTimeUpdateCapture?: import(\"react\").ReactEventHandler; onToggle?: import(\"react\").ToggleEventHandler; onTouchCancel?: import(\"react\").TouchEventHandler; onTouchCancelCapture?: import(\"react\").TouchEventHandler; onTouchEnd?: import(\"react\").TouchEventHandler; onTouchEndCapture?: import(\"react\").TouchEventHandler; onTouchMove?: import(\"react\").TouchEventHandler; onTouchMoveCapture?: import(\"react\").TouchEventHandler; onTouchStart?: import(\"react\").TouchEventHandler; onTouchStartCapture?: import(\"react\").TouchEventHandler; onTransitionCancel?: import(\"react\").TransitionEventHandler; onTransitionCancelCapture?: import(\"react\").TransitionEventHandler; onTransitionEnd?: import(\"react\").TransitionEventHandler; onTransitionEndCapture?: import(\"react\").TransitionEventHandler; onTransitionRun?: import(\"react\").TransitionEventHandler; onTransitionRunCapture?: import(\"react\").TransitionEventHandler; onTransitionStart?: import(\"react\").TransitionEventHandler; onTransitionStartCapture?: import(\"react\").TransitionEventHandler; onVolumeChange?: import(\"react\").ReactEventHandler; onVolumeChangeCapture?: import(\"react\").ReactEventHandler; onWaiting?: import(\"react\").ReactEventHandler; onWaitingCapture?: import(\"react\").ReactEventHandler; onWheel?: import(\"react\").WheelEventHandler; onWheelCapture?: import(\"react\").WheelEventHandler; part?: string; popover?: \"\" | \"auto\" | \"manual\" | \"hint\"; popoverTarget?: string; popoverTargetAction?: \"toggle\" | \"show\" | \"hide\"; prefix?: string; property?: string; radioGroup?: string; rel?: string; resource?: string; results?: number; rev?: string; role?: import(\"react\").AriaRole; security?: string; slot?: string; spellCheck?: (boolean | \"true\" | \"false\"); style?: import(\"react\").CSSProperties; suppressContentEditableWarning?: boolean; suppressHydrationWarning?: boolean; tabIndex?: number; title?: string; translate?: \"yes\" | \"no\"; typeof?: string; unselectable?: \"off\" | \"on\"; vocab?: string;", "SourceDesignationBadge": "className?: string; metadata?: SourceMetadataInput;", "SourceProvenance": "metadata?: SourceMetadataInput;", diff --git a/src/components/clinical-dashboard/guide-dialog.tsx b/src/components/clinical-dashboard/guide-dialog.tsx index 51450c45e1..b940a493e4 100644 --- a/src/components/clinical-dashboard/guide-dialog.tsx +++ b/src/components/clinical-dashboard/guide-dialog.tsx @@ -883,6 +883,7 @@ function GuideDialogSession({ onClose }: { onClose: () => void }) { contentClassName="relative font-sans sm:max-w-none lg:h-[min(56rem,calc(100dvh-3rem))] lg:max-w-[min(94vw,90rem)]" bodyClassName="p-0 sm:p-0" bodyRef={scrollBodyRef} + bodyTabIndex={0} onBodyScroll={handleBodyScroll} headerRef={headerRef} headerHidden={chromeHidden} diff --git a/src/components/ui/sheet.tsx b/src/components/ui/sheet.tsx index a5a06044fe..aafc1027a3 100644 --- a/src/components/ui/sheet.tsx +++ b/src/components/ui/sheet.tsx @@ -62,6 +62,13 @@ type SheetBaseProps = { contentStyle?: CSSProperties; bodyClassName?: string; bodyRef?: RefObject; + /** + * Makes the scrollable body reachable by keyboard when its content may not + * always include a focusable descendant (WCAG 2.1.1 / axe + * scrollable-region-focusable). Omit for bodies that always contain + * interactive content. + */ + bodyTabIndex?: number; onBodyScroll?: UIEventHandler; footerClassName?: string; placement?: "default" | "left"; @@ -121,6 +128,7 @@ export function Sheet({ contentStyle, bodyClassName, bodyRef, + bodyTabIndex, onBodyScroll, footerClassName, placement = "default", @@ -526,6 +534,7 @@ export function Sheet({
{children} diff --git a/tests/guide-centre.dom.test.tsx b/tests/guide-centre.dom.test.tsx index 93c318c10d..28392e8858 100644 --- a/tests/guide-centre.dom.test.tsx +++ b/tests/guide-centre.dom.test.tsx @@ -56,6 +56,10 @@ describe("Clinical KB Guide Centre", () => { expect(within(dialog).getByLabelText("Neutral illustrative answer")).toHaveTextContent( "place its citation beside the words it supports", ); + // Mount schedules an rAF-deferred hide-state reset (use-hide-on-scroll's + // resetKey effect); flush it before the first scroll so it cannot fire + // after and revert the scroll-triggered hide mid-assertion. + await new Promise((resolve) => window.requestAnimationFrame(() => resolve())); const scrollBody = dialog.querySelector(".polished-scroll"); const footer = dialog.querySelector("[data-guide-mobile-footer]"); @@ -247,4 +251,4 @@ describe("Clinical KB Guide Centre", () => { fireEvent.click(within(dialog).getByRole("button", { name: "Close guide" })); expect(onClose).toHaveBeenCalledTimes(1); }); -}); \ No newline at end of file +}); diff --git a/tests/ui-smoke.spec.ts b/tests/ui-smoke.spec.ts index 60dd158652..d707b2f58c 100644 --- a/tests/ui-smoke.spec.ts +++ b/tests/ui-smoke.spec.ts @@ -5403,19 +5403,25 @@ test.describe("Clinical KB UI smoke coverage", () => { const dialog = await openGuide(page); const guideScrollBody = dialog.locator(".polished-scroll"); const mobileFooter = dialog.locator("[data-guide-mobile-footer]"); + const mobileHeader = dialog.locator('[data-sheet-header="true"]'); await guideScrollBody.evaluate((element) => { - element.scrollTop = 80; + element.scrollTop = 140; element.dispatchEvent(new Event("scroll", { bubbles: true })); }); await expect(mobileFooter).toHaveAttribute("aria-hidden", "true"); await expect(mobileFooter).toHaveAttribute("inert", ""); + await expect(mobileHeader).toHaveAttribute("aria-hidden", "true"); + await expect(mobileHeader).toHaveAttribute("inert", ""); - // The hidden mobile footer must not be reachable by keyboard tabbing. - await dialog.getByRole("button", { name: "Close guide" }).focus(); + // The hidden mobile header and footer must not be reachable by keyboard + // tabbing. Close guide now lives in the header, which is itself inert + // while hidden, so start from a content control instead. + await dialog.getByRole("button", { name: "Ask a better question" }).focus(); const tabStopCount = await dialog.locator('button, input, [href], [tabindex]:not([tabindex="-1"])').count(); for (let tabIndex = 0; tabIndex <= tabStopCount; tabIndex += 1) { await page.keyboard.press("Tab"); await expect.poll(() => mobileFooter.evaluate((element) => element.contains(document.activeElement))).toBe(false); + await expect.poll(() => mobileHeader.evaluate((element) => element.contains(document.activeElement))).toBe(false); } await guideScrollBody.evaluate((element) => { From 846b8414f483b5de4bef4c2748837e929e832f55 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 17 Aug 2026 08:37:40 +0000 Subject: [PATCH 9/9] docs: record branch review ledger entry for PR 2007 CI fix Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01HR7cnmJRWZyg2Q9MFV1SCs --- ...62f6ba5bf9e1447b570eb90fa0026059959a4ca253be147df3a.record.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 docs/branch-review-records/d9883c1c107d462f6ba5bf9e1447b570eb90fa0026059959a4ca253be147df3a.record.md diff --git a/docs/branch-review-records/d9883c1c107d462f6ba5bf9e1447b570eb90fa0026059959a4ca253be147df3a.record.md b/docs/branch-review-records/d9883c1c107d462f6ba5bf9e1447b570eb90fa0026059959a4ca253be147df3a.record.md new file mode 100644 index 0000000000..f7059f4c02 --- /dev/null +++ b/docs/branch-review-records/d9883c1c107d462f6ba5bf9e1447b570eb90fa0026059959a4ca253be147df3a.record.md @@ -0,0 +1 @@ +| 2026-08-17 | codex/guide-search-chrome-20260815 | 7365c7f36751b15f155b5228bdce075d9c4e09ec | PR #2007 CI fix: prettier format, design-sync contract regen, guide-centre scroll-hide race, ui-smoke scroll threshold + a11y (bodyTabIndex) | Fixed 4 CI failures (Static PR checks, Unit coverage x2, Production UI) so PR is ready to merge once CI reruns | npx vitest run (design-sync-contract, design-sync-visual-exports, guide-centre.dom, guide-centre-design-contract.dom); npx eslint on touched files; npx prettier --check; local Playwright production build+run of tests/ui-smoke.spec.ts guide centre test (3 iterations to isolate/fix/verify) and tests/guide-centre-chrome.spec.ts (found unmatched by testMatch, noted not fixed) |