@keenmate/web-multiselect 2.0.0-rc12 → 2.0.0

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 CHANGED
@@ -21,6 +21,40 @@ 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.0.0
25
+
26
+ - **"Add new" creation mode — the picker doubles as a creation tool.** Turn on `allow-add-new`
27
+ and a search with no matches shows a clickable "Add new …" prompt (label via `add-new-text` /
28
+ `getAddNewTextCallback`). Choosing it (click, Enter, or arrow-to-focus) fires a new bubbling
29
+ `add` event; `addNewCallback` creates the option and is **async and cancelable** (return
30
+ `null`/`undefined` to abort after a confirm dialog or server round-trip) and may return a
31
+ **rich option** that renders like any other. While it runs the prompt shows a spinner +
32
+ `add-new-pending-text`. Creation also works with no callback — handle it entirely off the `add`
33
+ event. See `examples-events-callbacks.html` §EV4b/EV4c.
34
+
35
+ - **Scroll-to imperative API — jump to any option or group.** New `scrollToIndex()` /
36
+ `scrollToValue()` / `scrollToGroup()` on the element and picker bring a row into view — pair with
37
+ `open()` for an "open + jump" gesture. Mode-aware (virtual scroll, tree, mobile fullscreen sheet),
38
+ they align to the top by default (`{ block: 'center' }` to center) and return `false` when the
39
+ target isn't in the current filtered list. A companion public `clearSearch()` reveals a
40
+ filtered-out option so you can then scroll to it, plus a `searchText` getter and a `search(term)`
41
+ method to read and programmatically drive the query. See §BU06b, §VS03, §TR09b.
42
+
43
+ - **Checkbox check/dash + filter funnel now flow from the shared `--base-icon-*` contract.** The
44
+ checkmark and indeterminate dash are now `currentColor` mask glyphs (not CSS-border shapes) reading
45
+ `--base-icon-check` / `--base-icon-indeterminate`, and the search-mode funnel reads
46
+ `--base-icon-filter` — so one base override reskins them across every KeenMate component. Inline
47
+ Lucide fallbacks keep the default look unchanged.
48
+
49
+ - **`--ms-rem` now bridges to the shared `--base-rem` knob.** The global sizing unit resolves
50
+ `var(--base-rem, 10px)`, so a theme that sets `--base-rem` rescales the whole component from one
51
+ variable (the `10px` fallback and per-instance overrides still work with no base layer loaded).
52
+
53
+ - **Fixed: the count-chip clear ✕ and popover close ✕ vanished on hover.** Both derived their hover
54
+ background *and* glyph colour from the same accent, so the ✕ melted into its own hover state
55
+ (fully invisible on near-white accents like Minimal dark). They now fill with a solid accent
56
+ background and flip the glyph to the on-accent colour, matching the badge remove button.
57
+
24
58
  ## What's New in v2.0.0-rc12
25
59
 
26
60
  - **`overlay-group` — one overlay open at a time, across components.** The dropdown now joins a cross-component single-active-overlay group (core `registerOverlay`): opening it dismisses every other participating overlay — other multiselects, datepickers, or any external popover that fires the `km-overlay-activated` document event — and it closes itself when another overlay in its group opens. The new `overlay-group` attribute/property scopes this to a named group (same group = coordinate, different groups = independent, unset = the default ungrouped pool). Outside-click dismissal is unchanged and always on; this only governs the open-broadcast. Fixes the old behavior where two multiselects could sit open simultaneously.
@@ -35,18 +69,6 @@ Reads `--base-*` variables from the page if [`@keenmate/theme-designer`](https:/
35
69
 
36
70
  - **Dropdown / selected-items popover no longer render 2px wider than the field.** Both panels size from `--ms-input-current-width` (the field wrapper's border-box `offsetWidth`) but were themselves `content-box`, so each added its own 1px border on top and overhung the input it anchors to. Both now use `box-sizing: border-box`, so their outer width matches the field exactly.
37
71
 
38
- ## What's New in v2.0.0-rc11
39
-
40
- - **Imperative open/close API — drive the dropdown from code.** The `<web-multiselect>` element and the underlying `WebMultiSelect` now expose `open()`, `close()`, `toggle()`, and a read/write `isOpen` property, mirroring the calendar API in web-daterangepicker. Each element method flushes pending property writes first (the same contract as `getSelected()`/`setSelected()`), so `el.options = data; el.open()` works with no `await` in between. Calling `open()` from your own button's click handler now opens *and stays open* — previously the same click bubbled to the outside-click listener and re-closed it. See the new `examples-data-api.html` §API07 demo.
41
-
42
- - **Inline clear (✕) button — wipe the whole selection from inside the input.** A new opt-in `show-clear` attribute renders a small ✕ at the input's trailing edge that appears only while something is selected. Clicking it clears the selection and any search text, fires a single `change`, refocuses the input, and closes the selected-items popover if it was open — without popping the dropdown open. It's drawn as a themeable CSS mask icon (`--ms-input-clear-*`, whose corner radius follows `--ms-border-radius`). See the new `examples-basic.html` §BU01b demo.
43
-
44
- - **Input decorations rebuilt as a flex "field shell" — no more overlap or text bleed.** `.ms__input-wrapper` is now the bordered field (border, background, radius, focus ring via `:focus-within`), with the `<input>`, the `[N]` counter, the ✕ clear, and the chevron as real flex children in a spaced row. Previously each was absolutely pinned by a hard-coded inset, so `show-counter` + `show-clear` collided and long text could slide under the icons. Now they space themselves via `--ms-input-gap`, long text clips cleanly inside the input's own box, and RTL mirroring falls out of the flex direction for free. Several obsolete positioning vars were removed (`--ms-input-padding`, `--ms-input-padding-right`, `--ms-toggle-right`, `--ms-counter-offset`, `--ms-input-clear-inset`, `--ms-input-clear-gutter`, `--ms-transform-center-y`).
45
-
46
- - **Selected-items popover now lines up with the field.** `--ms-selected-popover-width` used to default to a fixed 32rem independent of the control, which looked detached under a wide field; it now defaults to `var(--ms-input-current-width)`, so the popover and the dropdown both track the field width and align under it. Set `selected-popover-width` (or the CSS var) to a fixed length to restore the old constant-width behavior.
47
-
48
- - **Toggle chevron is now a crisp icon, not a text character.** The dropdown indicator renders the shared `--ms-icon-chevron` glyph through a CSS mask — consistent with the ✕, count-clear, and badge-remove icons — instead of the Unicode `▼`, so it no longer depends on font rendering and themes uniformly via `--ms-toggle-icon-color` / `--ms-toggle-icon-size`. It still points down when closed and rotates up when open.
49
-
50
72
  ## Demos & docs
51
73
 
52
74
  - 🚀 [Live demo](https://web-multiselect.keenmate.dev)
@@ -53,7 +53,26 @@
53
53
  { "name": "base-input-size-sm-height", "required": false, "usage": "Small input height (multiplier)" },
54
54
  { "name": "base-input-size-md-height", "required": false, "usage": "Medium input height (multiplier)" },
55
55
  { "name": "base-input-size-lg-height", "required": false, "usage": "Large input height (multiplier)" },
56
- { "name": "base-input-size-xl-height", "required": false, "usage": "Extra large input height (multiplier)" }
56
+ { "name": "base-input-size-xl-height", "required": false, "usage": "Extra large input height (multiplier)" },
57
+ { "name": "base-rem", "required": false, "usage": "Global sizing unit — drives --ms-rem (falls back to 10px); scales the whole component" },
58
+ { "name": "base-ease-standard", "required": false, "usage": "Standard easing curve (drives --ms-easing-snappy)" },
59
+ { "name": "base-checkbox-border-color", "required": false, "usage": "Option checkbox border color" },
60
+ { "name": "base-input-clear-color", "required": false, "usage": "Inline field-clear (✕) icon color" },
61
+ { "name": "base-input-clear-bg-hover", "required": false, "usage": "Inline field-clear (✕) hover background" },
62
+ { "name": "base-icon-chevron", "required": false, "usage": "Shared chevron glyph (toggle indicator + fullscreen pager); inline Lucide SVG fallback" },
63
+ { "name": "base-icon-clear", "required": false, "usage": "Inline field-clear (✕) glyph; falls back to --ms-icon-remove" },
64
+ { "name": "base-icon-remove", "required": false, "usage": "Badge-remove glyph; falls back to base-icon-close then inline Lucide SVG" },
65
+ { "name": "base-icon-close", "required": false, "usage": "Generic close glyph (fallback for badge-remove)" },
66
+ { "name": "base-icon-search", "required": false, "usage": "Search glyph; inline Lucide SVG fallback" },
67
+ { "name": "base-icon-filter", "required": false, "usage": "Funnel/filter glyph (fullscreen search-mode toggle); chained by --ms-icon-filter; inline Lucide SVG fallback" },
68
+ { "name": "base-icon-check", "required": false, "usage": "Checkbox/option checkmark glyph; chained by --ms-icon-check; inline Lucide SVG fallback" },
69
+ { "name": "base-icon-indeterminate", "required": false, "usage": "Tri-state (partial) checkbox dash glyph; chained by --ms-icon-indeterminate; inline Lucide SVG fallback" },
70
+ { "name": "base-danger-bg", "required": false, "usage": "Error message background" },
71
+ { "name": "base-danger-color", "required": false, "usage": "Error message text color" },
72
+ { "name": "base-warning-bg", "required": false, "usage": "Warning message background" },
73
+ { "name": "base-warning-color", "required": false, "usage": "Warning message text color" },
74
+ { "name": "base-success-bg", "required": false, "usage": "Success message background" },
75
+ { "name": "base-success-color", "required": false, "usage": "Success message text color" }
57
76
  ],
58
77
  "componentVariables": [
59
78
  { "name": "ms-rem", "category": "sizing", "usage": "Base sizing unit for proportional scaling (default: 10px)" },
@@ -280,6 +299,9 @@
280
299
  { "name": "ms-badge-remove-bg-hover", "category": "badge", "usage": "Badge remove button hover background" },
281
300
  { "name": "ms-badge-remove-box-shadow-focus", "category": "badge", "usage": "Badge remove button focus shadow" },
282
301
  { "name": "ms-icon-remove", "category": "badge", "usage": "Remove icon as CSS url() to a mask-friendly SVG; color comes from currentColor" },
302
+ { "name": "ms-icon-filter", "category": "icon", "usage": "Funnel glyph (fullscreen search-mode toggle); chains to --base-icon-filter" },
303
+ { "name": "ms-icon-check", "category": "checkbox", "usage": "Checkmark glyph (mask) for a checked checkbox/option; chains to --base-icon-check" },
304
+ { "name": "ms-icon-indeterminate", "category": "checkbox", "usage": "Dash glyph (mask) for a tri-state/partial checkbox; chains to --base-icon-indeterminate" },
283
305
  { "name": "ms-badge-counter-bg", "category": "badge", "usage": "Counter badge background" },
284
306
  { "name": "ms-badge-counter-border", "category": "badge", "usage": "Counter badge border" },
285
307
  { "name": "ms-badge-counter-border-color", "category": "badge", "usage": "Counter badge border color" },