Skip to content

Upgrade catenary to 0.6.0; typeable dates, Tab-select boundaries, Run Query reason, audible toasts (#390)#394

Merged
drewda merged 6 commits into
mainfrom
catenary-0.5-a11y
Jun 10, 2026
Merged

Upgrade catenary to 0.6.0; typeable dates, Tab-select boundaries, Run Query reason, audible toasts (#390)#394
drewda merged 6 commits into
mainfrom
catenary-0.5-a11y

Conversation

@drewda

@drewda drewda commented Jun 10, 2026

Copy link
Copy Markdown
Member

Addresses the accessibility barriers in #390.

Summary

Upgrades @interline-io/catenary from 0.4.0 to 0.6.0 and completes the CALACT side of the accessibility barriers reported in #390. The catenary release carries the rebuilt datepicker (typeable input plus a calendar dialog button, replacing the screen-reader-inaccessible popup) and the rebuilt administrative boundary picker (ARIA 1.2 combobox where Tab selects the highlighted option), along with announced validation messages and live-region support for notifications. This PR removes the CALACT-side blockers that remained: the readonly props that made manual date entry impossible, the unexplained disabled state of the Run Query buttons, and toast notifications that screen readers never announced.

User-facing changes

Date entry (#390: "not possible to type in a date manually")

  • Dates can now be typed directly into the start/end date fields in the query panel and the Feed Archive modal (committed on Enter or when leaving the field; invalid text reverts and is announced).
  • The calendar opens from a dedicated, labeled button next to each date field; the button's name includes the currently selected date.
  • The end date's remove button is now visually attached to the date field as part of its addon group (catenary 0.6.0 addon slot) instead of floating beside it.

Administrative boundary selection (#390: "allow user to select an option using Tab or Enter key")

  • Tab now selects the highlighted boundary before moving on (Enter continues to work).
  • Selections and removals are announced ("Added ...", "Removed ..."), as are empty search results.

Run Query buttons (#390: "error message for why the Run Query button can't be pressed")

  • When the run buttons are disabled, the specific reason now appears below them (e.g. "Cannot run query: select at least one administrative boundary."), is announced when it appears or clears, and is attached to both buttons via aria-describedby so screen readers read it when focusing the disabled button.

Toast notifications

  • Toasts (query errors, confirmations) are now announced by screen readers; error toasts interrupt via role="alert". Previously all toasts were silent.

Boundary actions

  • "Show on map" and "Clear all" are now reachable and operable by keyboard (previously click-only). They moved out of the field label into a row above the picker; a tidier layout for the whole Geographic Bounds section is deferred to a follow-up PR.

Implementation details

Catenary 0.6.0 upgrade

  • package.json bump; no API changes required in CALACT beyond the removals below. The datepicker's left calendar icon moved onto the new toggle button.
  • end-date-field.vue moves the remove button into cat-datepicker's #addon slot and drops the cal-end-date-field-range flex wrapper, covering the query panel and Feed Archive modal via the shared component.
  • Removed readonly from the three cat-datepicker usages (query.vue, end-date-field.vue, feed-version-picker-modal.vue); it existed to force calendar-only entry, which is exactly what Urgent Accessibility Testing Barriers #390 reported as a barrier.

Run button reason

  • New queryBlockedReason computed mirrors the validQueryParams checks in priority order and renders into an always-present <p aria-live="polite"> below the buttons; both buttons reference it via a v-bind'd record (strictTemplates rejects undeclared attributes written directly on components).

Toast live region

  • useToastNotification's container is now created when the composable is first used (a live region must exist before content is inserted for announcements to fire) and is never removed; previously it was deleted when empty and recreated with its first toast, which screen readers miss. The container carries aria-live="polite"; danger toasts additionally carry role="alert" (an occasional double announcement in some screen readers is preferable to a missed error).
  • A proper cat-toast component in catenary (named dismiss button, pause-on-hover, per-variant roles) and migration of this composable are queued as a follow-up pair; the composable's existing TODO already points there.

Boundary actions and query form

  • The "Show on map" / "Clear all" boundary actions are now real (ghost-styled) cat-buttons in an actions row above the picker. The previous href-less anchors were keyboard-unreachable, and because they sat inside the field's label element, their text polluted the taginput's accessible name and clicks also triggered label activation.
  • The query controls are wrapped in a named form element (aria-label "Transit network query parameters"), giving screen reader users a landmark to jump to. All buttons inside are type=button and the widgets consume their own Enter keys, so there is no implicit submission; submit.prevent guards the rest.

Tests

  • New Playwright browser test (test/browser/query.test.ts) covering the disabled-state explanation: reason appears and is referenced via aria-describedby in administrative-boundary mode with no selection, and clears when resolved. Note the browser suite runs locally against the test database, not in CI.

User test plan

  • In the query panel, type a date (e.g. 2026-07-04) into Start date and press Enter; with VoiceOver, confirm "Date set to ..." is announced. Type invalid text and Tab away; confirm it reverts with an announcement.
  • Open the calendar with the button next to the date field; arrow around; press Escape; confirm focus returns to the button.
  • In Administrative boundaries, search, ArrowDown to highlight a boundary, press Tab; confirm it is selected and announced.
  • Clear the boundary selection while in adminBoundary mode; confirm "Cannot run query: select at least one administrative boundary." appears below the run buttons and is read when focusing the disabled Run Browse Query button.
  • Tab to "Show on map" / "Clear all" above the boundary picker and activate them with Enter.
  • Trigger a toast (e.g. a failed query) with VoiceOver running; confirm it is announced.
  • Check the Feed Archive modal dates work the same as the query panel.

Generated with Claude Code

drewda and others added 2 commits June 10, 2026 09:22
Bumps catenary to pick up the rebuilt datepicker (typeable input,
calendar dialog) and taginput (ARIA 1.2 combobox, Tab selects the
highlighted option), removes the readonly props that blocked manual
date entry in the query panel and Feed Archive modal, explains why the
run buttons are disabled (visible help text wired to both buttons via
aria-describedby, announced via a polite live region), and makes toast
notifications audible to screen readers (persistent live-region
container instead of one recreated per toast burst).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 10, 2026 16:30
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jun 10, 2026

Copy link
Copy Markdown

Deploying calact-network-analysis-tool with  Cloudflare Pages  Cloudflare Pages

Latest commit: 58c8eca
Status: ✅  Deploy successful!
Preview URL: https://a722e62c.calact-network-analysis-tool.pages.dev
Branch Preview URL: https://catenary-0-5-a11y.calact-network-analysis-tool.pages.dev

View logs

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR upgrades @interline-io/catenary to 0.5.0 and updates CALACT UI behavior to resolve the remaining accessibility blockers from #390 (typeable dates, boundary picker Tab-selection support, clearer “Run Query” disabled reasons, and screen-reader-announced toasts).

Changes:

  • Bump @interline-io/catenary from 0.4.0 → 0.5.0 (and lockfile updates).
  • Enable manual date entry by removing readonly from CALACT datepicker usages.
  • Improve accessibility feedback: persistent toast live region + “Run Query blocked reason” text wired via aria-describedby.

Reviewed changes

Copilot reviewed 5 out of 6 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
pnpm-lock.yaml Updates lockfile entries for catenary 0.5.0.
package.json Bumps @interline-io/catenary dependency to 0.5.0.
app/composables/useToastNotification.ts Makes the toast container a persistent polite live region; marks danger toasts as alerts.
app/components/cal/query.vue Adds an announced, always-rendered “blocked reason” and wires it to both Run buttons via aria-describedby.
app/components/cal/feed-version-picker-modal.vue Removes readonly on datepicker to allow typing.
app/components/cal/end-date-field.vue Removes readonly on datepicker (and contains a now-stale comment referencing catenary 0.4.0).
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported
Comments suppressed due to low confidence (1)

app/components/cal/end-date-field.vue:19

  • This inline comment is now outdated after upgrading @interline-io/catenary to 0.5.0; it still references “catenary 0.4.0”. Keeping version-specific wording here will drift again on the next upgrade—better to remove the version mention and describe the prop/attribute issue generically.
        :variant="invalid ? 'danger' : undefined"
      />
      <!-- camelCase keys in a v-bind object: matches the ariaLabel/title props
           (catenary 0.4.0) and avoids vue/attribute-hyphenation rewriting a
           camelCase attribute back to kebab (which vue-tsc won't map to the prop). -->

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread app/components/cal/query.vue
drewda and others added 4 commits June 10, 2026 10:28
Screen reader users can now jump directly to the query parameters via
landmark navigation. All buttons inside are type=button and the
datepicker/taginput consume their own Enter keys, so there is no
implicit submission; submit.prevent guards the residual cases.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The href-less anchors were not focusable (keyboard-unreachable) and
lived inside the field label element, so their text polluted the
taginput's accessible name and clicks also triggered label activation.
They are now ghost cat-buttons in an actions row above the picker.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Asserts the reason appears (and is referenced via aria-describedby)
when administrative-boundary mode has no selection, and clears when
the blocker resolves. Client-side state only; no query run needed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Catenary 0.6.0's addon slot lets the button join the picker's Bulma
addon group instead of floating beside it in a flex row; drops the
cal-end-date-field-range wrapper and its styles. Covers both the
query panel and the Feed Archive modal via the shared component.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@drewda drewda changed the title Upgrade catenary to 0.5.0; typeable dates, Tab-select boundaries, Run Query reason, audible toasts (#390) Upgrade catenary to 0.6.0; typeable dates, Tab-select boundaries, Run Query reason, audible toasts (#390) Jun 10, 2026
@drewda drewda merged commit 01d399b into main Jun 10, 2026
6 checks passed
@drewda drewda deleted the catenary-0.5-a11y branch June 10, 2026 21:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants