Commit Graph
5 Commits
Author SHA1 Message Date
stefan.tollkuehn a9b7fd11af Announce the suggestion list to screen readers
The invitee input had no combobox semantics: assistive
technology could not tell that the widget owns a listbox with
suggestions. Mark the input as role="combobox" with
aria-autocomplete="list" and an initial aria-expanded="false",
point aria-controls at the list and give the JS-built list a
matching id so the reference resolves.
2026-10-23 14:08:59 +02:00
stefan.tollkuehn 5bba3a93cd Align invitee separators with the server
The server splits the attendee input on whitespace, commas and
semicolons, but the search widget only treated commas and
semicolons as separators. Typing "a@x.com b" therefore sent the
whole string as the search query instead of "b", and picking a
contact dropped the whitespace-separated entry.

Split on /[\s;,]+/ in both fragment() and commit() so the
widget agrees with parseAttendees() on what an entry is.
2026-10-23 14:07:28 +02:00
stefan.tollkuehn e5432a0a38 Fix stale contact suggestions reopening
hide() did not invalidate in-flight search requests. Clearing
the input or picking a contact while a request was pending let
the old response re-render and pop the suggestion list back
open. Bump requestSeq in hide() so every dismissal retires
pending responses.

Add a Vitest + jsdom harness with black-box tests for the
invitee widget, covering the stale-response race both on
field clear and on contact pick.
2026-10-23 14:04:32 +02:00
stefan.tollkuehn e1a3fd12f0 fix indentation 2026-10-23 13:52:45 +02:00
stefan.tollkuehn cc1fd4e508 Add live contact search to invitee input
The static datalist only carried the first 50 address book
contacts, so typed fragments could not match anything beyond
that. A new read-only GET /contacts/search endpoint queries
the full address book per keystroke, and a small vanilla JS
combobox shows the results and replaces only the fragment
after the last separator, so comma-separated lists keep
working. The server-rendered datalist remains as the no-JS
fallback; the JS removes the list attribute at runtime so
the native popup does not double the custom one.
2026-10-22 18:50:46 +02:00