fix(tour): the guided tour says each step once and never drops focus (v0.18.2) - #323
Merged
Merged
Conversation
…(v0.18.2) Part of #308. Version 0.18.2. Measured on v0.18.1 before the change: the step popover is one dialog whose title and body change in place, the only live text was the `N / 6` position, so a screen reader heard `2 / 6` and nothing else from step 2 on; focus entered on the close control; pressing Back down to step 1 disabled the focused Back button and dropped focus to <body> inside the dialog; and a first-run tour ended by Done left focus on <body>. The contract, decided by Lumi on 2026-10-06 (docs/guided-tour.md §GT4): step 1 is said by the dialog's name (its `1 / 6` position and its title, both named by aria-labelledby, so the number is not lost) and description (its body, aria-describedby) when focus enters it, on Next. Every later step is said once by one hidden live region inside the popover (polite, atomic), written by the Next or Back press itself, as `N / 6. title. body`; it starts empty, so step 1 is not said twice, and a re-render that is not a step change (a language switch) writes nothing. The visible `N / 6` is no longer live and the title never was. The sentence is its own key, tour.nav.announce, in all 18 languages, with each language's own punctuation (the ideographic full stop in Japanese and Chinese, a space in Thai), not English joined in code. On Back to step 1, focus moves to Next before Back is disabled (disabled stays, not aria-disabled). Every exit (Done, Escape, the close control), first run or replay, lands on the Help button, the overflow button when the toolbar has folded Help into it, or More on a phone, skipping a target that is gone, hidden (visibility included: the overflow button at 1280 px is in the page with visibility: hidden), inert or disabled; only when none of them is usable, the last resort is the top bar's first usable menu button outside the palette, never a palette piece and never <body>. The Welcome card is described by its question; its buttons, order and first focus are unchanged. The phone tour has the same contract and the same layout. New e2e/tour-announcement.spec.ts (19 tests) records every text the tour's live regions come to hold and every focus loss to <body> from before the app boots. It pins the Welcome card's name and its aria-describedby question; step 1's dialog named `1 / 6` plus its title and described by its body, in Playwright's computation and in Chromium's own accessibility tree, with focus on Next and nothing live; steps 2 to 6 each said exactly once and the announcer as the tour's only live region; Back to step 1 leaving focus on Next; a language switch announcing nothing; and Done, Escape and the close control, first run and replay, at 1280 px, 760 px and 390 px, landing on Help, the overflow button or More, plus the fallback with Help hidden. Run against the code with the two focus fixes reverted, 9 of the 19 fail. Three release-note lines and the step sentence in 18 languages; the 16 other than English and Korean have not been reviewed by a native speaker. The English lines do not say "screen" (the pt-PT audit forbids it: the product has no screen concept). The per-language copy tests move their pinned counts by the four keys and declare the step sentence where it reads the same as English and Escape where each guard asks; the pt-PT audit's differing keys move from 269 to 270 and those outside the password keys from 241 to 242, under the unchanged bound of a quarter of the 970 non-password keys. The ICU argument total moves from 212 to 216 (two numbers and two catalog strings, classified by the checker itself). Docs: docs/guided-tour.md §GT4, §GT8, §GT9 and §GT10, CHANGELOG.md and README.md.
Deploying cozy-loop-studio with
|
| Latest commit: |
13f3745
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://78d96fc5.cozy-loop-studio.pages.dev |
| Branch Preview URL: | https://fix-tour-announcement.cozy-loop-studio.pages.dev |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of #308. Version 0.18.2: the guided tour says each step once, and focus is never lost.
What a person notices
1 / 6and the step title) and its description (the step text). Focus starts on Next.N / 6. title. text, when Next or Back reaches it. Focus stays on Next or Back.Before this change (measured on v0.18.1)
2 / 6was read: the title and text changed in place and the position was the only live text.How
src/components/GuidedTour.tsx: the popover is labelled by its position and title (aria-labelledby) and described by its body (aria-describedby); focus enters on Next (useDialogFocus'sinitialFocus).aria-live="polite",aria-atomic="true") is written by the Next or Back press itself, never by a render: it starts empty, so step 1 is not said twice, and a language switch mid-tour writes nothing. The visibleN / 6is no longer live.tour.nav.announce, in all 18 languages, with each language's own separators (。in Japanese and Chinese, a space in Thai, the full stop elsewhere), not English punctuation joined in code.disabled.visibilitycounts, because at 1280 px the overflow button is in the page withvisibility: hidden(measured: focusing it left focus on the page). Only when none is usable, the top bar's first usable menu button outside the palette.Tests
e2e/tour-announcement.spec.ts(19 tests). From before the app boots it records every text the tour's live regions come to hold and every focus loss to the page itself.aria-describedby, in Playwright's computation and in Chromium's own accessibility tree.1 / 6plus its title and described by its body, also in Chromium's tree; focus on Next; nothing written to the live region.Release, strings and docs
release:0.18.2, three lines dated 2026-10-06, and the step sentence, in 18 languages. The 16 languages other than English and Korean have not been reviewed by a native speaker.Escapewhere each guard asks. No bound is widened: the pt-PT audit's differing keys move from 269 to 270, and those outside the password keys from 241 to 242, under the unchanged quarter of the 970 non-password keys (242.5).docs/guided-tour.md§GT4 (the announcement and focus contract), §GT8, §GT9 and §GT10;CHANGELOG.md;README.md.Verification (local, at the head commit)
npx tsc -b, oxlint (39 warnings, the existing baseline), 3,107 unit tests and every check pass; the web, portable and PWA builds pass with the third-party notices unchanged.i18nspec): 689 of 689.mobileproject: 106 passed, 4 skipped by design (two desktop-only readouts incanvas-refresh-visual.spec.ts, two chromium-only cases inplayback-a11y-background.spec.ts). The new spec's phone cases run in the chromium project at 390 px.Before merging