@keenmate/web-multiselect 2.0.0-rc02 → 2.0.0-rc04

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,61 +21,90 @@ 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-rc02
25
-
26
- **Form association restored for host frameworks (`el.form`).** Selecting inside a
27
- `<web-multiselect>` that lives in a `<form>` again delivers changes to frameworks
28
- that resolve the parent form via `event.target.form` most notably Phoenix
29
- LiveView's `phx-change` delegation, which silently dropped changes in rc01.
30
- `<web-multiselect>` is a form-associated custom element, so it now exposes a real
31
- `el.form` / `event.target.form` like a native control. (rc01 had hardened its
32
- internal `ElementInternals` handle to a true `#private` field, which killed the
33
- `.form` that host-framework wrappers read.) The fix lives upstream in
34
- [`@keenmate/web-components-core`](https://www.npmjs.com/package/@keenmate/web-components-core)
35
- 1.0.0-rc02 (the `el.form` getter), which this release pins.
24
+ ## What's New in v2.0.0-rc04
25
+
26
+ **Phone search one-tap clear and a keyboard that gets out of the way** — The
27
+ full-screen search sheet gained the two things it was missing on touch. A clear button
28
+ now sits at the trailing edge of the search field (a distinct Lucide `search-x` glyph,
29
+ so it doesn't read as a second close ✕) to wipe the term in one tap and restore the full
30
+ list. And the soft keyboard, which used to stay pinned open once you focused the field,
31
+ now tucks away on the three natural "done typing" gestures — scrolling the list, tapping
32
+ an option, or pressing Enter/Search while never dismissing itself mid-type from a
33
+ programmatic scroll-to-match.
34
+
35
+ **A close button you can make your own** — The full-screen close is now a themeable
36
+ chip: the new `--ms-fullscreen-close-bg`, `--ms-fullscreen-close-border`, and
37
+ `--ms-fullscreen-close-border-radius` variables turn the bare glyph into a bordered
38
+ button (à la a command-palette close) while the defaults keep it a plain round ✕. Its
39
+ tap target was also fixed — the previously-dead padding around the button in the sheet's
40
+ top-trailing corner (the natural place to reach) now dismisses the sheet, without ever
41
+ stealing taps from the first option row or the search field.
42
+
43
+ **Right presentation on every device, via core rc07** — This release pins
44
+ `@keenmate/web-components-core` at `1.0.0-rc07` and adopts its reworked
45
+ `resolvePresentation` / `classifyDevice` API. Behavior is unchanged — full-screen on
46
+ phones, floating on tablet and desktop — with one refinement from the new capability
47
+ gate: a narrowed desktop window (fine pointer, hover) now stays `desktop` and keeps its
48
+ floating dropdown at any width, instead of ever flipping to the full-screen sheet.
36
49
 
37
50
  See `CHANGELOG.md` for the full list.
38
51
 
39
- ## What's New in v2.0.0-rc01
52
+ ## What's New in v2.0.0-rc03
53
+
54
+ **Full-screen dropdown on phones (`mobile-presentation`).** On a phone, a dropdown
55
+ that floats next to the input fights the on-screen keyboard. `<web-multiselect>`
56
+ now detects phones and, by default (`mobile-presentation="auto"`), presents the
57
+ open dropdown as a **full-screen overlay** with its own search field and close (✕)
58
+ button — while desktop and tablets keep the familiar floating panel, unchanged. A
59
+ "phone" is a touch-primary device whose **shorter** viewport side is `< 600px`
60
+ (the Material `sw600dp` line), so a phone in **landscape** still gets the overlay
61
+ and tablets never do. The **selected-items popover** goes full-screen on phones
62
+ too, with a matching header. The phone view is scaled up ~1.2× for comfortable
63
+ touch targets via the `--ms-fullscreen-rem` knob (default `12px` vs the base
64
+ `--ms-rem: 10px`) — one value grows rows, text, checkboxes, header and search
65
+ together. Override the mode per instance with `mobile-presentation="floating"`
66
+ (anchored panel everywhere) or `"fullscreen"` (force the overlay on any device —
67
+ handy for previews). Theme it with the new `--ms-fullscreen-*` CSS variables.
40
68
 
41
- **The core-adoption major.** `<web-multiselect>` is now built on
42
- [`@keenmate/web-components-core`](https://www.npmjs.com/package/@keenmate/web-components-core)
43
- (`BlissElement`) — shared, tested custom-element plumbing (attribute parsing,
44
- reactivity, reflection, event handling, logging, registration, positioning). The
45
- dropdown, tree, virtual scroll, theming, and every attribute behave the same; the
46
- change is under the hood, with three **breaking** API changes to be aware of:
47
-
48
- - **`onSelect` / `onDeselect` / `onChange` are event-handler properties now.** They
49
- receive the `CustomEvent` (like `el.onclick`), so read `e.detail.option` /
50
- `e.detail.selectedOptions` / `e.detail.selectedValues` instead of a bare
51
- argument — equivalent to `addEventListener('select', …)`. The bubbling
52
- `select` / `deselect` / `change` events are unchanged.
53
- - **`setAttributes()` takes typed property values by camelCase key.**
54
- `el.setAttributes({ searchPlaceholder: 'Search…', isCounterShown: true })`. To
55
- batch attribute **strings**, use `el.batch(() => { el.setAttribute('search-placeholder', 'Search…'); … })`.
56
- - **Property writes are async (coalesced).** Setting a property (e.g.
57
- `el.options = […]`) applies on a microtask; `await el.whenSettled()` before
58
- reading back rendered state. `setAttributes()` / `batch()` still flush
59
- synchronously.
60
- - **`data-options` gains CSV & plain formats.** The `data-options` attribute now
61
- takes `data-options-format="json|csv|plain"` (default `json`) — feed a CSV table
62
- (first row is a header; columns mapped via `*-member`) or a bare, newline-
63
- delimited value list without hand-writing JSON. Field and row delimiters are
64
- configurable via `data-options-splitter` / `data-options-row-splitter` (so TSV
65
- or a custom separator is expressible in the attribute), and `data-options` is
66
- now a fully reactive, shape-validated input — changing any of these re-renders.
69
+ ```html
70
+ <!-- auto (default): full-screen on phones, floating on desktop/tablet -->
71
+ <web-multiselect mobile-presentation="auto"></web-multiselect>
67
72
 
68
- See `CHANGELOG.md` for the full list.
73
+ <!-- never go full-screen -->
74
+ <web-multiselect mobile-presentation="floating"></web-multiselect>
69
75
 
70
- ## What's New in v1.12.0-rc08
76
+ <!-- always full-screen (preview the mobile view on desktop) -->
77
+ <web-multiselect mobile-presentation="fullscreen"></web-multiselect>
78
+ ```
71
79
 
72
- - **Panel sizing dropdown and popover are independently sizable via CSS variables** — The options dropdown and selected-items popover no longer inherit the input's width. `--ms-dropdown-width` (defaults to the live input width) and `--ms-selected-popover-width` (intrinsic 32rem) drive them, alongside the existing max-height variables. Set them at app level (`web-multiselect { --ms-dropdown-width: 60rem }`) or override a single instance with the new `dropdown-width` / `selected-popover-width` attributes, which write those variables inline on the element. This also fixes a latent bug where `--ms-selected-popover-width` was dead (an internal width-sync always overrode it), so the popover now honours its 32rem default. See section 14 of `examples-tree.html`.
73
- - **Tree rendering — the option render callback receives full tree context** — `renderOptionContentCallback(item, ctx)` gains `isTreeNode`, `isBranch`, `isLeaf`, `childCount`, `level`, `depth`, `path`, `isSelectable`, and the cascade `isIndeterminate` tristate. Rendering a child-count badge on branches or branch/leaf-specific markup is now a one-liner, without re-deriving the hierarchy yourself. All fields are optional (flat options report `isTreeNode: false`), so existing callbacks are untouched. Demoed as the new "Custom Node Rendering" section.
74
- - **Cascade counter — the `[N]` chip counts what you actually picked** — In cascade mode the counter used to show the emitted value count, which balloons under `cascade-select-policy="leaves"` / `"all"` (one branch click can emit five values) — jarring next to a couple of rolled-up badges. It now counts the rolled-up minimal cover — the branches you selected — regardless of emit policy, and gained a hover tooltip listing those items. Under the default `rolled-up` policy nothing changes.
75
- - **Theming cleanup dead input size-variant surface removed from the bundle** — The unused `.ms__input--xs/sm/lg/xl` preset classes and their `--ms-input-size-*` variable chain were never wired to anything (no `size` attribute toggles them), so they've been commented out — kept for a possible future preset API but no longer shipped as dead CSS (the compiled stylesheet shrank ~2 kB). Input sizing still works through `--ms-rem` for proportional global scale or the individual `--ms-input-*` variables for targeted overrides.
76
- - **Fixes — badge hover and live cascade switching** — Badge hover no longer washes the chip to white (the hover background fell through to the white input background; it now deepens the accent tint, dark-mode aware). And switching `checkbox-mode` or `cascade-select-policy` live rebuilds the cascade index and silently re-projects the current selection, so badges, form value, and checkboxes all reflect the new mode instantly.
80
+ This is powered by device/viewport/orientation detection in
81
+ [`@keenmate/web-components-core`](https://www.npmjs.com/package/@keenmate/web-components-core)
82
+ (via `BlissElement`'s `environmentChanged` hook), which this release pins at
83
+ **1.0.0-rc06** — rc04 also **dropped `loglevel`** as a transitive runtime
84
+ dependency. The floating dropdown additionally gains a viewport-width safety cap so
85
+ a wide panel can't overflow the screen edge.
86
+
87
+ **Right-to-left, done properly — including runtime switching.** Give the element (or
88
+ any ancestor) `dir="rtl"` and the whole component mirrors: the toggle and in-input
89
+ counter move to the left, checkboxes sit on the right of each row, badges reverse,
90
+ and the full-screen overlay mirrors too (search/close swap sides, the match
91
+ navigator flips). RTL is now built on CSS **logical properties** driven by the
92
+ inherited direction, which fixes cases that silently never worked before — the
93
+ dropdown, hint, and selected-popover live in the shadow root, so the old `.ms--rtl`
94
+ override rules never reached them. And flipping `dir` at runtime — an app-wide
95
+ language switch — re-mirrors the live picker without a rebuild (via core rc06's new
96
+ `directionChanged` hook).
97
+
98
+ **Friendlier phone browsing.** The full-screen sheet opens with the **keyboard
99
+ closed** by default, so you can scan long lists and reach the bottom action buttons
100
+ before typing (opt into immediate type-to-filter with `fullscreen-autofocus="true"`).
101
+ The phone **Back gesture** now closes the sheet instead of navigating the page away.
102
+ In `search-mode="navigate"`, an on-screen **match navigator** (an `N of M` count plus
103
+ prev/next buttons) stands in for the desktop `Ctrl`+`Arrow` match-stepping that touch
104
+ can't do — and the focused match now stays visible above the keyboard instead of
105
+ scrolling behind it. Tapping an option no longer pops the keyboard mid-browse.
77
106
 
78
- > ⚠️ **Security notice:** This component intentionally allows raw HTML in rendering callbacks to give developers full control over content display. If you display user-generated content, you must sanitize it yourself. See [docs/examples.md → HTML Injection (XSS) notice](./docs/examples.md#html-injection-xss-notice) for the complete list of affected callbacks.
107
+ See `CHANGELOG.md` for the full list.
79
108
 
80
109
  ## Demos & docs
81
110