@proyecto-viviana/solidaria-components 0.3.2 → 0.4.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/dist/ActionBar.js +184 -0
- package/dist/ActionBar.js.map +1 -0
- package/dist/ActionBar.jsx +128 -0
- package/dist/ActionBar.jsx.map +1 -0
- package/dist/ActionGroup.js +179 -0
- package/dist/ActionGroup.js.map +1 -0
- package/dist/ActionGroup.jsx +129 -0
- package/dist/ActionGroup.jsx.map +1 -0
- package/dist/Alert.js +111 -0
- package/dist/Alert.js.map +1 -0
- package/dist/Alert.jsx +82 -0
- package/dist/Alert.jsx.map +1 -0
- package/dist/Autocomplete.js +130 -0
- package/dist/Autocomplete.js.map +1 -0
- package/dist/Autocomplete.jsx +116 -0
- package/dist/Autocomplete.jsx.map +1 -0
- package/dist/Breadcrumbs.d.ts.map +1 -1
- package/dist/Breadcrumbs.js +334 -0
- package/dist/Breadcrumbs.js.map +1 -0
- package/dist/Breadcrumbs.jsx +266 -0
- package/dist/Breadcrumbs.jsx.map +1 -0
- package/dist/Button.d.ts.map +1 -1
- package/dist/Button.js +348 -0
- package/dist/Button.js.map +1 -0
- package/dist/Button.jsx +314 -0
- package/dist/Button.jsx.map +1 -0
- package/dist/Calendar.d.ts +4 -4
- package/dist/Calendar.d.ts.map +1 -1
- package/dist/Calendar.js +538 -0
- package/dist/Calendar.js.map +1 -0
- package/dist/Calendar.jsx +333 -0
- package/dist/Calendar.jsx.map +1 -0
- package/dist/CalendarPicker.d.ts +33 -0
- package/dist/CalendarPicker.d.ts.map +1 -0
- package/dist/CalendarPicker.js +44 -0
- package/dist/CalendarPicker.js.map +1 -0
- package/dist/CalendarPicker.jsx +44 -0
- package/dist/CalendarPicker.jsx.map +1 -0
- package/dist/Checkbox.d.ts +83 -4
- package/dist/Checkbox.d.ts.map +1 -1
- package/dist/Checkbox.js +923 -0
- package/dist/Checkbox.js.map +1 -0
- package/dist/Checkbox.jsx +707 -0
- package/dist/Checkbox.jsx.map +1 -0
- package/dist/Collection.d.ts.map +1 -1
- package/dist/Collection.js +202 -0
- package/dist/Collection.js.map +1 -0
- package/dist/Collection.jsx +152 -0
- package/dist/Collection.jsx.map +1 -0
- package/dist/Color.d.ts.map +1 -1
- package/dist/Color.js +1720 -0
- package/dist/Color.js.map +1 -0
- package/dist/Color.jsx +1344 -0
- package/dist/Color.jsx.map +1 -0
- package/dist/ColorEditor.js +208 -0
- package/dist/ColorEditor.js.map +1 -0
- package/dist/ColorEditor.jsx +120 -0
- package/dist/ColorEditor.jsx.map +1 -0
- package/dist/ComboBox.d.ts +4 -4
- package/dist/ComboBox.d.ts.map +1 -1
- package/dist/ComboBox.js +992 -0
- package/dist/ComboBox.js.map +1 -0
- package/dist/ComboBox.jsx +714 -0
- package/dist/ComboBox.jsx.map +1 -0
- package/dist/ContextualHelpTrigger.js +146 -0
- package/dist/ContextualHelpTrigger.js.map +1 -0
- package/dist/ContextualHelpTrigger.jsx +109 -0
- package/dist/ContextualHelpTrigger.jsx.map +1 -0
- package/dist/DateField.d.ts +3 -3
- package/dist/DateField.d.ts.map +1 -1
- package/dist/DateField.js +4 -0
- package/dist/DateField.jsx +4 -0
- package/dist/DateField2.js +499 -0
- package/dist/DateField2.js.map +1 -0
- package/dist/DateField2.jsx +317 -0
- package/dist/DateField2.jsx.map +1 -0
- package/dist/DatePicker.d.ts +4 -4
- package/dist/DatePicker.d.ts.map +1 -1
- package/dist/DatePicker.js +991 -0
- package/dist/DatePicker.js.map +1 -0
- package/dist/DatePicker.jsx +682 -0
- package/dist/DatePicker.jsx.map +1 -0
- package/dist/Dialog.d.ts.map +1 -1
- package/dist/Dialog.js +337 -0
- package/dist/Dialog.js.map +1 -0
- package/dist/Dialog.jsx +192 -0
- package/dist/Dialog.jsx.map +1 -0
- package/dist/Disclosure.d.ts.map +1 -1
- package/dist/Disclosure.js +328 -0
- package/dist/Disclosure.js.map +1 -0
- package/dist/Disclosure.jsx +230 -0
- package/dist/Disclosure.jsx.map +1 -0
- package/dist/DragAndDrop.d.ts.map +1 -1
- package/dist/DragAndDrop.js +176 -0
- package/dist/DragAndDrop.js.map +1 -0
- package/dist/DragAndDrop.jsx +160 -0
- package/dist/DragAndDrop.jsx.map +1 -0
- package/dist/DropZone.d.ts.map +1 -1
- package/dist/DropZone.js +189 -0
- package/dist/DropZone.js.map +1 -0
- package/dist/DropZone.jsx +144 -0
- package/dist/DropZone.jsx.map +1 -0
- package/dist/FieldError.js +66 -0
- package/dist/FieldError.js.map +1 -0
- package/dist/FieldError.jsx +47 -0
- package/dist/FieldError.jsx.map +1 -0
- package/dist/FileTrigger.js +79 -0
- package/dist/FileTrigger.js.map +1 -0
- package/dist/FileTrigger.jsx +49 -0
- package/dist/FileTrigger.jsx.map +1 -0
- package/dist/Focusable.js +70 -0
- package/dist/Focusable.js.map +1 -0
- package/dist/Focusable.jsx +69 -0
- package/dist/Focusable.jsx.map +1 -0
- package/dist/Form.js +99 -0
- package/dist/Form.js.map +1 -0
- package/dist/Form.jsx +73 -0
- package/dist/Form.jsx.map +1 -0
- package/dist/GridList.d.ts +34 -2
- package/dist/GridList.d.ts.map +1 -1
- package/dist/GridList.js +723 -0
- package/dist/GridList.js.map +1 -0
- package/dist/GridList.jsx +552 -0
- package/dist/GridList.jsx.map +1 -0
- package/dist/HiddenTimeInput.js +104 -0
- package/dist/HiddenTimeInput.js.map +1 -0
- package/dist/HiddenTimeInput.jsx +69 -0
- package/dist/HiddenTimeInput.jsx.map +1 -0
- package/dist/Icon.d.ts.map +1 -1
- package/dist/Icon.js +127 -0
- package/dist/Icon.js.map +1 -0
- package/dist/Icon.jsx +72 -0
- package/dist/Icon.jsx.map +1 -0
- package/dist/Keyboard.js +30 -0
- package/dist/Keyboard.js.map +1 -0
- package/dist/Keyboard.jsx +24 -0
- package/dist/Keyboard.jsx.map +1 -0
- package/dist/Landmark.js +134 -0
- package/dist/Landmark.js.map +1 -0
- package/dist/Landmark.jsx +118 -0
- package/dist/Landmark.jsx.map +1 -0
- package/dist/Link.d.ts.map +1 -1
- package/dist/Link.js +219 -0
- package/dist/Link.js.map +1 -0
- package/dist/Link.jsx +189 -0
- package/dist/Link.jsx.map +1 -0
- package/dist/ListBox.d.ts.map +1 -1
- package/dist/ListBox.js +670 -0
- package/dist/ListBox.js.map +1 -0
- package/dist/ListBox.jsx +508 -0
- package/dist/ListBox.jsx.map +1 -0
- package/dist/Menu.d.ts +27 -9
- package/dist/Menu.d.ts.map +1 -1
- package/dist/Menu.js +1254 -0
- package/dist/Menu.js.map +1 -0
- package/dist/Menu.jsx +1042 -0
- package/dist/Menu.jsx.map +1 -0
- package/dist/Meter.d.ts.map +1 -1
- package/dist/Meter.js +123 -0
- package/dist/Meter.js.map +1 -0
- package/dist/Meter.jsx +107 -0
- package/dist/Meter.jsx.map +1 -0
- package/dist/Modal.d.ts.map +1 -1
- package/dist/Modal.js +380 -0
- package/dist/Modal.js.map +1 -0
- package/dist/Modal.jsx +314 -0
- package/dist/Modal.jsx.map +1 -0
- package/dist/NumberField.d.ts +3 -3
- package/dist/NumberField.d.ts.map +1 -1
- package/dist/NumberField.js +573 -0
- package/dist/NumberField.js.map +1 -0
- package/dist/NumberField.jsx +443 -0
- package/dist/NumberField.jsx.map +1 -0
- package/dist/Popover.d.ts +10 -2
- package/dist/Popover.d.ts.map +1 -1
- package/dist/Popover.js +464 -0
- package/dist/Popover.js.map +1 -0
- package/dist/Popover.jsx +333 -0
- package/dist/Popover.jsx.map +1 -0
- package/dist/Pressable.js +69 -0
- package/dist/Pressable.js.map +1 -0
- package/dist/Pressable.jsx +68 -0
- package/dist/Pressable.jsx.map +1 -0
- package/dist/ProgressBar.d.ts.map +1 -1
- package/dist/ProgressBar.js +130 -0
- package/dist/ProgressBar.js.map +1 -0
- package/dist/ProgressBar.jsx +114 -0
- package/dist/ProgressBar.jsx.map +1 -0
- package/dist/RadioGroup.d.ts +82 -4
- package/dist/RadioGroup.d.ts.map +1 -1
- package/dist/RadioGroup.js +931 -0
- package/dist/RadioGroup.js.map +1 -0
- package/dist/RadioGroup.jsx +681 -0
- package/dist/RadioGroup.jsx.map +1 -0
- package/dist/RangeCalendar.d.ts.map +1 -1
- package/dist/RangeCalendar.js +410 -0
- package/dist/RangeCalendar.js.map +1 -0
- package/dist/RangeCalendar.jsx +253 -0
- package/dist/RangeCalendar.jsx.map +1 -0
- package/dist/RouterProvider.js +118 -0
- package/dist/RouterProvider.js.map +1 -0
- package/dist/RouterProvider.jsx +112 -0
- package/dist/RouterProvider.jsx.map +1 -0
- package/dist/SearchField.d.ts +2 -2
- package/dist/SearchField.d.ts.map +1 -1
- package/dist/SearchField.js +643 -0
- package/dist/SearchField.js.map +1 -0
- package/dist/SearchField.jsx +526 -0
- package/dist/SearchField.jsx.map +1 -0
- package/dist/Select.d.ts.map +1 -1
- package/dist/Select.js +1031 -0
- package/dist/Select.js.map +1 -0
- package/dist/Select.jsx +744 -0
- package/dist/Select.jsx.map +1 -0
- package/dist/SelectionIndicator.d.ts.map +1 -1
- package/dist/SelectionIndicator.js +86 -0
- package/dist/SelectionIndicator.js.map +1 -0
- package/dist/SelectionIndicator.jsx +50 -0
- package/dist/SelectionIndicator.jsx.map +1 -0
- package/dist/Separator.js +97 -0
- package/dist/Separator.js.map +1 -0
- package/dist/Separator.jsx +85 -0
- package/dist/Separator.jsx.map +1 -0
- package/dist/SharedElementTransition.d.ts.map +1 -1
- package/dist/SharedElementTransition.js +165 -0
- package/dist/SharedElementTransition.js.map +1 -0
- package/dist/SharedElementTransition.jsx +138 -0
- package/dist/SharedElementTransition.jsx.map +1 -0
- package/dist/Slider.d.ts +33 -1
- package/dist/Slider.d.ts.map +1 -1
- package/dist/Slider.js +515 -0
- package/dist/Slider.js.map +1 -0
- package/dist/Slider.jsx +403 -0
- package/dist/Slider.jsx.map +1 -0
- package/dist/StepList.js +198 -0
- package/dist/StepList.js.map +1 -0
- package/dist/StepList.jsx +141 -0
- package/dist/StepList.jsx.map +1 -0
- package/dist/Switch.d.ts +65 -2
- package/dist/Switch.d.ts.map +1 -1
- package/dist/Switch.js +534 -0
- package/dist/Switch.js.map +1 -0
- package/dist/Switch.jsx +393 -0
- package/dist/Switch.jsx.map +1 -0
- package/dist/Table.d.ts +48 -0
- package/dist/Table.d.ts.map +1 -1
- package/dist/Table.js +1759 -0
- package/dist/Table.js.map +1 -0
- package/dist/Table.jsx +1348 -0
- package/dist/Table.jsx.map +1 -0
- package/dist/Tabs.d.ts +0 -4
- package/dist/Tabs.d.ts.map +1 -1
- package/dist/Tabs.js +595 -0
- package/dist/Tabs.js.map +1 -0
- package/dist/Tabs.jsx +367 -0
- package/dist/Tabs.jsx.map +1 -0
- package/dist/TagGroup.d.ts.map +1 -1
- package/dist/TagGroup.js +378 -0
- package/dist/TagGroup.js.map +1 -0
- package/dist/TagGroup.jsx +270 -0
- package/dist/TagGroup.jsx.map +1 -0
- package/dist/Text.d.ts +18 -6
- package/dist/Text.d.ts.map +1 -1
- package/dist/Text.js +42 -0
- package/dist/Text.js.map +1 -0
- package/dist/Text.jsx +35 -0
- package/dist/Text.jsx.map +1 -0
- package/dist/TextField.d.ts +6 -6
- package/dist/TextField.d.ts.map +1 -1
- package/dist/TextField.js +436 -0
- package/dist/TextField.js.map +1 -0
- package/dist/TextField.jsx +403 -0
- package/dist/TextField.jsx.map +1 -0
- package/dist/TimeField.d.ts +3 -3
- package/dist/TimeField.d.ts.map +1 -1
- package/dist/TimeField.js +372 -0
- package/dist/TimeField.js.map +1 -0
- package/dist/TimeField.jsx +224 -0
- package/dist/TimeField.jsx.map +1 -0
- package/dist/Toast.d.ts +14 -0
- package/dist/Toast.d.ts.map +1 -1
- package/dist/Toast.js +551 -0
- package/dist/Toast.js.map +1 -0
- package/dist/Toast.jsx +361 -0
- package/dist/Toast.jsx.map +1 -0
- package/dist/ToggleButton.d.ts.map +1 -1
- package/dist/ToggleButton.js +123 -0
- package/dist/ToggleButton.js.map +1 -0
- package/dist/ToggleButton.jsx +88 -0
- package/dist/ToggleButton.jsx.map +1 -0
- package/dist/ToggleButtonGroup.d.ts.map +1 -1
- package/dist/ToggleButtonGroup.js +114 -0
- package/dist/ToggleButtonGroup.js.map +1 -0
- package/dist/ToggleButtonGroup.jsx +85 -0
- package/dist/ToggleButtonGroup.jsx.map +1 -0
- package/dist/Toolbar.js +112 -0
- package/dist/Toolbar.js.map +1 -0
- package/dist/Toolbar.jsx +92 -0
- package/dist/Toolbar.jsx.map +1 -0
- package/dist/Tooltip.d.ts.map +1 -1
- package/dist/Tooltip.js +539 -0
- package/dist/Tooltip.js.map +1 -0
- package/dist/Tooltip.jsx +465 -0
- package/dist/Tooltip.jsx.map +1 -0
- package/dist/Tree.d.ts +14 -2
- package/dist/Tree.d.ts.map +1 -1
- package/dist/Tree.js +1424 -0
- package/dist/Tree.js.map +1 -0
- package/dist/Tree.jsx +1172 -0
- package/dist/Tree.jsx.map +1 -0
- package/dist/Virtualizer.d.ts +16 -2
- package/dist/Virtualizer.d.ts.map +1 -1
- package/dist/Virtualizer.js +2 -0
- package/dist/Virtualizer.jsx +2 -0
- package/dist/Virtualizer2.js +751 -0
- package/dist/Virtualizer2.js.map +1 -0
- package/dist/Virtualizer2.jsx +730 -0
- package/dist/Virtualizer2.jsx.map +1 -0
- package/dist/VirtualizerLayouts.d.ts +18 -0
- package/dist/VirtualizerLayouts.d.ts.map +1 -1
- package/dist/VisuallyHidden.js +42 -0
- package/dist/VisuallyHidden.js.map +1 -0
- package/dist/VisuallyHidden.jsx +35 -0
- package/dist/VisuallyHidden.jsx.map +1 -0
- package/dist/contexts.js +33 -0
- package/dist/contexts.js.map +1 -0
- package/dist/contexts.jsx +33 -0
- package/dist/contexts.jsx.map +1 -0
- package/dist/index.d.ts +7 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +70 -23932
- package/dist/index.jsx +70 -18337
- package/dist/useDragAndDrop.js +2 -0
- package/dist/useDragAndDrop.jsx +2 -0
- package/dist/useDragAndDrop2.js +395 -0
- package/dist/useDragAndDrop2.js.map +1 -0
- package/dist/useDragAndDrop2.jsx +395 -0
- package/dist/useDragAndDrop2.jsx.map +1 -0
- package/dist/utils.d.ts +83 -11
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +285 -0
- package/dist/utils.js.map +1 -0
- package/dist/utils.jsx +277 -0
- package/dist/utils.jsx.map +1 -0
- package/dist/virtualizer/Layout.js +144 -0
- package/dist/virtualizer/Layout.js.map +1 -0
- package/dist/virtualizer/Layout.jsx +144 -0
- package/dist/virtualizer/Layout.jsx.map +1 -0
- package/package.json +401 -4
- package/src/Breadcrumbs.tsx +3 -1
- package/src/Button.tsx +22 -2
- package/src/Calendar.tsx +27 -10
- package/src/CalendarPicker.tsx +73 -0
- package/src/Checkbox.tsx +539 -3
- package/src/Collection.tsx +9 -3
- package/src/Color.tsx +42 -14
- package/src/ComboBox.tsx +50 -6
- package/src/DateField.tsx +20 -2
- package/src/DatePicker.tsx +57 -5
- package/src/Dialog.tsx +13 -5
- package/src/Disclosure.tsx +3 -1
- package/src/DragAndDrop.tsx +3 -1
- package/src/DropZone.tsx +3 -1
- package/src/GridList.tsx +125 -24
- package/src/Icon.tsx +3 -1
- package/src/Link.tsx +3 -1
- package/src/ListBox.tsx +31 -4
- package/src/Menu.tsx +252 -128
- package/src/Meter.tsx +3 -1
- package/src/Modal.tsx +100 -52
- package/src/NumberField.tsx +51 -8
- package/src/Popover.tsx +40 -10
- package/src/ProgressBar.tsx +3 -1
- package/src/RadioGroup.tsx +468 -4
- package/src/RangeCalendar.tsx +3 -1
- package/src/SearchField.tsx +27 -3
- package/src/Select.tsx +22 -7
- package/src/SelectionIndicator.tsx +3 -1
- package/src/SharedElementTransition.tsx +3 -1
- package/src/Slider.tsx +159 -13
- package/src/Switch.tsx +395 -2
- package/src/Table.tsx +409 -95
- package/src/Tabs.tsx +16 -45
- package/src/TagGroup.tsx +3 -1
- package/src/Text.tsx +31 -10
- package/src/TextField.tsx +43 -5
- package/src/TimeField.tsx +20 -2
- package/src/Toast.tsx +79 -14
- package/src/ToggleButton.tsx +3 -1
- package/src/ToggleButtonGroup.tsx +3 -1
- package/src/Tooltip.tsx +3 -1
- package/src/Tree.tsx +77 -9
- package/src/Virtualizer.tsx +180 -31
- package/src/VirtualizerLayouts.ts +45 -10
- package/src/index.ts +50 -0
- package/src/utils.tsx +243 -27
- package/dist/index.js.map +0 -1
- package/dist/index.jsx.map +0 -1
package/src/Menu.tsx
CHANGED
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
createHover,
|
|
27
27
|
createButton,
|
|
28
28
|
createInteractOutside,
|
|
29
|
+
createScrollIntoViewOnFocus,
|
|
29
30
|
mergeProps,
|
|
30
31
|
FocusScope,
|
|
31
32
|
type AriaMenuProps,
|
|
@@ -86,7 +87,7 @@ export interface MenuRenderProps {
|
|
|
86
87
|
|
|
87
88
|
export interface MenuProps<T>
|
|
88
89
|
extends
|
|
89
|
-
Omit<AriaMenuProps
|
|
90
|
+
Omit<AriaMenuProps<T>, "children">,
|
|
90
91
|
SlotProps,
|
|
91
92
|
Pick<
|
|
92
93
|
MenuStateProps<T>,
|
|
@@ -108,8 +109,10 @@ export interface MenuProps<T>
|
|
|
108
109
|
getDisabled?: (item: T) => boolean;
|
|
109
110
|
/** Keys of disabled items. */
|
|
110
111
|
disabledKeys?: Iterable<Key>;
|
|
111
|
-
/**
|
|
112
|
-
|
|
112
|
+
/** Whether disabled items can still receive focus. */
|
|
113
|
+
disabledBehavior?: "selection" | "all";
|
|
114
|
+
/** Handler called when an item is activated, with the activated item's value. */
|
|
115
|
+
onAction?: (key: Key, value: T) => void;
|
|
113
116
|
/** Handler called when the menu should close. */
|
|
114
117
|
onClose?: () => void;
|
|
115
118
|
/** The children of the component. A function may be provided to render each item. */
|
|
@@ -125,12 +128,9 @@ export interface MenuProps<T>
|
|
|
125
128
|
/** Whether the menu should close when an item is selected. */
|
|
126
129
|
shouldCloseOnSelect?: boolean;
|
|
127
130
|
/** Ref for the menu element. */
|
|
128
|
-
ref?: RefLike<
|
|
131
|
+
ref?: RefLike<HTMLDivElement>;
|
|
129
132
|
/** Custom renderer for the menu element. */
|
|
130
|
-
render?: (
|
|
131
|
-
props: JSX.HTMLAttributes<HTMLUListElement>,
|
|
132
|
-
renderProps: MenuRenderProps,
|
|
133
|
-
) => JSX.Element;
|
|
133
|
+
render?: (props: JSX.HTMLAttributes<HTMLDivElement>, renderProps: MenuRenderProps) => JSX.Element;
|
|
134
134
|
/** Drag and drop hooks from `useDragAndDrop`. */
|
|
135
135
|
dragAndDropHooks?: DragAndDropHooks<T>;
|
|
136
136
|
}
|
|
@@ -154,9 +154,22 @@ export interface MenuItemRenderProps {
|
|
|
154
154
|
hasSubmenu: boolean;
|
|
155
155
|
/** Whether the submenu is currently open. */
|
|
156
156
|
isOpen: boolean;
|
|
157
|
+
/**
|
|
158
|
+
* Internal: props (carrying the slot `id` the item's `aria-describedby`
|
|
159
|
+
* references) for the item's description text element. Threaded to the styled
|
|
160
|
+
* `Text slot="description"` so it receives the id — mirrors upstream's
|
|
161
|
+
* `TextContext` description-slot delegation.
|
|
162
|
+
*/
|
|
163
|
+
descriptionProps?: JSX.HTMLAttributes<HTMLElement>;
|
|
164
|
+
/**
|
|
165
|
+
* Internal: props (id + `aria-hidden`) for the item's keyboard-shortcut
|
|
166
|
+
* element, threaded to the styled `Keyboard`.
|
|
167
|
+
*/
|
|
168
|
+
keyboardShortcutProps?: JSX.HTMLAttributes<HTMLElement>;
|
|
157
169
|
}
|
|
158
170
|
|
|
159
|
-
export interface MenuItemProps<T>
|
|
171
|
+
export interface MenuItemProps<T>
|
|
172
|
+
extends Omit<AriaMenuItemProps, "children" | "key" | "id">, SlotProps {
|
|
160
173
|
/** The unique key for the item. */
|
|
161
174
|
id: Key;
|
|
162
175
|
/** The item value. */
|
|
@@ -185,11 +198,11 @@ export interface MenuItemProps<T> extends Omit<AriaMenuItemProps, "children" | "
|
|
|
185
198
|
onHoverEnd?: () => void;
|
|
186
199
|
/** Handler called when hover state changes. */
|
|
187
200
|
onHoverChange?: (isHovered: boolean) => void;
|
|
188
|
-
/** Ref for the menu item element. */
|
|
189
|
-
ref?: RefLike<
|
|
201
|
+
/** Ref for the menu item element (a `<div>`, or an `<a>` for link items). */
|
|
202
|
+
ref?: RefLike<HTMLElement>;
|
|
190
203
|
/** Custom renderer for the menu item element. */
|
|
191
204
|
render?: (
|
|
192
|
-
props: JSX.HTMLAttributes<
|
|
205
|
+
props: JSX.HTMLAttributes<HTMLElement>,
|
|
193
206
|
renderProps: MenuItemRenderProps,
|
|
194
207
|
) => JSX.Element;
|
|
195
208
|
}
|
|
@@ -249,13 +262,15 @@ interface MenuTriggerContextValue {
|
|
|
249
262
|
state: OverlayTriggerState;
|
|
250
263
|
triggerProps: JSX.HTMLAttributes<HTMLElement>;
|
|
251
264
|
menuProps: JSX.HTMLAttributes<HTMLElement>;
|
|
265
|
+
isPressed?: () => boolean;
|
|
266
|
+
onPressStart?: (e: { pointerType?: string }) => void;
|
|
252
267
|
}
|
|
253
268
|
|
|
254
269
|
interface MenuItemContextValue {
|
|
255
270
|
props?: () => JSX.HTMLAttributes<HTMLElement>;
|
|
256
271
|
closeOnSelect?: boolean;
|
|
257
272
|
onAction?: () => void;
|
|
258
|
-
setItemRef?: (el:
|
|
273
|
+
setItemRef?: (el: HTMLElement | null) => void;
|
|
259
274
|
}
|
|
260
275
|
|
|
261
276
|
interface StaticMenuCollectionItem {
|
|
@@ -283,6 +298,12 @@ interface MenuSectionSelectionRegistryContextValue {
|
|
|
283
298
|
selectItem(key: Key, event?: MenuSelectionEvent): boolean;
|
|
284
299
|
}
|
|
285
300
|
|
|
301
|
+
interface MenuItemCloseRegistryContextValue {
|
|
302
|
+
registerItem(key: Key, shouldCloseOnSelect: () => boolean | undefined): void;
|
|
303
|
+
unregisterItem(key: Key, shouldCloseOnSelect: () => boolean | undefined): void;
|
|
304
|
+
shouldCloseOnSelect(key: Key | null): boolean | undefined;
|
|
305
|
+
}
|
|
306
|
+
|
|
286
307
|
export const MenuContext = createContext<MenuContextValue<unknown> | null>(null);
|
|
287
308
|
export const MenuStateContext = createContext<MenuState<unknown> | null>(null);
|
|
288
309
|
export const MenuTriggerContext = createContext<MenuTriggerContextValue | null>(null);
|
|
@@ -292,6 +313,7 @@ const StaticMenuCollectionContext = createContext<StaticMenuCollectionContextVal
|
|
|
292
313
|
const MenuSectionSelectionContext = createContext<MenuSectionSelectionContextValue | null>(null);
|
|
293
314
|
const MenuSectionSelectionRegistryContext =
|
|
294
315
|
createContext<MenuSectionSelectionRegistryContextValue | null>(null);
|
|
316
|
+
const MenuItemCloseRegistryContext = createContext<MenuItemCloseRegistryContextValue | null>(null);
|
|
295
317
|
|
|
296
318
|
type RefLike<T> = ((el: T) => void) | { current?: T | null } | undefined;
|
|
297
319
|
|
|
@@ -323,6 +345,22 @@ export function MenuTrigger(props: MenuTriggerProps): JSX.Element {
|
|
|
323
345
|
},
|
|
324
346
|
});
|
|
325
347
|
|
|
348
|
+
const [isMousePressed, setMousePressed] = createSignal(false);
|
|
349
|
+
const onPressStart = (e: { pointerType?: string }) => {
|
|
350
|
+
if (e.pointerType !== "mouse" || typeof document === "undefined") {
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
setMousePressed(true);
|
|
355
|
+
document.addEventListener(
|
|
356
|
+
"pointerup",
|
|
357
|
+
() => {
|
|
358
|
+
setMousePressed(false);
|
|
359
|
+
},
|
|
360
|
+
{ once: true, capture: true },
|
|
361
|
+
);
|
|
362
|
+
};
|
|
363
|
+
|
|
326
364
|
const menuTrigger = createMenuTrigger(
|
|
327
365
|
{
|
|
328
366
|
get isDisabled() {
|
|
@@ -343,6 +381,8 @@ export function MenuTrigger(props: MenuTriggerProps): JSX.Element {
|
|
|
343
381
|
get menuProps() {
|
|
344
382
|
return menuTrigger.menuProps;
|
|
345
383
|
},
|
|
384
|
+
isPressed: isMousePressed,
|
|
385
|
+
onPressStart,
|
|
346
386
|
}}
|
|
347
387
|
>
|
|
348
388
|
{props.children}
|
|
@@ -369,7 +409,7 @@ export function SubmenuTrigger(props: SubmenuTriggerProps): JSX.Element {
|
|
|
369
409
|
},
|
|
370
410
|
});
|
|
371
411
|
|
|
372
|
-
let triggerRef:
|
|
412
|
+
let triggerRef: HTMLElement | null = null;
|
|
373
413
|
const triggerId = createUniqueId();
|
|
374
414
|
const menuId = createUniqueId();
|
|
375
415
|
let hoverTimeout: number | undefined;
|
|
@@ -448,7 +488,7 @@ export function SubmenuTrigger(props: SubmenuTriggerProps): JSX.Element {
|
|
|
448
488
|
},
|
|
449
489
|
triggerRef: () => triggerRef,
|
|
450
490
|
setTriggerRef: (el: HTMLElement | null) => {
|
|
451
|
-
triggerRef = el
|
|
491
|
+
triggerRef = el;
|
|
452
492
|
},
|
|
453
493
|
triggerId,
|
|
454
494
|
trigger: "SubmenuTrigger",
|
|
@@ -550,6 +590,9 @@ export function MenuButton(props: MenuButtonProps): JSX.Element {
|
|
|
550
590
|
get isDisabled() {
|
|
551
591
|
return local.isDisabled;
|
|
552
592
|
},
|
|
593
|
+
onPressStart(e) {
|
|
594
|
+
context.onPressStart?.(e);
|
|
595
|
+
},
|
|
553
596
|
onPress() {
|
|
554
597
|
state.toggle();
|
|
555
598
|
},
|
|
@@ -567,14 +610,16 @@ export function MenuButton(props: MenuButtonProps): JSX.Element {
|
|
|
567
610
|
isOpen: state.isOpen(),
|
|
568
611
|
isFocused: isFocused(),
|
|
569
612
|
isFocusVisible: isFocusVisible(),
|
|
570
|
-
isPressed: buttonAria.isPressed(),
|
|
613
|
+
isPressed: context.isPressed?.() || buttonAria.isPressed(),
|
|
571
614
|
isHovered: isHovered(),
|
|
572
615
|
isDisabled: !!local.isDisabled,
|
|
573
616
|
}));
|
|
574
617
|
|
|
575
618
|
const renderProps = useRenderProps(
|
|
576
619
|
{
|
|
577
|
-
children
|
|
620
|
+
get children() {
|
|
621
|
+
return props.children;
|
|
622
|
+
},
|
|
578
623
|
class: local.class,
|
|
579
624
|
style: local.style,
|
|
580
625
|
defaultClassName: "solidaria-MenuButton",
|
|
@@ -624,7 +669,7 @@ export function MenuButton(props: MenuButtonProps): JSX.Element {
|
|
|
624
669
|
data-open={state.isOpen() || undefined}
|
|
625
670
|
data-focused={isFocused() || undefined}
|
|
626
671
|
data-focus-visible={isFocusVisible() || undefined}
|
|
627
|
-
data-pressed={buttonAria.isPressed() || undefined}
|
|
672
|
+
data-pressed={context.isPressed?.() || buttonAria.isPressed() || undefined}
|
|
628
673
|
data-hovered={isHovered() || undefined}
|
|
629
674
|
data-disabled={local.isDisabled || undefined}
|
|
630
675
|
>
|
|
@@ -639,23 +684,14 @@ export function MenuButton(props: MenuButtonProps): JSX.Element {
|
|
|
639
684
|
export function Menu<T>(props: MenuProps<T>): JSX.Element {
|
|
640
685
|
const [local, stateProps, ariaProps] = splitProps(
|
|
641
686
|
props,
|
|
642
|
-
[
|
|
643
|
-
"children",
|
|
644
|
-
"class",
|
|
645
|
-
"style",
|
|
646
|
-
"render",
|
|
647
|
-
"slot",
|
|
648
|
-
"renderEmptyState",
|
|
649
|
-
"shouldCloseOnSelect",
|
|
650
|
-
"ref",
|
|
651
|
-
"staticChildren",
|
|
652
|
-
],
|
|
687
|
+
["children", "class", "style", "render", "slot", "renderEmptyState", "ref", "staticChildren"],
|
|
653
688
|
[
|
|
654
689
|
"items",
|
|
655
690
|
"getKey",
|
|
656
691
|
"getTextValue",
|
|
657
692
|
"getDisabled",
|
|
658
693
|
"disabledKeys",
|
|
694
|
+
"disabledBehavior",
|
|
659
695
|
"selectionMode",
|
|
660
696
|
"selectionBehavior",
|
|
661
697
|
"disallowEmptySelection",
|
|
@@ -665,16 +701,18 @@ export function Menu<T>(props: MenuProps<T>): JSX.Element {
|
|
|
665
701
|
"allowDuplicateSelectionEvents",
|
|
666
702
|
"onAction",
|
|
667
703
|
"onClose",
|
|
704
|
+
"shouldCloseOnSelect",
|
|
668
705
|
"dragAndDropHooks",
|
|
669
706
|
],
|
|
670
707
|
);
|
|
671
708
|
|
|
672
709
|
const triggerContext = useContext(MenuTriggerContext);
|
|
673
710
|
|
|
674
|
-
const [menuRef, setMenuRef] = createSignal<
|
|
711
|
+
const [menuRef, setMenuRef] = createSignal<HTMLDivElement | null>(null);
|
|
675
712
|
const [staticItems, setStaticItems] = createSignal<StaticMenuCollectionItem[]>([]);
|
|
676
713
|
const staticItemMap = new Map<Key, StaticMenuCollectionItem>();
|
|
677
714
|
const sectionSelectionMap = new Map<Key, MenuSectionSelectionContextValue>();
|
|
715
|
+
const itemCloseMap = new Map<Key, () => boolean | undefined>();
|
|
678
716
|
const usesStaticChildren = () => local.staticChildren != null || stateProps.items == null;
|
|
679
717
|
|
|
680
718
|
const syncStaticItems = () => {
|
|
@@ -720,9 +758,27 @@ export function Menu<T>(props: MenuProps<T>): JSX.Element {
|
|
|
720
758
|
return true;
|
|
721
759
|
},
|
|
722
760
|
};
|
|
723
|
-
const
|
|
761
|
+
const itemCloseRegistry: MenuItemCloseRegistryContextValue = {
|
|
762
|
+
registerItem(key, shouldCloseOnSelect) {
|
|
763
|
+
itemCloseMap.set(key, shouldCloseOnSelect);
|
|
764
|
+
},
|
|
765
|
+
unregisterItem(key, shouldCloseOnSelect) {
|
|
766
|
+
if (itemCloseMap.get(key) === shouldCloseOnSelect) {
|
|
767
|
+
itemCloseMap.delete(key);
|
|
768
|
+
}
|
|
769
|
+
},
|
|
770
|
+
shouldCloseOnSelect(key) {
|
|
771
|
+
return key == null ? undefined : itemCloseMap.get(key)?.();
|
|
772
|
+
},
|
|
773
|
+
};
|
|
774
|
+
const handleAction = (key: Key, value?: T) => {
|
|
724
775
|
sectionSelectionRegistry.selectItem(key);
|
|
725
|
-
|
|
776
|
+
// Forward the activated item's value, which `createMenuState` sets from the
|
|
777
|
+
// collection node. For dynamic collections this is the user's data item.
|
|
778
|
+
// Static children are modeled with an internal item descriptor that upstream
|
|
779
|
+
// RAC does not expose as `value` (MenuItem only carries `value` for dynamic
|
|
780
|
+
// collections), so it is suppressed there to match.
|
|
781
|
+
stateProps.onAction?.(key, (usesStaticChildren() ? undefined : value) as T);
|
|
726
782
|
};
|
|
727
783
|
|
|
728
784
|
const flatItems = createMemo<T[]>(() => {
|
|
@@ -757,6 +813,9 @@ export function Menu<T>(props: MenuProps<T>): JSX.Element {
|
|
|
757
813
|
get disabledKeys() {
|
|
758
814
|
return stateProps.disabledKeys;
|
|
759
815
|
},
|
|
816
|
+
get disabledBehavior() {
|
|
817
|
+
return stateProps.disabledBehavior;
|
|
818
|
+
},
|
|
760
819
|
get selectionMode() {
|
|
761
820
|
return stateProps.selectionMode;
|
|
762
821
|
},
|
|
@@ -808,6 +867,12 @@ export function Menu<T>(props: MenuProps<T>): JSX.Element {
|
|
|
808
867
|
get onClose() {
|
|
809
868
|
return stateProps.onClose ?? (() => triggerContext?.state.close());
|
|
810
869
|
},
|
|
870
|
+
get shouldCloseOnSelect() {
|
|
871
|
+
return (
|
|
872
|
+
itemCloseRegistry.shouldCloseOnSelect(state.focusedKey()) ??
|
|
873
|
+
stateProps.shouldCloseOnSelect
|
|
874
|
+
);
|
|
875
|
+
},
|
|
811
876
|
get "aria-label"() {
|
|
812
877
|
return ariaProps["aria-label"];
|
|
813
878
|
},
|
|
@@ -821,6 +886,15 @@ export function Menu<T>(props: MenuProps<T>): JSX.Element {
|
|
|
821
886
|
state,
|
|
822
887
|
);
|
|
823
888
|
|
|
889
|
+
// Reveal the activedescendant-focused item on keyboard navigation. The menu
|
|
890
|
+
// keeps real DOM focus on itself, so the browser won't natively scroll an
|
|
891
|
+
// off-screen focused item into view the way roving tabindex would.
|
|
892
|
+
createScrollIntoViewOnFocus({
|
|
893
|
+
focusedKey: () => state.focusedKey(),
|
|
894
|
+
isActive: () => state.isFocused(),
|
|
895
|
+
ref: () => menuRef(),
|
|
896
|
+
});
|
|
897
|
+
|
|
824
898
|
const { isFocused, focusProps } = createFocusRing();
|
|
825
899
|
|
|
826
900
|
createInteractOutside({
|
|
@@ -870,7 +944,7 @@ export function Menu<T>(props: MenuProps<T>): JSX.Element {
|
|
|
870
944
|
const { ref: _ref4, ...rest } = labelProps as Record<string, unknown>;
|
|
871
945
|
return rest;
|
|
872
946
|
};
|
|
873
|
-
const setResolvedMenuRef = (el:
|
|
947
|
+
const setResolvedMenuRef = (el: HTMLDivElement): void => {
|
|
874
948
|
setMenuRef(el);
|
|
875
949
|
assignRef(local.ref, el);
|
|
876
950
|
};
|
|
@@ -1067,31 +1141,31 @@ export function Menu<T>(props: MenuProps<T>): JSX.Element {
|
|
|
1067
1141
|
parentCollectionRenderer?.renderDropIndicator?.(index, position),
|
|
1068
1142
|
}));
|
|
1069
1143
|
const menuItemContextValue = createMemo<MenuItemContextValue>(() =>
|
|
1070
|
-
|
|
1071
|
-
? { closeOnSelect:
|
|
1144
|
+
stateProps.shouldCloseOnSelect !== undefined
|
|
1145
|
+
? { closeOnSelect: stateProps.shouldCloseOnSelect }
|
|
1072
1146
|
: {},
|
|
1073
1147
|
);
|
|
1074
1148
|
const menuListChildren = () => (
|
|
1075
1149
|
<SharedElementTransition>
|
|
1076
1150
|
{state.collection().size === 0 && !usesStaticChildren() && local.renderEmptyState ? (
|
|
1077
|
-
<
|
|
1151
|
+
<div role="presentation" data-empty-state>
|
|
1078
1152
|
<div role="menuitem" style={{ display: "contents" }}>
|
|
1079
1153
|
{local.renderEmptyState()}
|
|
1080
1154
|
</div>
|
|
1081
|
-
</
|
|
1155
|
+
</div>
|
|
1082
1156
|
) : usesStaticChildren() ? (
|
|
1083
1157
|
renderStaticChildren()
|
|
1084
1158
|
) : hasSections() ? (
|
|
1085
1159
|
<For each={sectionedRenderEntries()}>
|
|
1086
1160
|
{(entry) =>
|
|
1087
1161
|
entry.type === "section" ? (
|
|
1088
|
-
<
|
|
1162
|
+
<div role="presentation" data-section-wrapper>
|
|
1089
1163
|
<Section class="solidaria-Menu-section">
|
|
1090
1164
|
{entry.section.title != null && (
|
|
1091
1165
|
<Header class="solidaria-Menu-sectionHeader">{entry.section.title}</Header>
|
|
1092
1166
|
)}
|
|
1093
1167
|
<Group class="solidaria-Menu-sectionGroup">
|
|
1094
|
-
<
|
|
1168
|
+
<div role="group" aria-label={entry.section["aria-label"]}>
|
|
1095
1169
|
<For each={entry.items}>
|
|
1096
1170
|
{(indexedItem) => (
|
|
1097
1171
|
<>
|
|
@@ -1105,10 +1179,10 @@ export function Menu<T>(props: MenuProps<T>): JSX.Element {
|
|
|
1105
1179
|
</>
|
|
1106
1180
|
)}
|
|
1107
1181
|
</For>
|
|
1108
|
-
</
|
|
1182
|
+
</div>
|
|
1109
1183
|
</Group>
|
|
1110
1184
|
</Section>
|
|
1111
|
-
</
|
|
1185
|
+
</div>
|
|
1112
1186
|
) : (
|
|
1113
1187
|
<>
|
|
1114
1188
|
{collectionRenderer().renderDropIndicator?.(entry.item.index, "before")}
|
|
@@ -1122,7 +1196,7 @@ export function Menu<T>(props: MenuProps<T>): JSX.Element {
|
|
|
1122
1196
|
) : (
|
|
1123
1197
|
<>
|
|
1124
1198
|
{virtualRange()?.offsetTop ? (
|
|
1125
|
-
<
|
|
1199
|
+
<div
|
|
1126
1200
|
role="presentation"
|
|
1127
1201
|
aria-hidden="true"
|
|
1128
1202
|
style={{ height: `${virtualRange()!.offsetTop}px` }}
|
|
@@ -1149,7 +1223,7 @@ export function Menu<T>(props: MenuProps<T>): JSX.Element {
|
|
|
1149
1223
|
}}
|
|
1150
1224
|
</For>
|
|
1151
1225
|
{virtualRange()?.offsetBottom ? (
|
|
1152
|
-
<
|
|
1226
|
+
<div
|
|
1153
1227
|
role="presentation"
|
|
1154
1228
|
aria-hidden="true"
|
|
1155
1229
|
style={{ height: `${virtualRange()!.offsetBottom}px` }}
|
|
@@ -1178,7 +1252,7 @@ export function Menu<T>(props: MenuProps<T>): JSX.Element {
|
|
|
1178
1252
|
"data-empty": state.collection().size === 0 || undefined,
|
|
1179
1253
|
"data-drop-target": isRootDropTarget() || undefined,
|
|
1180
1254
|
children: menuListChildren(),
|
|
1181
|
-
}) as JSX.HTMLAttributes<
|
|
1255
|
+
}) as JSX.HTMLAttributes<HTMLDivElement>;
|
|
1182
1256
|
|
|
1183
1257
|
// Only use FocusScope when inside a MenuTrigger (for popover behavior)
|
|
1184
1258
|
// Standalone menus don't need focus restoration
|
|
@@ -1196,44 +1270,46 @@ export function Menu<T>(props: MenuProps<T>): JSX.Element {
|
|
|
1196
1270
|
>
|
|
1197
1271
|
<MenuStateContext.Provider value={state}>
|
|
1198
1272
|
<MenuSectionSelectionRegistryContext.Provider value={sectionSelectionRegistry}>
|
|
1199
|
-
<
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
<
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
<
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
local.render
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1273
|
+
<MenuItemCloseRegistryContext.Provider value={itemCloseRegistry}>
|
|
1274
|
+
<StaticMenuCollectionContext.Provider
|
|
1275
|
+
value={usesStaticChildren() ? staticCollectionContext : null}
|
|
1276
|
+
>
|
|
1277
|
+
<MenuItemContext.Provider value={menuItemContextValue()}>
|
|
1278
|
+
<CollectionRendererContext.Provider value={collectionRenderer()}>
|
|
1279
|
+
<>
|
|
1280
|
+
<Show when={ariaProps.label}>
|
|
1281
|
+
<span {...cleanLabelProps()}>{ariaProps.label as JSX.Element}</span>
|
|
1282
|
+
</Show>
|
|
1283
|
+
{local.render ? (
|
|
1284
|
+
local.render(menuListProps(), renderValues())
|
|
1285
|
+
) : (
|
|
1286
|
+
<div
|
|
1287
|
+
ref={setResolvedMenuRef}
|
|
1288
|
+
{...mergeProps(
|
|
1289
|
+
domProps(),
|
|
1290
|
+
cleanMenuProps(),
|
|
1291
|
+
cleanTriggerMenuProps(),
|
|
1292
|
+
cleanFocusProps(),
|
|
1293
|
+
(droppableCollection()?.collectionProps as
|
|
1294
|
+
| Record<string, unknown>
|
|
1295
|
+
| undefined) ?? {},
|
|
1296
|
+
)}
|
|
1297
|
+
class={renderProps.class()}
|
|
1298
|
+
style={renderProps.style()}
|
|
1299
|
+
slot={local.slot}
|
|
1300
|
+
data-focused={state.isFocused() || undefined}
|
|
1301
|
+
data-disabled={resolveDisabled() || undefined}
|
|
1302
|
+
data-empty={state.collection().size === 0 || undefined}
|
|
1303
|
+
data-drop-target={isRootDropTarget() || undefined}
|
|
1304
|
+
>
|
|
1305
|
+
{menuListChildren()}
|
|
1306
|
+
</div>
|
|
1307
|
+
)}
|
|
1308
|
+
</>
|
|
1309
|
+
</CollectionRendererContext.Provider>
|
|
1310
|
+
</MenuItemContext.Provider>
|
|
1311
|
+
</StaticMenuCollectionContext.Provider>
|
|
1312
|
+
</MenuItemCloseRegistryContext.Provider>
|
|
1237
1313
|
</MenuSectionSelectionRegistryContext.Provider>
|
|
1238
1314
|
</MenuStateContext.Provider>
|
|
1239
1315
|
</MenuContext.Provider>
|
|
@@ -1283,17 +1359,26 @@ export function MenuItem<T>(props: MenuItemProps<T>): JSX.Element {
|
|
|
1283
1359
|
const staticCollection = useContext(StaticMenuCollectionContext);
|
|
1284
1360
|
const sectionSelection = useContext(MenuSectionSelectionContext);
|
|
1285
1361
|
const sectionSelectionRegistry = useContext(MenuSectionSelectionRegistryContext);
|
|
1286
|
-
const
|
|
1362
|
+
const itemCloseRegistry = useContext(MenuItemCloseRegistryContext);
|
|
1363
|
+
// Tracks the focusable menuitem element (the <div>, or the <a> for link
|
|
1364
|
+
// items) so roving focus can be moved onto it imperatively.
|
|
1365
|
+
const [ref, setRef] = createSignal<HTMLElement | null>(null);
|
|
1287
1366
|
const contextProps = () => itemContext?.props?.() ?? {};
|
|
1288
1367
|
const combinedOnAction = () => {
|
|
1289
1368
|
local.onAction?.();
|
|
1290
1369
|
itemContext?.onAction?.();
|
|
1291
1370
|
};
|
|
1371
|
+
const itemCloseOnSelect = () =>
|
|
1372
|
+
ariaProps.closeOnSelect ??
|
|
1373
|
+
sectionSelection?.shouldCloseOnSelect() ??
|
|
1374
|
+
itemContext?.closeOnSelect;
|
|
1292
1375
|
const activeSectionSelection = () =>
|
|
1293
1376
|
sectionSelection && sectionSelection.selectionMode() !== "none" ? sectionSelection : null;
|
|
1294
1377
|
let registeredStaticKey: Key | null = null;
|
|
1295
1378
|
let registeredSectionSelectionKey: Key | null = null;
|
|
1296
1379
|
let registeredSectionSelection: MenuSectionSelectionContextValue | null = null;
|
|
1380
|
+
let registeredCloseKey: Key | null = null;
|
|
1381
|
+
let registeredCloseAccessor: (() => boolean | undefined) | null = null;
|
|
1297
1382
|
|
|
1298
1383
|
const unregisterSectionSelection = () => {
|
|
1299
1384
|
if (registeredSectionSelectionKey != null && registeredSectionSelection) {
|
|
@@ -1347,9 +1432,38 @@ export function MenuItem<T>(props: MenuItemProps<T>): JSX.Element {
|
|
|
1347
1432
|
|
|
1348
1433
|
onCleanup(unregisterSectionSelection);
|
|
1349
1434
|
|
|
1435
|
+
const unregisterItemClose = () => {
|
|
1436
|
+
if (registeredCloseKey != null && registeredCloseAccessor) {
|
|
1437
|
+
itemCloseRegistry?.unregisterItem(registeredCloseKey, registeredCloseAccessor);
|
|
1438
|
+
registeredCloseKey = null;
|
|
1439
|
+
registeredCloseAccessor = null;
|
|
1440
|
+
}
|
|
1441
|
+
};
|
|
1442
|
+
|
|
1443
|
+
createEffect(() => {
|
|
1444
|
+
if (!itemCloseRegistry) {
|
|
1445
|
+
unregisterItemClose();
|
|
1446
|
+
return;
|
|
1447
|
+
}
|
|
1448
|
+
|
|
1449
|
+
if (registeredCloseKey === local.id && registeredCloseAccessor === itemCloseOnSelect) {
|
|
1450
|
+
return;
|
|
1451
|
+
}
|
|
1452
|
+
|
|
1453
|
+
unregisterItemClose();
|
|
1454
|
+
registeredCloseKey = local.id;
|
|
1455
|
+
registeredCloseAccessor = itemCloseOnSelect;
|
|
1456
|
+
itemCloseRegistry.registerItem(local.id, itemCloseOnSelect);
|
|
1457
|
+
});
|
|
1458
|
+
|
|
1459
|
+
onCleanup(unregisterItemClose);
|
|
1460
|
+
|
|
1350
1461
|
const itemAria = createMenuItem<T>(
|
|
1351
1462
|
{
|
|
1352
1463
|
key: local.id,
|
|
1464
|
+
get id() {
|
|
1465
|
+
return contextProps().id as string | undefined;
|
|
1466
|
+
},
|
|
1353
1467
|
get isDisabled() {
|
|
1354
1468
|
return Boolean(
|
|
1355
1469
|
ariaProps.isDisabled ||
|
|
@@ -1360,15 +1474,20 @@ export function MenuItem<T>(props: MenuItemProps<T>): JSX.Element {
|
|
|
1360
1474
|
get "aria-label"() {
|
|
1361
1475
|
return ariaProps["aria-label"] ?? local.textValue;
|
|
1362
1476
|
},
|
|
1477
|
+
get "aria-controls"() {
|
|
1478
|
+
return contextProps()["aria-controls"] as string | undefined;
|
|
1479
|
+
},
|
|
1480
|
+
get "aria-haspopup"() {
|
|
1481
|
+
return contextProps()["aria-haspopup"] as string | boolean | undefined;
|
|
1482
|
+
},
|
|
1483
|
+
get "aria-expanded"() {
|
|
1484
|
+
return contextProps()["aria-expanded"] as boolean | "true" | "false" | undefined;
|
|
1485
|
+
},
|
|
1363
1486
|
get onAction() {
|
|
1364
1487
|
return combinedOnAction;
|
|
1365
1488
|
},
|
|
1366
1489
|
get closeOnSelect() {
|
|
1367
|
-
return (
|
|
1368
|
-
ariaProps.closeOnSelect ??
|
|
1369
|
-
sectionSelection?.shouldCloseOnSelect() ??
|
|
1370
|
-
itemContext?.closeOnSelect
|
|
1371
|
-
);
|
|
1490
|
+
return itemCloseOnSelect();
|
|
1372
1491
|
},
|
|
1373
1492
|
get href() {
|
|
1374
1493
|
return local.href;
|
|
@@ -1384,6 +1503,7 @@ export function MenuItem<T>(props: MenuItemProps<T>): JSX.Element {
|
|
|
1384
1503
|
},
|
|
1385
1504
|
},
|
|
1386
1505
|
state,
|
|
1506
|
+
() => ref(),
|
|
1387
1507
|
);
|
|
1388
1508
|
|
|
1389
1509
|
const { isHovered, hoverProps } = createHover({
|
|
@@ -1407,12 +1527,16 @@ export function MenuItem<T>(props: MenuItemProps<T>): JSX.Element {
|
|
|
1407
1527
|
isDisabled: itemAria.isDisabled(),
|
|
1408
1528
|
hasSubmenu: Boolean(contextProps()["aria-haspopup"]),
|
|
1409
1529
|
isOpen: contextProps()["aria-expanded"] === true,
|
|
1530
|
+
descriptionProps: itemAria.descriptionProps,
|
|
1531
|
+
keyboardShortcutProps: itemAria.keyboardShortcutProps,
|
|
1410
1532
|
};
|
|
1411
1533
|
});
|
|
1412
1534
|
|
|
1413
1535
|
const renderProps = useRenderProps(
|
|
1414
1536
|
{
|
|
1415
|
-
children
|
|
1537
|
+
get children() {
|
|
1538
|
+
return props.children;
|
|
1539
|
+
},
|
|
1416
1540
|
class: local.class,
|
|
1417
1541
|
style: local.style,
|
|
1418
1542
|
defaultClassName: "solidaria-Menu-item",
|
|
@@ -1424,11 +1548,13 @@ export function MenuItem<T>(props: MenuItemProps<T>): JSX.Element {
|
|
|
1424
1548
|
};
|
|
1425
1549
|
|
|
1426
1550
|
const cleanItemProps = () => {
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1551
|
+
// Keep `aria-describedby`: the headless emits it (via `createSlotId`) only
|
|
1552
|
+
// when a description/keyboard element is actually rendered, so it points at
|
|
1553
|
+
// the styled `Text slot="description"` + `Keyboard` ids threaded through
|
|
1554
|
+
// `renderValues` below — restoring upstream's two-context description
|
|
1555
|
+
// delegation. `createSlotId` clears it to `undefined` on description-less
|
|
1556
|
+
// items, so nothing dangles.
|
|
1557
|
+
const { ref: _ref1, ...rest } = itemAria.menuItemProps as Record<string, unknown>;
|
|
1432
1558
|
if (!hasPrimitiveLabel() && rest["aria-label"] == null) {
|
|
1433
1559
|
delete rest["aria-labelledby"];
|
|
1434
1560
|
}
|
|
@@ -1519,7 +1645,7 @@ export function MenuItem<T>(props: MenuItemProps<T>): JSX.Element {
|
|
|
1519
1645
|
) : (
|
|
1520
1646
|
renderProps.renderChildren()
|
|
1521
1647
|
);
|
|
1522
|
-
const setResolvedItemRef = (el:
|
|
1648
|
+
const setResolvedItemRef = (el: HTMLElement | null) => {
|
|
1523
1649
|
setRef(el);
|
|
1524
1650
|
itemContext?.setItemRef?.(el);
|
|
1525
1651
|
if (el) assignRef(local.ref, el);
|
|
@@ -1539,7 +1665,7 @@ export function MenuItem<T>(props: MenuItemProps<T>): JSX.Element {
|
|
|
1539
1665
|
style: renderProps.style(),
|
|
1540
1666
|
...dataAttrs(),
|
|
1541
1667
|
children: childContent(),
|
|
1542
|
-
}) as JSX.HTMLAttributes<
|
|
1668
|
+
}) as JSX.HTMLAttributes<HTMLElement>;
|
|
1543
1669
|
const linkMenuItemProps = () =>
|
|
1544
1670
|
({
|
|
1545
1671
|
...mergeProps(
|
|
@@ -1555,7 +1681,7 @@ export function MenuItem<T>(props: MenuItemProps<T>): JSX.Element {
|
|
|
1555
1681
|
style: renderProps.style(),
|
|
1556
1682
|
...dataAttrs(),
|
|
1557
1683
|
children: childContent(),
|
|
1558
|
-
}) as JSX.HTMLAttributes<
|
|
1684
|
+
}) as JSX.HTMLAttributes<HTMLElement>;
|
|
1559
1685
|
|
|
1560
1686
|
if (local.render && !isLink()) {
|
|
1561
1687
|
return local.render(menuItemProps(), renderValues());
|
|
@@ -1565,7 +1691,7 @@ export function MenuItem<T>(props: MenuItemProps<T>): JSX.Element {
|
|
|
1565
1691
|
<Show
|
|
1566
1692
|
when={isLink()}
|
|
1567
1693
|
fallback={
|
|
1568
|
-
<
|
|
1694
|
+
<div
|
|
1569
1695
|
ref={(el) => {
|
|
1570
1696
|
setRef(el);
|
|
1571
1697
|
itemContext?.setItemRef?.(el);
|
|
@@ -1584,38 +1710,36 @@ export function MenuItem<T>(props: MenuItemProps<T>): JSX.Element {
|
|
|
1584
1710
|
{...dataAttrs()}
|
|
1585
1711
|
>
|
|
1586
1712
|
{childContent()}
|
|
1587
|
-
</
|
|
1713
|
+
</div>
|
|
1588
1714
|
}
|
|
1589
1715
|
>
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
)}
|
|
1618
|
-
</li>
|
|
1716
|
+
{local.render ? (
|
|
1717
|
+
local.render(linkMenuItemProps(), renderValues())
|
|
1718
|
+
) : (
|
|
1719
|
+
// Upstream renders the link menuitem as a bare <a role="menuitem"> (no
|
|
1720
|
+
// presentation wrapper); the <div> root makes the wrapper unnecessary.
|
|
1721
|
+
<a
|
|
1722
|
+
ref={(el) => {
|
|
1723
|
+
setRef(el);
|
|
1724
|
+
itemContext?.setItemRef?.(el);
|
|
1725
|
+
assignRef(local.ref, el);
|
|
1726
|
+
}}
|
|
1727
|
+
{...mergeProps(
|
|
1728
|
+
cleanItemPropsForLink(),
|
|
1729
|
+
contextProps() as Record<string, unknown>,
|
|
1730
|
+
domProps(),
|
|
1731
|
+
cleanHoverProps(),
|
|
1732
|
+
linkDomProps(),
|
|
1733
|
+
(draggableItem()?.dragProps as Record<string, unknown> | undefined) ?? {},
|
|
1734
|
+
(droppableItem()?.dropProps as Record<string, unknown> | undefined) ?? {},
|
|
1735
|
+
)}
|
|
1736
|
+
class={renderProps.class()}
|
|
1737
|
+
style={renderProps.style()}
|
|
1738
|
+
{...dataAttrs()}
|
|
1739
|
+
>
|
|
1740
|
+
{childContent()}
|
|
1741
|
+
</a>
|
|
1742
|
+
)}
|
|
1619
1743
|
</Show>
|
|
1620
1744
|
);
|
|
1621
1745
|
}
|