Accessibility: add Semantics support across the app #45

Open
opened 2026-08-26 12:31:18 +00:00 by ImBenji · 1 comment
Owner

Zero Semantics widgets exist anywhere in lib/ or packages/ (verified 2026-08-26), so the app is currently unusable with a screen reader and would fail an accessibility audit outright.

This has stopped being technical debt and become a commercial and legal blocker. UK transit authorities assess accessibility as part of supplier review, so any authority licensing conversation runs into it. Separately, the Public Sector Bodies Accessibility Regulations cover mobile apps, which means a branded passenger app built on this engine could not ship at all until it is addressed.

It is also the longest lead-time item on the board, because it touches every panel, dialog and control rather than one subsystem. That is the argument for starting it before it is needed rather than after someone asks.

Scope is at least the Blender-mode editor chrome, panels and dialogs, plus the garage_ui components (buttons, selects, text fields, menus, toasts). The canvas itself is a harder problem and probably wants a separate issue — a custom-painted map surface needs a deliberate semantics model rather than widget annotations.

Context in STRATEGY.md sections 6, 9 and 12.

Zero `Semantics` widgets exist anywhere in `lib/` or `packages/` (verified 2026-08-26), so the app is currently unusable with a screen reader and would fail an accessibility audit outright. This has stopped being technical debt and become a commercial and legal blocker. UK transit authorities assess accessibility as part of supplier review, so any authority licensing conversation runs into it. Separately, the Public Sector Bodies Accessibility Regulations cover mobile apps, which means a branded passenger app built on this engine could not ship at all until it is addressed. It is also the longest lead-time item on the board, because it touches every panel, dialog and control rather than one subsystem. That is the argument for starting it before it is needed rather than after someone asks. Scope is at least the Blender-mode editor chrome, panels and dialogs, plus the `garage_ui` components (buttons, selects, text fields, menus, toasts). The canvas itself is a harder problem and probably wants a separate issue — a custom-painted map surface needs a deliberate semantics model rather than widget annotations. Context in STRATEGY.md sections 6, 9 and 12.
ImBenji added the enhancementarea:ui/ux labels 2026-08-26 12:31:18 +00:00
ImBenji added this to the Arcs & Angles project 2026-08-26 12:31:18 +00:00
Author
Owner

Status correction - the opening line of this issue is now false. Re-counted 2026-09-05 during the roadmap audit.

"Zero Semantics widgets exist anywhere in lib/ or packages/" was true when this was written. There are now 53 Semantics( call sites across 24 files, covering both halves of the stated scope:

  • packages/garage_ui/: button, select, text_field, date_input, menu, toast, overlay, navigation, properties, selection_controls, color_input
    • app chrome and panels: explorer_panel, professional_mode_shell, blender_slots_list, blender_agent_panel, script_editor_panel, pane_dialog, panel_layout, settings_content, custom_fonts_dialog, window_controls, ana_link
    • the canvas floor: lib/pages/map/canvas/ui/canvas_semantics.dart, with test/canvas_semantics_test.dart and test/canvas_semantics_perf_test.dart
      Leaving this open rather than closing it, because "53 call sites exist" is not the same as "the scope in the body is complete" and nobody has audited coverage panel by panel or run it against a real screen reader. But the body should not keep telling a reader the number is zero.

The canvas remainder is correctly split out into #47, which is accurate as written.

One note on the perf caveat in #47: the semantics layer's cost has now been measured. canvas_semantics_perf_test.dart reports ~0.2ms/frame mid-pan on a 3000-station, 30-line map against a ~0.16ms baseline, because the settle debounce hands back the cached subtree and Flutter skips it on identity. Before the debounce the same sweep was 9.0ms/frame. So it is not the pan-cost risk that issue flagged.

Status correction - the opening line of this issue is now false. Re-counted 2026-09-05 during the roadmap audit. "Zero `Semantics` widgets exist anywhere in `lib/` or `packages/`" was true when this was written. There are now **53 `Semantics(` call sites across 24 files**, covering both halves of the stated scope: - `packages/garage_ui/`: button, select, text_field, date_input, menu, toast, overlay, navigation, properties, selection_controls, color_input - - app chrome and panels: explorer_panel, professional_mode_shell, blender_slots_list, blender_agent_panel, script_editor_panel, pane_dialog, panel_layout, settings_content, custom_fonts_dialog, window_controls, ana_link - - the canvas floor: `lib/pages/map/canvas/ui/canvas_semantics.dart`, with `test/canvas_semantics_test.dart` and `test/canvas_semantics_perf_test.dart` Leaving this open rather than closing it, because "53 call sites exist" is not the same as "the scope in the body is complete" and nobody has audited coverage panel by panel or run it against a real screen reader. But the body should not keep telling a reader the number is zero. The canvas remainder is correctly split out into #47, which is accurate as written. One note on the perf caveat in #47: the semantics layer's cost has now been measured. `canvas_semantics_perf_test.dart` reports ~0.2ms/frame mid-pan on a 3000-station, 30-line map against a ~0.16ms baseline, because the settle debounce hands back the cached subtree and Flutter skips it on identity. Before the debounce the same sweep was 9.0ms/frame. So it is not the pan-cost risk that issue flagged.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: IMBENJI.NET/Metro-Map-Maker#45