From 6a2932fb5b816dee23ee155f427ff341ce8e406b Mon Sep 17 00:00:00 2001 From: Michael Falk Date: Wed, 17 Jun 2026 11:26:39 -0700 Subject: [PATCH] =?UTF-8?q?feat:=20a11y=20completion,=20AbortSignal=20for?= =?UTF-8?q?=20async=20sources,=20grouped=20options=20=E2=80=94=20v3.2.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tier 1 of the feature roadmap: - Accessibility: ARIA combobox/listbox pattern. Options get stable ids; active row gets aria-selected and is referenced by the input's aria-activedescendant; input gains aria-controls/aria-haspopup; a visually-hidden aria-live region announces result counts, "Searching…", and the no-matches/create state. - AbortSignal: async source ctx now carries a real `signal` (a newer search aborts the previous; remoteSource passes it to fetch; destroy() aborts too). Fixes the doc/code mismatch where `signal` was documented but never provided. - Grouped options: groupBy(option) fn or per-option `group` field render optgroup-style headings (.liveselect__group); results stably reordered. Includes 4 new jsdom tests (30 total), CSS for group headings, README sections (Grouped options, Accessibility) + options-table rows, a grouped-options demo in examples/vanilla.html, and CHANGELOG/version bump to 3.2.0. Co-Authored-By: Claude Opus 4.8 (1M context) --- CHANGELOG.md | 20 +++++++ README.md | 46 ++++++++++++++- dist/liveselect.css | 9 +++ dist/liveselect.js | 132 +++++++++++++++++++++++++++++++++++++----- examples/vanilla.html | 22 +++++++ package.json | 2 +- test/client.test.js | 80 ++++++++++++++++++++++++- 7 files changed, 295 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b865f77..dfd134f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,26 @@ All notable changes to this project are documented here. This project adheres to [Semantic Versioning](https://semver.org/). +## [3.2.0] - 2026-06-17 + +### Added +- **Accessibility (ARIA combobox/listbox pattern).** Options now get stable `id`s; + the active row carries `aria-selected` and is referenced by the input's + `aria-activedescendant`; the input gains `aria-controls` / `aria-haspopup`; and a + visually-hidden `aria-live="polite"` region announces result counts, “Searching…”, + and the no-matches/create state. Keyboard nav is now announced to screen readers. +- **AbortSignal for async sources.** The async `source` `ctx` now includes a real + `signal` (`{ scope, limit, query, signal }`). A newer search aborts the previous + one's signal, and the built-in `remoteSource` passes it to `fetch`, so stale + in-flight requests are cancelled rather than merely ignored. (`destroy()` also + aborts any in-flight request.) +- **Grouped options.** Pass a `groupBy(option) => string` function or a per-option + `group` field to render ``-style headings (`.liveselect__group`). + Results are stably reordered so same-group items sit together. + +### Changed +- `normalizeOption` output now includes a `group` field (`''` when absent). + ## [3.1.0] - 2026-06-17 ### Added diff --git a/README.md b/README.md index 1b1d755..e7be33b 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,7 @@ Node/Express, EJS templates, and Blaze**. - 🔁 **Drop-in `` in place; a hidden `` means it submits inside a plain `
` like a native control. - 🎨 **Fully themeable** — restyle with `--liveselect-*` CSS custom properties or target the BEM-ish classes; ships a light and dark theme. - 🧩 **Custom item templates** — render each result row _and_ the `[+ Add]` row however you like with `renderOption` / `renderCreate`; return a DOM node (XSS-safe) or an HTML string. See [Custom item templates](#custom-item-templates). +- ♿ **Accessible by default** — full ARIA combobox/listbox wiring (`aria-activedescendant`, `aria-selected`, live-region announcements) so keyboard nav is screen-reader friendly. Optional **grouped options** with ``-style headings. - 🔒 **Security-hardened server** — registry-gated collection access, field allow-listing, ReDoS-capped regex, scope filters, tenant isolation hook, prototype-pollution guards. - 📦 **Zero dependencies**, ~12 KB. Works as a `