@keenmate/web-multiselect 2.1.0 → 2.2.0-rc02
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -9
- package/custom-elements.json +335 -26
- package/dist/index.d.ts +192 -14
- package/dist/multiselect.js +1417 -1212
- package/dist/multiselect.umd.js +12 -12
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/css/controls.css +6 -3
- package/src/css/options.css +49 -0
- package/src/css/variables.css +2 -0
- package/vscode.html-custom-data.json +27 -1
- package/web-types.json +68 -10
package/README.md
CHANGED
|
@@ -21,21 +21,27 @@ Reads `--base-*` variables from the page if [`@keenmate/theme-designer`](https:/
|
|
|
21
21
|
- Custom rendering callbacks for options, badges, and group headers.
|
|
22
22
|
- Form integration via standard hidden inputs (FormData-compatible).
|
|
23
23
|
|
|
24
|
-
## What's New in v2.
|
|
24
|
+
## What's New in v2.2.0-rc02
|
|
25
25
|
|
|
26
|
-
-
|
|
27
|
-
- **External controls no longer close the dropdown they just re-drove** — Driving an already-open panel from your *own* button — a repeat `open()`/`toggle()`, or a `scrollToIndex()`/`scrollToValue()`/`scrollToGroup()` command — used to let that click bubble to the component's outside-click listener and immediately re-close the panel (the "every second click closes it" symptom). `open()` armed a one-tick guard against exactly this but bailed early when already open, and the `scrollTo*` methods never armed it at all. The guard is now centralized in `armClickGuard()` and armed by `open()` before its early-return and by every `scrollTo*` entry point. Consumers who worked around this with `stopPropagation()` can drop it.
|
|
26
|
+
- **`custom-styles` attribute — style shadow-DOM internals with zero JavaScript** — The existing `customStylesCallback` was the only way to inject custom CSS into the component's shadow root, which locked out consumers who can't reach into script: static HTML pages, server-rendered markup, no-build sites. The new `custom-styles` attribute takes raw CSS as a string (`<web-multiselect custom-styles=".ms__badge { font-weight: bold; }">`) and injects it verbatim — selectors and all — into the same replaceable style slot at the top of the shadow root that the callback uses, so you can restyle badges, options, and your own custom-rendered content declaratively. It's reactive (changing or removing the attribute re-applies or clears the slot), mirrored by a `customStyles` property, and flows through the same dev-mode `--ms-*` lint. When both are set, `customStylesCallback` still wins — the attribute is the static fallback. Demonstrated no-JS on the Custom Rendering page (CR09) and the Basic Usage declarative card.
|
|
28
27
|
|
|
29
|
-
|
|
28
|
+
- **Single-select no longer holds a stale multi-selection when seeded with several values** — `parseInitialSelection()` used to add every seeded value to the selection unconditionally, so a `multiple="false"` picker could hold — and highlight — multiple rows at once. It surfaced both from a declarative `initial-values="a,b,c"` on a single-select and, more visibly, from flipping `multiple` from `true` to `false` at runtime while items were selected: the reinit reseeds the live selection into the fresh single-select and left the extra rows highlighted. The picker now trims the seed to the first value when it isn't in multiple mode, so exactly one row stays selected.
|
|
30
29
|
|
|
31
|
-
- **
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
30
|
+
- **Async-search dropdown no longer runs off the bottom of the viewport** — An async `searchCallback` that seeds no options anchors its panel while it's still empty or showing the loader — short enough to fit below the input, so with the default `lock-placement` it froze its placement to `bottom`. When results arrived the panel grew to full height but stayed pinned below the input, overflowing the bottom edge instead of flipping up into the free space, because `renderDropdown()` rewrote the list without re-anchoring. `performAsyncSearch()` now calls a new `repositionDropdown()` after results render, tearing down and recreating the Floating-UI anchor so the flip-on-first-compute re-evaluates against the panel's real height, then re-freezes. Scoped to the async path only — locally filtered dropdowns open already populated and are unaffected.
|
|
31
|
+
|
|
32
|
+
## What's New in v2.2.0-rc01
|
|
33
|
+
|
|
34
|
+
- **Tree cascade is now the default — check a branch, check its subtree** — In a multi-select tree, `checkbox-mode` now defaults to `cascade` (previously `independent`), so ticking a branch selects its whole subtree and branches render a tristate (checked / indeterminate / unchecked) box — what most tree-select UIs do. The emitted selection follows `cascade-select-policy` (default `rolled-up`: a fully-checked subtree collapses to its root value). This is a behavior change for existing tree consumers — set `checkbox-mode="independent"` to keep the old per-node toggling. Flat and single-select lists are unaffected, since there's no subtree to cascade into.
|
|
35
|
+
- **Per-group select-all in flat grouped lists — `group-select-mode="cascade"`** — A new attribute puts a tristate checkbox on each group header in a flat, multi-select, grouped list; clicking it checks or unchecks all of that group's currently-visible members. The group name itself is never a selected value — `getValue()`, badges, and form output carry member values only — a partially-selected group reads indeterminate, and a header toggle fires a single `change`. Disabled members are excluded from the select-all. Default `none` leaves headers inert, as before.
|
|
36
|
+
- **Per-group selected counts + one shared count formatter** — Every group header now shows a count of that group's selected members, rendered as the same small chip as the in-input `[N]` counter (not a new badge style). A new `getCountLabelCallback((selected, total) => string)` formats both the in-input counter and the group chip together so they always read the same way — default `[3]`, or return `` `${s}/${t}` `` for an "x / y of total" style, where `total` is the whole option list for the counter and the group's member count for a header.
|
|
37
|
+
- **Order the selected items — `selected-order`** — Control the sequence chosen items appear in across badges, partial "+N more", and the selected-items popover: `as-selected` (default), `label-asc` / `label-desc`, `member` (by a `selected-order-member` property or `getSelectedOrderCallback`), or `custom` (a comparator). It's display-only — `getValue()`, form output, and `getSelected()` keep insertion order — and because the ordering runs in one shared place, the partial "+N more" split and its remove button always act on the items sorted *after* the visible slice.
|
|
38
|
+
- **Every render callback now receives a context** — `renderGroupLabelContentCallback` gains a second `GroupLabelRenderContext` argument (the group's members and selection, e.g. `selectedCount`), and `renderSelectedItemContentCallback` / `renderSelectedContentCallback` now also receive a context carrying the presentation (`isFullscreen` / `isModal`) — matching the option and badge callbacks. Everything is additive, so existing one-argument callbacks keep working; branch on `isFullscreen` to render leaner content in the phone overlay.
|
|
39
|
+
- **Fixes — selection preservation, hidden search field, "+N more" ✕** — Changing a cosmetic attribute (`badges-display-mode` / `badges-position`) no longer wipes the current selection (it's applied in place, and genuine rebuilds now preserve the runtime selection); `search-input-mode="hidden"` no longer collapses the input row, so the toggle stays at the trailing edge; and the "+N more" badge's ✕ now removes exactly the hidden items instead of silently opening the popover.
|
|
35
40
|
|
|
36
41
|
## Demos & docs
|
|
37
42
|
|
|
38
|
-
- 🚀 [
|
|
43
|
+
- 🚀 [Showcase](https://web-multiselect.keenmate.dev)
|
|
44
|
+
- 🧪 [Live demo](https://examples.web-multiselect.keenmate.dev)
|
|
39
45
|
- 📘 [Usage / API reference](./docs/usage.md) — attributes, properties, methods, events.
|
|
40
46
|
- 🎨 [Theming](./docs/theming.md) — `--ms-*` variables, dark mode, cascade layers, Theme Designer integration.
|
|
41
47
|
- 📚 [Examples / cookbook](./docs/examples.md) — rich content, async search, virtual scroll, custom rendering, forms.
|