@keenmate/web-multiselect 1.8.6 → 1.9.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 +5 -1
- package/dist/index.d.ts +99 -45
- package/dist/multiselect.js +1435 -1416
- package/dist/multiselect.umd.js +14 -24
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/css/_badges-display.css +8 -1
- package/src/css/_variables.css +594 -597
package/README.md
CHANGED
|
@@ -327,11 +327,15 @@ multiselect.addNewCallback = async (value) => {
|
|
|
327
327
|
|
|
328
328
|
- **↑ ↓** - Navigate up/down through options
|
|
329
329
|
- **Ctrl+↑ Ctrl+↓** - Jump between matched items (navigate mode only)
|
|
330
|
-
- **
|
|
330
|
+
- **Page Up / Page Down** - Move focus by 10 options at a time
|
|
331
|
+
- **Home / End** - Jump to first / last option
|
|
332
|
+
- **Enter** - Select focused option (or add new entry when `allow-add-new="true"` and the search has text)
|
|
331
333
|
- **Escape** - Close popover → Clear search → Close dropdown (priority order)
|
|
332
334
|
- **Tab** - Close dropdown and move to next field
|
|
333
335
|
- **Type** - Filter options by search term
|
|
334
336
|
|
|
337
|
+
> 💡 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">`.
|
|
338
|
+
|
|
335
339
|
## Advanced Features
|
|
336
340
|
|
|
337
341
|
### Rich Content with Icons
|
package/dist/index.d.ts
CHANGED
|
@@ -321,8 +321,19 @@ export declare class MultiSelectElement<T = any> extends BaseElement {
|
|
|
321
321
|
*/
|
|
322
322
|
private parseDeclarativeOptions;
|
|
323
323
|
private _declarativeSelectedValues?;
|
|
324
|
+
/** Parse all observed attributes via ATTRIBUTE_TABLE into a partial config object. */
|
|
325
|
+
private parseAttributesFromTable;
|
|
324
326
|
private initializePicker;
|
|
325
327
|
private reinitialize;
|
|
328
|
+
/**
|
|
329
|
+
* Apply a partial config update to the live picker. Falls back to a full reinit if the
|
|
330
|
+
* picker can't apply the change in place (e.g. adding/removing the `searchHint` element).
|
|
331
|
+
* No-op if the picker hasn't been initialized yet — the next `initializePicker` will pick
|
|
332
|
+
* up the new programmatic state.
|
|
333
|
+
*/
|
|
334
|
+
private updatePicker;
|
|
335
|
+
/** Normalize the picker's getValue() return into the array form expected by event detail. */
|
|
336
|
+
private collectSelectedValues;
|
|
326
337
|
get options(): T[] | undefined;
|
|
327
338
|
set options(value: T[] | undefined);
|
|
328
339
|
set valueMember(value: string | null);
|
|
@@ -492,9 +503,10 @@ export declare type SearchInputMode = 'normal' | 'readonly' | 'hidden';
|
|
|
492
503
|
export declare type SearchMode = 'filter' | 'navigate';
|
|
493
504
|
|
|
494
505
|
/**
|
|
495
|
-
* Set log level for a specific category
|
|
496
|
-
*
|
|
497
|
-
* @param
|
|
506
|
+
* Set log level for a specific category. Accepts either the full prefixed name
|
|
507
|
+
* (e.g. `MULTISELECT:UI`) or the bare suffix (`UI`) for convenience.
|
|
508
|
+
* @param category Category logger name; bare names (UI/DATA/INIT/INTERACTION) are normalized to the prefixed form.
|
|
509
|
+
* @param level Log level ('trace' | 'debug' | 'info' | 'warn' | 'error' | 'silent')
|
|
498
510
|
*/
|
|
499
511
|
export declare function setCategoryLevel(category: string, level: string): void;
|
|
500
512
|
|
|
@@ -534,12 +546,7 @@ export declare class WebMultiSelect<T = any> {
|
|
|
534
546
|
private dropdownCleanup;
|
|
535
547
|
private hintCleanup;
|
|
536
548
|
private selectedPopoverCleanup;
|
|
537
|
-
private
|
|
538
|
-
private badgeTooltipCleanups;
|
|
539
|
-
private badgeTooltipShowTimeouts;
|
|
540
|
-
private badgeTooltipHideTimeouts;
|
|
541
|
-
private actionButtonTooltips;
|
|
542
|
-
private actionButtonTooltipCleanups;
|
|
549
|
+
private tooltips;
|
|
543
550
|
private virtualScroll;
|
|
544
551
|
private optionsContainer;
|
|
545
552
|
private selectedPopoverVirtualScroll;
|
|
@@ -554,41 +561,31 @@ export declare class WebMultiSelect<T = any> {
|
|
|
554
561
|
private documentKeydownHandler;
|
|
555
562
|
private documentClickHandler;
|
|
556
563
|
/**
|
|
557
|
-
*
|
|
558
|
-
*
|
|
564
|
+
* Generic field extractor with the precedence:
|
|
565
|
+
* tuple short-circuit -> member property -> callback -> fallback
|
|
566
|
+
*
|
|
567
|
+
* Tuple handling:
|
|
568
|
+
* - `tupleIndex` (0 | 1): for `[key, value]` items, return that slot.
|
|
569
|
+
* - `tupleSkip: true`: for any tuple, skip directly to fallback (used for icon/subtitle/group/disabled —
|
|
570
|
+
* fields that don't make sense on a 2-element array).
|
|
571
|
+
* - neither: tuples flow through the member/callback/fallback chain as if they were objects.
|
|
572
|
+
*
|
|
573
|
+
* `transform` is applied to tuple-slot and member-property reads (not to callback returns or the fallback),
|
|
574
|
+
* so e.g. you can pass `String` to coerce numeric members to strings while letting a typed callback return its
|
|
575
|
+
* own type unchanged.
|
|
559
576
|
*/
|
|
577
|
+
private extractField;
|
|
560
578
|
private getItemValue;
|
|
561
|
-
/**
|
|
562
|
-
* Extract display value from item
|
|
563
|
-
* Precedence: tuple[1] -> displayValueMember -> getDisplayValueCallback -> '[N/A]'
|
|
564
|
-
*/
|
|
565
579
|
private getItemDisplayValue;
|
|
566
580
|
/**
|
|
567
|
-
*
|
|
568
|
-
*
|
|
569
|
-
* This allows customizing badge text separately from dropdown display text
|
|
581
|
+
* Badge display falls back to the regular display value rather than '[N/A]', so consumers can override badge
|
|
582
|
+
* text independently. Doesn't fit the extractField shape (no tuple/member layer of its own).
|
|
570
583
|
*/
|
|
571
584
|
private getItemBadgeDisplayValue;
|
|
572
|
-
/**
|
|
573
|
-
* Extract search value from item
|
|
574
|
-
* Precedence: searchValueMember -> getSearchValueCallback -> displayValue
|
|
575
|
-
*/
|
|
576
585
|
private getItemSearchValue;
|
|
577
|
-
/**
|
|
578
|
-
* Extract icon from item
|
|
579
|
-
*/
|
|
580
586
|
private getItemIcon;
|
|
581
|
-
/**
|
|
582
|
-
* Extract subtitle from item
|
|
583
|
-
*/
|
|
584
587
|
private getItemSubtitle;
|
|
585
|
-
/**
|
|
586
|
-
* Extract group from item
|
|
587
|
-
*/
|
|
588
588
|
private getItemGroup;
|
|
589
|
-
/**
|
|
590
|
-
* Extract disabled state from item
|
|
591
|
-
*/
|
|
592
589
|
private getItemDisabled;
|
|
593
590
|
constructor(element: HTMLElement, options?: Partial<MultiSelectConfig<T>>);
|
|
594
591
|
private init;
|
|
@@ -607,6 +604,11 @@ export declare class WebMultiSelect<T = any> {
|
|
|
607
604
|
* Render dropdown with virtual scrolling
|
|
608
605
|
*/
|
|
609
606
|
private renderDropdownVirtual;
|
|
607
|
+
/**
|
|
608
|
+
* Render the Select All / Clear All / custom action buttons row.
|
|
609
|
+
* Returns the empty string if multiple-select is off or no buttons are configured.
|
|
610
|
+
*/
|
|
611
|
+
private renderActionsHTML;
|
|
610
612
|
private renderOption;
|
|
611
613
|
private highlightMatch;
|
|
612
614
|
private groupOptions;
|
|
@@ -617,14 +619,19 @@ export declare class WebMultiSelect<T = any> {
|
|
|
617
619
|
private handleDropdownClick;
|
|
618
620
|
private handleBadgeClick;
|
|
619
621
|
private handleClickOutside;
|
|
622
|
+
/**
|
|
623
|
+
* Move focus by computing a new index from (current, total).
|
|
624
|
+
* Returning -1 from `compute` is a no-op (used for empty list / no match).
|
|
625
|
+
*/
|
|
626
|
+
private focusBy;
|
|
620
627
|
private focusNext;
|
|
621
628
|
private focusPrevious;
|
|
622
629
|
private focusFirst;
|
|
623
630
|
private focusLast;
|
|
624
|
-
private focusNextMatch;
|
|
625
|
-
private focusPreviousMatch;
|
|
626
631
|
private focusPageUp;
|
|
627
632
|
private focusPageDown;
|
|
633
|
+
private focusNextMatch;
|
|
634
|
+
private focusPreviousMatch;
|
|
628
635
|
private scrollToFocused;
|
|
629
636
|
private toggleOption;
|
|
630
637
|
private handleAddNew;
|
|
@@ -632,8 +639,22 @@ export declare class WebMultiSelect<T = any> {
|
|
|
632
639
|
private deselectOption;
|
|
633
640
|
private selectAll;
|
|
634
641
|
private clearAll;
|
|
642
|
+
/**
|
|
643
|
+
* Re-render and fire callbacks after a selection state change.
|
|
644
|
+
* `added` / `removed` drive per-item select/deselect callbacks.
|
|
645
|
+
* `changeCallback` fires once if anything actually changed.
|
|
646
|
+
*/
|
|
647
|
+
private commit;
|
|
635
648
|
private open;
|
|
636
649
|
private close;
|
|
650
|
+
/**
|
|
651
|
+
* Anchor a floating panel (dropdown or selected-items popover) below/above the input with
|
|
652
|
+
* placement-locking and width-syncing. Returns the `autoUpdate` cleanup.
|
|
653
|
+
*
|
|
654
|
+
* Both panels share: anchor on input, sync width, default to 'bottom-start', flip on first
|
|
655
|
+
* compute then lock the resulting placement, optionally clamp by dropdownMin/MaxWidth.
|
|
656
|
+
*/
|
|
657
|
+
private anchorFloatingPanel;
|
|
637
658
|
private positionDropdown;
|
|
638
659
|
private positionHint;
|
|
639
660
|
private parseInitialSelection;
|
|
@@ -642,27 +663,60 @@ export declare class WebMultiSelect<T = any> {
|
|
|
642
663
|
private hideSelectedPopover;
|
|
643
664
|
private renderSelectedPopover;
|
|
644
665
|
private renderSelectedPopoverVirtual;
|
|
645
|
-
|
|
666
|
+
/**
|
|
667
|
+
* Render a removable badge for a selected option (used by the badges/partial display modes
|
|
668
|
+
* and by the selected-items popover).
|
|
669
|
+
*
|
|
670
|
+
* - In the popover, `renderSelectedItemContentCallback` and `getSelectedItemClassCallback` win
|
|
671
|
+
* over the regular badge callbacks; that's how consumers customize popover items independently.
|
|
672
|
+
* - The `data-value` and aria-label both go through `getItemBadgeDisplayValue` so badge text and
|
|
673
|
+
* accessible name stay in sync.
|
|
674
|
+
*/
|
|
675
|
+
private renderBadgeHTML;
|
|
646
676
|
private handleSelectedPopoverClick;
|
|
647
677
|
private positionSelectedPopover;
|
|
648
678
|
private updateHiddenInput;
|
|
649
679
|
private getFormValue;
|
|
650
680
|
getSelected(): T[];
|
|
651
681
|
setSelected(values: (string | number)[]): void;
|
|
682
|
+
/**
|
|
683
|
+
* Merge a partial config update into the live picker without tearing down the DOM.
|
|
684
|
+
*
|
|
685
|
+
* Handles the cheap structural toggles inline (no-checkboxes class, badges-position class,
|
|
686
|
+
* input placeholder, search-input mode) and re-renders dropdown + badges + hidden inputs.
|
|
687
|
+
*
|
|
688
|
+
* Returns `true` if the change could be applied in place. Returns `false` for changes that
|
|
689
|
+
* truly require rebuilding the DOM scaffolding (currently: adding/removing the `searchHint`
|
|
690
|
+
* element, since it's only created in `buildHTML` if a hint string was provided). The caller
|
|
691
|
+
* should fall back to destroy + re-init in that case.
|
|
692
|
+
*/
|
|
693
|
+
updateOptions(partial: Partial<MultiSelectConfig<T>>): boolean;
|
|
652
694
|
get selectedItem(): T | null;
|
|
653
695
|
get selectedValue(): string | number | (string | number)[] | null;
|
|
654
696
|
getValue(): string | number | (string | number)[] | null;
|
|
697
|
+
/**
|
|
698
|
+
* Create or replace a tracked tooltip with the given id. Replacing destroys the old one,
|
|
699
|
+
* which is the normal flow when re-rendering badges/actions.
|
|
700
|
+
*/
|
|
701
|
+
private spawnTooltip;
|
|
702
|
+
private destroyAllTooltips;
|
|
703
|
+
/** Build the badge-text tooltip content (callback overrides; default = displayValue + optional subtitle on next line). */
|
|
704
|
+
private buildBadgeTooltipContent;
|
|
705
|
+
/** Build the remove-button tooltip text (callback > format string with {0} > "Remove {name}"). */
|
|
706
|
+
private buildRemoveButtonTooltipText;
|
|
655
707
|
private attachBadgeTooltips;
|
|
656
|
-
private createTooltipForElement;
|
|
657
|
-
private createRemoveButtonTooltip;
|
|
658
|
-
private positionBadgeTooltip;
|
|
659
|
-
private cleanupBadgeTooltip;
|
|
660
|
-
private destroyAllBadgeTooltips;
|
|
661
708
|
private attachActionButtonTooltips;
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
709
|
+
/**
|
|
710
|
+
* Destroy only the action-button tooltips. Called from `renderDropdown`/`renderDropdownVirtual`
|
|
711
|
+
* before rebuilding the actions row, so per-button tooltip state doesn't leak.
|
|
712
|
+
*/
|
|
665
713
|
private destroyAllActionButtonTooltips;
|
|
714
|
+
/**
|
|
715
|
+
* Destroy main-badges-container tooltips. Called before re-rendering the badges container.
|
|
716
|
+
* Popover tooltips (prefixed `popover-`) survive — they're owned by the popover lifecycle and
|
|
717
|
+
* cleaned up in `hideSelectedPopover`. Action-button tooltips (prefixed `action-`) survive too.
|
|
718
|
+
*/
|
|
719
|
+
private destroyAllBadgeTooltips;
|
|
666
720
|
destroy(): void;
|
|
667
721
|
}
|
|
668
722
|
|