@keenmate/web-multiselect 1.8.6 → 1.10.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 +30 -2
- package/component-variables.manifest.json +8 -5
- package/dist/index.d.ts +120 -47
- package/dist/multiselect.js +1511 -1443
- package/dist/multiselect.umd.js +16 -26
- package/dist/style.css +1 -1
- package/package.json +8 -3
- package/src/css/_badges-display.css +22 -5
- package/src/css/_input-dropdown.css +2 -2
- package/src/css/_tooltips-popover.css +11 -1
- package/src/css/_variables.css +599 -597
package/README.md
CHANGED
|
@@ -7,6 +7,28 @@ A lightweight, accessible multiselect web component with typeahead search, RTL l
|
|
|
7
7
|
|
|
8
8
|
> **⚠️ 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 [HTML Injection (XSS) Notice](#html-injection-xss-notice) for the complete list of affected callbacks.
|
|
9
9
|
|
|
10
|
+
## What's New in v1.10.0
|
|
11
|
+
|
|
12
|
+
- **`data-options` attribute on `<web-multiselect>`** — set options declaratively from HTML, no JS bootstrap required (works alongside `initial-values` for pure-HTML / server-rendered / SharePoint workbench scenarios).
|
|
13
|
+
- **`form.reset()` now clears the selection** — the element is now form-associated (`static formAssociated = true` + `ElementInternals` + `formResetCallback()`).
|
|
14
|
+
- **Dropdown / hint / selected popover no longer clipped inside scrollable ancestors** — Floating UI now uses `strategy: 'fixed'` for all three panels, so they escape `overflow: hidden|auto|scroll` containers (e.g. SharePoint Framework workbenches).
|
|
15
|
+
- **`initial-values` now works when options arrive after init** — values are reconciled on every `options` mutation, not just at construction.
|
|
16
|
+
- **Remove / close (×) buttons render as SVG masks** — pixel-centered regardless of font; color still flows through the existing `--ms-*-color` variables via `currentColor`; three new `--ms-*-icon-size` variables for theming.
|
|
17
|
+
- **Keyboard navigation now keeps working after a mouse click on an option** — previously, clicking an option moved focus from the search input to the option's checkbox (knocking the `keydown` listener offline) *and* left `focusedIndex` at its pre-click value, so subsequent ArrowDown / ArrowUp / Enter went nowhere visible. Click now anchors `focusedIndex` to the clicked option and refocuses the search input, so arrow keys continue from where you clicked and Enter toggles the option under the cursor.
|
|
18
|
+
- **Count-clear / popover-close hover backdrop now matches the rest of the component** — was a circle (`border-radius: 50%`), now a small rounded rectangle (`--ms-border-radius-sm`) consistent with every other interactive element. Themes that prefer the circle can set `--ms-count-clear-border-radius` and `--ms-selected-popover-close-border-radius` back to `50%`.
|
|
19
|
+
- **Keyboard `Enter` respects disabled options** — previously only the click handler did.
|
|
20
|
+
- **End-to-end test suite** — 114 Playwright specs across 19 fixture pages (`npm run test:e2e`).
|
|
21
|
+
- **`THEMING.md`** — new reference cataloguing every theme-able component state and the CSS variables that drive it.
|
|
22
|
+
|
|
23
|
+
## What's New in v1.9.0
|
|
24
|
+
|
|
25
|
+
- **Live attribute / callback updates no longer rebuild the DOM** — `updateOptions(partial)` merges in place; selection state, scroll position, focus, and tooltips are preserved across attribute changes.
|
|
26
|
+
- **9 previously-dead per-component CSS override hooks are now wired** — `--ms-hint-border-color`, `--ms-dropdown-border-color`, `--ms-actions-border-color`, `--ms-group-border-color`, `--ms-badge-counter-border-color`, `--ms-selected-popover-border-color`, `--ms-selected-popover-header-border-color`, `--ms-option-outline-color-focused`, `--ms-option-border-matched-color`.
|
|
27
|
+
- **`selectAll` / `clearAll` now fire per-item `selectCallback` / `deselectCallback`** — consumers wiring per-item analytics or side effects no longer silently miss bulk operations.
|
|
28
|
+
- **New `Tooltip` class** consolidating three previous tooltip implementations; fixes a handle leak and a popover-vs-main-container collision.
|
|
29
|
+
- **`--base-primary-bg` theming variable** — `--ms-primary-bg` reads it first, then `--base-main-bg`, then a hardcoded default.
|
|
30
|
+
- Plus many fixes across custom action buttons, grouped-option focus, badge cursors, focus rings, and logging.
|
|
31
|
+
|
|
10
32
|
## Features
|
|
11
33
|
|
|
12
34
|
- 📝 **Declarative HTML** - Use standard `<option>` and `<optgroup>` elements - no JavaScript required for simple cases!
|
|
@@ -327,11 +349,15 @@ multiselect.addNewCallback = async (value) => {
|
|
|
327
349
|
|
|
328
350
|
- **↑ ↓** - Navigate up/down through options
|
|
329
351
|
- **Ctrl+↑ Ctrl+↓** - Jump between matched items (navigate mode only)
|
|
330
|
-
- **
|
|
352
|
+
- **Page Up / Page Down** - Move focus by 10 options at a time
|
|
353
|
+
- **Home / End** - Jump to first / last option
|
|
354
|
+
- **Enter** - Select focused option (or add new entry when `allow-add-new="true"` and the search has text)
|
|
331
355
|
- **Escape** - Close popover → Clear search → Close dropdown (priority order)
|
|
332
356
|
- **Tab** - Close dropdown and move to next field
|
|
333
357
|
- **Type** - Filter options by search term
|
|
334
358
|
|
|
359
|
+
> 💡 To surface these shortcuts to your users, set the `search-hint` attribute — the hint floats above the input when focused. Example: `<web-multiselect search-mode="navigate" search-hint="Ctrl/Cmd + ↓ / ↑ to jump between matches">`.
|
|
360
|
+
|
|
335
361
|
## Advanced Features
|
|
336
362
|
|
|
337
363
|
### Rich Content with Icons
|
|
@@ -1787,7 +1813,9 @@ For the complete list of all available CSS variables, see:
|
|
|
1787
1813
|
| `--ms-badge-font-size` | `0.75rem` | Badge font size |
|
|
1788
1814
|
| `--ms-badge-border-radius` | `0.375rem` | Badge border radius |
|
|
1789
1815
|
| `--ms-badge-remove-bg` | `var(--ms-accent-color)` | Remove button background |
|
|
1790
|
-
| `--ms-badge-remove-color` | `var(--ms-text-color-on-accent)` | Remove button color |
|
|
1816
|
+
| `--ms-badge-remove-color` | `var(--ms-text-color-on-accent)` | Remove button (X) color — applied to the SVG via `currentColor` |
|
|
1817
|
+
| `--ms-badge-remove-icon-size` | `calc(1.0 * var(--ms-rem))` | Size of the X glyph inside the remove button |
|
|
1818
|
+
| `--ms-icon-remove` | (inline SVG `url(...)`) | The X mask SVG; override to swap the glyph shape (alpha-only — color comes from `--ms-badge-remove-color`) |
|
|
1791
1819
|
| `--ms-badge-counter-text-bg` | `var(--ms-primary-bg)` | BadgeCounter text background ("+X more") |
|
|
1792
1820
|
| `--ms-badge-counter-text-color` | `var(--ms-text-color-3)` | BadgeCounter text color |
|
|
1793
1821
|
| `--ms-badge-counter-remove-bg` | `var(--ms-text-color-3)` | BadgeCounter remove button background |
|
|
@@ -270,10 +270,11 @@
|
|
|
270
270
|
{ "name": "ms-badge-remove-bg", "category": "badge", "usage": "Badge remove button background" },
|
|
271
271
|
{ "name": "ms-badge-remove-color", "category": "badge", "usage": "Badge remove button color" },
|
|
272
272
|
{ "name": "ms-badge-remove-border", "category": "badge", "usage": "Badge remove button border" },
|
|
273
|
-
{ "name": "ms-badge-remove-font-size", "category": "badge", "usage": "Badge remove button font size" },
|
|
273
|
+
{ "name": "ms-badge-remove-font-size", "category": "badge", "usage": "Badge remove button font size (unused since 1.10.0 — kept for backward-compat)" },
|
|
274
|
+
{ "name": "ms-badge-remove-icon-size", "category": "badge", "usage": "Badge remove X icon size (mask SVG)" },
|
|
274
275
|
{ "name": "ms-badge-remove-bg-hover", "category": "badge", "usage": "Badge remove button hover background" },
|
|
275
276
|
{ "name": "ms-badge-remove-box-shadow-focus", "category": "badge", "usage": "Badge remove button focus shadow" },
|
|
276
|
-
{ "name": "ms-icon-remove", "category": "badge", "usage": "Remove icon
|
|
277
|
+
{ "name": "ms-icon-remove", "category": "badge", "usage": "Remove icon as CSS url() to a mask-friendly SVG; color comes from currentColor" },
|
|
277
278
|
{ "name": "ms-badge-counter-bg", "category": "badge", "usage": "Counter badge background" },
|
|
278
279
|
{ "name": "ms-badge-counter-border", "category": "badge", "usage": "Counter badge border" },
|
|
279
280
|
{ "name": "ms-badge-counter-border-color", "category": "badge", "usage": "Counter badge border color" },
|
|
@@ -306,11 +307,12 @@
|
|
|
306
307
|
{ "name": "ms-count-clear-size", "category": "count", "usage": "Count clear button size" },
|
|
307
308
|
{ "name": "ms-count-clear-bg", "category": "count", "usage": "Count clear button background" },
|
|
308
309
|
{ "name": "ms-count-clear-color", "category": "count", "usage": "Count clear button color" },
|
|
309
|
-
{ "name": "ms-count-clear-font-size", "category": "count", "usage": "Count clear button font size" },
|
|
310
|
+
{ "name": "ms-count-clear-font-size", "category": "count", "usage": "Count clear button font size (unused since 1.10.0 — kept for backward-compat)" },
|
|
311
|
+
{ "name": "ms-count-clear-icon-size", "category": "count", "usage": "Count clear X icon size (mask SVG)" },
|
|
310
312
|
{ "name": "ms-count-clear-border-radius", "category": "count", "usage": "Count clear button border radius" },
|
|
311
313
|
{ "name": "ms-count-clear-bg-hover", "category": "count", "usage": "Count clear button hover background" },
|
|
312
314
|
{ "name": "ms-count-clear-color-hover", "category": "count", "usage": "Count clear button hover color" },
|
|
313
|
-
{ "name": "ms-icon-clear", "category": "count", "usage": "Clear icon
|
|
315
|
+
{ "name": "ms-icon-clear", "category": "count", "usage": "Clear icon as CSS url() to a mask-friendly SVG; defaults to var(--ms-icon-remove)" },
|
|
314
316
|
|
|
315
317
|
{ "name": "ms-tooltip-bg", "category": "tooltip", "usage": "Tooltip background" },
|
|
316
318
|
{ "name": "ms-tooltip-text-color", "category": "tooltip", "usage": "Tooltip text color" },
|
|
@@ -340,7 +342,8 @@
|
|
|
340
342
|
{ "name": "ms-popover-close-size", "category": "popover", "usage": "Popover close button size" },
|
|
341
343
|
{ "name": "ms-selected-popover-close-bg", "category": "popover", "usage": "Popover close button background" },
|
|
342
344
|
{ "name": "ms-selected-popover-close-color", "category": "popover", "usage": "Popover close button color" },
|
|
343
|
-
{ "name": "ms-selected-popover-close-font-size", "category": "popover", "usage": "Popover close button font size" },
|
|
345
|
+
{ "name": "ms-selected-popover-close-font-size", "category": "popover", "usage": "Popover close button font size (unused since 1.10.0 — kept for backward-compat)" },
|
|
346
|
+
{ "name": "ms-selected-popover-close-icon-size", "category": "popover", "usage": "Popover close X icon size (mask SVG)" },
|
|
344
347
|
{ "name": "ms-selected-popover-close-border-radius", "category": "popover", "usage": "Popover close button border radius" },
|
|
345
348
|
{ "name": "ms-selected-popover-close-bg-hover", "category": "popover", "usage": "Popover close button hover background" },
|
|
346
349
|
{ "name": "ms-selected-popover-close-color-hover", "category": "popover", "usage": "Popover close button hover color" },
|
package/dist/index.d.ts
CHANGED
|
@@ -194,7 +194,7 @@ declare interface MultiSelectConfig<T = any> {
|
|
|
194
194
|
isVirtualScrollEnabled?: boolean;
|
|
195
195
|
/** Vertical alignment of checkboxes relative to option content */
|
|
196
196
|
checkboxAlign?: 'top' | 'center' | 'bottom';
|
|
197
|
-
/** Hint text shown above the input
|
|
197
|
+
/** Hint text shown above the input while the dropdown is open. */
|
|
198
198
|
searchHint?: string;
|
|
199
199
|
/** Placeholder text for the search input */
|
|
200
200
|
searchPlaceholder?: string;
|
|
@@ -269,9 +269,11 @@ declare interface MultiSelectConfig<T = any> {
|
|
|
269
269
|
}
|
|
270
270
|
|
|
271
271
|
export declare class MultiSelectElement<T = any> extends BaseElement {
|
|
272
|
+
static formAssociated: boolean;
|
|
272
273
|
private picker?;
|
|
273
274
|
private containerElement?;
|
|
274
275
|
private shadow;
|
|
276
|
+
private internals?;
|
|
275
277
|
private _options?;
|
|
276
278
|
private _valueMember?;
|
|
277
279
|
private _getValueCallback?;
|
|
@@ -309,6 +311,14 @@ export declare class MultiSelectElement<T = any> extends BaseElement {
|
|
|
309
311
|
private _changeCallback?;
|
|
310
312
|
static get observedAttributes(): string[];
|
|
311
313
|
constructor();
|
|
314
|
+
/**
|
|
315
|
+
* Called by the browser when the surrounding <form> is reset. Clears the
|
|
316
|
+
* picker's selection so the multiselect actually participates in the
|
|
317
|
+
* standard reset lifecycle. (Before form-association, reset was a no-op
|
|
318
|
+
* because the hidden inputs were re-stamped from internal state on every
|
|
319
|
+
* render.)
|
|
320
|
+
*/
|
|
321
|
+
formResetCallback(): void;
|
|
312
322
|
connectedCallback(): void;
|
|
313
323
|
disconnectedCallback(): void;
|
|
314
324
|
attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
|
|
@@ -321,8 +331,19 @@ export declare class MultiSelectElement<T = any> extends BaseElement {
|
|
|
321
331
|
*/
|
|
322
332
|
private parseDeclarativeOptions;
|
|
323
333
|
private _declarativeSelectedValues?;
|
|
334
|
+
/** Parse all observed attributes via ATTRIBUTE_TABLE into a partial config object. */
|
|
335
|
+
private parseAttributesFromTable;
|
|
324
336
|
private initializePicker;
|
|
325
337
|
private reinitialize;
|
|
338
|
+
/**
|
|
339
|
+
* Apply a partial config update to the live picker. Falls back to a full reinit if the
|
|
340
|
+
* picker can't apply the change in place (e.g. adding/removing the `searchHint` element).
|
|
341
|
+
* No-op if the picker hasn't been initialized yet — the next `initializePicker` will pick
|
|
342
|
+
* up the new programmatic state.
|
|
343
|
+
*/
|
|
344
|
+
private updatePicker;
|
|
345
|
+
/** Normalize the picker's getValue() return into the array form expected by event detail. */
|
|
346
|
+
private collectSelectedValues;
|
|
326
347
|
get options(): T[] | undefined;
|
|
327
348
|
set options(value: T[] | undefined);
|
|
328
349
|
set valueMember(value: string | null);
|
|
@@ -492,9 +513,10 @@ export declare type SearchInputMode = 'normal' | 'readonly' | 'hidden';
|
|
|
492
513
|
export declare type SearchMode = 'filter' | 'navigate';
|
|
493
514
|
|
|
494
515
|
/**
|
|
495
|
-
* Set log level for a specific category
|
|
496
|
-
*
|
|
497
|
-
* @param
|
|
516
|
+
* Set log level for a specific category. Accepts either the full prefixed name
|
|
517
|
+
* (e.g. `MULTISELECT:UI`) or the bare suffix (`UI`) for convenience.
|
|
518
|
+
* @param category Category logger name; bare names (UI/DATA/INIT/INTERACTION) are normalized to the prefixed form.
|
|
519
|
+
* @param level Log level ('trace' | 'debug' | 'info' | 'warn' | 'error' | 'silent')
|
|
498
520
|
*/
|
|
499
521
|
export declare function setCategoryLevel(category: string, level: string): void;
|
|
500
522
|
|
|
@@ -534,12 +556,7 @@ export declare class WebMultiSelect<T = any> {
|
|
|
534
556
|
private dropdownCleanup;
|
|
535
557
|
private hintCleanup;
|
|
536
558
|
private selectedPopoverCleanup;
|
|
537
|
-
private
|
|
538
|
-
private badgeTooltipCleanups;
|
|
539
|
-
private badgeTooltipShowTimeouts;
|
|
540
|
-
private badgeTooltipHideTimeouts;
|
|
541
|
-
private actionButtonTooltips;
|
|
542
|
-
private actionButtonTooltipCleanups;
|
|
559
|
+
private tooltips;
|
|
543
560
|
private virtualScroll;
|
|
544
561
|
private optionsContainer;
|
|
545
562
|
private selectedPopoverVirtualScroll;
|
|
@@ -554,41 +571,31 @@ export declare class WebMultiSelect<T = any> {
|
|
|
554
571
|
private documentKeydownHandler;
|
|
555
572
|
private documentClickHandler;
|
|
556
573
|
/**
|
|
557
|
-
*
|
|
558
|
-
*
|
|
574
|
+
* Generic field extractor with the precedence:
|
|
575
|
+
* tuple short-circuit -> member property -> callback -> fallback
|
|
576
|
+
*
|
|
577
|
+
* Tuple handling:
|
|
578
|
+
* - `tupleIndex` (0 | 1): for `[key, value]` items, return that slot.
|
|
579
|
+
* - `tupleSkip: true`: for any tuple, skip directly to fallback (used for icon/subtitle/group/disabled —
|
|
580
|
+
* fields that don't make sense on a 2-element array).
|
|
581
|
+
* - neither: tuples flow through the member/callback/fallback chain as if they were objects.
|
|
582
|
+
*
|
|
583
|
+
* `transform` is applied to tuple-slot and member-property reads (not to callback returns or the fallback),
|
|
584
|
+
* so e.g. you can pass `String` to coerce numeric members to strings while letting a typed callback return its
|
|
585
|
+
* own type unchanged.
|
|
559
586
|
*/
|
|
587
|
+
private extractField;
|
|
560
588
|
private getItemValue;
|
|
561
|
-
/**
|
|
562
|
-
* Extract display value from item
|
|
563
|
-
* Precedence: tuple[1] -> displayValueMember -> getDisplayValueCallback -> '[N/A]'
|
|
564
|
-
*/
|
|
565
589
|
private getItemDisplayValue;
|
|
566
590
|
/**
|
|
567
|
-
*
|
|
568
|
-
*
|
|
569
|
-
* This allows customizing badge text separately from dropdown display text
|
|
591
|
+
* Badge display falls back to the regular display value rather than '[N/A]', so consumers can override badge
|
|
592
|
+
* text independently. Doesn't fit the extractField shape (no tuple/member layer of its own).
|
|
570
593
|
*/
|
|
571
594
|
private getItemBadgeDisplayValue;
|
|
572
|
-
/**
|
|
573
|
-
* Extract search value from item
|
|
574
|
-
* Precedence: searchValueMember -> getSearchValueCallback -> displayValue
|
|
575
|
-
*/
|
|
576
595
|
private getItemSearchValue;
|
|
577
|
-
/**
|
|
578
|
-
* Extract icon from item
|
|
579
|
-
*/
|
|
580
596
|
private getItemIcon;
|
|
581
|
-
/**
|
|
582
|
-
* Extract subtitle from item
|
|
583
|
-
*/
|
|
584
597
|
private getItemSubtitle;
|
|
585
|
-
/**
|
|
586
|
-
* Extract group from item
|
|
587
|
-
*/
|
|
588
598
|
private getItemGroup;
|
|
589
|
-
/**
|
|
590
|
-
* Extract disabled state from item
|
|
591
|
-
*/
|
|
592
599
|
private getItemDisabled;
|
|
593
600
|
constructor(element: HTMLElement, options?: Partial<MultiSelectConfig<T>>);
|
|
594
601
|
private init;
|
|
@@ -607,6 +614,11 @@ export declare class WebMultiSelect<T = any> {
|
|
|
607
614
|
* Render dropdown with virtual scrolling
|
|
608
615
|
*/
|
|
609
616
|
private renderDropdownVirtual;
|
|
617
|
+
/**
|
|
618
|
+
* Render the Select All / Clear All / custom action buttons row.
|
|
619
|
+
* Returns the empty string if multiple-select is off or no buttons are configured.
|
|
620
|
+
*/
|
|
621
|
+
private renderActionsHTML;
|
|
610
622
|
private renderOption;
|
|
611
623
|
private highlightMatch;
|
|
612
624
|
private groupOptions;
|
|
@@ -617,52 +629,113 @@ export declare class WebMultiSelect<T = any> {
|
|
|
617
629
|
private handleDropdownClick;
|
|
618
630
|
private handleBadgeClick;
|
|
619
631
|
private handleClickOutside;
|
|
632
|
+
/**
|
|
633
|
+
* Move focus by computing a new index from (current, total).
|
|
634
|
+
* Returning -1 from `compute` is a no-op (used for empty list / no match).
|
|
635
|
+
*/
|
|
636
|
+
private focusBy;
|
|
620
637
|
private focusNext;
|
|
621
638
|
private focusPrevious;
|
|
622
639
|
private focusFirst;
|
|
623
640
|
private focusLast;
|
|
624
|
-
private focusNextMatch;
|
|
625
|
-
private focusPreviousMatch;
|
|
626
641
|
private focusPageUp;
|
|
627
642
|
private focusPageDown;
|
|
643
|
+
private focusNextMatch;
|
|
644
|
+
private focusPreviousMatch;
|
|
628
645
|
private scrollToFocused;
|
|
629
646
|
private toggleOption;
|
|
630
647
|
private handleAddNew;
|
|
631
648
|
private selectOption;
|
|
632
649
|
private deselectOption;
|
|
633
650
|
private selectAll;
|
|
634
|
-
|
|
651
|
+
clearAll(): void;
|
|
652
|
+
/**
|
|
653
|
+
* Re-render and fire callbacks after a selection state change.
|
|
654
|
+
* `added` / `removed` drive per-item select/deselect callbacks.
|
|
655
|
+
* `changeCallback` fires once if anything actually changed.
|
|
656
|
+
*/
|
|
657
|
+
private commit;
|
|
635
658
|
private open;
|
|
636
659
|
private close;
|
|
660
|
+
/**
|
|
661
|
+
* Anchor a floating panel (dropdown or selected-items popover) below/above the input with
|
|
662
|
+
* placement-locking and width-syncing. Returns the `autoUpdate` cleanup.
|
|
663
|
+
*
|
|
664
|
+
* Both panels share: anchor on input, sync width, default to 'bottom-start', flip on first
|
|
665
|
+
* compute then lock the resulting placement, optionally clamp by dropdownMin/MaxWidth.
|
|
666
|
+
*/
|
|
667
|
+
private anchorFloatingPanel;
|
|
637
668
|
private positionDropdown;
|
|
638
669
|
private positionHint;
|
|
639
670
|
private parseInitialSelection;
|
|
671
|
+
/**
|
|
672
|
+
* Resolve any `selectedValues` entries that don't yet have a matching
|
|
673
|
+
* `selectedOptions` object by looking them up in the current `allOptions`.
|
|
674
|
+
* Idempotent; safe to call after init *and* after `options` is replaced
|
|
675
|
+
* (e.g., async fetch, `searchCallback` result, or late `element.options =`
|
|
676
|
+
* assignment). Without this, `initial-values` declared before options
|
|
677
|
+
* arrive ends up with phantom values that `getValue()` can never report.
|
|
678
|
+
*/
|
|
679
|
+
private reconcileSelectedOptions;
|
|
640
680
|
private toggleSelectedPopover;
|
|
641
681
|
private showPopover;
|
|
642
682
|
private hideSelectedPopover;
|
|
643
683
|
private renderSelectedPopover;
|
|
644
684
|
private renderSelectedPopoverVirtual;
|
|
645
|
-
|
|
685
|
+
/**
|
|
686
|
+
* Render a removable badge for a selected option (used by the badges/partial display modes
|
|
687
|
+
* and by the selected-items popover).
|
|
688
|
+
*
|
|
689
|
+
* - In the popover, `renderSelectedItemContentCallback` and `getSelectedItemClassCallback` win
|
|
690
|
+
* over the regular badge callbacks; that's how consumers customize popover items independently.
|
|
691
|
+
* - The `data-value` and aria-label both go through `getItemBadgeDisplayValue` so badge text and
|
|
692
|
+
* accessible name stay in sync.
|
|
693
|
+
*/
|
|
694
|
+
private renderBadgeHTML;
|
|
646
695
|
private handleSelectedPopoverClick;
|
|
647
696
|
private positionSelectedPopover;
|
|
648
697
|
private updateHiddenInput;
|
|
649
698
|
private getFormValue;
|
|
650
699
|
getSelected(): T[];
|
|
651
700
|
setSelected(values: (string | number)[]): void;
|
|
701
|
+
/**
|
|
702
|
+
* Merge a partial config update into the live picker without tearing down the DOM.
|
|
703
|
+
*
|
|
704
|
+
* Handles the cheap structural toggles inline (no-checkboxes class, badges-position class,
|
|
705
|
+
* input placeholder, search-input mode) and re-renders dropdown + badges + hidden inputs.
|
|
706
|
+
*
|
|
707
|
+
* Returns `true` if the change could be applied in place. Returns `false` for changes that
|
|
708
|
+
* truly require rebuilding the DOM scaffolding (currently: adding/removing the `searchHint`
|
|
709
|
+
* element, since it's only created in `buildHTML` if a hint string was provided). The caller
|
|
710
|
+
* should fall back to destroy + re-init in that case.
|
|
711
|
+
*/
|
|
712
|
+
updateOptions(partial: Partial<MultiSelectConfig<T>>): boolean;
|
|
652
713
|
get selectedItem(): T | null;
|
|
653
714
|
get selectedValue(): string | number | (string | number)[] | null;
|
|
654
715
|
getValue(): string | number | (string | number)[] | null;
|
|
716
|
+
/**
|
|
717
|
+
* Create or replace a tracked tooltip with the given id. Replacing destroys the old one,
|
|
718
|
+
* which is the normal flow when re-rendering badges/actions.
|
|
719
|
+
*/
|
|
720
|
+
private spawnTooltip;
|
|
721
|
+
private destroyAllTooltips;
|
|
722
|
+
/** Build the badge-text tooltip content (callback overrides; default = displayValue + optional subtitle on next line). */
|
|
723
|
+
private buildBadgeTooltipContent;
|
|
724
|
+
/** Build the remove-button tooltip text (callback > format string with {0} > "Remove {name}"). */
|
|
725
|
+
private buildRemoveButtonTooltipText;
|
|
655
726
|
private attachBadgeTooltips;
|
|
656
|
-
private createTooltipForElement;
|
|
657
|
-
private createRemoveButtonTooltip;
|
|
658
|
-
private positionBadgeTooltip;
|
|
659
|
-
private cleanupBadgeTooltip;
|
|
660
|
-
private destroyAllBadgeTooltips;
|
|
661
727
|
private attachActionButtonTooltips;
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
728
|
+
/**
|
|
729
|
+
* Destroy only the action-button tooltips. Called from `renderDropdown`/`renderDropdownVirtual`
|
|
730
|
+
* before rebuilding the actions row, so per-button tooltip state doesn't leak.
|
|
731
|
+
*/
|
|
665
732
|
private destroyAllActionButtonTooltips;
|
|
733
|
+
/**
|
|
734
|
+
* Destroy main-badges-container tooltips. Called before re-rendering the badges container.
|
|
735
|
+
* Popover tooltips (prefixed `popover-`) survive — they're owned by the popover lifecycle and
|
|
736
|
+
* cleaned up in `hideSelectedPopover`. Action-button tooltips (prefixed `action-`) survive too.
|
|
737
|
+
*/
|
|
738
|
+
private destroyAllBadgeTooltips;
|
|
666
739
|
destroy(): void;
|
|
667
740
|
}
|
|
668
741
|
|