@salt-ds/core 1.70.0 → 1.72.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/CHANGELOG.md +144 -0
- package/css/salt-core.css +466 -106
- package/dist-cjs/accordion/AccordionHeader.css.js +1 -1
- package/dist-cjs/aria-announcer/AriaAnnouncerProvider.js +8 -0
- package/dist-cjs/aria-announcer/AriaAnnouncerProvider.js.map +1 -1
- package/dist-cjs/avatar/Avatar.css.js +1 -1
- package/dist-cjs/badge/Badge.css.js +1 -1
- package/dist-cjs/banner/Banner.css.js +1 -1
- package/dist-cjs/breadcrumbs/Breadcrumb.css.js +1 -1
- package/dist-cjs/breadcrumbs/Breadcrumbs.css.js +1 -1
- package/dist-cjs/card/Card.css.js +1 -1
- package/dist-cjs/card/Card.js +4 -0
- package/dist-cjs/card/Card.js.map +1 -1
- package/dist-cjs/checkbox/Checkbox.css.js +1 -1
- package/dist-cjs/checkbox/CheckboxIcon.css.js +1 -1
- package/dist-cjs/combo-box/ComboBox.js +18 -36
- package/dist-cjs/combo-box/ComboBox.js.map +1 -1
- package/dist-cjs/combo-box/useComboBox.js +21 -21
- package/dist-cjs/combo-box/useComboBox.js.map +1 -1
- package/dist-cjs/drawer/Drawer.css.js +1 -1
- package/dist-cjs/drawer/Drawer.js +30 -5
- package/dist-cjs/drawer/Drawer.js.map +1 -1
- package/dist-cjs/drawer/DrawerCloseButton.js +1 -1
- package/dist-cjs/drawer/DrawerCloseButton.js.map +1 -1
- package/dist-cjs/drawer/DrawerContent.css.js +6 -0
- package/dist-cjs/drawer/DrawerContent.css.js.map +1 -0
- package/dist-cjs/drawer/DrawerContent.js +75 -0
- package/dist-cjs/drawer/DrawerContent.js.map +1 -0
- package/dist-cjs/drawer/DrawerContext.js +30 -0
- package/dist-cjs/drawer/DrawerContext.js.map +1 -0
- package/dist-cjs/drawer/DrawerFooter.css.js +6 -0
- package/dist-cjs/drawer/DrawerFooter.css.js.map +1 -0
- package/dist-cjs/drawer/DrawerFooter.js +30 -0
- package/dist-cjs/drawer/DrawerFooter.js.map +1 -0
- package/dist-cjs/drawer/DrawerHeader.css.js +6 -0
- package/dist-cjs/drawer/DrawerHeader.css.js.map +1 -0
- package/dist-cjs/drawer/DrawerHeader.js +95 -0
- package/dist-cjs/drawer/DrawerHeader.js.map +1 -0
- package/dist-cjs/drawer/hasDrawerSection.js +22 -0
- package/dist-cjs/drawer/hasDrawerSection.js.map +1 -0
- package/dist-cjs/dropdown/Dropdown.js +29 -30
- package/dist-cjs/dropdown/Dropdown.js.map +1 -1
- package/dist-cjs/file-drop-zone/FileDropZone.css.js +1 -1
- package/dist-cjs/form-field/FormField.css.js +1 -1
- package/dist-cjs/form-field/FormField.js +15 -0
- package/dist-cjs/form-field/FormField.js.map +1 -1
- package/dist-cjs/form-field/FormFieldHelperText.css.js +1 -1
- package/dist-cjs/form-field/FormFieldLabel.css.js +1 -1
- package/dist-cjs/form-field/FormFieldLabel.js +1 -1
- package/dist-cjs/form-field/FormFieldLabel.js.map +1 -1
- package/dist-cjs/index.js +10 -0
- package/dist-cjs/index.js.map +1 -1
- package/dist-cjs/input/Input.css.js +1 -1
- package/dist-cjs/interactable-card/InteractableCard.css.js +1 -1
- package/dist-cjs/interactable-card/InteractableCard.js +23 -7
- package/dist-cjs/interactable-card/InteractableCard.js.map +1 -1
- package/dist-cjs/interactable-card/InteractableCardGroup.js +71 -39
- package/dist-cjs/interactable-card/InteractableCardGroup.js.map +1 -1
- package/dist-cjs/interactable-card/InteractableCardGroupContext.js.map +1 -1
- package/dist-cjs/interactable-card/useInteractableCard.js +2 -3
- package/dist-cjs/interactable-card/useInteractableCard.js.map +1 -1
- package/dist-cjs/kbd/Kbd.css.js +1 -1
- package/dist-cjs/link/Link.css.js +1 -1
- package/dist-cjs/link-button/LinkButton.css.js +6 -0
- package/dist-cjs/link-button/LinkButton.css.js.map +1 -0
- package/dist-cjs/link-button/LinkButton.js +87 -0
- package/dist-cjs/link-button/LinkButton.js.map +1 -0
- package/dist-cjs/link-card/LinkCard.css.js +1 -1
- package/dist-cjs/link-card/LinkCard.js +4 -0
- package/dist-cjs/link-card/LinkCard.js.map +1 -1
- package/dist-cjs/list-box/ListBox.js +19 -26
- package/dist-cjs/list-box/ListBox.js.map +1 -1
- package/dist-cjs/list-control/ListControlNavigationKeys.js +74 -0
- package/dist-cjs/list-control/ListControlNavigationKeys.js.map +1 -0
- package/dist-cjs/list-control/ListControlOptionContext.js +47 -0
- package/dist-cjs/list-control/ListControlOptionContext.js.map +1 -0
- package/dist-cjs/list-control/ListControlOptionStore.js +159 -0
- package/dist-cjs/list-control/ListControlOptionStore.js.map +1 -0
- package/dist-cjs/list-control/ListControlProvider.js +39 -0
- package/dist-cjs/list-control/ListControlProvider.js.map +1 -0
- package/dist-cjs/list-control/ListControlRegistry.js +161 -0
- package/dist-cjs/list-control/ListControlRegistry.js.map +1 -0
- package/dist-cjs/list-control/ListControlState.js +137 -109
- package/dist-cjs/list-control/ListControlState.js.map +1 -1
- package/dist-cjs/mega-menu/MegaMenuGroupHeading.css.js +1 -1
- package/dist-cjs/mega-menu/MegaMenuListItem.css.js +1 -1
- package/dist-cjs/menu/MenuGroup.css.js +1 -1
- package/dist-cjs/menu/MenuItem.css.js +1 -1
- package/dist-cjs/menu/MenuItem.js +0 -1
- package/dist-cjs/menu/MenuItem.js.map +1 -1
- package/dist-cjs/navigation-item/NavigationItem.css.js +1 -1
- package/dist-cjs/number-input/NumberInput.js +2 -2
- package/dist-cjs/number-input/NumberInput.js.map +1 -1
- package/dist-cjs/option/Option.js +58 -39
- package/dist-cjs/option/Option.js.map +1 -1
- package/dist-cjs/option/OptionGroup.css.js +1 -1
- package/dist-cjs/overlay/Overlay.js +12 -2
- package/dist-cjs/overlay/Overlay.js.map +1 -1
- package/dist-cjs/overlay/OverlayContext.js +6 -0
- package/dist-cjs/overlay/OverlayContext.js.map +1 -1
- package/dist-cjs/overlay/OverlayFooter.css.js +6 -0
- package/dist-cjs/overlay/OverlayFooter.css.js.map +1 -0
- package/dist-cjs/overlay/OverlayFooter.js +30 -0
- package/dist-cjs/overlay/OverlayFooter.js.map +1 -0
- package/dist-cjs/overlay/OverlayHeader.css.js +1 -1
- package/dist-cjs/overlay/OverlayHeader.js +51 -11
- package/dist-cjs/overlay/OverlayHeader.js.map +1 -1
- package/dist-cjs/overlay/OverlayPanel.css.js +1 -1
- package/dist-cjs/overlay/OverlayPanel.js +20 -7
- package/dist-cjs/overlay/OverlayPanel.js.map +1 -1
- package/dist-cjs/overlay/OverlayPanelContent.css.js +1 -1
- package/dist-cjs/overlay/OverlayPanelContent.js +11 -13
- package/dist-cjs/overlay/OverlayPanelContent.js.map +1 -1
- package/dist-cjs/overlay/hasOverlaySection.js +24 -0
- package/dist-cjs/overlay/hasOverlaySection.js.map +1 -0
- package/dist-cjs/panel/Panel.css.js +1 -1
- package/dist-cjs/panel/Panel.js +13 -2
- package/dist-cjs/panel/Panel.js.map +1 -1
- package/dist-cjs/pill-input/PillInput.css.js +1 -1
- package/dist-cjs/pill-input/PillInput.js +2 -2
- package/dist-cjs/pill-input/PillInput.js.map +1 -1
- package/dist-cjs/radio-button/RadioButton.css.js +1 -1
- package/dist-cjs/radio-button/RadioButtonIcon.css.js +1 -1
- package/dist-cjs/rating/Rating.css.js +1 -1
- package/dist-cjs/slider/internal/SliderTrack.css.js +1 -1
- package/dist-cjs/stepper/internal/StepText.css.js +1 -1
- package/dist-cjs/switch/Switch.css.js +1 -1
- package/dist-cjs/table/Table.css.js +1 -1
- package/dist-cjs/tabs/internal/overflow/useOverflowSelectionState.js +10 -2
- package/dist-cjs/tabs/internal/overflow/useOverflowSelectionState.js.map +1 -1
- package/dist-cjs/tag/Tag.css.js +1 -1
- package/dist-cjs/text/Text.css.js +1 -1
- package/dist-cjs/toast/Toast.css.js +1 -1
- package/dist-cjs/toggle-button/ToggleButton.js +8 -2
- package/dist-cjs/toggle-button/ToggleButton.js.map +1 -1
- package/dist-cjs/toggle-button-group/ToggleButtonGroup.js +71 -8
- package/dist-cjs/toggle-button-group/ToggleButtonGroup.js.map +1 -1
- package/dist-cjs/toggle-button-group/ToggleButtonGroupContext.js.map +1 -1
- package/dist-cjs/toggletip/ToggletipPanel.css.js +1 -1
- package/dist-cjs/tooltip/Tooltip.css.js +1 -1
- package/dist-cjs/vertical-navigation/VerticalNavigationItemContent.css.js +1 -1
- package/dist-cjs/vertical-navigation/VerticalNavigationSubMenu.css.js +1 -1
- package/dist-es/accordion/AccordionHeader.css.js +1 -1
- package/dist-es/aria-announcer/AriaAnnouncerProvider.js +8 -0
- package/dist-es/aria-announcer/AriaAnnouncerProvider.js.map +1 -1
- package/dist-es/avatar/Avatar.css.js +1 -1
- package/dist-es/badge/Badge.css.js +1 -1
- package/dist-es/banner/Banner.css.js +1 -1
- package/dist-es/breadcrumbs/Breadcrumb.css.js +1 -1
- package/dist-es/breadcrumbs/Breadcrumbs.css.js +1 -1
- package/dist-es/card/Card.css.js +1 -1
- package/dist-es/card/Card.js +4 -0
- package/dist-es/card/Card.js.map +1 -1
- package/dist-es/checkbox/Checkbox.css.js +1 -1
- package/dist-es/checkbox/CheckboxIcon.css.js +1 -1
- package/dist-es/combo-box/ComboBox.js +18 -36
- package/dist-es/combo-box/ComboBox.js.map +1 -1
- package/dist-es/combo-box/useComboBox.js +21 -21
- package/dist-es/combo-box/useComboBox.js.map +1 -1
- package/dist-es/drawer/Drawer.css.js +1 -1
- package/dist-es/drawer/Drawer.js +31 -6
- package/dist-es/drawer/Drawer.js.map +1 -1
- package/dist-es/drawer/DrawerCloseButton.js +1 -1
- package/dist-es/drawer/DrawerCloseButton.js.map +1 -1
- package/dist-es/drawer/DrawerContent.css.js +4 -0
- package/dist-es/drawer/DrawerContent.css.js.map +1 -0
- package/dist-es/drawer/DrawerContent.js +73 -0
- package/dist-es/drawer/DrawerContent.js.map +1 -0
- package/dist-es/drawer/DrawerContext.js +27 -0
- package/dist-es/drawer/DrawerContext.js.map +1 -0
- package/dist-es/drawer/DrawerFooter.css.js +4 -0
- package/dist-es/drawer/DrawerFooter.css.js.map +1 -0
- package/dist-es/drawer/DrawerFooter.js +28 -0
- package/dist-es/drawer/DrawerFooter.js.map +1 -0
- package/dist-es/drawer/DrawerHeader.css.js +4 -0
- package/dist-es/drawer/DrawerHeader.css.js.map +1 -0
- package/dist-es/drawer/DrawerHeader.js +93 -0
- package/dist-es/drawer/DrawerHeader.js.map +1 -0
- package/dist-es/drawer/hasDrawerSection.js +20 -0
- package/dist-es/drawer/hasDrawerSection.js.map +1 -0
- package/dist-es/dropdown/Dropdown.js +29 -30
- package/dist-es/dropdown/Dropdown.js.map +1 -1
- package/dist-es/file-drop-zone/FileDropZone.css.js +1 -1
- package/dist-es/form-field/FormField.css.js +1 -1
- package/dist-es/form-field/FormField.js +16 -1
- package/dist-es/form-field/FormField.js.map +1 -1
- package/dist-es/form-field/FormFieldHelperText.css.js +1 -1
- package/dist-es/form-field/FormFieldLabel.css.js +1 -1
- package/dist-es/form-field/FormFieldLabel.js +1 -1
- package/dist-es/form-field/FormFieldLabel.js.map +1 -1
- package/dist-es/index.js +5 -0
- package/dist-es/index.js.map +1 -1
- package/dist-es/input/Input.css.js +1 -1
- package/dist-es/interactable-card/InteractableCard.css.js +1 -1
- package/dist-es/interactable-card/InteractableCard.js +23 -7
- package/dist-es/interactable-card/InteractableCard.js.map +1 -1
- package/dist-es/interactable-card/InteractableCardGroup.js +72 -40
- package/dist-es/interactable-card/InteractableCardGroup.js.map +1 -1
- package/dist-es/interactable-card/InteractableCardGroupContext.js.map +1 -1
- package/dist-es/interactable-card/useInteractableCard.js +2 -3
- package/dist-es/interactable-card/useInteractableCard.js.map +1 -1
- package/dist-es/kbd/Kbd.css.js +1 -1
- package/dist-es/link/Link.css.js +1 -1
- package/dist-es/link-button/LinkButton.css.js +4 -0
- package/dist-es/link-button/LinkButton.css.js.map +1 -0
- package/dist-es/link-button/LinkButton.js +85 -0
- package/dist-es/link-button/LinkButton.js.map +1 -0
- package/dist-es/link-card/LinkCard.css.js +1 -1
- package/dist-es/link-card/LinkCard.js +4 -0
- package/dist-es/link-card/LinkCard.js.map +1 -1
- package/dist-es/list-box/ListBox.js +19 -26
- package/dist-es/list-box/ListBox.js.map +1 -1
- package/dist-es/list-control/ListControlNavigationKeys.js +69 -0
- package/dist-es/list-control/ListControlNavigationKeys.js.map +1 -0
- package/dist-es/list-control/ListControlOptionContext.js +44 -0
- package/dist-es/list-control/ListControlOptionContext.js.map +1 -0
- package/dist-es/list-control/ListControlOptionStore.js +153 -0
- package/dist-es/list-control/ListControlOptionStore.js.map +1 -0
- package/dist-es/list-control/ListControlProvider.js +37 -0
- package/dist-es/list-control/ListControlProvider.js.map +1 -0
- package/dist-es/list-control/ListControlRegistry.js +158 -0
- package/dist-es/list-control/ListControlRegistry.js.map +1 -0
- package/dist-es/list-control/ListControlState.js +137 -110
- package/dist-es/list-control/ListControlState.js.map +1 -1
- package/dist-es/mega-menu/MegaMenuGroupHeading.css.js +1 -1
- package/dist-es/mega-menu/MegaMenuListItem.css.js +1 -1
- package/dist-es/menu/MenuGroup.css.js +1 -1
- package/dist-es/menu/MenuItem.css.js +1 -1
- package/dist-es/menu/MenuItem.js +0 -1
- package/dist-es/menu/MenuItem.js.map +1 -1
- package/dist-es/navigation-item/NavigationItem.css.js +1 -1
- package/dist-es/number-input/NumberInput.js +2 -2
- package/dist-es/number-input/NumberInput.js.map +1 -1
- package/dist-es/option/Option.js +59 -40
- package/dist-es/option/Option.js.map +1 -1
- package/dist-es/option/OptionGroup.css.js +1 -1
- package/dist-es/overlay/Overlay.js +13 -3
- package/dist-es/overlay/Overlay.js.map +1 -1
- package/dist-es/overlay/OverlayContext.js +6 -0
- package/dist-es/overlay/OverlayContext.js.map +1 -1
- package/dist-es/overlay/OverlayFooter.css.js +4 -0
- package/dist-es/overlay/OverlayFooter.css.js.map +1 -0
- package/dist-es/overlay/OverlayFooter.js +28 -0
- package/dist-es/overlay/OverlayFooter.js.map +1 -0
- package/dist-es/overlay/OverlayHeader.css.js +1 -1
- package/dist-es/overlay/OverlayHeader.js +51 -11
- package/dist-es/overlay/OverlayHeader.js.map +1 -1
- package/dist-es/overlay/OverlayPanel.css.js +1 -1
- package/dist-es/overlay/OverlayPanel.js +20 -7
- package/dist-es/overlay/OverlayPanel.js.map +1 -1
- package/dist-es/overlay/OverlayPanelContent.css.js +1 -1
- package/dist-es/overlay/OverlayPanelContent.js +11 -13
- package/dist-es/overlay/OverlayPanelContent.js.map +1 -1
- package/dist-es/overlay/hasOverlaySection.js +22 -0
- package/dist-es/overlay/hasOverlaySection.js.map +1 -0
- package/dist-es/panel/Panel.css.js +1 -1
- package/dist-es/panel/Panel.js +13 -2
- package/dist-es/panel/Panel.js.map +1 -1
- package/dist-es/pill-input/PillInput.css.js +1 -1
- package/dist-es/pill-input/PillInput.js +2 -2
- package/dist-es/pill-input/PillInput.js.map +1 -1
- package/dist-es/radio-button/RadioButton.css.js +1 -1
- package/dist-es/radio-button/RadioButtonIcon.css.js +1 -1
- package/dist-es/rating/Rating.css.js +1 -1
- package/dist-es/slider/internal/SliderTrack.css.js +1 -1
- package/dist-es/stepper/internal/StepText.css.js +1 -1
- package/dist-es/switch/Switch.css.js +1 -1
- package/dist-es/table/Table.css.js +1 -1
- package/dist-es/tabs/internal/overflow/useOverflowSelectionState.js +10 -2
- package/dist-es/tabs/internal/overflow/useOverflowSelectionState.js.map +1 -1
- package/dist-es/tag/Tag.css.js +1 -1
- package/dist-es/text/Text.css.js +1 -1
- package/dist-es/toast/Toast.css.js +1 -1
- package/dist-es/toggle-button/ToggleButton.js +8 -2
- package/dist-es/toggle-button/ToggleButton.js.map +1 -1
- package/dist-es/toggle-button-group/ToggleButtonGroup.js +71 -8
- package/dist-es/toggle-button-group/ToggleButtonGroup.js.map +1 -1
- package/dist-es/toggle-button-group/ToggleButtonGroupContext.js.map +1 -1
- package/dist-es/toggletip/ToggletipPanel.css.js +1 -1
- package/dist-es/tooltip/Tooltip.css.js +1 -1
- package/dist-es/vertical-navigation/VerticalNavigationItemContent.css.js +1 -1
- package/dist-es/vertical-navigation/VerticalNavigationSubMenu.css.js +1 -1
- package/dist-types/card/Card.d.ts +10 -0
- package/dist-types/combo-box/useComboBox.d.ts +3 -6
- package/dist-types/drawer/Drawer.d.ts +1 -1
- package/dist-types/drawer/DrawerCloseButton.d.ts +3 -0
- package/dist-types/drawer/DrawerContent.d.ts +3 -0
- package/dist-types/drawer/DrawerContext.d.ts +9 -0
- package/dist-types/drawer/DrawerFooter.d.ts +3 -0
- package/dist-types/drawer/DrawerHeader.d.ts +24 -0
- package/dist-types/drawer/hasDrawerSection.d.ts +2 -0
- package/dist-types/drawer/index.d.ts +3 -0
- package/dist-types/index.d.ts +1 -0
- package/dist-types/interactable-card/InteractableCard.d.ts +9 -1
- package/dist-types/interactable-card/InteractableCardGroupContext.d.ts +2 -0
- package/dist-types/interactable-card/useInteractableCard.d.ts +1 -2
- package/dist-types/link-button/LinkButton.d.ts +26 -0
- package/dist-types/link-button/index.d.ts +1 -0
- package/dist-types/link-card/LinkCard.d.ts +8 -0
- package/dist-types/list-control/ListControlNavigationKeys.d.ts +30 -0
- package/dist-types/list-control/ListControlOptionContext.d.ts +18 -0
- package/dist-types/list-control/ListControlOptionStore.d.ts +17 -0
- package/dist-types/list-control/ListControlProvider.d.ts +11 -0
- package/dist-types/list-control/ListControlRegistry.d.ts +22 -0
- package/dist-types/list-control/ListControlState.d.ts +6 -6
- package/dist-types/option/Option.d.ts +3 -1
- package/dist-types/overlay/Overlay.d.ts +2 -1
- package/dist-types/overlay/OverlayContext.d.ts +4 -0
- package/dist-types/overlay/OverlayFooter.d.ts +4 -0
- package/dist-types/overlay/hasOverlaySection.d.ts +2 -0
- package/dist-types/overlay/index.d.ts +1 -0
- package/dist-types/panel/Panel.d.ts +4 -0
- package/dist-types/toggle-button-group/ToggleButtonGroupContext.d.ts +2 -1
- package/dist-types/utils/useIsomorphicLayoutEffect.d.ts +2 -2
- package/package.json +14 -10
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var __typeError = (msg) => {
|
|
4
|
+
throw TypeError(msg);
|
|
5
|
+
};
|
|
6
|
+
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
|
|
7
|
+
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
|
|
8
|
+
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
|
|
9
|
+
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), member.set(obj, value), value);
|
|
10
|
+
var __privateWrapper = (obj, member, setter, getter) => ({
|
|
11
|
+
set _(value) {
|
|
12
|
+
__privateSet(obj, member, value);
|
|
13
|
+
},
|
|
14
|
+
get _() {
|
|
15
|
+
return __privateGet(obj, member, getter);
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
var _entries, _ordered, _indexById, _nextGeneration, _hasGaps;
|
|
19
|
+
function createCoalescedRebuild(rebuild, enqueue = (callback) => {
|
|
20
|
+
Promise.resolve().then(callback);
|
|
21
|
+
}) {
|
|
22
|
+
let pending = false;
|
|
23
|
+
let cancelled = false;
|
|
24
|
+
return {
|
|
25
|
+
schedule() {
|
|
26
|
+
if (pending || cancelled) return;
|
|
27
|
+
pending = true;
|
|
28
|
+
enqueue(() => {
|
|
29
|
+
pending = false;
|
|
30
|
+
if (!cancelled) rebuild();
|
|
31
|
+
});
|
|
32
|
+
},
|
|
33
|
+
cancel() {
|
|
34
|
+
cancelled = true;
|
|
35
|
+
pending = false;
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
class ListControlRegistry {
|
|
40
|
+
constructor() {
|
|
41
|
+
__privateAdd(this, _entries, /* @__PURE__ */ new Map());
|
|
42
|
+
__privateAdd(this, _ordered, []);
|
|
43
|
+
__privateAdd(this, _indexById, /* @__PURE__ */ new Map());
|
|
44
|
+
__privateAdd(this, _nextGeneration, 0);
|
|
45
|
+
__privateAdd(this, _hasGaps, false);
|
|
46
|
+
}
|
|
47
|
+
register(option, element) {
|
|
48
|
+
const entry = {
|
|
49
|
+
data: option,
|
|
50
|
+
element,
|
|
51
|
+
generation: __privateWrapper(this, _nextGeneration)._++
|
|
52
|
+
};
|
|
53
|
+
__privateGet(this, _entries).set(option.id, entry);
|
|
54
|
+
const currentIndex = __privateGet(this, _indexById).get(option.id);
|
|
55
|
+
if (currentIndex === void 0) {
|
|
56
|
+
__privateGet(this, _indexById).set(option.id, __privateGet(this, _ordered).length);
|
|
57
|
+
__privateGet(this, _ordered).push(entry);
|
|
58
|
+
} else {
|
|
59
|
+
__privateGet(this, _ordered)[currentIndex] = entry;
|
|
60
|
+
}
|
|
61
|
+
return () => {
|
|
62
|
+
const current = __privateGet(this, _entries).get(option.id);
|
|
63
|
+
if ((current == null ? void 0 : current.generation) !== entry.generation) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
__privateGet(this, _entries).delete(option.id);
|
|
67
|
+
const index = __privateGet(this, _indexById).get(option.id);
|
|
68
|
+
if (index !== void 0 && __privateGet(this, _ordered)[index] === entry) {
|
|
69
|
+
__privateGet(this, _ordered)[index] = void 0;
|
|
70
|
+
__privateGet(this, _indexById).delete(option.id);
|
|
71
|
+
__privateSet(this, _hasGaps, true);
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
rebuild(listElement) {
|
|
76
|
+
const ordered = [];
|
|
77
|
+
const indexById = /* @__PURE__ */ new Map();
|
|
78
|
+
for (const element of listElement.querySelectorAll(
|
|
79
|
+
'[role="option"]'
|
|
80
|
+
)) {
|
|
81
|
+
const entry = __privateGet(this, _entries).get(element.id);
|
|
82
|
+
if ((entry == null ? void 0 : entry.element) === element && element.isConnected) {
|
|
83
|
+
indexById.set(entry.data.id, ordered.length);
|
|
84
|
+
ordered.push(entry);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
for (const id of __privateGet(this, _entries).keys()) {
|
|
88
|
+
if (!indexById.has(id)) {
|
|
89
|
+
__privateGet(this, _entries).delete(id);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
__privateSet(this, _ordered, ordered);
|
|
93
|
+
__privateSet(this, _indexById, indexById);
|
|
94
|
+
__privateSet(this, _hasGaps, false);
|
|
95
|
+
}
|
|
96
|
+
getAt(index) {
|
|
97
|
+
if (!__privateGet(this, _hasGaps)) {
|
|
98
|
+
return __privateGet(this, _ordered)[index];
|
|
99
|
+
}
|
|
100
|
+
let currentIndex = 0;
|
|
101
|
+
for (const entry of __privateGet(this, _ordered)) {
|
|
102
|
+
if (entry && __privateGet(this, _entries).get(entry.data.id) === entry) {
|
|
103
|
+
if (currentIndex === index) return entry;
|
|
104
|
+
currentIndex++;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return void 0;
|
|
108
|
+
}
|
|
109
|
+
get length() {
|
|
110
|
+
return __privateGet(this, _hasGaps) ? __privateGet(this, _entries).size : __privateGet(this, _ordered).length;
|
|
111
|
+
}
|
|
112
|
+
indexOfId(id) {
|
|
113
|
+
const physicalIndex = __privateGet(this, _indexById).get(id);
|
|
114
|
+
if (physicalIndex === void 0 || !__privateGet(this, _hasGaps)) {
|
|
115
|
+
return physicalIndex ?? -1;
|
|
116
|
+
}
|
|
117
|
+
let logicalIndex = 0;
|
|
118
|
+
for (let index = 0; index < physicalIndex; index++) {
|
|
119
|
+
const entry = __privateGet(this, _ordered)[index];
|
|
120
|
+
if (entry && __privateGet(this, _entries).get(entry.data.id) === entry) logicalIndex++;
|
|
121
|
+
}
|
|
122
|
+
return logicalIndex;
|
|
123
|
+
}
|
|
124
|
+
indexOfValue(value) {
|
|
125
|
+
let logicalIndex = 0;
|
|
126
|
+
for (const entry of __privateGet(this, _ordered)) {
|
|
127
|
+
if (entry && __privateGet(this, _entries).get(entry.data.id) === entry) {
|
|
128
|
+
if (entry.data.value === value) return logicalIndex;
|
|
129
|
+
logicalIndex++;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
return -1;
|
|
133
|
+
}
|
|
134
|
+
findByData(option) {
|
|
135
|
+
const entry = __privateGet(this, _entries).get(option.id);
|
|
136
|
+
return (entry == null ? void 0 : entry.data) === option ? entry : void 0;
|
|
137
|
+
}
|
|
138
|
+
matching(predicate) {
|
|
139
|
+
const matches = [];
|
|
140
|
+
for (const entry of __privateGet(this, _ordered)) {
|
|
141
|
+
if (entry !== void 0 && __privateGet(this, _entries).get(entry.data.id) === entry && predicate(entry.data)) {
|
|
142
|
+
matches.push(entry);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return matches;
|
|
146
|
+
}
|
|
147
|
+
snapshot() {
|
|
148
|
+
return __privateGet(this, _ordered).filter(
|
|
149
|
+
(entry) => entry !== void 0
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
_entries = new WeakMap();
|
|
154
|
+
_ordered = new WeakMap();
|
|
155
|
+
_indexById = new WeakMap();
|
|
156
|
+
_nextGeneration = new WeakMap();
|
|
157
|
+
_hasGaps = new WeakMap();
|
|
158
|
+
|
|
159
|
+
exports.ListControlRegistry = ListControlRegistry;
|
|
160
|
+
exports.createCoalescedRebuild = createCoalescedRebuild;
|
|
161
|
+
//# sourceMappingURL=ListControlRegistry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ListControlRegistry.js","sources":["../src/list-control/ListControlRegistry.ts"],"sourcesContent":["import type { OptionValue } from \"./ListControlContext\";\n\nexport interface RegisteredOption<Item> {\n data: OptionValue<Item>;\n element: HTMLElement;\n}\n\ninterface RegistryEntry<Item> extends RegisteredOption<Item> {\n generation: number;\n}\n\nexport function createCoalescedRebuild(\n rebuild: () => void,\n enqueue: (callback: () => void) => void = (callback) => {\n // Promise jobs are supported by Chrome 86.\n Promise.resolve().then(callback);\n },\n): { schedule: () => void; cancel: () => void } {\n let pending = false;\n let cancelled = false;\n\n return {\n schedule() {\n if (pending || cancelled) return;\n pending = true;\n enqueue(() => {\n pending = false;\n if (!cancelled) rebuild();\n });\n },\n cancel() {\n cancelled = true;\n pending = false;\n },\n };\n}\n\n/** Internal option registry optimized for large, non-virtualized lists. */\nexport class ListControlRegistry<Item> {\n readonly #entries = new Map<string, RegistryEntry<Item>>();\n #ordered: (RegistryEntry<Item> | undefined)[] = [];\n #indexById = new Map<string, number>();\n #nextGeneration = 0;\n #hasGaps = false;\n\n register(option: OptionValue<Item>, element: HTMLElement): () => void {\n const entry: RegistryEntry<Item> = {\n data: option,\n element,\n generation: this.#nextGeneration++,\n };\n this.#entries.set(option.id, entry);\n\n const currentIndex = this.#indexById.get(option.id);\n if (currentIndex === undefined) {\n this.#indexById.set(option.id, this.#ordered.length);\n this.#ordered.push(entry);\n } else {\n this.#ordered[currentIndex] = entry;\n }\n\n return () => {\n const current = this.#entries.get(option.id);\n if (current?.generation !== entry.generation) {\n return;\n }\n this.#entries.delete(option.id);\n\n const index = this.#indexById.get(option.id);\n if (index !== undefined && this.#ordered[index] === entry) {\n // Rebuild compacts the snapshot after the corresponding DOM removal.\n this.#ordered[index] = undefined;\n this.#indexById.delete(option.id);\n this.#hasGaps = true;\n }\n };\n }\n\n rebuild(listElement: Pick<HTMLElement, \"querySelectorAll\">): void {\n const ordered: RegistryEntry<Item>[] = [];\n const indexById = new Map<string, number>();\n\n for (const element of listElement.querySelectorAll<HTMLElement>(\n '[role=\"option\"]',\n )) {\n const entry = this.#entries.get(element.id);\n if (entry?.element === element && element.isConnected) {\n indexById.set(entry.data.id, ordered.length);\n ordered.push(entry);\n }\n }\n\n for (const id of this.#entries.keys()) {\n if (!indexById.has(id)) {\n this.#entries.delete(id);\n }\n }\n\n this.#ordered = ordered;\n this.#indexById = indexById;\n this.#hasGaps = false;\n }\n\n getAt(index: number): RegisteredOption<Item> | undefined {\n if (!this.#hasGaps) {\n return this.#ordered[index];\n }\n\n let currentIndex = 0;\n for (const entry of this.#ordered) {\n if (entry && this.#entries.get(entry.data.id) === entry) {\n if (currentIndex === index) return entry;\n currentIndex++;\n }\n }\n return undefined;\n }\n\n get length(): number {\n return this.#hasGaps ? this.#entries.size : this.#ordered.length;\n }\n\n indexOfId(id: string): number {\n const physicalIndex = this.#indexById.get(id);\n if (physicalIndex === undefined || !this.#hasGaps) {\n return physicalIndex ?? -1;\n }\n\n let logicalIndex = 0;\n for (let index = 0; index < physicalIndex; index++) {\n const entry = this.#ordered[index];\n if (entry && this.#entries.get(entry.data.id) === entry) logicalIndex++;\n }\n return logicalIndex;\n }\n\n indexOfValue(value: Item): number {\n let logicalIndex = 0;\n for (const entry of this.#ordered) {\n if (entry && this.#entries.get(entry.data.id) === entry) {\n if (entry.data.value === value) return logicalIndex;\n logicalIndex++;\n }\n }\n return -1;\n }\n\n findByData(option: OptionValue<Item>): RegisteredOption<Item> | undefined {\n const entry = this.#entries.get(option.id);\n return entry?.data === option ? entry : undefined;\n }\n\n matching(\n predicate: (option: OptionValue<Item>) => boolean,\n ): RegisteredOption<Item>[] {\n const matches: RegistryEntry<Item>[] = [];\n for (const entry of this.#ordered) {\n if (\n entry !== undefined &&\n this.#entries.get(entry.data.id) === entry &&\n predicate(entry.data)\n ) {\n matches.push(entry);\n }\n }\n return matches;\n }\n\n snapshot(): readonly RegisteredOption<Item>[] {\n return this.#ordered.filter(\n (entry): entry is RegistryEntry<Item> => entry !== undefined,\n );\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -4,15 +4,53 @@ var React = require('react');
|
|
|
4
4
|
require('clsx');
|
|
5
5
|
require('react/jsx-runtime');
|
|
6
6
|
var useControlled = require('../utils/useControlled.js');
|
|
7
|
+
var useEventCallback = require('../utils/useEventCallback.js');
|
|
7
8
|
require('../utils/useFloatingUI/useFloatingUI.js');
|
|
8
9
|
var useForkRef = require('../utils/useForkRef.js');
|
|
9
10
|
require('../utils/useId.js');
|
|
11
|
+
var useIsomorphicLayoutEffect = require('../utils/useIsomorphicLayoutEffect.js');
|
|
10
12
|
require('../salt-provider/SaltProvider.js');
|
|
11
13
|
require('../viewport/ViewportProvider.js');
|
|
14
|
+
var ListControlOptionStore = require('./ListControlOptionStore.js');
|
|
15
|
+
var ListControlRegistry = require('./ListControlRegistry.js');
|
|
12
16
|
|
|
13
17
|
function defaultValueToString(item) {
|
|
14
18
|
return String(item);
|
|
15
19
|
}
|
|
20
|
+
function findOptionFromSearch(options, search, valueToString, startFrom) {
|
|
21
|
+
var _a;
|
|
22
|
+
const collator = new Intl.Collator("en", {
|
|
23
|
+
usage: "search",
|
|
24
|
+
sensitivity: "base"
|
|
25
|
+
});
|
|
26
|
+
const startFromIndex = startFrom ? options.findIndex((item) => item.data.value === startFrom.value) : -1;
|
|
27
|
+
const startIndex = startFrom ? startFromIndex + 1 : 0;
|
|
28
|
+
const firstIndexByValue = /* @__PURE__ */ new Map();
|
|
29
|
+
for (let index = 0; index < options.length; index++) {
|
|
30
|
+
const value = options[index].data.value;
|
|
31
|
+
if ((typeof value !== "number" || !Number.isNaN(value)) && !firstIndexByValue.has(value)) {
|
|
32
|
+
firstIndexByValue.set(value, index);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
const letters = search.split("");
|
|
36
|
+
const allSameLetter = letters.length > 0 && letters.every((letter) => collator.compare(letter, letters[0]) === 0);
|
|
37
|
+
let repeatedCharacterMatch;
|
|
38
|
+
for (let offset = 0; offset < options.length; offset++) {
|
|
39
|
+
const index = (startIndex + offset) % options.length;
|
|
40
|
+
const option = options[index].data;
|
|
41
|
+
if (firstIndexByValue.get(option.value) !== index) {
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
const optionText = valueToString(option.value);
|
|
45
|
+
if (collator.compare(optionText.substring(0, search.length), search) === 0) {
|
|
46
|
+
return option;
|
|
47
|
+
}
|
|
48
|
+
if (repeatedCharacterMatch === void 0 && allSameLetter && collator.compare((_a = optionText[0]) == null ? void 0 : _a.toLowerCase(), letters[0]) === 0) {
|
|
49
|
+
repeatedCharacterMatch = option;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return repeatedCharacterMatch;
|
|
53
|
+
}
|
|
16
54
|
function useListControl(props) {
|
|
17
55
|
const {
|
|
18
56
|
open: openProp,
|
|
@@ -26,6 +64,13 @@ function useListControl(props) {
|
|
|
26
64
|
readOnly,
|
|
27
65
|
valueToString = defaultValueToString
|
|
28
66
|
} = props;
|
|
67
|
+
const optionStateStoreRef = React.useRef(null);
|
|
68
|
+
if (optionStateStoreRef.current === null) {
|
|
69
|
+
optionStateStoreRef.current = new ListControlOptionStore.ListControlOptionStore(
|
|
70
|
+
selectedProp ?? defaultSelected ?? []
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
const optionStateStore = optionStateStoreRef.current;
|
|
29
74
|
const listRef = React.useRef(null);
|
|
30
75
|
const [listElement, setListElement] = React.useState(null);
|
|
31
76
|
const setListRef = useForkRef.useForkRef(listRef, setListElement);
|
|
@@ -37,16 +82,9 @@ function useListControl(props) {
|
|
|
37
82
|
setFocusVisibleState(false);
|
|
38
83
|
}
|
|
39
84
|
}, [disabled, focusedState]);
|
|
40
|
-
const [activeState,
|
|
85
|
+
const [activeState, setActive] = React.useState(
|
|
41
86
|
void 0
|
|
42
87
|
);
|
|
43
|
-
const setActive = React.useCallback((option) => {
|
|
44
|
-
if (option) {
|
|
45
|
-
setActiveState(option);
|
|
46
|
-
} else {
|
|
47
|
-
setActiveState(void 0);
|
|
48
|
-
}
|
|
49
|
-
}, []);
|
|
50
88
|
const [openState, setOpenState] = useControlled.useControlled({
|
|
51
89
|
controlled: openProp,
|
|
52
90
|
default: Boolean(defaultOpen),
|
|
@@ -70,152 +108,143 @@ function useListControl(props) {
|
|
|
70
108
|
name: "ListControl",
|
|
71
109
|
state: "selected"
|
|
72
110
|
});
|
|
73
|
-
const select = (
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
if (
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
111
|
+
const select = useEventCallback.useEventCallback(
|
|
112
|
+
(event, option) => {
|
|
113
|
+
if (option.disabled || readOnly || disabled) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
let newSelected = [option.value];
|
|
117
|
+
if (multiselect) {
|
|
118
|
+
if (selectedState.includes(option.value)) {
|
|
119
|
+
newSelected = selectedState.filter((item) => item !== option.value);
|
|
120
|
+
} else {
|
|
121
|
+
newSelected = selectedState.concat([option.value]);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
setSelectedState(newSelected);
|
|
125
|
+
onSelectionChange == null ? void 0 : onSelectionChange(event, newSelected);
|
|
126
|
+
if (!multiselect) {
|
|
127
|
+
setOpen(false);
|
|
83
128
|
}
|
|
84
129
|
}
|
|
85
|
-
|
|
86
|
-
onSelectionChange == null ? void 0 : onSelectionChange(event, newSelected);
|
|
87
|
-
if (!multiselect) {
|
|
88
|
-
setOpen(false);
|
|
89
|
-
}
|
|
90
|
-
};
|
|
130
|
+
);
|
|
91
131
|
const clear = (event) => {
|
|
92
132
|
setSelectedState([]);
|
|
93
133
|
if (selectedState.length !== 0) {
|
|
94
134
|
onSelectionChange == null ? void 0 : onSelectionChange(event, []);
|
|
95
135
|
}
|
|
96
136
|
};
|
|
97
|
-
const
|
|
137
|
+
const registryRef = React.useRef(null);
|
|
138
|
+
if (registryRef.current === null) {
|
|
139
|
+
registryRef.current = new ListControlRegistry.ListControlRegistry();
|
|
140
|
+
}
|
|
141
|
+
const registry = registryRef.current;
|
|
142
|
+
const scheduleRebuildRef = React.useRef(void 0);
|
|
143
|
+
useIsomorphicLayoutEffect.useIsomorphicLayoutEffect(() => {
|
|
144
|
+
optionStateStore.setActiveId(activeState == null ? void 0 : activeState.id);
|
|
145
|
+
}, [activeState == null ? void 0 : activeState.id, optionStateStore]);
|
|
146
|
+
useIsomorphicLayoutEffect.useIsomorphicLayoutEffect(() => {
|
|
147
|
+
optionStateStore.setFocusVisible(focusVisibleState);
|
|
148
|
+
}, [focusVisibleState, optionStateStore]);
|
|
149
|
+
useIsomorphicLayoutEffect.useIsomorphicLayoutEffect(() => {
|
|
150
|
+
optionStateStore.setSelected(selectedState);
|
|
151
|
+
}, [optionStateStore, selectedState]);
|
|
98
152
|
const register = React.useCallback(
|
|
99
153
|
(optionValue, element) => {
|
|
100
|
-
|
|
101
|
-
const
|
|
102
|
-
|
|
103
|
-
);
|
|
104
|
-
if (existingIndex !== -1) {
|
|
105
|
-
optionsRef.current.splice(existingIndex, 1);
|
|
106
|
-
}
|
|
107
|
-
optionsRef.current.push({ data: optionValue, element });
|
|
154
|
+
var _a;
|
|
155
|
+
const unregisterOptionState = optionStateStore.register(optionValue);
|
|
156
|
+
const unregisterRegistry = registry.register(optionValue, element);
|
|
157
|
+
(_a = scheduleRebuildRef.current) == null ? void 0 : _a.call(scheduleRebuildRef);
|
|
108
158
|
return () => {
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
);
|
|
159
|
+
var _a2;
|
|
160
|
+
unregisterRegistry();
|
|
161
|
+
unregisterOptionState();
|
|
162
|
+
(_a2 = scheduleRebuildRef.current) == null ? void 0 : _a2.call(scheduleRebuildRef);
|
|
112
163
|
};
|
|
113
164
|
},
|
|
114
|
-
[]
|
|
165
|
+
[optionStateStore, registry]
|
|
115
166
|
);
|
|
116
167
|
React.useEffect(() => {
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
if (pos & Node.DOCUMENT_POSITION_FOLLOWING) return -1;
|
|
122
|
-
if (pos & Node.DOCUMENT_POSITION_PRECEDING) return 1;
|
|
123
|
-
return 0;
|
|
124
|
-
});
|
|
168
|
+
if (!listElement) return;
|
|
169
|
+
const rebuild = () => {
|
|
170
|
+
mutationObserver.takeRecords();
|
|
171
|
+
registry.rebuild(listElement);
|
|
125
172
|
};
|
|
173
|
+
const coalescedRebuild = ListControlRegistry.createCoalescedRebuild(rebuild);
|
|
174
|
+
scheduleRebuildRef.current = coalescedRebuild.schedule;
|
|
175
|
+
const containsOption = (node) => node.nodeType === Node.ELEMENT_NODE && (node.matches('[role="option"]') || node.querySelector('[role="option"]') !== null);
|
|
126
176
|
const mutationObserver = new MutationObserver((mutations) => {
|
|
127
|
-
|
|
128
|
-
(
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
return node instanceof HTMLElement && ((_a = node.matches) == null ? void 0 : _a.call(node, '[role="option"]'));
|
|
132
|
-
}
|
|
133
|
-
)
|
|
134
|
-
);
|
|
135
|
-
if (optionsChanged) {
|
|
136
|
-
sortOptions();
|
|
177
|
+
if (mutations.some(
|
|
178
|
+
({ addedNodes, removedNodes }) => Array.from(addedNodes).some(containsOption) || Array.from(removedNodes).some(containsOption)
|
|
179
|
+
)) {
|
|
180
|
+
coalescedRebuild.schedule();
|
|
137
181
|
}
|
|
138
182
|
});
|
|
139
|
-
if (!listElement) return;
|
|
140
183
|
mutationObserver.observe(listElement, {
|
|
141
184
|
childList: true,
|
|
142
185
|
subtree: true
|
|
143
186
|
});
|
|
144
|
-
|
|
145
|
-
return () =>
|
|
146
|
-
|
|
187
|
+
rebuild();
|
|
188
|
+
return () => {
|
|
189
|
+
scheduleRebuildRef.current = void 0;
|
|
190
|
+
coalescedRebuild.cancel();
|
|
191
|
+
mutationObserver.disconnect();
|
|
192
|
+
};
|
|
193
|
+
}, [listElement, registry]);
|
|
147
194
|
const getOptionAtIndex = React.useCallback(
|
|
148
195
|
(index) => {
|
|
149
|
-
return
|
|
196
|
+
return registry.getAt(index);
|
|
150
197
|
},
|
|
151
|
-
[]
|
|
198
|
+
[registry]
|
|
199
|
+
);
|
|
200
|
+
const getIndexOfOption = React.useCallback(
|
|
201
|
+
(option) => {
|
|
202
|
+
return registry.indexOfValue(option.value);
|
|
203
|
+
},
|
|
204
|
+
[registry]
|
|
152
205
|
);
|
|
153
|
-
const getIndexOfOption = React.useCallback((option) => {
|
|
154
|
-
return optionsRef.current.findIndex(
|
|
155
|
-
(item) => item.data.value === option.value
|
|
156
|
-
);
|
|
157
|
-
}, []);
|
|
158
206
|
const getOptionsMatching = React.useCallback(
|
|
159
207
|
(predicate) => {
|
|
160
|
-
return
|
|
208
|
+
return registry.matching(predicate);
|
|
161
209
|
},
|
|
162
|
-
[]
|
|
210
|
+
[registry]
|
|
163
211
|
);
|
|
164
212
|
const getOptionFromSearch = React.useCallback(
|
|
165
213
|
(search, startFrom) => {
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
const searchList = optionsRef.current.map((item) => item.data);
|
|
172
|
-
let matches = searchList.filter(
|
|
173
|
-
(option) => collator.compare(
|
|
174
|
-
valueToString(option.value).substring(0, search.length),
|
|
175
|
-
search
|
|
176
|
-
) === 0
|
|
214
|
+
return findOptionFromSearch(
|
|
215
|
+
registry.snapshot(),
|
|
216
|
+
search,
|
|
217
|
+
valueToString,
|
|
218
|
+
startFrom
|
|
177
219
|
);
|
|
178
|
-
if (matches.length === 0) {
|
|
179
|
-
const letters = search.split("");
|
|
180
|
-
const allSameLetter = letters.length > 0 && letters.every((letter) => collator.compare(letter, letters[0]) === 0);
|
|
181
|
-
if (allSameLetter) {
|
|
182
|
-
matches = searchList.filter(
|
|
183
|
-
(option) => collator.compare(
|
|
184
|
-
valueToString(option.value)[0].toLowerCase(),
|
|
185
|
-
letters[0]
|
|
186
|
-
) === 0
|
|
187
|
-
);
|
|
188
|
-
}
|
|
189
|
-
}
|
|
190
|
-
return matches.find((option) => getIndexOfOption(option) >= startIndex);
|
|
191
220
|
},
|
|
192
|
-
[
|
|
221
|
+
[registry, valueToString]
|
|
193
222
|
);
|
|
194
223
|
const getFirstOption = React.useCallback(() => {
|
|
195
224
|
return getOptionAtIndex(0);
|
|
196
225
|
}, [getOptionAtIndex]);
|
|
197
226
|
const getLastOption = React.useCallback(() => {
|
|
198
|
-
return getOptionAtIndex(
|
|
199
|
-
}, [getOptionAtIndex]);
|
|
227
|
+
return getOptionAtIndex(registry.length - 1);
|
|
228
|
+
}, [getOptionAtIndex, registry]);
|
|
200
229
|
const getOptionBefore = React.useCallback(
|
|
201
230
|
(option) => {
|
|
202
|
-
const index =
|
|
231
|
+
const index = registry.indexOfId(option.id);
|
|
203
232
|
return getOptionAtIndex(index - 1);
|
|
204
233
|
},
|
|
205
|
-
[
|
|
234
|
+
[getOptionAtIndex, registry]
|
|
206
235
|
);
|
|
207
236
|
const getOptionAfter = React.useCallback(
|
|
208
237
|
(option) => {
|
|
209
|
-
const index =
|
|
238
|
+
const index = registry.indexOfId(option.id);
|
|
210
239
|
return getOptionAtIndex(index + 1);
|
|
211
240
|
},
|
|
212
|
-
[
|
|
241
|
+
[getOptionAtIndex, registry]
|
|
213
242
|
);
|
|
214
243
|
const getOptionPageAbove = React.useCallback(
|
|
215
244
|
(start) => {
|
|
216
245
|
var _a;
|
|
217
246
|
const list = listRef.current;
|
|
218
|
-
let option =
|
|
247
|
+
let option = registry.findByData(start);
|
|
219
248
|
if (!list || !option) {
|
|
220
249
|
return void 0;
|
|
221
250
|
}
|
|
@@ -232,12 +261,12 @@ function useListControl(props) {
|
|
|
232
261
|
}
|
|
233
262
|
return option ?? getFirstOption();
|
|
234
263
|
},
|
|
235
|
-
[getFirstOption, getOptionBefore]
|
|
264
|
+
[getFirstOption, getOptionBefore, registry]
|
|
236
265
|
);
|
|
237
266
|
const getOptionPageBelow = React.useCallback(
|
|
238
267
|
(start) => {
|
|
239
268
|
const list = listRef.current;
|
|
240
|
-
let option =
|
|
269
|
+
let option = registry.findByData(start);
|
|
241
270
|
if (!list || !option) {
|
|
242
271
|
return void 0;
|
|
243
272
|
}
|
|
@@ -254,14 +283,12 @@ function useListControl(props) {
|
|
|
254
283
|
}
|
|
255
284
|
return option ?? getLastOption();
|
|
256
285
|
},
|
|
257
|
-
[getLastOption, getOptionAfter]
|
|
286
|
+
[getLastOption, getOptionAfter, registry]
|
|
258
287
|
);
|
|
259
288
|
React.useEffect(() => {
|
|
260
289
|
var _a;
|
|
261
290
|
if (listRef.current) {
|
|
262
|
-
const activeElement = (_a =
|
|
263
|
-
(option) => option.data === activeState
|
|
264
|
-
)) == null ? void 0 : _a.element;
|
|
291
|
+
const activeElement = activeState ? (_a = registry.findByData(activeState)) == null ? void 0 : _a.element : void 0;
|
|
265
292
|
if (!activeElement) {
|
|
266
293
|
return;
|
|
267
294
|
}
|
|
@@ -270,7 +297,7 @@ function useListControl(props) {
|
|
|
270
297
|
inline: "nearest"
|
|
271
298
|
});
|
|
272
299
|
}
|
|
273
|
-
}, [activeState]);
|
|
300
|
+
}, [activeState, registry]);
|
|
274
301
|
return {
|
|
275
302
|
multiselect: Boolean(multiselect),
|
|
276
303
|
openState,
|
|
@@ -288,7 +315,6 @@ function useListControl(props) {
|
|
|
288
315
|
setFocusedState,
|
|
289
316
|
setListRef,
|
|
290
317
|
listRef,
|
|
291
|
-
options: optionsRef.current.map((option) => option.element),
|
|
292
318
|
register,
|
|
293
319
|
getOptionAtIndex,
|
|
294
320
|
getIndexOfOption,
|
|
@@ -301,10 +327,12 @@ function useListControl(props) {
|
|
|
301
327
|
getFirstOption,
|
|
302
328
|
getLastOption,
|
|
303
329
|
valueToString,
|
|
304
|
-
disabled
|
|
330
|
+
disabled,
|
|
331
|
+
optionStateStore
|
|
305
332
|
};
|
|
306
333
|
}
|
|
307
334
|
|
|
308
335
|
exports.defaultValueToString = defaultValueToString;
|
|
336
|
+
exports.findOptionFromSearch = findOptionFromSearch;
|
|
309
337
|
exports.useListControl = useListControl;
|
|
310
338
|
//# sourceMappingURL=ListControlState.js.map
|