@reactzero/combo 0.1.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 +31 -0
- package/LICENSE +21 -0
- package/README.md +188 -0
- package/dist/Combo-Cx3kSkop.cjs +2 -0
- package/dist/Combo-Cx3kSkop.cjs.map +1 -0
- package/dist/Combo-qs6_L512.js +439 -0
- package/dist/Combo-qs6_L512.js.map +1 -0
- package/dist/components/Combo.d.ts +71 -0
- package/dist/components/Combo.d.ts.map +1 -0
- package/dist/components/LiveRegion.d.ts +7 -0
- package/dist/components/LiveRegion.d.ts.map +1 -0
- package/dist/components/Portal.d.ts +8 -0
- package/dist/components/Portal.d.ts.map +1 -0
- package/dist/components/slots/CheckboxItem.d.ts +38 -0
- package/dist/components/slots/CheckboxItem.d.ts.map +1 -0
- package/dist/components/slots/CustomItem.d.ts +35 -0
- package/dist/components/slots/CustomItem.d.ts.map +1 -0
- package/dist/components/slots/FooterActions.d.ts +42 -0
- package/dist/components/slots/FooterActions.d.ts.map +1 -0
- package/dist/components/slots/GroupSeparator.d.ts +30 -0
- package/dist/components/slots/GroupSeparator.d.ts.map +1 -0
- package/dist/components/slots/index.d.ts +9 -0
- package/dist/components/slots/index.d.ts.map +1 -0
- package/dist/components/tabs/TabbedCombo.d.ts +45 -0
- package/dist/components/tabs/TabbedCombo.d.ts.map +1 -0
- package/dist/components/tabs/index.d.ts +3 -0
- package/dist/components/tabs/index.d.ts.map +1 -0
- package/dist/core/announce.d.ts +10 -0
- package/dist/core/announce.d.ts.map +1 -0
- package/dist/core/ids.d.ts +13 -0
- package/dist/core/ids.d.ts.map +1 -0
- package/dist/core/keyboard.d.ts +13 -0
- package/dist/core/keyboard.d.ts.map +1 -0
- package/dist/core/scroll.d.ts +5 -0
- package/dist/core/scroll.d.ts.map +1 -0
- package/dist/core/stateMachine.d.ts +32 -0
- package/dist/core/stateMachine.d.ts.map +1 -0
- package/dist/core/utils.d.ts +26 -0
- package/dist/core/utils.d.ts.map +1 -0
- package/dist/defaults-iFGq2Q-7.cjs +2 -0
- package/dist/defaults-iFGq2Q-7.cjs.map +1 -0
- package/dist/defaults-rhC5DFTg.js +53 -0
- package/dist/defaults-rhC5DFTg.js.map +1 -0
- package/dist/entries/hook-bare.d.ts +4 -0
- package/dist/entries/hook-bare.d.ts.map +1 -0
- package/dist/entries/hook.d.ts +4 -0
- package/dist/entries/hook.d.ts.map +1 -0
- package/dist/entries/icons.d.ts +4 -0
- package/dist/entries/icons.d.ts.map +1 -0
- package/dist/entries/index.d.ts +9 -0
- package/dist/entries/index.d.ts.map +1 -0
- package/dist/entries/position.d.ts +3 -0
- package/dist/entries/position.d.ts.map +1 -0
- package/dist/entries/slots.d.ts +9 -0
- package/dist/entries/slots.d.ts.map +1 -0
- package/dist/entries/tabs.d.ts +4 -0
- package/dist/entries/tabs.d.ts.map +1 -0
- package/dist/hook-bare.cjs +2 -0
- package/dist/hook-bare.cjs.map +1 -0
- package/dist/hook-bare.js +9 -0
- package/dist/hook-bare.js.map +1 -0
- package/dist/hook.cjs +2 -0
- package/dist/hook.cjs.map +1 -0
- package/dist/hook.js +11 -0
- package/dist/hook.js.map +1 -0
- package/dist/hooks/useCombo.d.ts +3 -0
- package/dist/hooks/useCombo.d.ts.map +1 -0
- package/dist/hooks/usePosition.d.ts +16 -0
- package/dist/hooks/usePosition.d.ts.map +1 -0
- package/dist/icons/defaults.d.ts +16 -0
- package/dist/icons/defaults.d.ts.map +1 -0
- package/dist/icons/icons.d.ts +30 -0
- package/dist/icons/icons.d.ts.map +1 -0
- package/dist/icons-Ch1Q5AhF.js +40 -0
- package/dist/icons-Ch1Q5AhF.js.map +1 -0
- package/dist/icons-vzkEacAb.cjs +2 -0
- package/dist/icons-vzkEacAb.cjs.map +1 -0
- package/dist/icons.cjs +2 -0
- package/dist/icons.cjs.map +1 -0
- package/dist/icons.js +20 -0
- package/dist/icons.js.map +1 -0
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/position.cjs +2 -0
- package/dist/position.cjs.map +1 -0
- package/dist/position.js +5 -0
- package/dist/position.js.map +1 -0
- package/dist/slots.cjs +2 -0
- package/dist/slots.cjs.map +1 -0
- package/dist/slots.js +92 -0
- package/dist/slots.js.map +1 -0
- package/dist/style.css +1 -0
- package/dist/styles/base.css +205 -0
- package/dist/styles/checkbox.css +36 -0
- package/dist/styles/chips.css +71 -0
- package/dist/styles/custom-item.css +64 -0
- package/dist/styles/footer.css +73 -0
- package/dist/styles/groups.css +23 -0
- package/dist/styles/meta.css +30 -0
- package/dist/styles/radio.css +36 -0
- package/dist/styles/select.css +35 -0
- package/dist/styles/states.css +22 -0
- package/dist/tabs.cjs +2 -0
- package/dist/tabs.cjs.map +1 -0
- package/dist/tabs.js +132 -0
- package/dist/tabs.js.map +1 -0
- package/dist/themes/dark.css +96 -0
- package/dist/themes/default.css +126 -0
- package/dist/themes/high-contrast.css +98 -0
- package/dist/types.d.ts +168 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/useCombo-D_vriwVz.cjs +2 -0
- package/dist/useCombo-D_vriwVz.cjs.map +1 -0
- package/dist/useCombo-gPeBdkRf.js +887 -0
- package/dist/useCombo-gPeBdkRf.js.map +1 -0
- package/dist/usePosition-6GfutqGX.cjs +2 -0
- package/dist/usePosition-6GfutqGX.cjs.map +1 -0
- package/dist/usePosition-DVw8IlwA.js +36 -0
- package/dist/usePosition-DVw8IlwA.js.map +1 -0
- package/package.json +219 -0
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
:root,
|
|
2
|
+
[data-rzero-theme="default"] {
|
|
3
|
+
/* Layout */
|
|
4
|
+
--rzero-combo-z-index: 9999;
|
|
5
|
+
--rzero-combo-max-height: 320px;
|
|
6
|
+
--rzero-combo-min-width: 200px;
|
|
7
|
+
|
|
8
|
+
/* Input */
|
|
9
|
+
--rzero-combo-input-height: 40px;
|
|
10
|
+
--rzero-combo-input-padding: 8px 12px;
|
|
11
|
+
--rzero-combo-input-bg: #ffffff;
|
|
12
|
+
--rzero-combo-input-border: 1px solid #d1d5db;
|
|
13
|
+
--rzero-combo-input-border-radius: 6px;
|
|
14
|
+
--rzero-combo-input-font-size: 14px;
|
|
15
|
+
--rzero-combo-input-color: #111827;
|
|
16
|
+
--rzero-combo-input-focus-ring: 0 0 0 2px #3b82f6;
|
|
17
|
+
|
|
18
|
+
/* Popover */
|
|
19
|
+
--rzero-combo-popover-bg: #ffffff;
|
|
20
|
+
--rzero-combo-popover-border: 1px solid #e5e7eb;
|
|
21
|
+
--rzero-combo-popover-border-radius: 8px;
|
|
22
|
+
--rzero-combo-popover-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
|
|
23
|
+
|
|
24
|
+
/* Items */
|
|
25
|
+
--rzero-combo-item-height: 36px;
|
|
26
|
+
--rzero-combo-item-padding: 0 12px;
|
|
27
|
+
--rzero-combo-item-color: #374151;
|
|
28
|
+
--rzero-combo-item-hover-bg: #f3f4f6;
|
|
29
|
+
--rzero-combo-item-selected-bg: #eff6ff;
|
|
30
|
+
--rzero-combo-item-selected-color: #1d4ed8;
|
|
31
|
+
--rzero-combo-item-highlighted-bg: #dbeafe;
|
|
32
|
+
--rzero-combo-item-disabled-opacity: 0.4;
|
|
33
|
+
|
|
34
|
+
/* Group headers */
|
|
35
|
+
--rzero-combo-group-header-color: #6b7280;
|
|
36
|
+
--rzero-combo-group-header-font-size: 11px;
|
|
37
|
+
--rzero-combo-group-header-font-weight: 600;
|
|
38
|
+
--rzero-combo-group-header-text-transform: uppercase;
|
|
39
|
+
--rzero-combo-group-header-letter-spacing: 0.05em;
|
|
40
|
+
|
|
41
|
+
/* Icons */
|
|
42
|
+
--rzero-combo-icon-size-sm: 12px;
|
|
43
|
+
--rzero-combo-icon-size-md: 16px;
|
|
44
|
+
--rzero-combo-icon-size-lg: 20px;
|
|
45
|
+
--rzero-combo-icon-color: currentColor;
|
|
46
|
+
--rzero-combo-icon-muted-color: #9ca3af;
|
|
47
|
+
|
|
48
|
+
/* Chips */
|
|
49
|
+
--rzero-combo-chip-bg: #e0e7ff;
|
|
50
|
+
--rzero-combo-chip-color: #3730a3;
|
|
51
|
+
--rzero-combo-chip-border-radius: 4px;
|
|
52
|
+
--rzero-combo-chip-font-size: 12px;
|
|
53
|
+
|
|
54
|
+
/* Transitions */
|
|
55
|
+
--rzero-combo-transition-duration: 150ms;
|
|
56
|
+
--rzero-combo-transition-easing: ease;
|
|
57
|
+
|
|
58
|
+
/* Checkbox variant */
|
|
59
|
+
--rzero-combo-checkbox-size: 16px;
|
|
60
|
+
--rzero-combo-checkbox-border: #d1d5db;
|
|
61
|
+
--rzero-combo-checkbox-bg: #ffffff;
|
|
62
|
+
--rzero-combo-checkbox-radius: 3px;
|
|
63
|
+
--rzero-combo-checkbox-checked-bg: #3b82f6;
|
|
64
|
+
--rzero-combo-checkbox-checked-border: #3b82f6;
|
|
65
|
+
--rzero-combo-checkbox-hover-border: #9ca3af;
|
|
66
|
+
|
|
67
|
+
/* Radio variant */
|
|
68
|
+
--rzero-combo-radio-size: 16px;
|
|
69
|
+
--rzero-combo-radio-border: #d1d5db;
|
|
70
|
+
--rzero-combo-radio-bg: #ffffff;
|
|
71
|
+
--rzero-combo-radio-checked-border: #3b82f6;
|
|
72
|
+
--rzero-combo-radio-checked-dot: #3b82f6;
|
|
73
|
+
--rzero-combo-radio-hover-border: #9ca3af;
|
|
74
|
+
|
|
75
|
+
/* Custom item */
|
|
76
|
+
--rzero-combo-custom-item-icon-size: 32px;
|
|
77
|
+
--rzero-combo-custom-item-icon-radius: 6px;
|
|
78
|
+
--rzero-combo-item-description-font-size: 12px;
|
|
79
|
+
--rzero-combo-item-description-color: #6b7280;
|
|
80
|
+
--rzero-combo-item-meta-font-size: 12px;
|
|
81
|
+
--rzero-combo-item-meta-color: #9ca3af;
|
|
82
|
+
|
|
83
|
+
/* Badges */
|
|
84
|
+
--rzero-combo-badge-radius: 10px;
|
|
85
|
+
--rzero-combo-badge-bg: #e5e7eb;
|
|
86
|
+
--rzero-combo-badge-color: #374151;
|
|
87
|
+
--rzero-combo-badge-font-size: 11px;
|
|
88
|
+
|
|
89
|
+
/* Footer actions */
|
|
90
|
+
--rzero-combo-footer-action-border: 1px solid #d1d5db;
|
|
91
|
+
--rzero-combo-footer-action-border-radius: 4px;
|
|
92
|
+
--rzero-combo-footer-action-bg: transparent;
|
|
93
|
+
--rzero-combo-footer-action-color: #374151;
|
|
94
|
+
--rzero-combo-footer-action-font-size: 13px;
|
|
95
|
+
--rzero-combo-footer-action-hover-bg: #f3f4f6;
|
|
96
|
+
--rzero-combo-footer-action-primary-bg: #3b82f6;
|
|
97
|
+
--rzero-combo-footer-action-primary-color: #ffffff;
|
|
98
|
+
--rzero-combo-footer-action-primary-hover-bg: #2563eb;
|
|
99
|
+
--rzero-combo-footer-note-font-size: 12px;
|
|
100
|
+
--rzero-combo-footer-note-color: #9ca3af;
|
|
101
|
+
|
|
102
|
+
/* Separator */
|
|
103
|
+
--rzero-combo-separator-color: #e5e7eb;
|
|
104
|
+
|
|
105
|
+
/* Group header count badge */
|
|
106
|
+
--rzero-combo-group-header-count-bg: #e5e7eb;
|
|
107
|
+
--rzero-combo-group-header-count-color: #6b7280;
|
|
108
|
+
|
|
109
|
+
/* Tabs */
|
|
110
|
+
--rzero-combo-tab-border-color: #e5e7eb;
|
|
111
|
+
--rzero-combo-tab-padding: 8px 12px;
|
|
112
|
+
--rzero-combo-tab-bg: transparent;
|
|
113
|
+
--rzero-combo-tab-color: #6b7280;
|
|
114
|
+
--rzero-combo-tab-font-size: 13px;
|
|
115
|
+
--rzero-combo-tab-font-weight: 500;
|
|
116
|
+
--rzero-combo-tab-hover-bg: #f3f4f6;
|
|
117
|
+
--rzero-combo-tab-hover-color: #374151;
|
|
118
|
+
--rzero-combo-tab-focus-ring: #3b82f6;
|
|
119
|
+
--rzero-combo-tab-active-color: #111827;
|
|
120
|
+
--rzero-combo-tab-active-border-color: #3b82f6;
|
|
121
|
+
--rzero-combo-tab-active-bg: transparent;
|
|
122
|
+
--rzero-combo-tab-badge-bg: #e5e7eb;
|
|
123
|
+
--rzero-combo-tab-badge-color: #6b7280;
|
|
124
|
+
--rzero-combo-tab-badge-active-bg: #dbeafe;
|
|
125
|
+
--rzero-combo-tab-badge-active-color: #1d4ed8;
|
|
126
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
[data-rzero-theme="high-contrast"] {
|
|
2
|
+
/* Input */
|
|
3
|
+
--rzero-combo-input-bg: #000000;
|
|
4
|
+
--rzero-combo-input-border: 2px solid #ffffff;
|
|
5
|
+
--rzero-combo-input-color: #ffffff;
|
|
6
|
+
--rzero-combo-input-hover-border: #ffff00;
|
|
7
|
+
--rzero-combo-input-focus-ring: 0 0 0 3px #ffff00;
|
|
8
|
+
|
|
9
|
+
/* Label & hint */
|
|
10
|
+
--rzero-combo-label-color: #ffffff;
|
|
11
|
+
--rzero-combo-hint-color: #cccccc;
|
|
12
|
+
|
|
13
|
+
/* Error states */
|
|
14
|
+
--rzero-combo-error-border: #ff6666;
|
|
15
|
+
--rzero-combo-error-color: #ff6666;
|
|
16
|
+
--rzero-combo-error-text-color: #ff6666;
|
|
17
|
+
--rzero-combo-error-focus-ring: 0 0 0 3px #ff6666;
|
|
18
|
+
|
|
19
|
+
/* Selection count */
|
|
20
|
+
--rzero-combo-selection-count-color: #cccccc;
|
|
21
|
+
--rzero-combo-selection-count-warning-color: #ffff00;
|
|
22
|
+
|
|
23
|
+
/* Chips */
|
|
24
|
+
--rzero-combo-chip-remove-color: #000000;
|
|
25
|
+
--rzero-combo-chip-remove-hover-color: #000000;
|
|
26
|
+
--rzero-combo-chip-remove-hover-bg: rgba(0, 0, 0, 0.2);
|
|
27
|
+
|
|
28
|
+
--rzero-combo-popover-bg: #000000;
|
|
29
|
+
--rzero-combo-popover-border: 2px solid #ffffff;
|
|
30
|
+
--rzero-combo-popover-shadow: none;
|
|
31
|
+
|
|
32
|
+
--rzero-combo-item-color: #ffffff;
|
|
33
|
+
--rzero-combo-item-hover-bg: #333333;
|
|
34
|
+
--rzero-combo-item-selected-bg: #ffff00;
|
|
35
|
+
--rzero-combo-item-selected-color: #000000;
|
|
36
|
+
--rzero-combo-item-highlighted-bg: #0000ff;
|
|
37
|
+
--rzero-combo-item-disabled-opacity: 0.6;
|
|
38
|
+
|
|
39
|
+
--rzero-combo-group-header-color: #ffffff;
|
|
40
|
+
|
|
41
|
+
--rzero-combo-icon-muted-color: #cccccc;
|
|
42
|
+
|
|
43
|
+
--rzero-combo-chip-bg: #ffff00;
|
|
44
|
+
--rzero-combo-chip-color: #000000;
|
|
45
|
+
|
|
46
|
+
/* Checkbox variant */
|
|
47
|
+
--rzero-combo-checkbox-border: #ffffff;
|
|
48
|
+
--rzero-combo-checkbox-bg: #000000;
|
|
49
|
+
--rzero-combo-checkbox-checked-bg: #ffff00;
|
|
50
|
+
--rzero-combo-checkbox-checked-border: #ffff00;
|
|
51
|
+
--rzero-combo-checkbox-hover-border: #ffff00;
|
|
52
|
+
|
|
53
|
+
/* Radio variant */
|
|
54
|
+
--rzero-combo-radio-border: #ffffff;
|
|
55
|
+
--rzero-combo-radio-bg: #000000;
|
|
56
|
+
--rzero-combo-radio-checked-border: #ffff00;
|
|
57
|
+
--rzero-combo-radio-checked-dot: #ffff00;
|
|
58
|
+
--rzero-combo-radio-hover-border: #ffff00;
|
|
59
|
+
|
|
60
|
+
/* Custom item */
|
|
61
|
+
--rzero-combo-item-description-color: #cccccc;
|
|
62
|
+
--rzero-combo-item-meta-color: #cccccc;
|
|
63
|
+
|
|
64
|
+
/* Badges */
|
|
65
|
+
--rzero-combo-badge-bg: #ffffff;
|
|
66
|
+
--rzero-combo-badge-color: #000000;
|
|
67
|
+
|
|
68
|
+
/* Footer */
|
|
69
|
+
--rzero-combo-footer-border-top: 2px solid #ffffff;
|
|
70
|
+
--rzero-combo-footer-color: #cccccc;
|
|
71
|
+
--rzero-combo-footer-action-border: 2px solid #ffffff;
|
|
72
|
+
--rzero-combo-footer-action-color: #ffffff;
|
|
73
|
+
--rzero-combo-footer-action-hover-bg: #333333;
|
|
74
|
+
--rzero-combo-footer-action-primary-bg: #ffff00;
|
|
75
|
+
--rzero-combo-footer-action-primary-color: #000000;
|
|
76
|
+
--rzero-combo-footer-action-primary-hover-bg: #cccc00;
|
|
77
|
+
--rzero-combo-footer-note-color: #cccccc;
|
|
78
|
+
|
|
79
|
+
/* Separator */
|
|
80
|
+
--rzero-combo-separator-color: #ffffff;
|
|
81
|
+
|
|
82
|
+
/* Group header count badge */
|
|
83
|
+
--rzero-combo-group-header-count-bg: #ffffff;
|
|
84
|
+
--rzero-combo-group-header-count-color: #000000;
|
|
85
|
+
|
|
86
|
+
/* Tabs */
|
|
87
|
+
--rzero-combo-tab-border-color: #ffffff;
|
|
88
|
+
--rzero-combo-tab-color: #cccccc;
|
|
89
|
+
--rzero-combo-tab-hover-bg: #333333;
|
|
90
|
+
--rzero-combo-tab-hover-color: #ffffff;
|
|
91
|
+
--rzero-combo-tab-focus-ring: #ffff00;
|
|
92
|
+
--rzero-combo-tab-active-color: #ffffff;
|
|
93
|
+
--rzero-combo-tab-active-border-color: #ffff00;
|
|
94
|
+
--rzero-combo-tab-badge-bg: #ffffff;
|
|
95
|
+
--rzero-combo-tab-badge-color: #000000;
|
|
96
|
+
--rzero-combo-tab-badge-active-bg: #ffff00;
|
|
97
|
+
--rzero-combo-tab-badge-active-color: #000000;
|
|
98
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import type { ReactNode, HTMLAttributes, RefObject, MutableRefObject } from 'react';
|
|
2
|
+
export type ComboStatus = 'IDLE' | 'FOCUSED_CLOSED' | 'OPEN_IDLE' | 'OPEN_HIGHLIGHTED' | 'LOADING' | 'LOADING_MORE' | 'ERROR';
|
|
3
|
+
export interface ComboState<T> {
|
|
4
|
+
status: ComboStatus;
|
|
5
|
+
selectedItem: T | null;
|
|
6
|
+
selectedItems: T[];
|
|
7
|
+
inputValue: string;
|
|
8
|
+
lastConfirmedValue: string;
|
|
9
|
+
highlightedIndex: number;
|
|
10
|
+
filteredItems: T[];
|
|
11
|
+
expandedItems: Set<string>;
|
|
12
|
+
activeTabId: string | null;
|
|
13
|
+
isLoading: boolean;
|
|
14
|
+
isLoadingMore: boolean;
|
|
15
|
+
error: Error | null;
|
|
16
|
+
visibleChipCount: number;
|
|
17
|
+
}
|
|
18
|
+
export type ComboAction<T> = {
|
|
19
|
+
type: 'FOCUS';
|
|
20
|
+
} | {
|
|
21
|
+
type: 'BLUR';
|
|
22
|
+
} | {
|
|
23
|
+
type: 'INPUT_CHANGE';
|
|
24
|
+
value: string;
|
|
25
|
+
} | {
|
|
26
|
+
type: 'TOGGLE_MENU';
|
|
27
|
+
} | {
|
|
28
|
+
type: 'OPEN_MENU';
|
|
29
|
+
} | {
|
|
30
|
+
type: 'CLOSE_MENU';
|
|
31
|
+
} | {
|
|
32
|
+
type: 'HIGHLIGHT_ITEM';
|
|
33
|
+
index: number;
|
|
34
|
+
} | {
|
|
35
|
+
type: 'HIGHLIGHT_FIRST';
|
|
36
|
+
} | {
|
|
37
|
+
type: 'HIGHLIGHT_LAST';
|
|
38
|
+
} | {
|
|
39
|
+
type: 'HIGHLIGHT_NEXT';
|
|
40
|
+
} | {
|
|
41
|
+
type: 'HIGHLIGHT_PREV';
|
|
42
|
+
} | {
|
|
43
|
+
type: 'SELECT_HIGHLIGHTED';
|
|
44
|
+
} | {
|
|
45
|
+
type: 'SELECT_ITEM';
|
|
46
|
+
item: T;
|
|
47
|
+
} | {
|
|
48
|
+
type: 'DESELECT_ITEM';
|
|
49
|
+
item: T;
|
|
50
|
+
} | {
|
|
51
|
+
type: 'CLEAR_SELECTION';
|
|
52
|
+
} | {
|
|
53
|
+
type: 'REMOVE_LAST_CHIP';
|
|
54
|
+
} | {
|
|
55
|
+
type: 'SELECT_ALL';
|
|
56
|
+
} | {
|
|
57
|
+
type: 'SYNC_ITEMS';
|
|
58
|
+
} | {
|
|
59
|
+
type: 'RESET';
|
|
60
|
+
};
|
|
61
|
+
export interface IconSlots {
|
|
62
|
+
chevronDown: ReactNode;
|
|
63
|
+
check: ReactNode;
|
|
64
|
+
clear: ReactNode;
|
|
65
|
+
search: ReactNode;
|
|
66
|
+
loading: ReactNode;
|
|
67
|
+
}
|
|
68
|
+
export type ChevronStyle = 'caret' | 'arrow' | 'angle' | 'plusminus' | 'dots' | 'none' | 'custom';
|
|
69
|
+
export interface ComboGroup<T> {
|
|
70
|
+
label: string;
|
|
71
|
+
items: T[];
|
|
72
|
+
disabled?: boolean;
|
|
73
|
+
disabledReason?: string;
|
|
74
|
+
}
|
|
75
|
+
export type PropGetter<TElement extends HTMLElement = HTMLElement, TExtra = Record<string, unknown>> = (userProps?: HTMLAttributes<TElement> & TExtra) => HTMLAttributes<TElement> & Record<string, unknown>;
|
|
76
|
+
export type ComboRef<T extends HTMLElement> = RefObject<T | null> | MutableRefObject<T | null> | ((instance: T | null) => void) | null;
|
|
77
|
+
export interface UseComboOptions<T> {
|
|
78
|
+
items: T[];
|
|
79
|
+
itemToString?: (item: T | null) => string;
|
|
80
|
+
itemToValue?: (item: T) => string | number;
|
|
81
|
+
mode?: 'single' | 'multi';
|
|
82
|
+
variant?: 'input' | 'select';
|
|
83
|
+
selectedItem?: T | null;
|
|
84
|
+
defaultSelectedItem?: T | null;
|
|
85
|
+
selectedItems?: T[];
|
|
86
|
+
defaultSelectedItems?: T[];
|
|
87
|
+
inputValue?: string;
|
|
88
|
+
defaultInputValue?: string;
|
|
89
|
+
isOpen?: boolean;
|
|
90
|
+
defaultIsOpen?: boolean;
|
|
91
|
+
filterFunction?: (items: T[], inputValue: string) => T[];
|
|
92
|
+
closeOnSelect?: boolean;
|
|
93
|
+
commitOnBlur?: boolean;
|
|
94
|
+
clearOnSelect?: boolean;
|
|
95
|
+
deselectionAllowed?: boolean;
|
|
96
|
+
maxSelected?: number;
|
|
97
|
+
id?: string;
|
|
98
|
+
ariaLabel?: string;
|
|
99
|
+
ariaLabelledBy?: string;
|
|
100
|
+
onSelectedItemChange?: (item: T | null) => void;
|
|
101
|
+
onSelectedItemsChange?: (items: T[]) => void;
|
|
102
|
+
onIsOpenChange?: (isOpen: boolean) => void;
|
|
103
|
+
onHighlightedIndexChange?: (index: number) => void;
|
|
104
|
+
onStateChange?: (state: ComboState<T>) => void;
|
|
105
|
+
onInputChange?: (value: string) => void;
|
|
106
|
+
/** @experimental Planned for Phase 3 — not yet implemented. Passing this prop has no effect. */
|
|
107
|
+
debounceMs?: number;
|
|
108
|
+
isLoading?: boolean;
|
|
109
|
+
/** @experimental Planned for Phase 3 — not yet implemented. Passing this prop has no effect. */
|
|
110
|
+
hasMore?: boolean;
|
|
111
|
+
/** @experimental Planned for Phase 3 — not yet implemented. Passing this prop has no effect. */
|
|
112
|
+
onLoadMore?: () => void;
|
|
113
|
+
disabled?: boolean | 'loading';
|
|
114
|
+
readOnly?: boolean;
|
|
115
|
+
isItemDisabled?: (item: T) => boolean;
|
|
116
|
+
hideDisabled?: boolean;
|
|
117
|
+
disabledItemBehavior?: 'skip' | 'focus';
|
|
118
|
+
icons?: Partial<IconSlots>;
|
|
119
|
+
chevronStyle?: ChevronStyle;
|
|
120
|
+
portalTarget?: Element | null;
|
|
121
|
+
disablePortal?: boolean;
|
|
122
|
+
groups?: ComboGroup<T>[];
|
|
123
|
+
}
|
|
124
|
+
export interface UseComboReturn<T> {
|
|
125
|
+
getInputProps: PropGetter<HTMLInputElement>;
|
|
126
|
+
getToggleButtonProps: PropGetter<HTMLButtonElement>;
|
|
127
|
+
getLabelProps: PropGetter<HTMLLabelElement>;
|
|
128
|
+
getClearButtonProps: PropGetter<HTMLButtonElement>;
|
|
129
|
+
getMenuProps: PropGetter<HTMLElement>;
|
|
130
|
+
getItemProps: (options: {
|
|
131
|
+
item: T;
|
|
132
|
+
index: number;
|
|
133
|
+
} & Record<string, unknown>) => HTMLAttributes<HTMLLIElement> & Record<string, unknown>;
|
|
134
|
+
getGroupProps: (options: {
|
|
135
|
+
group: ComboGroup<T>;
|
|
136
|
+
index: number;
|
|
137
|
+
} & Record<string, unknown>) => HTMLAttributes<HTMLElement> & Record<string, unknown>;
|
|
138
|
+
getChevronProps: PropGetter<HTMLElement>;
|
|
139
|
+
getTriggerProps: PropGetter<HTMLElement>;
|
|
140
|
+
getControlProps: PropGetter<HTMLElement>;
|
|
141
|
+
isOpen: boolean;
|
|
142
|
+
inputValue: string;
|
|
143
|
+
selectedItem: T | null;
|
|
144
|
+
selectedItems: T[];
|
|
145
|
+
highlightedIndex: number;
|
|
146
|
+
filteredItems: T[];
|
|
147
|
+
hasSelection: boolean;
|
|
148
|
+
triggerLabel: string;
|
|
149
|
+
isLoading: boolean;
|
|
150
|
+
isEmpty: boolean;
|
|
151
|
+
isError: boolean;
|
|
152
|
+
error: Error | null;
|
|
153
|
+
icons: IconSlots;
|
|
154
|
+
chevronIcon: ReactNode;
|
|
155
|
+
openMenu: () => void;
|
|
156
|
+
closeMenu: () => void;
|
|
157
|
+
toggleMenu: () => void;
|
|
158
|
+
selectItem: (item: T) => void;
|
|
159
|
+
removeItem: (item: T) => void;
|
|
160
|
+
selectAll: () => void;
|
|
161
|
+
clearSelection: () => void;
|
|
162
|
+
setInputValue: (value: string) => void;
|
|
163
|
+
reset: () => void;
|
|
164
|
+
inputRef: RefObject<HTMLInputElement | null>;
|
|
165
|
+
listboxRef: RefObject<HTMLElement | null>;
|
|
166
|
+
triggerRef: RefObject<HTMLElement | null>;
|
|
167
|
+
}
|
|
168
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";const s=require("react"),Y=require("./icons-vzkEacAb.cjs"),h=(...e)=>(...r)=>{e.forEach(t=>t?.(...r))},Q=e=>e==null?"":typeof e=="string"?e:typeof e=="object"&&"label"in e?String(e.label):String(e),ke=e=>typeof e=="string"||typeof e=="number"?e:typeof e=="object"&&e!=null&&"value"in e?e.value:String(e),Me=(e,r,t)=>{if(!r)return e;const l=r.toLowerCase();return e.filter(u=>t(u).toLowerCase().includes(l))},W=(e,r,t)=>Math.min(Math.max(e,r),t);function x(...e){return r=>{e.forEach(t=>{typeof t=="function"?t(r):t!=null&&(t.current=r)})}}function O(e){return e==="OPEN_IDLE"||e==="OPEN_HIGHLIGHTED"}function k(e,r,t){const l=t.filterFunction?t.filterFunction(e,r):Me(e,r,u=>t.itemToString(u));return t.hideDisabled?l.filter(u=>!t.isItemDisabled(u)):l}function J(e,r,t,l,u){const o=e.length;if(o===0)return-1;if(u==="focus"){let f=r+t;return f>=o&&(f=0),f<0&&(f=o-1),f}let I=r+t,C=0;for(;C<o;){if(I>=o&&(I=0),I<0&&(I=o-1),!l(e[I]))return I;I+=t,C++}return-1}function Re(e,r,t){if(e.length===0)return-1;if(t==="focus")return 0;for(let l=0;l<e.length;l++)if(!r(e[l]))return l;return-1}function we(e,r,t){if(e.length===0)return-1;if(t==="focus")return e.length-1;for(let l=e.length-1;l>=0;l--)if(!r(e[l]))return l;return-1}function Z(e){const r=e.itemToString??Q,t=e.selectedItem??e.defaultSelectedItem??null;return{status:"IDLE",selectedItem:t,selectedItems:e.selectedItems??e.defaultSelectedItems??[],inputValue:e.inputValue??e.defaultInputValue??(t?r(t):""),lastConfirmedValue:t?r(t):"",highlightedIndex:-1,filteredItems:e.items,expandedItems:new Set,activeTabId:null,isLoading:e.isLoading??!1,isLoadingMore:!1,error:null,visibleChipCount:0}}function Ue(e,r,t){switch(r.type){case"FOCUS":return e.status!=="IDLE"?e:{...e,status:"FOCUSED_CLOSED",lastConfirmedValue:e.inputValue};case"BLUR":{if(e.status==="IDLE")return e;if(t.mode==="multi")return{...e,status:"IDLE",inputValue:"",lastConfirmedValue:"",highlightedIndex:-1,filteredItems:t.items};if(t.commitOnBlur&&O(e.status)&&e.highlightedIndex>=0&&e.highlightedIndex<e.filteredItems.length){const l=e.filteredItems[e.highlightedIndex];if(!t.isItemDisabled(l)){const u=t.itemToString(l);return{...e,status:"IDLE",selectedItem:l,inputValue:u,lastConfirmedValue:u,highlightedIndex:-1}}}return{...e,status:"IDLE",inputValue:e.lastConfirmedValue,highlightedIndex:-1}}case"INPUT_CHANGE":{if(t.variant==="select")return e;const l=k(t.items,r.value,t);return{...e,status:"OPEN_IDLE",inputValue:r.value,filteredItems:l,highlightedIndex:-1}}case"TOGGLE_MENU":{if(O(e.status))return{...e,status:"FOCUSED_CLOSED",inputValue:t.mode==="multi"?"":e.lastConfirmedValue,highlightedIndex:-1,...t.mode==="multi"?{filteredItems:t.items}:{}};const l=t.mode==="multi"?e.inputValue:"",u=k(t.items,l,t);return{...e,status:"OPEN_IDLE",inputValue:l,filteredItems:u,highlightedIndex:-1}}case"OPEN_MENU":{if(O(e.status))return e;const l=t.mode==="multi"?e.inputValue:"",u=k(t.items,l,t);return{...e,status:"OPEN_IDLE",inputValue:l,filteredItems:u,highlightedIndex:-1}}case"CLOSE_MENU":return O(e.status)?{...e,status:"FOCUSED_CLOSED",inputValue:t.mode==="multi"?"":e.lastConfirmedValue,highlightedIndex:-1,...t.mode==="multi"?{filteredItems:t.items}:{}}:e;case"HIGHLIGHT_ITEM":{if(!O(e.status)&&e.status!=="FOCUSED_CLOSED")return e;const l=r.index;return l<0?{...e,status:"OPEN_IDLE",highlightedIndex:-1}:l>=e.filteredItems.length||t.disabledItemBehavior==="skip"&&t.isItemDisabled(e.filteredItems[l])?e:{...e,status:"OPEN_HIGHLIGHTED",highlightedIndex:l}}case"HIGHLIGHT_FIRST":{const l=Re(e.filteredItems,t.isItemDisabled,t.disabledItemBehavior);return l<0?{...e,status:"OPEN_IDLE",highlightedIndex:-1}:{...e,status:"OPEN_HIGHLIGHTED",highlightedIndex:l}}case"HIGHLIGHT_LAST":{const l=we(e.filteredItems,t.isItemDisabled,t.disabledItemBehavior);return l<0?{...e,status:"OPEN_IDLE",highlightedIndex:-1}:{...e,status:"OPEN_HIGHLIGHTED",highlightedIndex:l}}case"HIGHLIGHT_NEXT":{const l=e.highlightedIndex,u=J(e.filteredItems,l,1,t.isItemDisabled,t.disabledItemBehavior);return u<0?e:{...e,status:"OPEN_HIGHLIGHTED",highlightedIndex:u}}case"HIGHLIGHT_PREV":{const l=e.highlightedIndex,u=J(e.filteredItems,l,-1,t.isItemDisabled,t.disabledItemBehavior);return u<0?e:{...e,status:"OPEN_HIGHLIGHTED",highlightedIndex:u}}case"SELECT_HIGHLIGHTED":{if(e.highlightedIndex<0||e.highlightedIndex>=e.filteredItems.length)return e;const l=e.filteredItems[e.highlightedIndex];if(t.isItemDisabled(l))return e;if(t.mode==="multi"){const o=t.itemToValue(l),I=e.selectedItems.some(f=>t.itemToValue(f)===o);if(!I&&t.maxSelected!=null&&e.selectedItems.length>=t.maxSelected)return e;const C=I?e.selectedItems.filter(f=>t.itemToValue(f)!==o):[...e.selectedItems,l];return{...e,status:t.closeOnSelect?"FOCUSED_CLOSED":e.status,selectedItems:C,highlightedIndex:t.closeOnSelect?-1:e.highlightedIndex}}if(t.deselectionAllowed&&e.selectedItem!=null){const o=t.itemToValue(e.selectedItem),I=t.itemToValue(l);if(o===I)return{...e,status:t.closeOnSelect?"FOCUSED_CLOSED":e.status,selectedItem:null,inputValue:"",lastConfirmedValue:"",highlightedIndex:t.closeOnSelect?-1:e.highlightedIndex}}const u=t.itemToString(l);return{...e,status:t.closeOnSelect?"FOCUSED_CLOSED":e.status,selectedItem:l,inputValue:u,lastConfirmedValue:u,highlightedIndex:t.closeOnSelect?-1:e.highlightedIndex}}case"SELECT_ITEM":{const l=r.item;if(t.isItemDisabled(l))return e;if(t.mode==="multi"){const o=t.itemToValue(l),I=e.selectedItems.some(f=>t.itemToValue(f)===o);if(!I&&t.maxSelected!=null&&e.selectedItems.length>=t.maxSelected)return e;const C=I?e.selectedItems.filter(f=>t.itemToValue(f)!==o):[...e.selectedItems,l];return{...e,status:t.closeOnSelect?"FOCUSED_CLOSED":e.status,selectedItems:C,highlightedIndex:t.closeOnSelect?-1:e.highlightedIndex}}if(t.deselectionAllowed&&e.selectedItem!=null){const o=t.itemToValue(e.selectedItem),I=t.itemToValue(l);if(o===I)return{...e,status:t.closeOnSelect?"FOCUSED_CLOSED":e.status,selectedItem:null,inputValue:"",lastConfirmedValue:"",highlightedIndex:t.closeOnSelect?-1:e.highlightedIndex}}const u=t.itemToString(l);return{...e,status:t.closeOnSelect?"FOCUSED_CLOSED":e.status,selectedItem:l,inputValue:u,lastConfirmedValue:u,highlightedIndex:t.closeOnSelect?-1:e.highlightedIndex}}case"DESELECT_ITEM":{if(t.mode==="multi"){const l=t.itemToValue(r.item);return{...e,selectedItems:e.selectedItems.filter(u=>t.itemToValue(u)!==l)}}return e.selectedItem==null?e:{...e,selectedItem:null,inputValue:"",lastConfirmedValue:""}}case"CLEAR_SELECTION":return{...e,selectedItem:null,selectedItems:[],inputValue:"",lastConfirmedValue:"",filteredItems:t.items};case"REMOVE_LAST_CHIP":return t.mode!=="multi"||e.selectedItems.length===0||e.inputValue!==""?e:{...e,selectedItems:e.selectedItems.slice(0,-1)};case"SELECT_ALL":{if(t.mode!=="multi")return e;let l=e.filteredItems.filter(u=>!t.isItemDisabled(u));return t.maxSelected!=null&&(l=l.slice(0,t.maxSelected)),{...e,selectedItems:l}}case"SYNC_ITEMS":{const l=k(t.items,e.inputValue,t);return{...e,filteredItems:l,highlightedIndex:-1}}case"RESET":return Z({items:t.items,itemToString:t.itemToString,itemToValue:t.itemToValue});default:return e}}function xe(e,r,t){return l=>{const u=r.status==="OPEN_IDLE"||r.status==="OPEN_HIGHLIGHTED";switch(l.key){case"ArrowDown":{l.preventDefault(),u?e({type:"HIGHLIGHT_NEXT"}):(e({type:"OPEN_MENU"}),e({type:"HIGHLIGHT_FIRST"}));break}case"ArrowUp":{l.preventDefault(),u?e({type:"HIGHLIGHT_PREV"}):(e({type:"OPEN_MENU"}),e({type:"HIGHLIGHT_LAST"}));break}case"Enter":{u&&r.highlightedIndex>=0&&(l.preventDefault(),e({type:"SELECT_HIGHLIGHTED"}));break}case"Escape":{u&&(l.preventDefault(),e({type:"CLOSE_MENU"}));break}case"Home":{u&&(l.preventDefault(),e({type:"HIGHLIGHT_FIRST"}));break}case"End":{u&&(l.preventDefault(),e({type:"HIGHLIGHT_LAST"}));break}case"PageDown":{if(u){l.preventDefault();const o=r.filteredItems.length-1;e({type:"HIGHLIGHT_ITEM",index:W(r.highlightedIndex+10,0,o)})}break}case"PageUp":{u&&(l.preventDefault(),e({type:"HIGHLIGHT_ITEM",index:W(r.highlightedIndex-10,0,r.filteredItems.length-1)}));break}case"Tab":{u&&(t.commitOnBlur&&r.highlightedIndex>=0&&e({type:"SELECT_HIGHLIGHTED"}),e({type:"CLOSE_MENU"}));break}case"Backspace":{r.inputValue===""&&e({type:"REMOVE_LAST_CHIP"});break}case" ":{t.variant==="select"&&!u?(l.preventDefault(),e({type:"OPEN_MENU"}),e({type:"HIGHLIGHT_FIRST"})):t.variant==="select"&&u&&r.highlightedIndex>=0&&(l.preventDefault(),e({type:"SELECT_HIGHLIGHTED"}));break}case"a":case"A":{(l.ctrlKey||l.metaKey)&&t.mode==="multi"&&(l.preventDefault(),e({type:"SELECT_ALL"}));break}}}}const S="rzero";function Fe(e){return{base:e,input:`${S}-input-${e}`,label:`${S}-label-${e}`,listbox:`${S}-listbox-${e}`,toggleButton:`${S}-toggle-${e}`,clearButton:`${S}-clear-${e}`,liveRegion:`${S}-live-${e}`,item:r=>`${S}-item-${e}-${r}`,group:r=>`${S}-group-${e}-${r}`}}function Ae(e){const r=s.useId(),t=e??r,l=s.useRef(null);return(!l.current||l.current.base!==t)&&(l.current=Fe(t)),l.current}let p=null,F=null;function $e(){return typeof document>"u"?null:(p&&document.body.contains(p)||(p=document.createElement("div"),p.setAttribute("role","status"),p.setAttribute("aria-live","polite"),p.setAttribute("aria-atomic","true"),p.setAttribute("data-rzero-live",""),Object.assign(p.style,{position:"absolute",width:"1px",height:"1px",padding:"0",margin:"-1px",overflow:"hidden",clip:"rect(0,0,0,0)",whiteSpace:"nowrap",borderWidth:"0"}),document.body.appendChild(p)),p)}function _(e,r=3e3){const t=$e();t&&(F&&clearTimeout(F),t.textContent="",requestAnimationFrame(()=>{t.textContent=e}),F=setTimeout(()=>{t.textContent=""},r))}function Pe(e,r){if(!e||r<0)return;const t=e.querySelector(`[data-rzero-index="${r}"]`);t&&typeof t.scrollIntoView=="function"&&t.scrollIntoView({block:"nearest"})}function Be(e){const{items:r,itemToString:t,itemToValue:l,mode:u="single",variant:o="input",filterFunction:I,closeOnSelect:C=u==="single",commitOnBlur:f=!1,deselectionAllowed:ee=!0,disabled:m=!1,readOnly:E=!1,isItemDisabled:te,hideDisabled:le=!1,disabledItemBehavior:M="skip",ariaLabel:T,ariaLabelledBy:L,icons:y,chevronStyle:A="caret",onSelectedItemChange:ne,onSelectedItemsChange:ie,onIsOpenChange:re,onHighlightedIndexChange:ue,onStateChange:se,onInputChange:oe}=e,D=t??Q,H=l??ke,R=te??(()=>!1),d=Ae(e.id),V=s.useRef(null),w=s.useRef(null),$=s.useRef(null),P=s.useRef(null);P.current={items:r,itemToString:D,itemToValue:H,filterFunction:I,closeOnSelect:C,commitOnBlur:f,deselectionAllowed:ee,isItemDisabled:R,disabledItemBehavior:M,hideDisabled:le,variant:o,mode:u,maxSelected:e.maxSelected};const[i,a]=s.useReducer((n,c)=>Ue(n,c,P.current),e,Z),B=s.useRef(r);s.useEffect(()=>{B.current!==r&&(B.current=r,a({type:"SYNC_ITEMS"}))},[r]);const g=i.status==="OPEN_IDLE"||i.status==="OPEN_HIGHLIGHTED",de=u==="multi"?i.selectedItems.length>0:i.selectedItem!=null,ae=u==="multi"?i.selectedItems.map(D).join(", "):i.selectedItem!=null?D(i.selectedItem):"",ce=s.useMemo(()=>Y.resolveIcons(y),[y]),Ie=s.useMemo(()=>Y.resolveChevron(A,y?.chevronDown),[A,y?.chevronDown]),K=s.useRef(i);K.current=i;const v=s.useCallback(n=>{if(m||E)return;xe(a,K.current,{variant:o,commitOnBlur:f,mode:u})(n)},[m,E,o,f,u]);s.useEffect(()=>{i.highlightedIndex>=0&&Pe(w.current,i.highlightedIndex)},[i.highlightedIndex]);const z=s.useRef(!1),j=s.useRef(0);s.useEffect(()=>{const n=z.current,c=j.current;if(z.current=g,j.current=i.filteredItems.length,g&&(!n||c!==i.filteredItems.length)){const b=i.filteredItems.length;_(b===0?"No options available":`${b} option${b!==1?"s":""} available`)}},[g,i.filteredItems.length]);const q=s.useRef(i);s.useEffect(()=>{const n=q.current;if(q.current=i,n.selectedItem!==i.selectedItem&&(ne?.(i.selectedItem),i.selectedItem?_(`${D(i.selectedItem)} selected`):n.selectedItem&&_(`${D(n.selectedItem)} deselected`)),n.selectedItems!==i.selectedItems)if(ie?.(i.selectedItems),i.selectedItems.length>n.selectedItems.length){const b=i.selectedItems[i.selectedItems.length-1];b&&_(`${D(b)} selected, ${i.selectedItems.length} total`)}else i.selectedItems.length<n.selectedItems.length&&_(`Item removed, ${i.selectedItems.length} selected`);(n.status==="OPEN_IDLE"||n.status==="OPEN_HIGHLIGHTED")!==g&&re?.(g),n.highlightedIndex!==i.highlightedIndex&&ue?.(i.highlightedIndex),n.inputValue!==i.inputValue&&oe?.(i.inputValue),se?.(i)},[i]);const me=s.useCallback((n={})=>({id:d.label,htmlFor:d.input,...n}),[d]),fe=s.useCallback((n={})=>({id:d.input,role:"combobox","aria-expanded":g,"aria-haspopup":"listbox","aria-controls":d.listbox,"aria-autocomplete":o==="select"?"none":"list","aria-activedescendant":i.highlightedIndex>=0?d.item(i.highlightedIndex):void 0,"aria-labelledby":L??d.label,"aria-label":T,"aria-disabled":m?!0:void 0,readOnly:E||o==="select",disabled:m===!0,autoComplete:"off",value:i.inputValue,...n,onChange:h(n.onChange,c=>{m||E||a({type:"INPUT_CHANGE",value:c.target.value})}),onKeyDown:h(n.onKeyDown,v),onFocus:h(n.onFocus,()=>{m||a({type:"FOCUS"})}),onBlur:h(n.onBlur,()=>{a({type:"BLUR"})}),onClick:h(n.onClick,()=>{m||E||g||a({type:"OPEN_MENU"})}),ref:x(V,n.ref)}),[d,g,i.highlightedIndex,i.inputValue,T,L,m,E,o,v]),he=s.useCallback((n={})=>({id:d.toggleButton,type:"button","aria-label":g?"Close options":"Open options","aria-expanded":g,"aria-haspopup":"listbox","aria-controls":d.listbox,tabIndex:-1,"aria-disabled":m?!0:void 0,...n,onMouseDown:h(n.onMouseDown,c=>c.preventDefault()),onClick:h(n.onClick,()=>{m||E||(a({type:"TOGGLE_MENU"}),V.current?.focus())})}),[d,g,m,E]),ge=s.useCallback((n={})=>({id:d.clearButton,type:"button","aria-label":"Clear selection",tabIndex:-1,...n,onMouseDown:h(n.onMouseDown,c=>c.preventDefault()),onClick:h(n.onClick,()=>{m||E||(a({type:"CLEAR_SELECTION"}),V.current?.focus())})}),[d,m,E]),Ee=s.useCallback((n={})=>({id:d.listbox,role:"listbox","aria-labelledby":L??d.label,"aria-label":T,"aria-multiselectable":u==="multi"?!0:void 0,...n,onMouseDown:h(n.onMouseDown,c=>c.preventDefault()),ref:x(w,n.ref)}),[d,T,L,u]),be=s.useCallback(({item:n,index:c,variant:b,...G})=>{const U=u==="multi"?i.selectedItems.some(Ne=>H(Ne)===H(n)):i.selectedItem!=null&&H(i.selectedItem)===H(n),ve=i.highlightedIndex===c,N=R(n),Ge=b==="checkbox"||b==="radio";return{id:d.item(c),role:"option","aria-selected":U,"aria-checked":Ge?U:void 0,"aria-disabled":N||void 0,"data-rzero-index":c,"data-highlighted":ve||void 0,"data-selected":U||void 0,"data-disabled":N||void 0,"data-variant":b||void 0,...G,onClick:h(G?.onClick,()=>{N||a({type:"SELECT_ITEM",item:n})}),onMouseEnter:h(G?.onMouseEnter,()=>{N&&M==="skip"||a({type:"HIGHLIGHT_ITEM",index:c})}),onMouseLeave:h(G?.onMouseLeave,()=>{a({type:"HIGHLIGHT_ITEM",index:-1})})}},[i.selectedItem,i.selectedItems,i.highlightedIndex,d,H,R,M,u]),pe=s.useCallback(({group:n,index:c,...b})=>({role:"group","aria-label":n.label,id:d.group(c),"data-disabled":n.disabled||void 0,...b}),[d]),Ce=s.useCallback((n={})=>({"data-rzero-chevron":"","aria-hidden":!0,...n}),[]),X=s.useCallback((n={})=>({role:"combobox","aria-expanded":g,"aria-haspopup":"listbox","aria-controls":d.listbox,"aria-activedescendant":i.highlightedIndex>=0?d.item(i.highlightedIndex):void 0,"aria-label":T,"aria-labelledby":L,"aria-disabled":m?!0:void 0,"data-rzero-trigger":"","data-disabled":m||void 0,"data-readonly":E||void 0,"data-loading":m==="loading"||void 0,tabIndex:0,...n,onKeyDown:h(n.onKeyDown,v),onClick:h(n.onClick,()=>{m||E||a({type:"TOGGLE_MENU"})}),onFocus:h(n.onFocus,()=>{m||a({type:"FOCUS"})}),onBlur:h(n.onBlur,()=>{a({type:"BLUR"})}),ref:x($,n.ref)}),[d,g,i.highlightedIndex,T,L,m,E,v]),Se=s.useCallback(()=>a({type:"OPEN_MENU"}),[]),Te=s.useCallback(()=>a({type:"CLOSE_MENU"}),[]),Le=s.useCallback(()=>a({type:"TOGGLE_MENU"}),[]),De=s.useCallback(n=>a({type:"SELECT_ITEM",item:n}),[]),He=s.useCallback(n=>a({type:"DESELECT_ITEM",item:n}),[]),Oe=s.useCallback(()=>a({type:"SELECT_ALL"}),[]),_e=s.useCallback(()=>a({type:"CLEAR_SELECTION"}),[]),ye=s.useCallback(n=>a({type:"INPUT_CHANGE",value:n}),[]),Ve=s.useCallback(()=>a({type:"RESET"}),[]);return{getInputProps:fe,getToggleButtonProps:he,getLabelProps:me,getClearButtonProps:ge,getMenuProps:Ee,getItemProps:be,getGroupProps:pe,getChevronProps:Ce,getTriggerProps:X,getControlProps:X,isOpen:g,inputValue:i.inputValue,selectedItem:i.selectedItem,selectedItems:i.selectedItems,highlightedIndex:i.highlightedIndex,filteredItems:i.filteredItems,hasSelection:de,triggerLabel:ae,isLoading:i.isLoading,isEmpty:g&&i.filteredItems.length===0,isError:i.error!=null,error:i.error,icons:ce,chevronIcon:Ie,openMenu:Se,closeMenu:Te,toggleMenu:Le,selectItem:De,removeItem:He,selectAll:Oe,clearSelection:_e,setInputValue:ye,reset:Ve,inputRef:V,listboxRef:w,triggerRef:$}}exports.useCombo=Be;
|
|
2
|
+
//# sourceMappingURL=useCombo-D_vriwVz.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useCombo-D_vriwVz.cjs","sources":["../src/core/utils.ts","../src/core/stateMachine.ts","../src/core/keyboard.ts","../src/core/ids.ts","../src/core/announce.ts","../src/core/scroll.ts","../src/hooks/useCombo.ts"],"sourcesContent":["import type { MutableRefObject, RefObject } from 'react';\n\n/**\n * Compose multiple event handlers — user's handler runs first, then ours.\n */\nexport const callAll =\n <E extends (...args: never[]) => void>(\n ...fns: (E | undefined)[]\n ) =>\n (...args: Parameters<E>) => {\n fns.forEach((fn) => fn?.(...args));\n };\n\n/**\n * Default itemToString — handles strings, objects with `.label`, null.\n */\nexport const defaultItemToString = <T>(item: T | null): string => {\n if (item == null) return '';\n if (typeof item === 'string') return item;\n if (typeof item === 'object' && 'label' in (item as object))\n return String((item as Record<string, unknown>).label);\n return String(item);\n};\n\n/**\n * Default itemToValue — handles objects with `.value`, primitives.\n */\nexport const defaultItemToValue = <T>(item: T): string | number => {\n if (typeof item === 'string' || typeof item === 'number') return item;\n if (typeof item === 'object' && item != null && 'value' in (item as object))\n return (item as Record<string, unknown>).value as string | number;\n return String(item);\n};\n\n/**\n * Default case-insensitive substring filter.\n */\nexport const defaultFilter = <T>(\n items: T[],\n inputValue: string,\n itemToString: (item: T) => string,\n): T[] => {\n if (!inputValue) return items;\n const lower = inputValue.toLowerCase();\n return items.filter((item) =>\n itemToString(item).toLowerCase().includes(lower),\n );\n};\n\n/**\n * Clamp a number to a range.\n */\nexport const clamp = (value: number, min: number, max: number): number =>\n Math.min(Math.max(value, min), max);\n\n/**\n * Merge multiple refs (callback refs, RefObjects, or null).\n */\nexport function mergeRefs<T>(\n ...refs: (\n | MutableRefObject<T | null>\n | RefObject<T | null>\n | ((instance: T | null) => void)\n | null\n | undefined\n )[]\n): (instance: T | null) => void {\n return (instance: T | null) => {\n refs.forEach((ref) => {\n if (typeof ref === 'function') {\n ref(instance);\n } else if (ref != null) {\n (ref as MutableRefObject<T | null>).current = instance;\n }\n });\n };\n}\n","import type {\n ComboState,\n ComboAction,\n ComboStatus,\n UseComboOptions,\n} from '../types';\nimport { defaultFilter, defaultItemToString } from './utils';\n\n// ---------------------------------------------------------------------------\n// Reducer context — passed alongside state and action\n// ---------------------------------------------------------------------------\n\nexport interface ReducerContext<T> {\n items: T[];\n itemToString: (item: T | null) => string;\n itemToValue: (item: T) => string | number;\n filterFunction?: (items: T[], inputValue: string) => T[];\n closeOnSelect: boolean;\n commitOnBlur: boolean;\n deselectionAllowed: boolean;\n isItemDisabled: (item: T) => boolean;\n disabledItemBehavior: 'skip' | 'focus';\n hideDisabled: boolean;\n variant: 'input' | 'select';\n mode: 'single' | 'multi';\n maxSelected?: number;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction isOpenStatus(status: ComboStatus): boolean {\n return status === 'OPEN_IDLE' || status === 'OPEN_HIGHLIGHTED';\n}\n\nfunction filterItems<T>(\n items: T[],\n inputValue: string,\n ctx: ReducerContext<T>,\n): T[] {\n const filtered = ctx.filterFunction\n ? ctx.filterFunction(items, inputValue)\n : defaultFilter(items, inputValue, (item: T) => ctx.itemToString(item));\n\n if (ctx.hideDisabled) {\n return filtered.filter((item) => !ctx.isItemDisabled(item));\n }\n return filtered;\n}\n\n/**\n * Find the next enabled index in a given direction, wrapping around.\n * Returns -1 if no enabled items exist.\n */\nexport function getNextEnabledIndex<T>(\n filteredItems: T[],\n currentIndex: number,\n direction: 1 | -1,\n isItemDisabled: (item: T) => boolean,\n behavior: 'skip' | 'focus',\n): number {\n const len = filteredItems.length;\n if (len === 0) return -1;\n\n // If behavior is 'focus', disabled items are still focusable\n if (behavior === 'focus') {\n let next = currentIndex + direction;\n if (next >= len) next = 0;\n if (next < 0) next = len - 1;\n return next;\n }\n\n // Skip disabled items\n let next = currentIndex + direction;\n let attempts = 0;\n while (attempts < len) {\n if (next >= len) next = 0;\n if (next < 0) next = len - 1;\n if (!isItemDisabled(filteredItems[next])) return next;\n next += direction;\n attempts++;\n }\n return -1; // All items disabled\n}\n\n/**\n * Find the first enabled index from a given starting position.\n */\nexport function getFirstEnabledIndex<T>(\n filteredItems: T[],\n isItemDisabled: (item: T) => boolean,\n behavior: 'skip' | 'focus',\n): number {\n if (filteredItems.length === 0) return -1;\n if (behavior === 'focus') return 0;\n for (let i = 0; i < filteredItems.length; i++) {\n if (!isItemDisabled(filteredItems[i])) return i;\n }\n return -1;\n}\n\n/**\n * Find the last enabled index.\n */\nexport function getLastEnabledIndex<T>(\n filteredItems: T[],\n isItemDisabled: (item: T) => boolean,\n behavior: 'skip' | 'focus',\n): number {\n if (filteredItems.length === 0) return -1;\n if (behavior === 'focus') return filteredItems.length - 1;\n for (let i = filteredItems.length - 1; i >= 0; i--) {\n if (!isItemDisabled(filteredItems[i])) return i;\n }\n return -1;\n}\n\n// ---------------------------------------------------------------------------\n// Initial state\n// ---------------------------------------------------------------------------\n\nexport function getInitialState<T>(\n options: UseComboOptions<T>,\n): ComboState<T> {\n const its = options.itemToString ?? defaultItemToString;\n const selectedItem = options.selectedItem ?? options.defaultSelectedItem ?? null;\n\n return {\n status: 'IDLE' as ComboStatus,\n selectedItem,\n selectedItems: options.selectedItems ?? options.defaultSelectedItems ?? [],\n inputValue:\n options.inputValue ??\n options.defaultInputValue ??\n (selectedItem ? its(selectedItem) : ''),\n lastConfirmedValue: selectedItem ? its(selectedItem) : '',\n highlightedIndex: -1,\n filteredItems: options.items,\n expandedItems: new Set<string>(),\n activeTabId: null,\n isLoading: options.isLoading ?? false,\n isLoadingMore: false,\n error: null,\n visibleChipCount: 0,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Reducer\n// ---------------------------------------------------------------------------\n\nexport function comboReducer<T>(\n state: ComboState<T>,\n action: ComboAction<T>,\n ctx: ReducerContext<T>,\n): ComboState<T> {\n switch (action.type) {\n case 'FOCUS': {\n if (state.status !== 'IDLE') return state;\n return {\n ...state,\n status: 'FOCUSED_CLOSED',\n lastConfirmedValue: state.inputValue,\n };\n }\n\n case 'BLUR': {\n if (state.status === 'IDLE') return state;\n\n // Multi mode: clear input text on blur, don't revert to a label\n if (ctx.mode === 'multi') {\n return {\n ...state,\n status: 'IDLE',\n inputValue: '',\n lastConfirmedValue: '',\n highlightedIndex: -1,\n filteredItems: ctx.items,\n };\n }\n\n // If commitOnBlur and something is highlighted, select it\n if (\n ctx.commitOnBlur &&\n isOpenStatus(state.status) &&\n state.highlightedIndex >= 0 &&\n state.highlightedIndex < state.filteredItems.length\n ) {\n const item = state.filteredItems[state.highlightedIndex];\n if (!ctx.isItemDisabled(item)) {\n const label = ctx.itemToString(item);\n return {\n ...state,\n status: 'IDLE',\n selectedItem: item,\n inputValue: label,\n lastConfirmedValue: label,\n highlightedIndex: -1,\n };\n }\n }\n\n // Revert input to last confirmed value\n return {\n ...state,\n status: 'IDLE',\n inputValue: state.lastConfirmedValue,\n highlightedIndex: -1,\n };\n }\n\n case 'INPUT_CHANGE': {\n // In select variant, input changes are ignored\n if (ctx.variant === 'select') return state;\n\n const filtered = filterItems(ctx.items, action.value, ctx);\n return {\n ...state,\n status: 'OPEN_IDLE',\n inputValue: action.value,\n filteredItems: filtered,\n highlightedIndex: -1,\n };\n }\n\n case 'TOGGLE_MENU': {\n if (isOpenStatus(state.status)) {\n return {\n ...state,\n status: 'FOCUSED_CLOSED',\n inputValue: ctx.mode === 'multi' ? '' : state.lastConfirmedValue,\n highlightedIndex: -1,\n ...(ctx.mode === 'multi' ? { filteredItems: ctx.items } : {}),\n };\n }\n // Single mode: clear input so re-open shows all items (not filtered by selected label)\n const toggleSearchValue = ctx.mode === 'multi' ? state.inputValue : '';\n const filtered = filterItems(ctx.items, toggleSearchValue, ctx);\n return {\n ...state,\n status: 'OPEN_IDLE',\n inputValue: toggleSearchValue,\n filteredItems: filtered,\n highlightedIndex: -1,\n };\n }\n\n case 'OPEN_MENU': {\n if (isOpenStatus(state.status)) return state;\n // Single mode: clear input so re-open shows all items (not filtered by selected label)\n const searchValue = ctx.mode === 'multi' ? state.inputValue : '';\n const filtered = filterItems(ctx.items, searchValue, ctx);\n return {\n ...state,\n status: 'OPEN_IDLE',\n inputValue: searchValue,\n filteredItems: filtered,\n highlightedIndex: -1,\n };\n }\n\n case 'CLOSE_MENU': {\n if (!isOpenStatus(state.status)) return state;\n return {\n ...state,\n status: 'FOCUSED_CLOSED',\n inputValue: ctx.mode === 'multi' ? '' : state.lastConfirmedValue,\n highlightedIndex: -1,\n ...(ctx.mode === 'multi' ? { filteredItems: ctx.items } : {}),\n };\n }\n\n case 'HIGHLIGHT_ITEM': {\n if (!isOpenStatus(state.status) && state.status !== 'FOCUSED_CLOSED')\n return state;\n const idx = action.index;\n if (idx < 0) {\n return { ...state, status: 'OPEN_IDLE', highlightedIndex: -1 };\n }\n // Bounds check\n if (idx >= state.filteredItems.length) return state;\n // If behavior is skip and item is disabled, don't highlight\n if (\n ctx.disabledItemBehavior === 'skip' &&\n ctx.isItemDisabled(state.filteredItems[idx])\n ) {\n return state;\n }\n return {\n ...state,\n status: 'OPEN_HIGHLIGHTED',\n highlightedIndex: idx,\n };\n }\n\n case 'HIGHLIGHT_FIRST': {\n const idx = getFirstEnabledIndex(\n state.filteredItems,\n ctx.isItemDisabled,\n ctx.disabledItemBehavior,\n );\n if (idx < 0) return { ...state, status: 'OPEN_IDLE', highlightedIndex: -1 };\n return {\n ...state,\n status: 'OPEN_HIGHLIGHTED',\n highlightedIndex: idx,\n };\n }\n\n case 'HIGHLIGHT_LAST': {\n const idx = getLastEnabledIndex(\n state.filteredItems,\n ctx.isItemDisabled,\n ctx.disabledItemBehavior,\n );\n if (idx < 0) return { ...state, status: 'OPEN_IDLE', highlightedIndex: -1 };\n return {\n ...state,\n status: 'OPEN_HIGHLIGHTED',\n highlightedIndex: idx,\n };\n }\n\n case 'HIGHLIGHT_NEXT': {\n const current = state.highlightedIndex;\n const idx = getNextEnabledIndex(\n state.filteredItems,\n current,\n 1,\n ctx.isItemDisabled,\n ctx.disabledItemBehavior,\n );\n if (idx < 0) return state;\n return {\n ...state,\n status: 'OPEN_HIGHLIGHTED',\n highlightedIndex: idx,\n };\n }\n\n case 'HIGHLIGHT_PREV': {\n const current = state.highlightedIndex;\n const idx = getNextEnabledIndex(\n state.filteredItems,\n current,\n -1,\n ctx.isItemDisabled,\n ctx.disabledItemBehavior,\n );\n if (idx < 0) return state;\n return {\n ...state,\n status: 'OPEN_HIGHLIGHTED',\n highlightedIndex: idx,\n };\n }\n\n case 'SELECT_HIGHLIGHTED': {\n if (state.highlightedIndex < 0) return state;\n if (state.highlightedIndex >= state.filteredItems.length) return state;\n\n const item = state.filteredItems[state.highlightedIndex];\n if (ctx.isItemDisabled(item)) return state;\n\n // Multi mode: toggle item in/out of selectedItems\n if (ctx.mode === 'multi') {\n const itemVal = ctx.itemToValue(item);\n const alreadySelected = state.selectedItems.some(\n (si) => ctx.itemToValue(si) === itemVal,\n );\n\n // Block adding beyond maxSelected (deselection always allowed)\n if (\n !alreadySelected &&\n ctx.maxSelected != null &&\n state.selectedItems.length >= ctx.maxSelected\n ) {\n return state;\n }\n\n const nextSelectedItems = alreadySelected\n ? state.selectedItems.filter((si) => ctx.itemToValue(si) !== itemVal)\n : [...state.selectedItems, item];\n\n return {\n ...state,\n status: ctx.closeOnSelect ? 'FOCUSED_CLOSED' : state.status,\n selectedItems: nextSelectedItems,\n highlightedIndex: ctx.closeOnSelect ? -1 : state.highlightedIndex,\n };\n }\n\n // Deselection check\n if (ctx.deselectionAllowed && state.selectedItem != null) {\n const currentVal = ctx.itemToValue(state.selectedItem);\n const newVal = ctx.itemToValue(item);\n if (currentVal === newVal) {\n // Deselect\n return {\n ...state,\n status: ctx.closeOnSelect ? 'FOCUSED_CLOSED' : state.status,\n selectedItem: null,\n inputValue: '',\n lastConfirmedValue: '',\n highlightedIndex: ctx.closeOnSelect ? -1 : state.highlightedIndex,\n };\n }\n }\n\n const label = ctx.itemToString(item);\n return {\n ...state,\n status: ctx.closeOnSelect ? 'FOCUSED_CLOSED' : state.status,\n selectedItem: item,\n inputValue: label,\n lastConfirmedValue: label,\n highlightedIndex: ctx.closeOnSelect ? -1 : state.highlightedIndex,\n };\n }\n\n case 'SELECT_ITEM': {\n const item = action.item;\n if (ctx.isItemDisabled(item)) return state;\n\n // Multi mode: toggle item in/out of selectedItems\n if (ctx.mode === 'multi') {\n const itemVal = ctx.itemToValue(item);\n const alreadySelected = state.selectedItems.some(\n (si) => ctx.itemToValue(si) === itemVal,\n );\n\n // Block adding beyond maxSelected (deselection always allowed)\n if (\n !alreadySelected &&\n ctx.maxSelected != null &&\n state.selectedItems.length >= ctx.maxSelected\n ) {\n return state;\n }\n\n const nextSelectedItems = alreadySelected\n ? state.selectedItems.filter((si) => ctx.itemToValue(si) !== itemVal)\n : [...state.selectedItems, item];\n\n return {\n ...state,\n status: ctx.closeOnSelect ? 'FOCUSED_CLOSED' : state.status,\n selectedItems: nextSelectedItems,\n highlightedIndex: ctx.closeOnSelect ? -1 : state.highlightedIndex,\n };\n }\n\n // Deselection check\n if (ctx.deselectionAllowed && state.selectedItem != null) {\n const currentVal = ctx.itemToValue(state.selectedItem);\n const newVal = ctx.itemToValue(item);\n if (currentVal === newVal) {\n return {\n ...state,\n status: ctx.closeOnSelect ? 'FOCUSED_CLOSED' : state.status,\n selectedItem: null,\n inputValue: '',\n lastConfirmedValue: '',\n highlightedIndex: ctx.closeOnSelect ? -1 : state.highlightedIndex,\n };\n }\n }\n\n const label = ctx.itemToString(item);\n return {\n ...state,\n status: ctx.closeOnSelect ? 'FOCUSED_CLOSED' : state.status,\n selectedItem: item,\n inputValue: label,\n lastConfirmedValue: label,\n highlightedIndex: ctx.closeOnSelect ? -1 : state.highlightedIndex,\n };\n }\n\n case 'DESELECT_ITEM': {\n // Multi mode: remove specific item from selectedItems\n if (ctx.mode === 'multi') {\n const itemVal = ctx.itemToValue(action.item);\n return {\n ...state,\n selectedItems: state.selectedItems.filter(\n (si) => ctx.itemToValue(si) !== itemVal,\n ),\n };\n }\n if (state.selectedItem == null) return state;\n return {\n ...state,\n selectedItem: null,\n inputValue: '',\n lastConfirmedValue: '',\n };\n }\n\n case 'CLEAR_SELECTION': {\n return {\n ...state,\n selectedItem: null,\n selectedItems: [],\n inputValue: '',\n lastConfirmedValue: '',\n filteredItems: ctx.items,\n };\n }\n\n case 'REMOVE_LAST_CHIP': {\n if (ctx.mode !== 'multi') return state;\n if (state.selectedItems.length === 0) return state;\n if (state.inputValue !== '') return state; // Only remove when input is empty\n return {\n ...state,\n selectedItems: state.selectedItems.slice(0, -1),\n };\n }\n\n case 'SELECT_ALL': {\n if (ctx.mode !== 'multi') return state;\n let enabledItems = state.filteredItems.filter(\n (item) => !ctx.isItemDisabled(item),\n );\n if (ctx.maxSelected != null) {\n enabledItems = enabledItems.slice(0, ctx.maxSelected);\n }\n return {\n ...state,\n selectedItems: enabledItems,\n };\n }\n\n case 'SYNC_ITEMS': {\n const filtered = filterItems(ctx.items, state.inputValue, ctx);\n return {\n ...state,\n filteredItems: filtered,\n highlightedIndex: -1,\n };\n }\n\n case 'RESET': {\n return getInitialState({\n items: ctx.items,\n itemToString: ctx.itemToString,\n itemToValue: ctx.itemToValue,\n });\n }\n\n default:\n return state;\n }\n}\n","import type { ComboAction, ComboState } from '../types';\nimport { clamp } from './utils';\n\ninterface KeyboardOptions {\n variant: 'input' | 'select';\n commitOnBlur: boolean;\n mode: 'single' | 'multi';\n}\n\n/**\n * Creates a keydown handler that dispatches combo actions.\n * The handler is a pure mapping from keyboard events to dispatch calls.\n */\nexport function createKeyboardHandler<T>(\n dispatch: (action: ComboAction<T>) => void,\n state: ComboState<T>,\n options: KeyboardOptions,\n): (event: React.KeyboardEvent) => void {\n return (event: React.KeyboardEvent) => {\n const isOpen =\n state.status === 'OPEN_IDLE' || state.status === 'OPEN_HIGHLIGHTED';\n\n switch (event.key) {\n case 'ArrowDown': {\n event.preventDefault();\n if (!isOpen) {\n dispatch({ type: 'OPEN_MENU' });\n dispatch({ type: 'HIGHLIGHT_FIRST' });\n } else {\n dispatch({ type: 'HIGHLIGHT_NEXT' });\n }\n break;\n }\n\n case 'ArrowUp': {\n event.preventDefault();\n if (!isOpen) {\n dispatch({ type: 'OPEN_MENU' });\n dispatch({ type: 'HIGHLIGHT_LAST' });\n } else {\n dispatch({ type: 'HIGHLIGHT_PREV' });\n }\n break;\n }\n\n case 'Enter': {\n if (isOpen && state.highlightedIndex >= 0) {\n event.preventDefault();\n dispatch({ type: 'SELECT_HIGHLIGHTED' });\n }\n break;\n }\n\n case 'Escape': {\n if (isOpen) {\n event.preventDefault();\n dispatch({ type: 'CLOSE_MENU' });\n }\n break;\n }\n\n case 'Home': {\n if (isOpen) {\n event.preventDefault();\n dispatch({ type: 'HIGHLIGHT_FIRST' });\n }\n break;\n }\n\n case 'End': {\n if (isOpen) {\n event.preventDefault();\n dispatch({ type: 'HIGHLIGHT_LAST' });\n }\n break;\n }\n\n case 'PageDown': {\n if (isOpen) {\n event.preventDefault();\n const maxIdx = state.filteredItems.length - 1;\n dispatch({\n type: 'HIGHLIGHT_ITEM',\n index: clamp(state.highlightedIndex + 10, 0, maxIdx),\n });\n }\n break;\n }\n\n case 'PageUp': {\n if (isOpen) {\n event.preventDefault();\n dispatch({\n type: 'HIGHLIGHT_ITEM',\n index: clamp(state.highlightedIndex - 10, 0, state.filteredItems.length - 1),\n });\n }\n break;\n }\n\n case 'Tab': {\n // Do NOT preventDefault — let focus move naturally\n if (isOpen) {\n if (options.commitOnBlur && state.highlightedIndex >= 0) {\n dispatch({ type: 'SELECT_HIGHLIGHTED' });\n }\n dispatch({ type: 'CLOSE_MENU' });\n }\n break;\n }\n\n case 'Backspace': {\n // In multi mode, remove last chip when input is empty\n if (state.inputValue === '') {\n dispatch({ type: 'REMOVE_LAST_CHIP' });\n }\n break;\n }\n\n case ' ': {\n // Space opens the menu in select variant (button trigger)\n if (options.variant === 'select' && !isOpen) {\n event.preventDefault();\n dispatch({ type: 'OPEN_MENU' });\n dispatch({ type: 'HIGHLIGHT_FIRST' });\n } else if (options.variant === 'select' && isOpen && state.highlightedIndex >= 0) {\n event.preventDefault();\n dispatch({ type: 'SELECT_HIGHLIGHTED' });\n }\n break;\n }\n\n case 'a':\n case 'A': {\n // Ctrl+A / Cmd+A selects all in multi mode\n if ((event.ctrlKey || event.metaKey) && options.mode === 'multi') {\n event.preventDefault();\n dispatch({ type: 'SELECT_ALL' });\n }\n break;\n }\n }\n };\n}\n","import { useId, useRef } from 'react';\n\nconst PREFIX = 'rzero';\n\nexport interface ComboIds {\n base: string;\n input: string;\n label: string;\n listbox: string;\n toggleButton: string;\n clearButton: string;\n liveRegion: string;\n item: (index: number) => string;\n group: (index: number) => string;\n}\n\nfunction buildIds(id: string): ComboIds {\n return {\n base: id,\n input: `${PREFIX}-input-${id}`,\n label: `${PREFIX}-label-${id}`,\n listbox: `${PREFIX}-listbox-${id}`,\n toggleButton: `${PREFIX}-toggle-${id}`,\n clearButton: `${PREFIX}-clear-${id}`,\n liveRegion: `${PREFIX}-live-${id}`,\n item: (index: number) => `${PREFIX}-item-${id}-${index}`,\n group: (index: number) => `${PREFIX}-group-${id}-${index}`,\n };\n}\n\nexport function useComboIds(userProvidedId?: string): ComboIds {\n const reactId = useId();\n const id = userProvidedId ?? reactId;\n\n const idsRef = useRef<ComboIds | null>(null);\n if (!idsRef.current || idsRef.current.base !== id) {\n idsRef.current = buildIds(id);\n }\n return idsRef.current;\n}\n","let liveRegionElement: HTMLElement | null = null;\nlet clearTimer: ReturnType<typeof setTimeout> | null = null;\n\nfunction ensureRegion(): HTMLElement | null {\n if (typeof document === 'undefined') return null;\n if (liveRegionElement && document.body.contains(liveRegionElement)) {\n return liveRegionElement;\n }\n liveRegionElement = document.createElement('div');\n liveRegionElement.setAttribute('role', 'status');\n liveRegionElement.setAttribute('aria-live', 'polite');\n liveRegionElement.setAttribute('aria-atomic', 'true');\n liveRegionElement.setAttribute('data-rzero-live', '');\n Object.assign(liveRegionElement.style, {\n position: 'absolute',\n width: '1px',\n height: '1px',\n padding: '0',\n margin: '-1px',\n overflow: 'hidden',\n clip: 'rect(0,0,0,0)',\n whiteSpace: 'nowrap',\n borderWidth: '0',\n });\n document.body.appendChild(liveRegionElement);\n return liveRegionElement;\n}\n\n/**\n * Announce a message to screen readers via a live region.\n * Clear-then-set pattern forces screen readers to re-read.\n */\nexport function announce(message: string, clearAfterMs = 3000): void {\n const region = ensureRegion();\n if (!region) return;\n if (clearTimer) clearTimeout(clearTimer);\n // Clear first, then set on next frame — forces re-announcement\n region.textContent = '';\n requestAnimationFrame(() => {\n region.textContent = message;\n });\n clearTimer = setTimeout(() => {\n region.textContent = '';\n }, clearAfterMs);\n}\n\n/**\n * Cleanup for tests.\n */\nexport function destroyAnnouncer(): void {\n if (typeof document !== 'undefined' && liveRegionElement && document.body.contains(liveRegionElement)) {\n document.body.removeChild(liveRegionElement);\n }\n liveRegionElement = null;\n if (clearTimer) clearTimeout(clearTimer);\n clearTimer = null;\n}\n","/**\n * Scroll a highlighted item into view within a scrollable listbox.\n */\nexport function scrollIntoView(\n listboxElement: HTMLElement | null,\n highlightedIndex: number,\n): void {\n if (!listboxElement || highlightedIndex < 0) return;\n const item = listboxElement.querySelector(\n `[data-rzero-index=\"${highlightedIndex}\"]`,\n );\n if (item && typeof item.scrollIntoView === 'function') {\n item.scrollIntoView({ block: 'nearest' });\n }\n}\n","import {\n useReducer,\n useRef,\n useCallback,\n useEffect,\n useMemo,\n} from 'react';\nimport type {\n UseComboOptions,\n UseComboReturn,\n ComboState,\n ComboAction,\n ComboGroup,\n} from '../types';\nimport {\n comboReducer,\n getInitialState,\n type ReducerContext,\n} from '../core/stateMachine';\nimport { createKeyboardHandler } from '../core/keyboard';\nimport { useComboIds } from '../core/ids';\nimport { announce } from '../core/announce';\nimport { scrollIntoView } from '../core/scroll';\nimport { resolveIcons, resolveChevron } from '../icons/icons';\nimport {\n callAll,\n defaultItemToString,\n defaultItemToValue,\n mergeRefs,\n} from '../core/utils';\n\nexport function useCombo<T>(\n options: UseComboOptions<T>,\n): UseComboReturn<T> {\n const {\n items,\n itemToString: userItemToString,\n itemToValue: userItemToValue,\n mode = 'single',\n variant = 'input',\n filterFunction,\n closeOnSelect = mode === 'single',\n commitOnBlur = false,\n deselectionAllowed = true,\n disabled = false,\n readOnly = false,\n isItemDisabled: userIsItemDisabled,\n hideDisabled = false,\n disabledItemBehavior = 'skip',\n ariaLabel,\n ariaLabelledBy,\n icons: iconOverrides,\n chevronStyle = 'caret',\n onSelectedItemChange,\n onSelectedItemsChange,\n onIsOpenChange,\n onHighlightedIndexChange,\n onStateChange,\n onInputChange,\n } = options;\n\n const itemToString = userItemToString ?? defaultItemToString;\n const itemToValue = userItemToValue ?? defaultItemToValue;\n const isItemDisabled = userIsItemDisabled ?? (() => false);\n\n // IDs\n const ids = useComboIds(options.id);\n\n // Refs\n const inputRef = useRef<HTMLInputElement | null>(null);\n const listboxRef = useRef<HTMLElement | null>(null);\n const triggerRef = useRef<HTMLElement | null>(null);\n\n // Reducer context\n const ctxRef = useRef<ReducerContext<T>>(null!);\n ctxRef.current = {\n items,\n itemToString,\n itemToValue,\n filterFunction,\n closeOnSelect,\n commitOnBlur,\n deselectionAllowed,\n isItemDisabled,\n disabledItemBehavior,\n hideDisabled,\n variant,\n mode,\n maxSelected: options.maxSelected,\n };\n\n // Reducer\n const [state, dispatch] = useReducer(\n (s: ComboState<T>, a: ComboAction<T>) =>\n comboReducer(s, a, ctxRef.current),\n options,\n getInitialState,\n );\n\n // Sync items when they change externally (e.g. tab switch in TabbedCombo)\n const prevItemsRef = useRef(items);\n useEffect(() => {\n if (prevItemsRef.current !== items) {\n prevItemsRef.current = items;\n dispatch({ type: 'SYNC_ITEMS' });\n }\n }, [items]);\n\n // Derived state\n const isOpen =\n state.status === 'OPEN_IDLE' || state.status === 'OPEN_HIGHLIGHTED';\n const hasSelection = mode === 'multi'\n ? state.selectedItems.length > 0\n : state.selectedItem != null;\n const triggerLabel = mode === 'multi'\n ? state.selectedItems.map(itemToString).join(', ')\n : state.selectedItem != null\n ? itemToString(state.selectedItem)\n : '';\n\n // Icons\n const icons = useMemo(\n () => resolveIcons(iconOverrides),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [iconOverrides],\n );\n const chevronIcon = useMemo(\n () => resolveChevron(chevronStyle, iconOverrides?.chevronDown),\n [chevronStyle, iconOverrides?.chevronDown],\n );\n\n // Keyboard handler — use ref-based approach to avoid stale closures\n const stateRef = useRef(state);\n stateRef.current = state;\n\n const handleKeyDown = useCallback(\n (event: React.KeyboardEvent) => {\n if (disabled || readOnly) return;\n const handler = createKeyboardHandler<T>(dispatch, stateRef.current, {\n variant,\n commitOnBlur,\n mode,\n });\n handler(event);\n },\n [disabled, readOnly, variant, commitOnBlur, mode],\n );\n\n // Scroll into view on highlight change\n useEffect(() => {\n if (state.highlightedIndex >= 0) {\n scrollIntoView(listboxRef.current, state.highlightedIndex);\n }\n }, [state.highlightedIndex]);\n\n // Announce filtered results count\n const prevIsOpenRef = useRef(false);\n const prevFilteredLenRef = useRef(0);\n useEffect(() => {\n const wasOpen = prevIsOpenRef.current;\n const prevLen = prevFilteredLenRef.current;\n prevIsOpenRef.current = isOpen;\n prevFilteredLenRef.current = state.filteredItems.length;\n\n if (isOpen && (!wasOpen || prevLen !== state.filteredItems.length)) {\n const count = state.filteredItems.length;\n announce(\n count === 0\n ? 'No options available'\n : `${count} option${count !== 1 ? 's' : ''} available`,\n );\n }\n }, [isOpen, state.filteredItems.length]);\n\n // Fire callbacks on state changes\n const prevStateRef = useRef(state);\n useEffect(() => {\n const prev = prevStateRef.current;\n prevStateRef.current = state;\n\n if (prev.selectedItem !== state.selectedItem) {\n onSelectedItemChange?.(state.selectedItem);\n if (state.selectedItem) {\n announce(`${itemToString(state.selectedItem)} selected`);\n } else if (prev.selectedItem) {\n announce(`${itemToString(prev.selectedItem)} deselected`);\n }\n }\n\n if (prev.selectedItems !== state.selectedItems) {\n onSelectedItemsChange?.(state.selectedItems);\n // Announce additions and removals in multi-select\n if (state.selectedItems.length > prev.selectedItems.length) {\n const added = state.selectedItems[state.selectedItems.length - 1];\n if (added) {\n announce(`${itemToString(added)} selected, ${state.selectedItems.length} total`);\n }\n } else if (state.selectedItems.length < prev.selectedItems.length) {\n announce(`Item removed, ${state.selectedItems.length} selected`);\n }\n }\n\n const wasOpen =\n prev.status === 'OPEN_IDLE' || prev.status === 'OPEN_HIGHLIGHTED';\n if (wasOpen !== isOpen) {\n onIsOpenChange?.(isOpen);\n }\n\n if (prev.highlightedIndex !== state.highlightedIndex) {\n onHighlightedIndexChange?.(state.highlightedIndex);\n }\n\n if (prev.inputValue !== state.inputValue) {\n onInputChange?.(state.inputValue);\n }\n\n onStateChange?.(state);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [state]);\n\n // ---- PROP GETTERS ----\n\n const getLabelProps = useCallback(\n (userProps: Record<string, unknown> = {}) => ({\n id: ids.label,\n htmlFor: ids.input,\n ...userProps,\n }),\n [ids],\n );\n\n const getInputProps = useCallback(\n (userProps: Record<string, unknown> = {}) => ({\n id: ids.input,\n role: 'combobox' as const,\n 'aria-expanded': isOpen,\n 'aria-haspopup': 'listbox' as const,\n 'aria-controls': ids.listbox,\n 'aria-autocomplete': (variant === 'select' ? 'none' : 'list') as\n | 'none'\n | 'list',\n 'aria-activedescendant':\n state.highlightedIndex >= 0\n ? ids.item(state.highlightedIndex)\n : undefined,\n 'aria-labelledby': ariaLabelledBy ?? ids.label,\n 'aria-label': ariaLabel,\n 'aria-disabled': disabled ? true : undefined,\n readOnly: readOnly || variant === 'select',\n disabled: disabled === true,\n autoComplete: 'off',\n value: state.inputValue,\n ...userProps,\n onChange: callAll(\n userProps.onChange as (() => void) | undefined,\n (e: React.ChangeEvent<HTMLInputElement>) => {\n if (disabled || readOnly) return;\n dispatch({ type: 'INPUT_CHANGE', value: e.target.value });\n },\n ),\n onKeyDown: callAll(\n userProps.onKeyDown as (() => void) | undefined,\n handleKeyDown,\n ),\n onFocus: callAll(\n userProps.onFocus as (() => void) | undefined,\n () => {\n if (disabled) return;\n dispatch({ type: 'FOCUS' });\n },\n ),\n onBlur: callAll(\n userProps.onBlur as (() => void) | undefined,\n () => {\n dispatch({ type: 'BLUR' });\n },\n ),\n onClick: callAll(\n userProps.onClick as (() => void) | undefined,\n () => {\n if (disabled || readOnly) return;\n if (!isOpen) dispatch({ type: 'OPEN_MENU' });\n },\n ),\n ref: mergeRefs(\n inputRef,\n userProps.ref as React.RefObject<HTMLInputElement | null> | undefined,\n ),\n }),\n [\n ids,\n isOpen,\n state.highlightedIndex,\n state.inputValue,\n ariaLabel,\n ariaLabelledBy,\n disabled,\n readOnly,\n variant,\n handleKeyDown,\n ],\n );\n\n const getToggleButtonProps = useCallback(\n (userProps: Record<string, unknown> = {}) => ({\n id: ids.toggleButton,\n type: 'button' as const,\n 'aria-label': isOpen ? 'Close options' : 'Open options',\n 'aria-expanded': isOpen,\n 'aria-haspopup': 'listbox' as const,\n 'aria-controls': ids.listbox,\n tabIndex: -1,\n 'aria-disabled': disabled ? true : undefined,\n ...userProps,\n onMouseDown: callAll(\n userProps.onMouseDown as (() => void) | undefined,\n (e: React.MouseEvent) => e.preventDefault(), // prevent input blur\n ),\n onClick: callAll(\n userProps.onClick as (() => void) | undefined,\n () => {\n if (disabled || readOnly) return;\n dispatch({ type: 'TOGGLE_MENU' });\n inputRef.current?.focus();\n },\n ),\n }),\n [ids, isOpen, disabled, readOnly],\n );\n\n const getClearButtonProps = useCallback(\n (userProps: Record<string, unknown> = {}) => ({\n id: ids.clearButton,\n type: 'button' as const,\n 'aria-label': 'Clear selection',\n tabIndex: -1,\n ...userProps,\n onMouseDown: callAll(\n userProps.onMouseDown as (() => void) | undefined,\n (e: React.MouseEvent) => e.preventDefault(), // prevent input blur\n ),\n onClick: callAll(\n userProps.onClick as (() => void) | undefined,\n () => {\n if (disabled || readOnly) return;\n dispatch({ type: 'CLEAR_SELECTION' });\n inputRef.current?.focus();\n },\n ),\n }),\n [ids, disabled, readOnly],\n );\n\n const getMenuProps = useCallback(\n (userProps: Record<string, unknown> = {}) => ({\n id: ids.listbox,\n role: 'listbox' as const,\n 'aria-labelledby': ariaLabelledBy ?? ids.label,\n 'aria-label': ariaLabel,\n 'aria-multiselectable': mode === 'multi' ? true : undefined,\n ...userProps,\n onMouseDown: callAll(\n userProps.onMouseDown as (() => void) | undefined,\n (e: React.MouseEvent) => e.preventDefault(), // prevent input blur\n ),\n ref: mergeRefs(\n listboxRef,\n userProps.ref as React.RefObject<HTMLElement | null> | undefined,\n ),\n }),\n [ids, ariaLabel, ariaLabelledBy, mode],\n );\n\n const getItemProps = useCallback(\n ({\n item,\n index,\n variant: itemVariant,\n ...userProps\n }: { item: T; index: number; variant?: string } & Record<\n string,\n unknown\n >) => {\n const isSelected = mode === 'multi'\n ? state.selectedItems.some((si) => itemToValue(si) === itemToValue(item))\n : state.selectedItem != null &&\n itemToValue(state.selectedItem) === itemToValue(item);\n const isHighlighted = state.highlightedIndex === index;\n const itemIsDisabled = isItemDisabled(item);\n\n const useChecked = itemVariant === 'checkbox' || itemVariant === 'radio';\n\n return {\n id: ids.item(index),\n role: 'option' as const,\n 'aria-selected': isSelected,\n 'aria-checked': useChecked ? isSelected : undefined,\n 'aria-disabled': itemIsDisabled || undefined,\n 'data-rzero-index': index,\n 'data-highlighted': isHighlighted || undefined,\n 'data-selected': isSelected || undefined,\n 'data-disabled': itemIsDisabled || undefined,\n 'data-variant': itemVariant || undefined,\n ...userProps,\n onClick: callAll(\n userProps?.onClick as (() => void) | undefined,\n () => {\n if (itemIsDisabled) return;\n dispatch({ type: 'SELECT_ITEM', item });\n },\n ),\n onMouseEnter: callAll(\n userProps?.onMouseEnter as (() => void) | undefined,\n () => {\n if (itemIsDisabled && disabledItemBehavior === 'skip') return;\n dispatch({ type: 'HIGHLIGHT_ITEM', index });\n },\n ),\n onMouseLeave: callAll(\n userProps?.onMouseLeave as (() => void) | undefined,\n () => {\n dispatch({ type: 'HIGHLIGHT_ITEM', index: -1 });\n },\n ),\n };\n },\n [\n state.selectedItem,\n state.selectedItems,\n state.highlightedIndex,\n ids,\n itemToValue,\n isItemDisabled,\n disabledItemBehavior,\n mode,\n ],\n );\n\n const getGroupProps = useCallback(\n ({\n group,\n index,\n ...userProps\n }: {\n group: ComboGroup<T>;\n index: number;\n } & Record<string, unknown>) => ({\n role: 'group' as const,\n 'aria-label': group.label,\n id: ids.group(index),\n 'data-disabled': group.disabled || undefined,\n ...userProps,\n }),\n [ids],\n );\n\n const getChevronProps = useCallback(\n (userProps: Record<string, unknown> = {}) => ({\n 'data-rzero-chevron': '',\n 'aria-hidden': true as const,\n ...userProps,\n }),\n [],\n );\n\n const getTriggerProps = useCallback(\n (userProps: Record<string, unknown> = {}) => ({\n role: 'combobox' as const,\n 'aria-expanded': isOpen,\n 'aria-haspopup': 'listbox' as const,\n 'aria-controls': ids.listbox,\n 'aria-activedescendant':\n state.highlightedIndex >= 0\n ? ids.item(state.highlightedIndex)\n : undefined,\n 'aria-label': ariaLabel,\n 'aria-labelledby': ariaLabelledBy,\n 'aria-disabled': disabled ? true : undefined,\n 'data-rzero-trigger': '',\n 'data-disabled': disabled || undefined,\n 'data-readonly': readOnly || undefined,\n 'data-loading': disabled === 'loading' || undefined,\n tabIndex: 0,\n ...userProps,\n onKeyDown: callAll(\n userProps.onKeyDown as (() => void) | undefined,\n handleKeyDown,\n ),\n onClick: callAll(\n userProps.onClick as (() => void) | undefined,\n () => {\n if (disabled || readOnly) return;\n dispatch({ type: 'TOGGLE_MENU' });\n },\n ),\n onFocus: callAll(\n userProps.onFocus as (() => void) | undefined,\n () => {\n if (disabled) return;\n dispatch({ type: 'FOCUS' });\n },\n ),\n onBlur: callAll(\n userProps.onBlur as (() => void) | undefined,\n () => {\n dispatch({ type: 'BLUR' });\n },\n ),\n ref: mergeRefs(\n triggerRef,\n userProps.ref as React.RefObject<HTMLElement | null> | undefined,\n ),\n }),\n [\n ids,\n isOpen,\n state.highlightedIndex,\n ariaLabel,\n ariaLabelledBy,\n disabled,\n readOnly,\n handleKeyDown,\n ],\n );\n\n // ---- IMPERATIVE ACTIONS ----\n const openMenu = useCallback(() => dispatch({ type: 'OPEN_MENU' }), []);\n const closeMenu = useCallback(() => dispatch({ type: 'CLOSE_MENU' }), []);\n const toggleMenu = useCallback(\n () => dispatch({ type: 'TOGGLE_MENU' }),\n [],\n );\n const selectItem = useCallback(\n (item: T) => dispatch({ type: 'SELECT_ITEM', item }),\n [],\n );\n const removeItem = useCallback(\n (item: T) => dispatch({ type: 'DESELECT_ITEM', item }),\n [],\n );\n const selectAll = useCallback(\n () => dispatch({ type: 'SELECT_ALL' }),\n [],\n );\n const clearSelection = useCallback(\n () => dispatch({ type: 'CLEAR_SELECTION' }),\n [],\n );\n const setInputValue = useCallback(\n (v: string) => dispatch({ type: 'INPUT_CHANGE', value: v }),\n [],\n );\n const reset = useCallback(() => dispatch({ type: 'RESET' }), []);\n\n return {\n // Prop getters\n getInputProps: getInputProps as UseComboReturn<T>['getInputProps'],\n getToggleButtonProps:\n getToggleButtonProps as UseComboReturn<T>['getToggleButtonProps'],\n getLabelProps: getLabelProps as UseComboReturn<T>['getLabelProps'],\n getClearButtonProps:\n getClearButtonProps as UseComboReturn<T>['getClearButtonProps'],\n getMenuProps: getMenuProps as UseComboReturn<T>['getMenuProps'],\n getItemProps,\n getGroupProps,\n getChevronProps: getChevronProps as UseComboReturn<T>['getChevronProps'],\n getTriggerProps:\n getTriggerProps as UseComboReturn<T>['getTriggerProps'],\n getControlProps:\n getTriggerProps as UseComboReturn<T>['getControlProps'],\n\n // State\n isOpen,\n inputValue: state.inputValue,\n selectedItem: state.selectedItem,\n selectedItems: state.selectedItems,\n highlightedIndex: state.highlightedIndex,\n filteredItems: state.filteredItems,\n hasSelection,\n triggerLabel,\n isLoading: state.isLoading,\n isEmpty: isOpen && state.filteredItems.length === 0,\n isError: state.error != null,\n error: state.error,\n\n // Icons\n icons,\n chevronIcon,\n\n // Actions\n openMenu,\n closeMenu,\n toggleMenu,\n selectItem,\n removeItem,\n selectAll,\n clearSelection,\n setInputValue,\n reset,\n\n // Refs\n inputRef,\n listboxRef,\n triggerRef,\n };\n}\n"],"names":["callAll","fns","args","fn","defaultItemToString","item","defaultItemToValue","defaultFilter","items","inputValue","itemToString","lower","clamp","value","min","max","mergeRefs","refs","instance","ref","isOpenStatus","status","filterItems","ctx","filtered","getNextEnabledIndex","filteredItems","currentIndex","direction","isItemDisabled","behavior","len","next","attempts","getFirstEnabledIndex","i","getLastEnabledIndex","getInitialState","options","its","selectedItem","comboReducer","state","action","label","toggleSearchValue","searchValue","idx","current","itemVal","alreadySelected","si","nextSelectedItems","currentVal","newVal","enabledItems","createKeyboardHandler","dispatch","event","isOpen","maxIdx","PREFIX","buildIds","id","index","useComboIds","userProvidedId","reactId","useId","idsRef","useRef","liveRegionElement","clearTimer","ensureRegion","announce","message","clearAfterMs","region","scrollIntoView","listboxElement","highlightedIndex","useCombo","userItemToString","userItemToValue","mode","variant","filterFunction","closeOnSelect","commitOnBlur","deselectionAllowed","disabled","readOnly","userIsItemDisabled","hideDisabled","disabledItemBehavior","ariaLabel","ariaLabelledBy","iconOverrides","chevronStyle","onSelectedItemChange","onSelectedItemsChange","onIsOpenChange","onHighlightedIndexChange","onStateChange","onInputChange","itemToValue","ids","inputRef","listboxRef","triggerRef","ctxRef","useReducer","s","a","prevItemsRef","useEffect","hasSelection","triggerLabel","icons","useMemo","resolveIcons","chevronIcon","resolveChevron","stateRef","handleKeyDown","useCallback","prevIsOpenRef","prevFilteredLenRef","wasOpen","prevLen","count","prevStateRef","prev","added","getLabelProps","userProps","getInputProps","e","getToggleButtonProps","getClearButtonProps","getMenuProps","getItemProps","itemVariant","isSelected","isHighlighted","itemIsDisabled","useChecked","getGroupProps","group","getChevronProps","getTriggerProps","openMenu","closeMenu","toggleMenu","selectItem","removeItem","selectAll","clearSelection","setInputValue","v","reset"],"mappings":"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"}
|