@proyecto-viviana/solidaria-components 0.2.9 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +39 -272
- package/dist/ActionBar.d.ts +21 -13
- package/dist/ActionBar.d.ts.map +1 -1
- package/dist/ActionGroup.d.ts +8 -8
- package/dist/ActionGroup.d.ts.map +1 -1
- package/dist/Alert.d.ts +5 -5
- package/dist/Alert.d.ts.map +1 -1
- package/dist/Autocomplete.d.ts +5 -5
- package/dist/Autocomplete.d.ts.map +1 -1
- package/dist/Breadcrumbs.d.ts +18 -7
- package/dist/Breadcrumbs.d.ts.map +1 -1
- package/dist/Button.d.ts +24 -5
- package/dist/Button.d.ts.map +1 -1
- package/dist/Calendar.d.ts +38 -7
- package/dist/Calendar.d.ts.map +1 -1
- package/dist/Checkbox.d.ts +32 -7
- package/dist/Checkbox.d.ts.map +1 -1
- package/dist/Collection.d.ts +19 -14
- package/dist/Collection.d.ts.map +1 -1
- package/dist/Color.d.ts +103 -14
- package/dist/Color.d.ts.map +1 -1
- package/dist/ColorEditor.d.ts +6 -6
- package/dist/ColorEditor.d.ts.map +1 -1
- package/dist/ComboBox.d.ts +85 -19
- package/dist/ComboBox.d.ts.map +1 -1
- package/dist/ContextualHelpTrigger.d.ts +2 -2
- package/dist/ContextualHelpTrigger.d.ts.map +1 -1
- package/dist/DateField.d.ts +8 -6
- package/dist/DateField.d.ts.map +1 -1
- package/dist/DatePicker.d.ts +53 -22
- package/dist/DatePicker.d.ts.map +1 -1
- package/dist/DateRangePickerContext.d.ts +30 -0
- package/dist/DateRangePickerContext.d.ts.map +1 -0
- package/dist/Dialog.d.ts +5 -5
- package/dist/Dialog.d.ts.map +1 -1
- package/dist/Disclosure.d.ts +23 -5
- package/dist/Disclosure.d.ts.map +1 -1
- package/dist/DragAndDrop.d.ts +6 -6
- package/dist/DragAndDrop.d.ts.map +1 -1
- package/dist/DragPreview.d.ts +2 -2
- package/dist/DragPreview.d.ts.map +1 -1
- package/dist/DropZone.d.ts +4 -4
- package/dist/DropZone.d.ts.map +1 -1
- package/dist/FieldError.d.ts +9 -5
- package/dist/FieldError.d.ts.map +1 -1
- package/dist/FileTrigger.d.ts +3 -3
- package/dist/FileTrigger.d.ts.map +1 -1
- package/dist/Focusable.d.ts +2 -2
- package/dist/Focusable.d.ts.map +1 -1
- package/dist/Form.d.ts +18 -4
- package/dist/Form.d.ts.map +1 -1
- package/dist/GridList.d.ts +32 -12
- package/dist/GridList.d.ts.map +1 -1
- package/dist/HiddenDateInput.d.ts +26 -0
- package/dist/HiddenDateInput.d.ts.map +1 -0
- package/dist/HiddenTimeInput.d.ts +25 -0
- package/dist/HiddenTimeInput.d.ts.map +1 -0
- package/dist/Icon.d.ts +5 -5
- package/dist/Icon.d.ts.map +1 -1
- package/dist/Keyboard.d.ts +1 -1
- package/dist/Landmark.d.ts +3 -3
- package/dist/Landmark.d.ts.map +1 -1
- package/dist/Link.d.ts +10 -4
- package/dist/Link.d.ts.map +1 -1
- package/dist/ListBox.d.ts +32 -12
- package/dist/ListBox.d.ts.map +1 -1
- package/dist/ListDropTargetDelegate.d.ts +6 -6
- package/dist/ListDropTargetDelegate.d.ts.map +1 -1
- package/dist/Menu.d.ts +65 -14
- package/dist/Menu.d.ts.map +1 -1
- package/dist/Meter.d.ts +3 -3
- package/dist/Meter.d.ts.map +1 -1
- package/dist/Modal.d.ts +5 -5
- package/dist/Modal.d.ts.map +1 -1
- package/dist/NumberField.d.ts +8 -12
- package/dist/NumberField.d.ts.map +1 -1
- package/dist/Popover.d.ts +28 -5
- package/dist/Popover.d.ts.map +1 -1
- package/dist/Pressable.d.ts +2 -2
- package/dist/Pressable.d.ts.map +1 -1
- package/dist/ProgressBar.d.ts +5 -3
- package/dist/ProgressBar.d.ts.map +1 -1
- package/dist/RadioGroup.d.ts +43 -9
- package/dist/RadioGroup.d.ts.map +1 -1
- package/dist/RangeCalendar.d.ts +34 -7
- package/dist/RangeCalendar.d.ts.map +1 -1
- package/dist/RouterProvider.d.ts +2 -2
- package/dist/RouterProvider.d.ts.map +1 -1
- package/dist/SearchField.d.ts +23 -20
- package/dist/SearchField.d.ts.map +1 -1
- package/dist/Select.d.ts +41 -11
- package/dist/Select.d.ts.map +1 -1
- package/dist/SelectionIndicator.d.ts +3 -3
- package/dist/SelectionIndicator.d.ts.map +1 -1
- package/dist/Separator.d.ts +9 -3
- package/dist/Separator.d.ts.map +1 -1
- package/dist/SharedElementTransition.d.ts +6 -4
- package/dist/SharedElementTransition.d.ts.map +1 -1
- package/dist/Slider.d.ts +12 -8
- package/dist/Slider.d.ts.map +1 -1
- package/dist/StepList.d.ts +90 -0
- package/dist/StepList.d.ts.map +1 -0
- package/dist/Switch.d.ts +11 -5
- package/dist/Switch.d.ts.map +1 -1
- package/dist/Table.d.ts +187 -23
- package/dist/Table.d.ts.map +1 -1
- package/dist/Tabs.d.ts +45 -9
- package/dist/Tabs.d.ts.map +1 -1
- package/dist/TagGroup.d.ts +12 -10
- package/dist/TagGroup.d.ts.map +1 -1
- package/dist/Text.d.ts +2 -2
- package/dist/TextField.d.ts +15 -11
- package/dist/TextField.d.ts.map +1 -1
- package/dist/TimeField.d.ts +6 -6
- package/dist/TimeField.d.ts.map +1 -1
- package/dist/Toast.d.ts +29 -14
- package/dist/Toast.d.ts.map +1 -1
- package/dist/ToggleButton.d.ts +11 -5
- package/dist/ToggleButton.d.ts.map +1 -1
- package/dist/ToggleButtonGroup.d.ts +7 -7
- package/dist/ToggleButtonGroup.d.ts.map +1 -1
- package/dist/Toolbar.d.ts +7 -3
- package/dist/Toolbar.d.ts.map +1 -1
- package/dist/Tooltip.d.ts +50 -8
- package/dist/Tooltip.d.ts.map +1 -1
- package/dist/Tree.d.ts +66 -17
- package/dist/Tree.d.ts.map +1 -1
- package/dist/Virtualizer.d.ts +12 -12
- package/dist/Virtualizer.d.ts.map +1 -1
- package/dist/VirtualizerLayouts.d.ts +2 -2
- package/dist/VirtualizerLayouts.d.ts.map +1 -1
- package/dist/VisuallyHidden.d.ts +1 -1
- package/dist/VisuallyHidden.d.ts.map +1 -1
- package/dist/contexts.d.ts +5 -1
- package/dist/contexts.d.ts.map +1 -1
- package/dist/index.d.ts +73 -71
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +23253 -18564
- package/dist/index.js.map +1 -1
- package/dist/index.jsx +18116 -0
- package/dist/index.jsx.map +1 -0
- package/dist/useDragAndDrop.d.ts +13 -13
- package/dist/useDragAndDrop.d.ts.map +1 -1
- package/dist/utils.d.ts +2 -2
- package/dist/utils.d.ts.map +1 -1
- package/dist/virtualizer/Layout.d.ts +1 -1
- package/dist/virtualizer/Layout.d.ts.map +1 -1
- package/package.json +31 -32
- package/src/ActionBar.tsx +75 -72
- package/src/ActionGroup.tsx +53 -61
- package/src/Alert.tsx +17 -42
- package/src/Autocomplete.tsx +39 -44
- package/src/Breadcrumbs.tsx +149 -80
- package/src/Button.tsx +267 -70
- package/src/Calendar.tsx +218 -138
- package/src/Checkbox.tsx +413 -121
- package/src/Collection.tsx +67 -58
- package/src/Color.tsx +803 -380
- package/src/ColorEditor.tsx +131 -149
- package/src/ComboBox.tsx +414 -249
- package/src/ContextualHelpTrigger.tsx +86 -74
- package/src/DateField.tsx +185 -91
- package/src/DatePicker.tsx +524 -213
- package/src/DateRangePickerContext.tsx +44 -0
- package/src/Dialog.tsx +156 -118
- package/src/Disclosure.tsx +127 -80
- package/src/DragAndDrop.tsx +60 -54
- package/src/DragPreview.tsx +13 -11
- package/src/DropZone.tsx +42 -22
- package/src/FieldError.tsx +45 -23
- package/src/FileTrigger.tsx +19 -19
- package/src/Focusable.tsx +21 -24
- package/src/Form.tsx +71 -16
- package/src/GridList.tsx +273 -197
- package/src/HiddenDateInput.tsx +153 -0
- package/src/HiddenTimeInput.tsx +133 -0
- package/src/Icon.tsx +22 -43
- package/src/Keyboard.tsx +3 -3
- package/src/Landmark.tsx +37 -63
- package/src/Link.tsx +125 -75
- package/src/ListBox.tsx +332 -233
- package/src/ListDropTargetDelegate.ts +81 -80
- package/src/Menu.tsx +1023 -274
- package/src/Meter.tsx +38 -56
- package/src/Modal.tsx +251 -176
- package/src/NumberField.tsx +139 -143
- package/src/Popover.tsx +396 -234
- package/src/Pressable.tsx +21 -21
- package/src/ProgressBar.tsx +48 -57
- package/src/RadioGroup.tsx +524 -122
- package/src/RangeCalendar.tsx +157 -90
- package/src/RouterProvider.tsx +30 -47
- package/src/SearchField.tsx +362 -143
- package/src/Select.tsx +656 -233
- package/src/SelectionIndicator.tsx +18 -15
- package/src/Separator.tsx +47 -49
- package/src/SharedElementTransition.tsx +103 -97
- package/src/Slider.tsx +138 -98
- package/src/StepList.tsx +272 -0
- package/src/Switch.tsx +93 -46
- package/src/Table.tsx +1308 -342
- package/src/Tabs.tsx +324 -103
- package/src/TagGroup.tsx +139 -126
- package/src/Text.tsx +3 -3
- package/src/TextField.tsx +389 -79
- package/src/TimeField.tsx +136 -76
- package/src/Toast.tsx +216 -158
- package/src/ToggleButton.tsx +47 -37
- package/src/ToggleButtonGroup.tsx +39 -34
- package/src/Toolbar.tsx +54 -69
- package/src/Tooltip.tsx +387 -119
- package/src/Tree.tsx +651 -368
- package/src/Virtualizer.tsx +208 -180
- package/src/VirtualizerLayouts.ts +45 -30
- package/src/VisuallyHidden.tsx +19 -19
- package/src/contexts.ts +29 -37
- package/src/index.ts +110 -195
- package/src/useDragAndDrop.ts +87 -71
- package/src/utils.tsx +49 -60
- package/src/virtualizer/Layout.ts +14 -22
- package/dist/index.ssr.js +0 -16996
- package/dist/index.ssr.js.map +0 -1
package/src/ComboBox.tsx
CHANGED
|
@@ -15,17 +15,19 @@ import {
|
|
|
15
15
|
useContext,
|
|
16
16
|
For,
|
|
17
17
|
Show,
|
|
18
|
-
} from
|
|
18
|
+
} from "solid-js";
|
|
19
19
|
import {
|
|
20
20
|
createComboBox,
|
|
21
21
|
createListBox,
|
|
22
22
|
createOption,
|
|
23
|
+
getComboBoxData,
|
|
23
24
|
createHover,
|
|
24
25
|
createInteractOutside,
|
|
26
|
+
mergeProps,
|
|
25
27
|
type AriaComboBoxProps,
|
|
26
28
|
type AriaListBoxProps,
|
|
27
29
|
type AriaOptionProps,
|
|
28
|
-
} from
|
|
30
|
+
} from "@proyecto-viviana/solidaria";
|
|
29
31
|
import {
|
|
30
32
|
createComboBoxState,
|
|
31
33
|
defaultContainsFilter,
|
|
@@ -34,7 +36,7 @@ import {
|
|
|
34
36
|
type Key,
|
|
35
37
|
type FilterFn,
|
|
36
38
|
type MenuTriggerAction,
|
|
37
|
-
} from
|
|
39
|
+
} from "@proyecto-viviana/solid-stately";
|
|
38
40
|
import {
|
|
39
41
|
type RenderChildren,
|
|
40
42
|
type ClassNameOrFunction,
|
|
@@ -42,15 +44,22 @@ import {
|
|
|
42
44
|
type SlotProps,
|
|
43
45
|
useRenderProps,
|
|
44
46
|
filterDOMProps,
|
|
45
|
-
} from
|
|
47
|
+
} from "./utils";
|
|
46
48
|
import {
|
|
47
49
|
SelectionIndicatorContext,
|
|
48
50
|
type SelectionIndicatorContextValue,
|
|
49
|
-
} from
|
|
51
|
+
} from "./SelectionIndicator";
|
|
50
52
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
53
|
+
type RefLike<T> = ((el: T) => void) | { current?: T | null } | undefined;
|
|
54
|
+
|
|
55
|
+
function assignRef<T>(ref: RefLike<T>, el: T): void {
|
|
56
|
+
if (!ref) return;
|
|
57
|
+
if (typeof ref === "function") {
|
|
58
|
+
ref(el);
|
|
59
|
+
} else {
|
|
60
|
+
ref.current = el;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
54
63
|
|
|
55
64
|
export interface ComboBoxRenderProps {
|
|
56
65
|
/** Whether the combobox listbox is open. */
|
|
@@ -65,17 +74,19 @@ export interface ComboBoxRenderProps {
|
|
|
65
74
|
isRequired: boolean;
|
|
66
75
|
/** Whether the combobox is invalid. */
|
|
67
76
|
isInvalid: boolean;
|
|
77
|
+
/** Whether the combobox is read only. */
|
|
78
|
+
isReadOnly: boolean;
|
|
68
79
|
/** Whether a value is selected. */
|
|
69
80
|
isSelected: boolean;
|
|
70
81
|
/** The current input value. */
|
|
71
82
|
inputValue: string;
|
|
72
83
|
}
|
|
73
84
|
|
|
74
|
-
export interface ComboBoxProps<T>
|
|
75
|
-
extends Omit<AriaComboBoxProps, 'children'>,
|
|
76
|
-
SlotProps {
|
|
85
|
+
export interface ComboBoxProps<T> extends Omit<AriaComboBoxProps, "children">, SlotProps {
|
|
77
86
|
/** The items to render in the combobox. */
|
|
78
|
-
items
|
|
87
|
+
items?: T[];
|
|
88
|
+
/** The default items to render in the combobox when uncontrolled. */
|
|
89
|
+
defaultItems?: T[];
|
|
79
90
|
/** Function to get the key from an item. */
|
|
80
91
|
getKey?: (item: T) => Key;
|
|
81
92
|
/** Function to get the text value from an item. */
|
|
@@ -84,12 +95,20 @@ export interface ComboBoxProps<T>
|
|
|
84
95
|
getDisabled?: (item: T) => boolean;
|
|
85
96
|
/** Keys of disabled items. */
|
|
86
97
|
disabledKeys?: Iterable<Key>;
|
|
87
|
-
/** The
|
|
98
|
+
/** The selection mode for the combobox. */
|
|
99
|
+
selectionMode?: "single" | "multiple";
|
|
100
|
+
/** The currently selected key (controlled, single mode). */
|
|
88
101
|
selectedKey?: Key | null;
|
|
89
|
-
/** The default selected key (uncontrolled). */
|
|
102
|
+
/** The default selected key (uncontrolled, single mode). */
|
|
90
103
|
defaultSelectedKey?: Key | null;
|
|
91
|
-
/**
|
|
104
|
+
/** The currently selected keys (controlled, multiple mode). */
|
|
105
|
+
selectedKeys?: Iterable<Key>;
|
|
106
|
+
/** The default selected keys (uncontrolled, multiple mode). */
|
|
107
|
+
defaultSelectedKeys?: Iterable<Key>;
|
|
108
|
+
/** Handler called when selection changes (single mode). */
|
|
92
109
|
onSelectionChange?: (key: Key | null) => void;
|
|
110
|
+
/** Handler called when selection changes (multiple mode). */
|
|
111
|
+
onSelectionChangeMultiple?: (keys: Set<Key>) => void;
|
|
93
112
|
/** The current input value (controlled). */
|
|
94
113
|
inputValue?: string;
|
|
95
114
|
/** The default input value (uncontrolled). */
|
|
@@ -109,7 +128,7 @@ export interface ComboBoxProps<T>
|
|
|
109
128
|
/** Whether to allow an empty collection (show listbox even with no matches). */
|
|
110
129
|
allowsEmptyCollection?: boolean;
|
|
111
130
|
/** The trigger mechanism for the combobox menu. */
|
|
112
|
-
menuTrigger?:
|
|
131
|
+
menuTrigger?: "focus" | "input" | "manual";
|
|
113
132
|
/** The name of the combobox, used when submitting an HTML form. */
|
|
114
133
|
name?: string;
|
|
115
134
|
/**
|
|
@@ -119,13 +138,19 @@ export interface ComboBoxProps<T>
|
|
|
119
138
|
*
|
|
120
139
|
* When allowsCustomValue is true, formValue is forced to 'text'.
|
|
121
140
|
*/
|
|
122
|
-
formValue?:
|
|
141
|
+
formValue?: "key" | "text";
|
|
123
142
|
/** The children of the component (compound components: ComboBoxInput, ComboBoxButton, ComboBoxListBox). */
|
|
124
|
-
children:
|
|
143
|
+
children: RenderChildren<ComboBoxRenderProps>;
|
|
125
144
|
/** The CSS className for the element. */
|
|
126
145
|
class?: ClassNameOrFunction<ComboBoxRenderProps>;
|
|
127
146
|
/** The inline style for the element. */
|
|
128
147
|
style?: StyleOrFunction<ComboBoxRenderProps>;
|
|
148
|
+
/** Ref for the root combobox element. */
|
|
149
|
+
ref?: RefLike<HTMLDivElement>;
|
|
150
|
+
/** Internal alias for libraries that wrap ComboBox and need a root ref. */
|
|
151
|
+
rootRef?: RefLike<HTMLDivElement>;
|
|
152
|
+
/** Slot definitions provided through ComboBoxContext. */
|
|
153
|
+
slots?: Record<string, Partial<ComboBoxProps<T>>>;
|
|
129
154
|
}
|
|
130
155
|
|
|
131
156
|
export interface ComboBoxInputRenderProps {
|
|
@@ -195,12 +220,16 @@ export interface ComboBoxButtonRenderProps {
|
|
|
195
220
|
export interface ComboBoxValueRenderProps {
|
|
196
221
|
textValue: string;
|
|
197
222
|
isPlaceholder: boolean;
|
|
223
|
+
selectedItems: unknown[];
|
|
224
|
+
selectedText: string;
|
|
225
|
+
state: ComboBoxState<unknown>;
|
|
198
226
|
}
|
|
199
227
|
|
|
200
228
|
export interface ComboBoxValueProps extends SlotProps {
|
|
201
229
|
children?: RenderChildren<ComboBoxValueRenderProps>;
|
|
202
230
|
class?: ClassNameOrFunction<ComboBoxValueRenderProps>;
|
|
203
231
|
style?: StyleOrFunction<ComboBoxValueRenderProps>;
|
|
232
|
+
placeholder?: JSX.Element;
|
|
204
233
|
}
|
|
205
234
|
|
|
206
235
|
export interface ComboBoxButtonProps extends SlotProps {
|
|
@@ -242,8 +271,7 @@ export interface ComboBoxOptionRenderProps {
|
|
|
242
271
|
}
|
|
243
272
|
|
|
244
273
|
export interface ComboBoxOptionProps<T>
|
|
245
|
-
extends Omit<AriaOptionProps,
|
|
246
|
-
SlotProps {
|
|
274
|
+
extends Omit<AriaOptionProps, "children" | "key">, SlotProps {
|
|
247
275
|
/** The unique key for the option. */
|
|
248
276
|
id: Key;
|
|
249
277
|
/** The item value. */
|
|
@@ -256,20 +284,18 @@ export interface ComboBoxOptionProps<T>
|
|
|
256
284
|
style?: StyleOrFunction<ComboBoxOptionRenderProps>;
|
|
257
285
|
/** The text value of the option (for typeahead). */
|
|
258
286
|
textValue?: string;
|
|
287
|
+
/** Handler called when the option is activated. */
|
|
288
|
+
onAction?: () => void;
|
|
259
289
|
}
|
|
260
290
|
|
|
261
|
-
// ============================================
|
|
262
|
-
// CONTEXT
|
|
263
|
-
// ============================================
|
|
264
|
-
|
|
265
291
|
interface ComboBoxContextValue<T> {
|
|
266
292
|
state: ComboBoxState<T>;
|
|
267
|
-
inputProps: JSX.InputHTMLAttributes<HTMLInputElement>;
|
|
268
|
-
buttonProps: JSX.HTMLAttributes<HTMLElement>;
|
|
269
|
-
listBoxProps: JSX.HTMLAttributes<HTMLElement>;
|
|
270
|
-
labelProps: JSX.HTMLAttributes<HTMLElement>;
|
|
271
|
-
descriptionProps: JSX.HTMLAttributes<HTMLElement>;
|
|
272
|
-
errorMessageProps: JSX.HTMLAttributes<HTMLElement>;
|
|
293
|
+
inputProps: () => JSX.InputHTMLAttributes<HTMLInputElement>;
|
|
294
|
+
buttonProps: () => JSX.HTMLAttributes<HTMLElement>;
|
|
295
|
+
listBoxProps: () => JSX.HTMLAttributes<HTMLElement>;
|
|
296
|
+
labelProps: () => JSX.HTMLAttributes<HTMLElement>;
|
|
297
|
+
descriptionProps: () => JSX.HTMLAttributes<HTMLElement>;
|
|
298
|
+
errorMessageProps: () => JSX.HTMLAttributes<HTMLElement>;
|
|
273
299
|
isOpen: Accessor<boolean>;
|
|
274
300
|
isFocused: Accessor<boolean>;
|
|
275
301
|
isFocusVisible: Accessor<boolean>;
|
|
@@ -278,59 +304,70 @@ interface ComboBoxContextValue<T> {
|
|
|
278
304
|
setInputRef: (el: HTMLInputElement | null) => void;
|
|
279
305
|
buttonRef: () => HTMLElement | null;
|
|
280
306
|
setButtonRef: (el: HTMLElement | null) => void;
|
|
307
|
+
triggerRef: () => HTMLElement | null;
|
|
308
|
+
setTriggerRef: (el: HTMLElement | null) => void;
|
|
281
309
|
listBoxRef: () => HTMLElement | null;
|
|
282
310
|
setListBoxRef: (el: HTMLElement | null) => void;
|
|
311
|
+
slots?: Record<string, Partial<ComboBoxProps<T>>>;
|
|
283
312
|
}
|
|
284
313
|
|
|
285
314
|
export const ComboBoxContext = createContext<ComboBoxContextValue<unknown> | null>(null);
|
|
286
315
|
export const ComboBoxStateContext = createContext<ComboBoxState<unknown> | null>(null);
|
|
287
316
|
export const ComboBoxValueContext = ComboBoxContext;
|
|
288
317
|
|
|
289
|
-
// ============================================
|
|
290
|
-
// COMPONENTS
|
|
291
|
-
// ============================================
|
|
292
|
-
|
|
293
318
|
/**
|
|
294
319
|
* A combobox combines a text input with a listbox, allowing users to filter a list of options.
|
|
295
320
|
*/
|
|
296
321
|
export function ComboBox<T>(props: ComboBoxProps<T>): JSX.Element {
|
|
322
|
+
const parentContext = useContext(ComboBoxContext) as ComboBoxContextValue<T> | null;
|
|
323
|
+
const contextSlotProps = parentContext?.slots?.[props.slot ?? "default"];
|
|
324
|
+
const mergedComboBoxProps = contextSlotProps
|
|
325
|
+
? (mergeProps(contextSlotProps, props) as ComboBoxProps<T>)
|
|
326
|
+
: props;
|
|
297
327
|
const [local, stateProps, ariaProps] = splitProps(
|
|
298
|
-
|
|
299
|
-
[
|
|
328
|
+
mergedComboBoxProps,
|
|
329
|
+
["class", "style", "slot", "children", "ref", "rootRef", "slots"],
|
|
300
330
|
[
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
331
|
+
"items",
|
|
332
|
+
"defaultItems",
|
|
333
|
+
"getKey",
|
|
334
|
+
"getTextValue",
|
|
335
|
+
"getDisabled",
|
|
336
|
+
"disabledKeys",
|
|
337
|
+
"selectionMode",
|
|
338
|
+
"selectedKey",
|
|
339
|
+
"defaultSelectedKey",
|
|
340
|
+
"selectedKeys",
|
|
341
|
+
"defaultSelectedKeys",
|
|
342
|
+
"onSelectionChange",
|
|
343
|
+
"onSelectionChangeMultiple",
|
|
344
|
+
"inputValue",
|
|
345
|
+
"defaultInputValue",
|
|
346
|
+
"onInputChange",
|
|
347
|
+
"isOpen",
|
|
348
|
+
"defaultOpen",
|
|
349
|
+
"onOpenChange",
|
|
350
|
+
"defaultFilter",
|
|
351
|
+
"allowsCustomValue",
|
|
352
|
+
"allowsEmptyCollection",
|
|
353
|
+
"menuTrigger",
|
|
354
|
+
"name",
|
|
355
|
+
"formValue",
|
|
356
|
+
],
|
|
322
357
|
);
|
|
323
358
|
|
|
324
|
-
// Refs
|
|
325
359
|
let inputRef: HTMLInputElement | null = null;
|
|
326
360
|
let buttonRef: HTMLElement | null = null;
|
|
361
|
+
let triggerRef: HTMLElement | null = null;
|
|
327
362
|
let listBoxRef: HTMLElement | null = null;
|
|
328
363
|
|
|
329
|
-
// Create combobox state
|
|
330
364
|
const state = createComboBoxState<T>({
|
|
331
365
|
get items() {
|
|
332
366
|
return stateProps.items;
|
|
333
367
|
},
|
|
368
|
+
get defaultItems() {
|
|
369
|
+
return stateProps.defaultItems;
|
|
370
|
+
},
|
|
334
371
|
get getKey() {
|
|
335
372
|
return stateProps.getKey;
|
|
336
373
|
},
|
|
@@ -343,15 +380,27 @@ export function ComboBox<T>(props: ComboBoxProps<T>): JSX.Element {
|
|
|
343
380
|
get disabledKeys() {
|
|
344
381
|
return stateProps.disabledKeys;
|
|
345
382
|
},
|
|
383
|
+
get selectionMode() {
|
|
384
|
+
return stateProps.selectionMode;
|
|
385
|
+
},
|
|
346
386
|
get selectedKey() {
|
|
347
387
|
return stateProps.selectedKey;
|
|
348
388
|
},
|
|
349
389
|
get defaultSelectedKey() {
|
|
350
390
|
return stateProps.defaultSelectedKey;
|
|
351
391
|
},
|
|
392
|
+
get selectedKeys() {
|
|
393
|
+
return stateProps.selectedKeys;
|
|
394
|
+
},
|
|
395
|
+
get defaultSelectedKeys() {
|
|
396
|
+
return stateProps.defaultSelectedKeys;
|
|
397
|
+
},
|
|
352
398
|
get onSelectionChange() {
|
|
353
399
|
return stateProps.onSelectionChange;
|
|
354
400
|
},
|
|
401
|
+
get onSelectionChangeMultiple() {
|
|
402
|
+
return stateProps.onSelectionChangeMultiple;
|
|
403
|
+
},
|
|
355
404
|
get inputValue() {
|
|
356
405
|
return stateProps.inputValue;
|
|
357
406
|
},
|
|
@@ -393,35 +442,42 @@ export function ComboBox<T>(props: ComboBoxProps<T>): JSX.Element {
|
|
|
393
442
|
},
|
|
394
443
|
});
|
|
395
444
|
|
|
396
|
-
const effectiveFormValue = createMemo<
|
|
445
|
+
const effectiveFormValue = createMemo<"key" | "text">(() => {
|
|
397
446
|
if (stateProps.allowsCustomValue) {
|
|
398
|
-
return
|
|
447
|
+
return "text";
|
|
399
448
|
}
|
|
400
|
-
return stateProps.formValue ??
|
|
449
|
+
return stateProps.formValue ?? "key";
|
|
450
|
+
});
|
|
451
|
+
|
|
452
|
+
const comboBoxAriaProps = createMemo(() => {
|
|
453
|
+
const cleanProps: Record<string, unknown> = {};
|
|
454
|
+
for (const key in ariaProps) {
|
|
455
|
+
if (!key.startsWith("data-")) {
|
|
456
|
+
cleanProps[key] = (ariaProps as Record<string, unknown>)[key];
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
return cleanProps as AriaComboBoxProps;
|
|
401
460
|
});
|
|
402
461
|
|
|
403
|
-
// Create combobox aria props
|
|
404
462
|
const comboBoxAria = createComboBox<T>(
|
|
405
|
-
{
|
|
406
|
-
...
|
|
463
|
+
() => ({
|
|
464
|
+
...comboBoxAriaProps(),
|
|
407
465
|
get name() {
|
|
408
|
-
return effectiveFormValue() ===
|
|
466
|
+
return effectiveFormValue() === "text" ? stateProps.name : undefined;
|
|
409
467
|
},
|
|
410
|
-
},
|
|
468
|
+
}),
|
|
411
469
|
state,
|
|
412
470
|
() => inputRef,
|
|
413
471
|
() => buttonRef,
|
|
414
|
-
() => listBoxRef
|
|
472
|
+
() => listBoxRef,
|
|
415
473
|
);
|
|
416
474
|
|
|
417
|
-
// Create hover for wrapper
|
|
418
475
|
const { isHovered, hoverProps } = createHover({
|
|
419
476
|
get isDisabled() {
|
|
420
477
|
return ariaProps.isDisabled;
|
|
421
478
|
},
|
|
422
479
|
});
|
|
423
480
|
|
|
424
|
-
// Render props values
|
|
425
481
|
const renderValues = createMemo<ComboBoxRenderProps>(() => ({
|
|
426
482
|
isOpen: comboBoxAria.isOpen(),
|
|
427
483
|
isFocused: comboBoxAria.isFocused(),
|
|
@@ -429,58 +485,78 @@ export function ComboBox<T>(props: ComboBoxProps<T>): JSX.Element {
|
|
|
429
485
|
isDisabled: !!ariaProps.isDisabled,
|
|
430
486
|
isRequired: !!ariaProps.isRequired,
|
|
431
487
|
isInvalid: !!ariaProps.isInvalid,
|
|
488
|
+
isReadOnly: !!ariaProps.isReadOnly,
|
|
432
489
|
isSelected: state.selectedKey() != null,
|
|
433
490
|
inputValue: state.inputValue(),
|
|
434
491
|
}));
|
|
435
492
|
|
|
436
|
-
// Resolve render props
|
|
437
493
|
const renderProps = useRenderProps(
|
|
438
494
|
{
|
|
439
495
|
class: local.class,
|
|
440
496
|
style: local.style,
|
|
441
|
-
defaultClassName:
|
|
497
|
+
defaultClassName: "solidaria-ComboBox",
|
|
442
498
|
},
|
|
443
|
-
renderValues
|
|
499
|
+
renderValues,
|
|
444
500
|
);
|
|
445
501
|
|
|
446
|
-
// Filter DOM props
|
|
447
502
|
const domProps = createMemo(() => {
|
|
448
503
|
const filtered = filterDOMProps(ariaProps as Record<string, unknown>, { global: true });
|
|
449
504
|
return filtered;
|
|
450
505
|
});
|
|
451
506
|
|
|
452
|
-
// Remove ref from hover props
|
|
453
507
|
const cleanHoverProps = () => {
|
|
454
508
|
const { ref: _ref, ...rest } = hoverProps as Record<string, unknown>;
|
|
455
509
|
return rest;
|
|
456
510
|
};
|
|
457
511
|
|
|
512
|
+
const ComboBoxChildren = () =>
|
|
513
|
+
typeof local.children === "function"
|
|
514
|
+
? (local.children as (values: ComboBoxRenderProps) => JSX.Element)(renderValues())
|
|
515
|
+
: local.children;
|
|
516
|
+
|
|
458
517
|
return (
|
|
459
518
|
<ComboBoxContext.Provider
|
|
460
|
-
value={
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
519
|
+
value={
|
|
520
|
+
{
|
|
521
|
+
state,
|
|
522
|
+
inputProps: () => comboBoxAria.inputProps,
|
|
523
|
+
buttonProps: () => comboBoxAria.buttonProps,
|
|
524
|
+
listBoxProps: () => comboBoxAria.listBoxProps,
|
|
525
|
+
labelProps: () => comboBoxAria.labelProps,
|
|
526
|
+
descriptionProps: () => comboBoxAria.descriptionProps,
|
|
527
|
+
errorMessageProps: () => comboBoxAria.errorMessageProps,
|
|
528
|
+
isOpen: comboBoxAria.isOpen,
|
|
529
|
+
isFocused: comboBoxAria.isFocused,
|
|
530
|
+
isFocusVisible: comboBoxAria.isFocusVisible,
|
|
531
|
+
items: stateProps.items ?? stateProps.defaultItems ?? [],
|
|
532
|
+
inputRef: () => inputRef,
|
|
533
|
+
setInputRef: (el) => {
|
|
534
|
+
inputRef = el;
|
|
535
|
+
},
|
|
536
|
+
buttonRef: () => buttonRef,
|
|
537
|
+
setButtonRef: (el) => {
|
|
538
|
+
buttonRef = el;
|
|
539
|
+
},
|
|
540
|
+
triggerRef: () => triggerRef,
|
|
541
|
+
setTriggerRef: (el) => {
|
|
542
|
+
triggerRef = el;
|
|
543
|
+
},
|
|
544
|
+
listBoxRef: () => listBoxRef,
|
|
545
|
+
setListBoxRef: (el) => {
|
|
546
|
+
listBoxRef = el;
|
|
547
|
+
},
|
|
548
|
+
slots: local.slots,
|
|
549
|
+
} as ComboBoxContextValue<unknown>
|
|
550
|
+
}
|
|
479
551
|
>
|
|
480
552
|
<ComboBoxStateContext.Provider value={state}>
|
|
481
553
|
<div
|
|
482
554
|
{...domProps()}
|
|
483
555
|
{...cleanHoverProps()}
|
|
556
|
+
ref={(el) => {
|
|
557
|
+
assignRef(local.ref, el);
|
|
558
|
+
assignRef(local.rootRef, el);
|
|
559
|
+
}}
|
|
484
560
|
class={renderProps.class()}
|
|
485
561
|
style={renderProps.style()}
|
|
486
562
|
data-open={comboBoxAria.isOpen() || undefined}
|
|
@@ -489,17 +565,20 @@ export function ComboBox<T>(props: ComboBoxProps<T>): JSX.Element {
|
|
|
489
565
|
data-disabled={ariaProps.isDisabled || undefined}
|
|
490
566
|
data-required={ariaProps.isRequired || undefined}
|
|
491
567
|
data-invalid={ariaProps.isInvalid || undefined}
|
|
568
|
+
data-readonly={ariaProps.isReadOnly || undefined}
|
|
492
569
|
data-hovered={isHovered() || undefined}
|
|
570
|
+
slot={local.slot}
|
|
493
571
|
>
|
|
494
572
|
{/* Hidden input for key-based form submission parity */}
|
|
495
|
-
<Show when={stateProps.name && effectiveFormValue() ===
|
|
573
|
+
<Show when={stateProps.name && effectiveFormValue() === "key"}>
|
|
496
574
|
<input
|
|
497
575
|
type="hidden"
|
|
498
576
|
name={stateProps.name}
|
|
499
|
-
|
|
577
|
+
form={ariaProps.form}
|
|
578
|
+
value={state.selectedKey()?.toString() ?? ""}
|
|
500
579
|
/>
|
|
501
580
|
</Show>
|
|
502
|
-
|
|
581
|
+
<ComboBoxChildren />
|
|
503
582
|
</div>
|
|
504
583
|
</ComboBoxStateContext.Provider>
|
|
505
584
|
</ComboBoxContext.Provider>
|
|
@@ -510,25 +589,20 @@ export function ComboBox<T>(props: ComboBoxProps<T>): JSX.Element {
|
|
|
510
589
|
* Label element for a combobox.
|
|
511
590
|
*/
|
|
512
591
|
export function ComboBoxLabel(props: ComboBoxLabelProps): JSX.Element {
|
|
513
|
-
const [local, domProps] = splitProps(props, [
|
|
592
|
+
const [local, domProps] = splitProps(props, ["class", "style", "slot", "children"]);
|
|
514
593
|
|
|
515
594
|
const context = useContext(ComboBoxContext);
|
|
516
595
|
if (!context) {
|
|
517
|
-
throw new Error(
|
|
596
|
+
throw new Error("ComboBoxLabel must be used within a ComboBox");
|
|
518
597
|
}
|
|
519
598
|
|
|
520
599
|
const cleanLabelProps = () => {
|
|
521
|
-
const { ref: _ref, ...rest } = context.labelProps as Record<string, unknown>;
|
|
600
|
+
const { ref: _ref, ...rest } = context.labelProps() as Record<string, unknown>;
|
|
522
601
|
return rest;
|
|
523
602
|
};
|
|
524
603
|
|
|
525
604
|
return (
|
|
526
|
-
<label
|
|
527
|
-
{...domProps}
|
|
528
|
-
{...cleanLabelProps()}
|
|
529
|
-
class={local.class}
|
|
530
|
-
style={local.style}
|
|
531
|
-
>
|
|
605
|
+
<label {...domProps} {...cleanLabelProps()} class={local.class} style={local.style}>
|
|
532
606
|
{local.children}
|
|
533
607
|
</label>
|
|
534
608
|
);
|
|
@@ -538,25 +612,20 @@ export function ComboBoxLabel(props: ComboBoxLabelProps): JSX.Element {
|
|
|
538
612
|
* Description element for a combobox.
|
|
539
613
|
*/
|
|
540
614
|
export function ComboBoxDescription(props: ComboBoxDescriptionProps): JSX.Element {
|
|
541
|
-
const [local, domProps] = splitProps(props, [
|
|
615
|
+
const [local, domProps] = splitProps(props, ["class", "style", "slot", "children"]);
|
|
542
616
|
|
|
543
617
|
const context = useContext(ComboBoxContext);
|
|
544
618
|
if (!context) {
|
|
545
|
-
throw new Error(
|
|
619
|
+
throw new Error("ComboBoxDescription must be used within a ComboBox");
|
|
546
620
|
}
|
|
547
621
|
|
|
548
622
|
const cleanDescriptionProps = () => {
|
|
549
|
-
const { ref: _ref, ...rest } = context.descriptionProps as Record<string, unknown>;
|
|
623
|
+
const { ref: _ref, ...rest } = context.descriptionProps() as Record<string, unknown>;
|
|
550
624
|
return rest;
|
|
551
625
|
};
|
|
552
626
|
|
|
553
627
|
return (
|
|
554
|
-
<div
|
|
555
|
-
{...domProps}
|
|
556
|
-
{...cleanDescriptionProps()}
|
|
557
|
-
class={local.class}
|
|
558
|
-
style={local.style}
|
|
559
|
-
>
|
|
628
|
+
<div {...domProps} {...cleanDescriptionProps()} class={local.class} style={local.style}>
|
|
560
629
|
{local.children}
|
|
561
630
|
</div>
|
|
562
631
|
);
|
|
@@ -566,25 +635,20 @@ export function ComboBoxDescription(props: ComboBoxDescriptionProps): JSX.Elemen
|
|
|
566
635
|
* Error message element for a combobox.
|
|
567
636
|
*/
|
|
568
637
|
export function ComboBoxErrorMessage(props: ComboBoxErrorMessageProps): JSX.Element {
|
|
569
|
-
const [local, domProps] = splitProps(props, [
|
|
638
|
+
const [local, domProps] = splitProps(props, ["class", "style", "slot", "children"]);
|
|
570
639
|
|
|
571
640
|
const context = useContext(ComboBoxContext);
|
|
572
641
|
if (!context) {
|
|
573
|
-
throw new Error(
|
|
642
|
+
throw new Error("ComboBoxErrorMessage must be used within a ComboBox");
|
|
574
643
|
}
|
|
575
644
|
|
|
576
645
|
const cleanErrorMessageProps = () => {
|
|
577
|
-
const { ref: _ref, ...rest } = context.errorMessageProps as Record<string, unknown>;
|
|
646
|
+
const { ref: _ref, ...rest } = context.errorMessageProps() as Record<string, unknown>;
|
|
578
647
|
return rest;
|
|
579
648
|
};
|
|
580
649
|
|
|
581
650
|
return (
|
|
582
|
-
<div
|
|
583
|
-
{...domProps}
|
|
584
|
-
{...cleanErrorMessageProps()}
|
|
585
|
-
class={local.class}
|
|
586
|
-
style={local.style}
|
|
587
|
-
>
|
|
651
|
+
<div {...domProps} {...cleanErrorMessageProps()} class={local.class} style={local.style}>
|
|
588
652
|
{local.children}
|
|
589
653
|
</div>
|
|
590
654
|
);
|
|
@@ -594,23 +658,20 @@ export function ComboBoxErrorMessage(props: ComboBoxErrorMessageProps): JSX.Elem
|
|
|
594
658
|
* The text input for a combobox.
|
|
595
659
|
*/
|
|
596
660
|
export function ComboBoxInput(props: ComboBoxInputProps): JSX.Element {
|
|
597
|
-
const [local, domProps] = splitProps(props, [
|
|
661
|
+
const [local, domProps] = splitProps(props, ["class", "style", "slot", "children"]);
|
|
598
662
|
|
|
599
|
-
// Get context
|
|
600
663
|
const context = useContext(ComboBoxContext);
|
|
601
664
|
if (!context) {
|
|
602
|
-
throw new Error(
|
|
665
|
+
throw new Error("ComboBoxInput must be used within a ComboBox");
|
|
603
666
|
}
|
|
604
|
-
const {
|
|
667
|
+
const { isOpen, isFocused, isFocusVisible, state, setInputRef } = context;
|
|
605
668
|
|
|
606
|
-
// Create hover
|
|
607
669
|
const { isHovered, hoverProps } = createHover({
|
|
608
670
|
get isDisabled() {
|
|
609
671
|
return state.isDisabled;
|
|
610
672
|
},
|
|
611
673
|
});
|
|
612
674
|
|
|
613
|
-
// Render props values
|
|
614
675
|
const renderValues = createMemo<ComboBoxInputRenderProps>(() => ({
|
|
615
676
|
isOpen: isOpen(),
|
|
616
677
|
isFocused: isFocused(),
|
|
@@ -620,20 +681,18 @@ export function ComboBoxInput(props: ComboBoxInputProps): JSX.Element {
|
|
|
620
681
|
inputValue: state.inputValue(),
|
|
621
682
|
}));
|
|
622
683
|
|
|
623
|
-
// Resolve render props
|
|
624
684
|
const renderProps = useRenderProps(
|
|
625
685
|
{
|
|
626
686
|
children: local.children,
|
|
627
687
|
class: local.class,
|
|
628
688
|
style: local.style,
|
|
629
|
-
defaultClassName:
|
|
689
|
+
defaultClassName: "solidaria-ComboBox-input",
|
|
630
690
|
},
|
|
631
|
-
renderValues
|
|
691
|
+
renderValues,
|
|
632
692
|
);
|
|
633
693
|
|
|
634
|
-
// Remove ref from spread props
|
|
635
694
|
const cleanInputProps = () => {
|
|
636
|
-
const { ref: _ref1, value: _value, ...rest } = inputProps as Record<string, unknown>;
|
|
695
|
+
const { ref: _ref1, value: _value, ...rest } = context.inputProps() as Record<string, unknown>;
|
|
637
696
|
return rest;
|
|
638
697
|
};
|
|
639
698
|
const cleanHoverProps = () => {
|
|
@@ -662,11 +721,27 @@ export function ComboBoxInput(props: ComboBoxInputProps): JSX.Element {
|
|
|
662
721
|
export function ComboBoxValue(props: ComboBoxValueProps): JSX.Element {
|
|
663
722
|
const context = useContext(ComboBoxContext);
|
|
664
723
|
if (!context) {
|
|
665
|
-
throw new Error(
|
|
724
|
+
throw new Error("ComboBoxValue must be used within a ComboBox");
|
|
666
725
|
}
|
|
667
726
|
|
|
668
727
|
const state = context.state;
|
|
669
|
-
const
|
|
728
|
+
const isMulti = createMemo(() => state.selectionMode() === "multiple");
|
|
729
|
+
const selectedItem = createMemo(() => state.selectedItem());
|
|
730
|
+
const selectedItems = createMemo(() => {
|
|
731
|
+
if (isMulti()) {
|
|
732
|
+
return state.selectedItems().map((node) => node.value ?? null);
|
|
733
|
+
}
|
|
734
|
+
const item = selectedItem();
|
|
735
|
+
return item ? [item.value ?? null] : [];
|
|
736
|
+
});
|
|
737
|
+
const selectedText = createMemo(() => {
|
|
738
|
+
if (isMulti()) {
|
|
739
|
+
const items = state.selectedItems();
|
|
740
|
+
return items.map((n) => n.textValue).join(", ");
|
|
741
|
+
}
|
|
742
|
+
return selectedItem()?.textValue ?? "";
|
|
743
|
+
});
|
|
744
|
+
const textValue = createMemo(() => selectedText() || state.inputValue() || "");
|
|
670
745
|
const isPlaceholder = createMemo(() => textValue().length === 0);
|
|
671
746
|
|
|
672
747
|
const renderProps = useRenderProps(
|
|
@@ -674,12 +749,15 @@ export function ComboBoxValue(props: ComboBoxValueProps): JSX.Element {
|
|
|
674
749
|
children: props.children,
|
|
675
750
|
class: props.class,
|
|
676
751
|
style: props.style,
|
|
677
|
-
defaultClassName:
|
|
752
|
+
defaultClassName: "solidaria-ComboBox-value",
|
|
678
753
|
},
|
|
679
754
|
() => ({
|
|
680
755
|
textValue: textValue(),
|
|
681
756
|
isPlaceholder: isPlaceholder(),
|
|
682
|
-
|
|
757
|
+
selectedItems: selectedItems(),
|
|
758
|
+
selectedText: selectedText(),
|
|
759
|
+
state: state as ComboBoxState<unknown>,
|
|
760
|
+
}),
|
|
683
761
|
);
|
|
684
762
|
|
|
685
763
|
return (
|
|
@@ -688,7 +766,11 @@ export function ComboBoxValue(props: ComboBoxValueProps): JSX.Element {
|
|
|
688
766
|
style={renderProps.style()}
|
|
689
767
|
data-placeholder={isPlaceholder() || undefined}
|
|
690
768
|
>
|
|
691
|
-
{props.children
|
|
769
|
+
{props.children
|
|
770
|
+
? renderProps.renderChildren()
|
|
771
|
+
: isPlaceholder()
|
|
772
|
+
? props.placeholder
|
|
773
|
+
: textValue()}
|
|
692
774
|
</span>
|
|
693
775
|
);
|
|
694
776
|
}
|
|
@@ -697,23 +779,20 @@ export function ComboBoxValue(props: ComboBoxValueProps): JSX.Element {
|
|
|
697
779
|
* The trigger button for a combobox.
|
|
698
780
|
*/
|
|
699
781
|
export function ComboBoxButton(props: ComboBoxButtonProps): JSX.Element {
|
|
700
|
-
const [local, domProps] = splitProps(props, [
|
|
782
|
+
const [local, domProps] = splitProps(props, ["class", "style", "slot", "children"]);
|
|
701
783
|
|
|
702
|
-
// Get context
|
|
703
784
|
const context = useContext(ComboBoxContext);
|
|
704
785
|
if (!context) {
|
|
705
|
-
throw new Error(
|
|
786
|
+
throw new Error("ComboBoxButton must be used within a ComboBox");
|
|
706
787
|
}
|
|
707
|
-
const {
|
|
788
|
+
const { isOpen, isFocused, state, setButtonRef } = context;
|
|
708
789
|
|
|
709
|
-
// Create hover
|
|
710
790
|
const { isHovered, hoverProps } = createHover({
|
|
711
791
|
get isDisabled() {
|
|
712
792
|
return state.isDisabled;
|
|
713
793
|
},
|
|
714
794
|
});
|
|
715
795
|
|
|
716
|
-
// Render props values
|
|
717
796
|
const renderValues = createMemo<ComboBoxButtonRenderProps>(() => ({
|
|
718
797
|
isOpen: isOpen(),
|
|
719
798
|
isFocused: isFocused(),
|
|
@@ -722,20 +801,18 @@ export function ComboBoxButton(props: ComboBoxButtonProps): JSX.Element {
|
|
|
722
801
|
isDisabled: state.isDisabled,
|
|
723
802
|
}));
|
|
724
803
|
|
|
725
|
-
// Resolve render props
|
|
726
804
|
const renderProps = useRenderProps(
|
|
727
805
|
{
|
|
728
806
|
children: local.children,
|
|
729
807
|
class: local.class,
|
|
730
808
|
style: local.style,
|
|
731
|
-
defaultClassName:
|
|
809
|
+
defaultClassName: "solidaria-ComboBox-button",
|
|
732
810
|
},
|
|
733
|
-
renderValues
|
|
811
|
+
renderValues,
|
|
734
812
|
);
|
|
735
813
|
|
|
736
|
-
// Remove ref from spread props
|
|
737
814
|
const cleanButtonProps = () => {
|
|
738
|
-
const { ref: _ref1, ...rest } = buttonProps as Record<string, unknown>;
|
|
815
|
+
const { ref: _ref1, ...rest } = context.buttonProps() as Record<string, unknown>;
|
|
739
816
|
return rest;
|
|
740
817
|
};
|
|
741
818
|
const cleanHoverProps = () => {
|
|
@@ -752,6 +829,7 @@ export function ComboBoxButton(props: ComboBoxButtonProps): JSX.Element {
|
|
|
752
829
|
class={renderProps.class()}
|
|
753
830
|
style={renderProps.style()}
|
|
754
831
|
data-open={isOpen() || undefined}
|
|
832
|
+
data-pressed={isOpen() || undefined}
|
|
755
833
|
data-focused={isFocused() || undefined}
|
|
756
834
|
data-hovered={isHovered() || undefined}
|
|
757
835
|
data-disabled={state.isDisabled || undefined}
|
|
@@ -765,27 +843,18 @@ export function ComboBoxButton(props: ComboBoxButtonProps): JSX.Element {
|
|
|
765
843
|
* The listbox popup for a combobox.
|
|
766
844
|
*/
|
|
767
845
|
export function ComboBoxListBox<T>(props: ComboBoxListBoxProps<T>): JSX.Element {
|
|
768
|
-
const [local, domProps] = splitProps(props, [
|
|
846
|
+
const [local, domProps] = splitProps(props, ["class", "style", "slot", "children"]);
|
|
769
847
|
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
throw new Error('ComboBoxListBox must be used within a ComboBox');
|
|
848
|
+
const rawContext = useContext(ComboBoxContext);
|
|
849
|
+
if (!rawContext) {
|
|
850
|
+
throw new Error("ComboBoxListBox must be used within a ComboBox");
|
|
774
851
|
}
|
|
775
|
-
const
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
inputRef,
|
|
780
|
-
buttonRef,
|
|
781
|
-
setListBoxRef,
|
|
782
|
-
} = context;
|
|
783
|
-
const state = comboBoxState as ComboBoxState<T>;
|
|
784
|
-
|
|
785
|
-
// Ref for the listbox element (for click outside detection)
|
|
852
|
+
const context = rawContext as ComboBoxContextValue<T>;
|
|
853
|
+
const { state: comboBoxState, isOpen, inputRef, buttonRef, setListBoxRef } = context;
|
|
854
|
+
const state = comboBoxState;
|
|
855
|
+
|
|
786
856
|
let listBoxRef: HTMLUListElement | undefined;
|
|
787
857
|
|
|
788
|
-
// Handle click outside to close combobox
|
|
789
858
|
createInteractOutside({
|
|
790
859
|
ref: () => listBoxRef ?? null,
|
|
791
860
|
onInteractOutside: (e) => {
|
|
@@ -810,28 +879,25 @@ export function ComboBoxListBox<T>(props: ComboBoxListBoxProps<T>): JSX.Element
|
|
|
810
879
|
|
|
811
880
|
// Create listbox aria props using ComboBoxState's ListState-compatible interface
|
|
812
881
|
const { listBoxProps } = createListBox(
|
|
813
|
-
|
|
814
|
-
createComboBoxListStateAdapter(state)
|
|
882
|
+
context.listBoxProps as unknown as AriaListBoxProps,
|
|
883
|
+
createComboBoxListStateAdapter(state),
|
|
815
884
|
);
|
|
816
885
|
|
|
817
|
-
// Render props values
|
|
818
886
|
const renderValues = createMemo<ComboBoxListBoxRenderProps>(() => ({
|
|
819
887
|
isFocused: state.isFocused(),
|
|
820
888
|
}));
|
|
821
889
|
|
|
822
|
-
// Resolve render props
|
|
823
890
|
const renderProps = useRenderProps(
|
|
824
891
|
{
|
|
825
892
|
class: local.class,
|
|
826
893
|
style: local.style,
|
|
827
|
-
defaultClassName:
|
|
894
|
+
defaultClassName: "solidaria-ComboBox-listbox",
|
|
828
895
|
},
|
|
829
|
-
renderValues
|
|
896
|
+
renderValues,
|
|
830
897
|
);
|
|
831
898
|
|
|
832
|
-
// Remove ref from spread props
|
|
833
899
|
const cleanContextProps = () => {
|
|
834
|
-
const { ref: _ref1, ...rest } =
|
|
900
|
+
const { ref: _ref1, ...rest } = context.listBoxProps() as Record<string, unknown>;
|
|
835
901
|
return rest;
|
|
836
902
|
};
|
|
837
903
|
const cleanListBoxProps = () => {
|
|
@@ -840,37 +906,26 @@ export function ComboBoxListBox<T>(props: ComboBoxListBoxProps<T>): JSX.Element
|
|
|
840
906
|
};
|
|
841
907
|
|
|
842
908
|
const items = () => Array.from(state.collection());
|
|
909
|
+
const getNodeValue = (node: { key: Key; value?: T | null; index?: number }): T | null => {
|
|
910
|
+
if (node.value != null) {
|
|
911
|
+
return node.value;
|
|
912
|
+
}
|
|
843
913
|
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
cleanupFocusGuard = undefined;
|
|
914
|
+
return (
|
|
915
|
+
context.items.find((item, index) => {
|
|
916
|
+
const candidate = item as { key?: Key; id?: Key };
|
|
917
|
+
const key = candidate.key ?? candidate.id ?? index;
|
|
918
|
+
return key === node.key;
|
|
919
|
+
}) ?? null
|
|
920
|
+
);
|
|
921
|
+
};
|
|
853
922
|
|
|
923
|
+
const setListBoxElement = (el: HTMLUListElement) => {
|
|
854
924
|
listBoxRef = el;
|
|
855
925
|
setListBoxRef(el);
|
|
856
|
-
if (el) {
|
|
857
|
-
const mouseHandler = (e: MouseEvent) => {
|
|
858
|
-
e.preventDefault();
|
|
859
|
-
};
|
|
860
|
-
const pointerHandler = (e: PointerEvent) => {
|
|
861
|
-
e.preventDefault();
|
|
862
|
-
};
|
|
863
|
-
el.addEventListener('mousedown', mouseHandler, true); // capture phase
|
|
864
|
-
el.addEventListener('pointerdown', pointerHandler, true); // capture phase
|
|
865
|
-
cleanupFocusGuard = () => {
|
|
866
|
-
el.removeEventListener('mousedown', mouseHandler, true);
|
|
867
|
-
el.removeEventListener('pointerdown', pointerHandler, true);
|
|
868
|
-
};
|
|
869
|
-
}
|
|
870
926
|
};
|
|
871
927
|
|
|
872
928
|
onCleanup(() => {
|
|
873
|
-
cleanupFocusGuard?.();
|
|
874
929
|
setListBoxRef(null);
|
|
875
930
|
});
|
|
876
931
|
|
|
@@ -878,24 +933,26 @@ export function ComboBoxListBox<T>(props: ComboBoxListBoxProps<T>): JSX.Element
|
|
|
878
933
|
<Show when={isOpen()}>
|
|
879
934
|
<ul
|
|
880
935
|
{...domProps}
|
|
881
|
-
ref={
|
|
936
|
+
ref={setListBoxElement}
|
|
882
937
|
{...cleanContextProps()}
|
|
883
938
|
{...cleanListBoxProps()}
|
|
884
939
|
class={renderProps.class()}
|
|
885
940
|
style={renderProps.style()}
|
|
886
941
|
data-focused={state.isFocused() || undefined}
|
|
887
942
|
>
|
|
888
|
-
<Show
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
}>
|
|
943
|
+
<Show
|
|
944
|
+
when={local.children}
|
|
945
|
+
fallback={
|
|
946
|
+
<For each={items()}>
|
|
947
|
+
{(node) => <ComboBoxOption id={node.key}>{node.textValue}</ComboBoxOption>}
|
|
948
|
+
</For>
|
|
949
|
+
}
|
|
950
|
+
>
|
|
897
951
|
<For each={items()}>
|
|
898
|
-
{(node) =>
|
|
952
|
+
{(node) => {
|
|
953
|
+
const value = getNodeValue(node);
|
|
954
|
+
return value != null ? (local.children as Function)!(value) : null;
|
|
955
|
+
}}
|
|
899
956
|
</For>
|
|
900
957
|
</Show>
|
|
901
958
|
</ul>
|
|
@@ -908,89 +965,102 @@ export function ComboBoxListBox<T>(props: ComboBoxListBoxProps<T>): JSX.Element
|
|
|
908
965
|
*/
|
|
909
966
|
export function ComboBoxOption<T>(props: ComboBoxOptionProps<T>): JSX.Element {
|
|
910
967
|
const [local, ariaProps] = splitProps(props, [
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
968
|
+
"class",
|
|
969
|
+
"style",
|
|
970
|
+
"slot",
|
|
971
|
+
"id",
|
|
972
|
+
"item",
|
|
973
|
+
"textValue",
|
|
974
|
+
"onAction",
|
|
917
975
|
]);
|
|
918
976
|
|
|
919
|
-
|
|
920
|
-
const
|
|
921
|
-
if (!
|
|
922
|
-
throw new Error(
|
|
977
|
+
const stateContext = useContext(ComboBoxStateContext);
|
|
978
|
+
const comboBoxContext = useContext(ComboBoxContext);
|
|
979
|
+
if (!stateContext) {
|
|
980
|
+
throw new Error("ComboBoxOption must be used within a ComboBox");
|
|
923
981
|
}
|
|
924
|
-
const state =
|
|
982
|
+
const state = stateContext as ComboBoxState<T>;
|
|
983
|
+
const optionId = () => {
|
|
984
|
+
const listBoxId = getComboBoxData(state as ComboBoxState<unknown>)?.listBoxId;
|
|
985
|
+
return listBoxId ? `${listBoxId}-option-${local.id}` : String(local.id);
|
|
986
|
+
};
|
|
925
987
|
|
|
926
988
|
// Create option aria props using ComboBoxState's ListState-compatible interface
|
|
927
989
|
const optionAria = createOption<T>(
|
|
928
990
|
{
|
|
929
991
|
key: local.id,
|
|
992
|
+
get optionId() {
|
|
993
|
+
return optionId();
|
|
994
|
+
},
|
|
930
995
|
get isDisabled() {
|
|
931
996
|
return ariaProps.isDisabled;
|
|
932
997
|
},
|
|
933
|
-
get
|
|
934
|
-
return ariaProps[
|
|
998
|
+
get "aria-label"() {
|
|
999
|
+
return ariaProps["aria-label"];
|
|
1000
|
+
},
|
|
1001
|
+
get onAction() {
|
|
1002
|
+
return local.onAction;
|
|
1003
|
+
},
|
|
1004
|
+
shouldSelectOnPressUp: true,
|
|
1005
|
+
shouldFocusOnHover: true,
|
|
1006
|
+
shouldUseVirtualFocus: true,
|
|
1007
|
+
allowsDifferentPressOrigin: true,
|
|
1008
|
+
get onHoverStart() {
|
|
1009
|
+
return ariaProps.onHoverStart;
|
|
1010
|
+
},
|
|
1011
|
+
get onHoverEnd() {
|
|
1012
|
+
return ariaProps.onHoverEnd;
|
|
1013
|
+
},
|
|
1014
|
+
get onHoverChange() {
|
|
1015
|
+
return ariaProps.onHoverChange;
|
|
935
1016
|
},
|
|
936
1017
|
},
|
|
937
|
-
createComboBoxListStateAdapter(state)
|
|
1018
|
+
createComboBoxListStateAdapter(state),
|
|
938
1019
|
);
|
|
939
1020
|
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
return optionAria.isDisabled();
|
|
944
|
-
},
|
|
945
|
-
});
|
|
1021
|
+
const isOptionFocusVisible = () =>
|
|
1022
|
+
optionAria.isFocusVisible() ||
|
|
1023
|
+
(optionAria.isFocused() && (comboBoxContext?.isFocusVisible() ?? false));
|
|
946
1024
|
|
|
947
|
-
// Render props values
|
|
948
1025
|
const renderValues = createMemo<ComboBoxOptionRenderProps>(() => ({
|
|
949
1026
|
isSelected: optionAria.isSelected(),
|
|
950
1027
|
isFocused: optionAria.isFocused(),
|
|
951
|
-
isFocusVisible:
|
|
1028
|
+
isFocusVisible: isOptionFocusVisible(),
|
|
952
1029
|
isPressed: optionAria.isPressed(),
|
|
953
|
-
isHovered: isHovered(),
|
|
1030
|
+
isHovered: optionAria.isHovered(),
|
|
954
1031
|
isDisabled: optionAria.isDisabled(),
|
|
955
1032
|
}));
|
|
956
1033
|
|
|
957
|
-
// Resolve render props
|
|
958
1034
|
const renderProps = useRenderProps(
|
|
959
1035
|
{
|
|
960
1036
|
children: props.children,
|
|
961
1037
|
class: local.class,
|
|
962
1038
|
style: local.style,
|
|
963
|
-
defaultClassName:
|
|
1039
|
+
defaultClassName: "solidaria-ComboBox-option",
|
|
964
1040
|
},
|
|
965
|
-
renderValues
|
|
1041
|
+
renderValues,
|
|
966
1042
|
);
|
|
967
1043
|
|
|
968
1044
|
const selectionIndicatorContext = createMemo<SelectionIndicatorContextValue>(() => ({
|
|
969
1045
|
isSelected: optionAria.isSelected,
|
|
970
1046
|
}));
|
|
971
1047
|
|
|
972
|
-
// Remove ref from spread props
|
|
973
1048
|
const cleanOptionProps = () => {
|
|
974
1049
|
const { ref: _ref1, ...rest } = optionAria.optionProps as Record<string, unknown>;
|
|
975
1050
|
return rest;
|
|
976
1051
|
};
|
|
977
|
-
const cleanHoverProps = () => {
|
|
978
|
-
const { ref: _ref2, ...rest } = hoverProps as Record<string, unknown>;
|
|
979
|
-
return rest;
|
|
980
|
-
};
|
|
981
1052
|
|
|
982
1053
|
return (
|
|
983
1054
|
<SelectionIndicatorContext.Provider value={selectionIndicatorContext()}>
|
|
984
1055
|
<li
|
|
985
1056
|
{...cleanOptionProps()}
|
|
986
|
-
{...cleanHoverProps()}
|
|
987
1057
|
class={renderProps.class()}
|
|
988
1058
|
style={renderProps.style()}
|
|
989
1059
|
data-selected={optionAria.isSelected() || undefined}
|
|
990
1060
|
data-focused={optionAria.isFocused() || undefined}
|
|
991
|
-
data-focus-visible={
|
|
1061
|
+
data-focus-visible={isOptionFocusVisible() || undefined}
|
|
992
1062
|
data-pressed={optionAria.isPressed() || undefined}
|
|
993
|
-
data-hovered={isHovered() || undefined}
|
|
1063
|
+
data-hovered={optionAria.isHovered() || undefined}
|
|
994
1064
|
data-disabled={optionAria.isDisabled() || undefined}
|
|
995
1065
|
>
|
|
996
1066
|
{renderProps.renderChildren()}
|
|
@@ -999,7 +1069,98 @@ export function ComboBoxOption<T>(props: ComboBoxOptionProps<T>): JSX.Element {
|
|
|
999
1069
|
);
|
|
1000
1070
|
}
|
|
1001
1071
|
|
|
1002
|
-
|
|
1072
|
+
export interface ComboBoxTagGroupProps {
|
|
1073
|
+
/** Render function for each selected item. */
|
|
1074
|
+
children: (item: { key: Key; label: string }) => JSX.Element;
|
|
1075
|
+
/** The CSS className for the container. */
|
|
1076
|
+
class?: string;
|
|
1077
|
+
/** The inline style for the container. */
|
|
1078
|
+
style?: JSX.CSSProperties;
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1081
|
+
/**
|
|
1082
|
+
* Renders selected items as tags in multi-select mode.
|
|
1083
|
+
*/
|
|
1084
|
+
export function ComboBoxTagGroup(props: ComboBoxTagGroupProps): JSX.Element {
|
|
1085
|
+
const context = useContext(ComboBoxContext);
|
|
1086
|
+
if (!context) {
|
|
1087
|
+
throw new Error("ComboBoxTagGroup must be used within a ComboBox");
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
const state = context.state;
|
|
1091
|
+
const items = createMemo(() =>
|
|
1092
|
+
state.selectedItems().map((node) => ({
|
|
1093
|
+
key: node.key,
|
|
1094
|
+
label: node.textValue,
|
|
1095
|
+
})),
|
|
1096
|
+
);
|
|
1097
|
+
|
|
1098
|
+
return (
|
|
1099
|
+
<Show when={items().length > 0}>
|
|
1100
|
+
<div
|
|
1101
|
+
class={props.class ?? "solidaria-ComboBox-tagGroup"}
|
|
1102
|
+
style={props.style}
|
|
1103
|
+
role="group"
|
|
1104
|
+
aria-label="Selected items"
|
|
1105
|
+
>
|
|
1106
|
+
<For each={items()}>{(item) => props.children(item)}</For>
|
|
1107
|
+
</div>
|
|
1108
|
+
</Show>
|
|
1109
|
+
);
|
|
1110
|
+
}
|
|
1111
|
+
|
|
1112
|
+
export interface ComboBoxTagProps {
|
|
1113
|
+
/** The item data. */
|
|
1114
|
+
item: { key: Key; label: string };
|
|
1115
|
+
/** Handler called when the tag remove button is clicked. */
|
|
1116
|
+
onRemove?: () => void;
|
|
1117
|
+
/** The children to render inside the tag. */
|
|
1118
|
+
children?: JSX.Element;
|
|
1119
|
+
/** The CSS className for the tag. */
|
|
1120
|
+
class?: string;
|
|
1121
|
+
/** The inline style for the tag. */
|
|
1122
|
+
style?: JSX.CSSProperties;
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
/**
|
|
1126
|
+
* A tag representing a selected item in a multi-select combobox.
|
|
1127
|
+
*/
|
|
1128
|
+
export function ComboBoxTag(props: ComboBoxTagProps): JSX.Element {
|
|
1129
|
+
const context = useContext(ComboBoxContext);
|
|
1130
|
+
if (!context) {
|
|
1131
|
+
throw new Error("ComboBoxTag must be used within a ComboBox");
|
|
1132
|
+
}
|
|
1133
|
+
|
|
1134
|
+
const state = context.state;
|
|
1135
|
+
|
|
1136
|
+
const handleRemove = () => {
|
|
1137
|
+
if (props.onRemove) {
|
|
1138
|
+
props.onRemove();
|
|
1139
|
+
} else {
|
|
1140
|
+
state.removeSelectedKey(props.item.key);
|
|
1141
|
+
}
|
|
1142
|
+
};
|
|
1143
|
+
|
|
1144
|
+
return (
|
|
1145
|
+
<span
|
|
1146
|
+
class={props.class ?? "solidaria-ComboBox-tag"}
|
|
1147
|
+
style={props.style}
|
|
1148
|
+
data-key={String(props.item.key)}
|
|
1149
|
+
>
|
|
1150
|
+
{props.children ?? props.item.label}
|
|
1151
|
+
<button
|
|
1152
|
+
type="button"
|
|
1153
|
+
aria-label={`Remove ${props.item.label}`}
|
|
1154
|
+
onClick={handleRemove}
|
|
1155
|
+
class="solidaria-ComboBox-tag-remove"
|
|
1156
|
+
tabIndex={-1}
|
|
1157
|
+
>
|
|
1158
|
+
×
|
|
1159
|
+
</button>
|
|
1160
|
+
</span>
|
|
1161
|
+
);
|
|
1162
|
+
}
|
|
1163
|
+
|
|
1003
1164
|
ComboBox.Input = ComboBoxInput;
|
|
1004
1165
|
ComboBox.Button = ComboBoxButton;
|
|
1005
1166
|
ComboBox.ListBox = ComboBoxListBox;
|
|
@@ -1007,12 +1168,16 @@ ComboBox.Option = ComboBoxOption;
|
|
|
1007
1168
|
ComboBox.Label = ComboBoxLabel;
|
|
1008
1169
|
ComboBox.Description = ComboBoxDescription;
|
|
1009
1170
|
ComboBox.ErrorMessage = ComboBoxErrorMessage;
|
|
1171
|
+
ComboBox.TagGroup = ComboBoxTagGroup;
|
|
1172
|
+
ComboBox.Tag = ComboBoxTag;
|
|
1010
1173
|
|
|
1011
|
-
// Re-export filter function for convenience
|
|
1012
1174
|
export { defaultContainsFilter };
|
|
1013
1175
|
|
|
1014
1176
|
function createComboBoxListStateAdapter<T>(state: ComboBoxState<T>): ListState<T> {
|
|
1015
1177
|
const selectedKeys = createMemo(() => {
|
|
1178
|
+
if (state.selectionMode() === "multiple") {
|
|
1179
|
+
return state.selectedKeys();
|
|
1180
|
+
}
|
|
1016
1181
|
const key = state.selectedKey();
|
|
1017
1182
|
return key != null ? new Set<Key>([key]) : new Set<Key>();
|
|
1018
1183
|
});
|
|
@@ -1033,11 +1198,11 @@ function createComboBoxListStateAdapter<T>(state: ComboBoxState<T>): ListState<T
|
|
|
1033
1198
|
setFocusedKey: (key) => state.setFocusedKey(key ?? null),
|
|
1034
1199
|
childFocusStrategy: () => null,
|
|
1035
1200
|
selectionMode: state.selectionMode,
|
|
1036
|
-
selectionBehavior: () =>
|
|
1201
|
+
selectionBehavior: () => "replace",
|
|
1037
1202
|
disallowEmptySelection: () => true,
|
|
1038
1203
|
selectedKeys,
|
|
1039
1204
|
disabledKeys,
|
|
1040
|
-
disabledBehavior: () =>
|
|
1205
|
+
disabledBehavior: () => "all",
|
|
1041
1206
|
isEmpty: () => selectedKeys().size === 0,
|
|
1042
1207
|
isSelectAll: () => false,
|
|
1043
1208
|
isSelected: state.isSelected,
|