fix: harden Therapy Compass recovery and error accessibility#800
fix: harden Therapy Compass recovery and error accessibility#800BigSimmo wants to merge 5 commits into
Conversation
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
Keep Retry focus during reload, guard the shared dataset cache against stale rejection handlers, and restore visible focus on error headings. Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
|
This pull request has been ignored for the connected project Preview Branches by Supabase. |
📝 WalkthroughWalkthroughError boundaries now move focus to their headings and use system color tokens. Therapy Compass adds retryable dataset loading, an error fallback with retry controls, and disables the unavailable favourites action. ChangesAccessibility and Therapy Compass recovery
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant TherapyCompassPage
participant TcProvider
participant useTherapyData
participant SharedDatasetCache
TherapyCompassPage->>TcProvider: invoke retryData
TcProvider->>useTherapyData: invoke retry
useTherapyData->>SharedDatasetCache: clear cache and start retry request
SharedDatasetCache-->>useTherapyData: return data or error
useTherapyData-->>TcProvider: update loading and error state
TcProvider-->>TherapyCompassPage: render retry state
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
31697fc to
ec42c40
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/components/route-error-boundary.tsx`:
- Line 62: Update the error heading’s focus styling in the route error boundary
to use focus-triggered utilities instead of focus-visible, ensuring the recovery
focus applied by useEffect always shows the outline. Preserve the existing
outline width, offset, and focus-ring color values.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 615b8417-e4ab-42ed-b04f-1c635639cc0c
📒 Files selected for processing (6)
src/app/global-error.tsxsrc/components/route-error-boundary.tsxsrc/components/therapy-compass/bindings.tsxsrc/components/therapy-compass/data/use-therapy-data.tssrc/components/therapy-compass/therapy-card.tsxsrc/components/therapy-compass/therapy-compass-page.tsx
| <h1 | ||
| ref={headingRef} | ||
| tabIndex={-1} | ||
| className="mt-4 text-lg font-semibold tracking-tight text-[color:var(--text-heading)] focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-[color:var(--focus-ring,Highlight)]" |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Map the component structure first, then read the relevant slice.
ast-grep outline src/components/route-error-boundary.tsx --view expanded || true
printf '\n--- file slice ---\n'
sed -n '1,180p' src/components/route-error-boundary.tsx | cat -nRepository: BigSimmo/Database
Length of output: 4976
🌐 Web query:
CSS :focus-visible script focus after pointer interaction heuristics MDN
💡 Result:
The:focus-visible pseudo-class applies to an element when it is focused and the browser's User Agent (UA) determines, through internal heuristics, that a visible focus indicator is necessary [1]. This allows developers to display focus styles only when they would be most helpful—primarily for keyboard users—while avoiding potentially distracting focus rings during pointer interactions [1][2][3]. Heuristics for:focus-visible The specific heuristics used by browsers are not defined normatively in the CSS specification, which grants UAs flexibility in implementation [4][5][6]. However, modern browser engines have converged on a common set of behaviors [2]: 1. Keyboard Interaction: If an element receives focus via a keyboard interaction (e.g., Tab key),:focus-visible will almost always match, as the user is clearly navigating by keyboard [1][2][3]. 2. Pointer Interaction: Generally, when an element is focused via a mouse click, touch, or other pointing device,:focus-visible does not match [1][3]. This prevents focus styles from "sticking" on elements like buttons after they are clicked, which can be confusing for users [7]. 3. Input Elements: Elements that require user input, such as text fields (e.g., or <textarea>), typically match:focus-visible regardless of how focus was received [1][2]. This is because it is essential for the user to know where their typed input will be placed [1][2]. Regarding the:focus-visible polyfill (WICG/focus-visible): Before widespread native support, a polyfill script was commonly used to achieve this behavior [8]. This script used its own set of heuristics to mimic native support [8][5]: - Keyboard Modality: It tracked whether the last interaction was a keyboard event (like Tab) and added a.focus-visible class accordingly [4][8]. - Focus Events: It would trigger focus visibility if an element that required keyboard interaction (like a text field) received focus [8]. - Limitations: Because the polyfill had to rely on events available to JavaScript, it could not perfectly replicate the internal, low-level browser heuristics, leading to slight variations in behavior compared to modern native implementations [8][5]. Today, developers are encouraged to use the native:focus-visible pseudo-class directly, as it is supported by all major browsers and integrates natively with the browser's own focus-tracking logic [1][2][8]. Top Results: [1][2][5][3]
Citations:
- 1: https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Selectors/:focus-visible
- 2: https://webkit.org/blog/12179/the-focus-indicated-pseudo-class-focus-visible/
- 3: https://www.w3.org/WAI/WCAG22/Techniques/css/C45
- 4: https://github.com/WICG/focus-visible/blob/HEAD/explainer.md
- 5: https://github.com/WICG/focus-visible/blob/main/explainer.md
- 6: [selectors] :focus-visible matching heuristic unclear for non-interactive elements with tabindex="-1" w3c/csswg-drafts#12127
- 7: https://css-tricks.com/focus-visible-and-backwards-compatibility/
- 8: https://github.com/WICG/focus-visible
🌐 Web query:
MDN :focus-visible keyboard modality pointer programmatic focus
💡 Result:
The:focus-visible pseudo-class is a CSS selector that matches an element only when the User Agent determines, via internal heuristics, that a focus indicator is necessary [1]. Its primary purpose is to distinguish between situations where a focus indicator is helpful (e.g., keyboard navigation) and where it might be considered obtrusive (e.g., clicking a button with a mouse) [1][2]. Regarding programmatic focus and modality: 1. Modality and Heuristics: Browsers use heuristics to determine the input modality [2]. Generally, if the user interacts via the keyboard,:focus-visible matches the focused element [1]. If the user interacts via a pointing device, it typically does not match on elements that do not require text input (like buttons) [1]. 2. Programmatic Focus (element.focus): When focus is moved programmatically, the behavior of:focus-visible depends on the context [3][4]. - Initial focus (e.g., page load or autofocus): Browsers typically trigger:focus-visible by default because there is no prior "modality" context [4]. - Focus transfer: If an element currently matches:focus-visible (e.g., the user is already navigating via keyboard), moving focus programmatically to a new element will often cause the new element to also match:focus-visible [3][4]. Conversely, if the element does not match, the new element typically will not [3][4]. 3. Forcing Visibility: Because browser heuristics for programmatic focus can sometimes lead to inconsistent results for developers, the focus method has been extended in many modern environments to accept an options object that includes a focusVisible property [5][6]. Example: element.focus({ focusVisible: true }); Setting focusVisible: true explicitly instructs the browser to show the focus indicator and ensures:focus-visible matches, regardless of the current inferred input modality [5][6].
Citations:
- 1: https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Selectors/:focus-visible
- 2: https://github.com/WICG/focus-visible/blob/HEAD/explainer.md
- 3: [selectors] :focus-visible matches on initial programmatic focus w3c/csswg-drafts#5885
- 4: [selectors] :focus-visible matches on initial programmatic focus w3c/csswg-drafts#5885
- 5: https://discourse.wicg.io/t/ability-to-explicitly-set-focus-visible-from-focus/5695/
- 6: https://stackoverflow.com/questions/79914412/focus-visible-not-triggered-on-parent-has-selector-when-focus-is-applied-pro
Use a focus style that always appears on the error heading.
Because this heading is focused in useEffect, focus-visible: can be skipped after pointer-driven failures. Switch these utilities to focus: or apply an explicit focused state so recovery focus is always visible.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/components/route-error-boundary.tsx` at line 62, Update the error
heading’s focus styling in the route error boundary to use focus-triggered
utilities instead of focus-visible, ensuring the recovery focus applied by
useEffect always shows the outline. Preserve the existing outline width, offset,
and focus-ring color values.
Summary
Verification
npm run verify:uievidence via hosted UI gates on predecessor heads.Risk and rollout
Clinical Governance Preflight
Clinical KB Database(sjrfecxgysukkwxsowpy)Summary by CodeRabbit
New Features
Bug Fixes