From 7132262303621b0ee35ac103e7c63144a9a0704e Mon Sep 17 00:00:00 2001 From: Michael Falk Date: Wed, 17 Jun 2026 11:37:17 -0700 Subject: [PATCH] =?UTF-8?q?feat:=20disabled=20options,=20required=20valida?= =?UTF-8?q?tion,=20+=20Tier=203=20polish=20=E2=80=94=20v3.3.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tier 2 (minus multi-select) plus all Tier 3 polish from the roadmap: - Disabled options: per-option `disabled: true` → non-selectable (dimmed, aria-disabled, skipped by keyboard nav, ignored on click/Enter). - Required validation: enforced via the Constraint Validation API on the visible input, so an empty required control blocks submit with a focusable, on-screen bubble. Makes enhance()'s required actually enforce (a display:none ` isn’t focusable. +- **Match highlighting.** `highlight: true` wraps the matched query substring in + each result’s label/sublabel with `` (built from + text nodes — still XSS-safe). Ignored for `renderOption` rows. +- **“Showing N of M” footer.** When results are capped by `limit`, a footer shows + the count. Array sources compute the total automatically; async sources can + return `{ items, total }`. Customize via `texts.more(shown, total)`. +- **Lifecycle events.** Bubbling `liveselect:open`, `liveselect:close`, and + `liveselect:search` ({ query }) CustomEvents, alongside `liveselect:change`. +- **Async result caching.** `cache: true` memoizes async results by + query+scope+limit so repeat queries skip the network. Cleared by + `setSource()` / `setScope()`. + +### Changed +- `normalizeOption` output now includes a `disabled` field (`false` when absent). + ## [3.2.0] - 2026-06-17 ### Added diff --git a/README.md b/README.md index e7be33b..48256e0 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ Node/Express, EJS templates, and Blaze**. - 🎨 **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. +- 🧰 **Polish where it counts** — real `required` form validation, disabled (non-selectable) options, match highlighting, a “Showing N of M” hint, async result caching, and `open`/`close`/`search` lifecycle events. - 🔒 **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 `