@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/dist/Menu.jsx
ADDED
|
@@ -0,0 +1,1042 @@
|
|
|
1
|
+
import { filterDOMProps, useRenderProps } from "./utils.jsx";
|
|
2
|
+
import { r as PopoverTriggerContext } from "./contexts.jsx";
|
|
3
|
+
import { SharedElementTransition } from "./SharedElementTransition.jsx";
|
|
4
|
+
import { CollectionRendererContext, Group, Header, Section, flattenCollectionEntries, isCollectionSection, useCollectionRenderer } from "./Collection.jsx";
|
|
5
|
+
import { r as useVirtualizerContext } from "./Virtualizer2.jsx";
|
|
6
|
+
import { getNormalizedDropTargetKey, mergePersistedKeysIntoVirtualRange, useDndPersistedKeys, useRenderDropIndicator } from "./DragAndDrop.jsx";
|
|
7
|
+
import { For, Show, createContext, createEffect, createMemo, createSignal, createUniqueId, onCleanup, splitProps, useContext } from "solid-js";
|
|
8
|
+
import { FocusScope, createButton, createFocusRing, createHover, createInteractOutside, createMenu, createMenuItem, createMenuTrigger, createScrollIntoViewOnFocus, mergeProps as mergeProps$1 } from "@proyecto-viviana/solidaria";
|
|
9
|
+
import { createMenuState, createMenuTriggerState, createSelectionState } from "@proyecto-viviana/solid-stately";
|
|
10
|
+
//#region src/Menu.tsx
|
|
11
|
+
/**
|
|
12
|
+
* Menu component for solidaria-components
|
|
13
|
+
*
|
|
14
|
+
* A pre-wired headless menu that combines state + aria hooks.
|
|
15
|
+
* Port of react-aria-components/src/Menu.tsx
|
|
16
|
+
*/
|
|
17
|
+
const MenuContext = createContext(null);
|
|
18
|
+
const MenuStateContext = createContext(null);
|
|
19
|
+
const MenuTriggerContext = createContext(null);
|
|
20
|
+
const RootMenuTriggerStateContext = createContext(null);
|
|
21
|
+
const MenuItemContext = createContext(null);
|
|
22
|
+
const StaticMenuCollectionContext = createContext(null);
|
|
23
|
+
const MenuSectionSelectionContext = createContext(null);
|
|
24
|
+
const MenuSectionSelectionRegistryContext = createContext(null);
|
|
25
|
+
const MenuItemCloseRegistryContext = createContext(null);
|
|
26
|
+
function assignRef(ref, el) {
|
|
27
|
+
if (!ref) return;
|
|
28
|
+
if (typeof ref === "function") ref(el);
|
|
29
|
+
else ref.current = el;
|
|
30
|
+
}
|
|
31
|
+
function resolveBoolean(value) {
|
|
32
|
+
return typeof value === "function" ? Boolean(value()) : Boolean(value);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* A menu trigger wraps a button and menu, handling the open/close state.
|
|
36
|
+
*/
|
|
37
|
+
function MenuTrigger(props) {
|
|
38
|
+
const [local, stateProps] = splitProps(props, ["slot"]);
|
|
39
|
+
const state = createMenuTriggerState({
|
|
40
|
+
get isOpen() {
|
|
41
|
+
return stateProps.isOpen;
|
|
42
|
+
},
|
|
43
|
+
get defaultOpen() {
|
|
44
|
+
return stateProps.defaultOpen;
|
|
45
|
+
},
|
|
46
|
+
get onOpenChange() {
|
|
47
|
+
return stateProps.onOpenChange;
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
const [isMousePressed, setMousePressed] = createSignal(false);
|
|
51
|
+
const onPressStart = (e) => {
|
|
52
|
+
if (e.pointerType !== "mouse" || typeof document === "undefined") return;
|
|
53
|
+
setMousePressed(true);
|
|
54
|
+
document.addEventListener("pointerup", () => {
|
|
55
|
+
setMousePressed(false);
|
|
56
|
+
}, {
|
|
57
|
+
once: true,
|
|
58
|
+
capture: true
|
|
59
|
+
});
|
|
60
|
+
};
|
|
61
|
+
const menuTrigger = createMenuTrigger({ get isDisabled() {
|
|
62
|
+
return stateProps.isDisabled;
|
|
63
|
+
} }, state);
|
|
64
|
+
return <RootMenuTriggerStateContext.Provider value={state}>
|
|
65
|
+
<MenuTriggerContext.Provider value={{
|
|
66
|
+
state,
|
|
67
|
+
get triggerProps() {
|
|
68
|
+
return menuTrigger.menuTriggerProps;
|
|
69
|
+
},
|
|
70
|
+
get menuProps() {
|
|
71
|
+
return menuTrigger.menuProps;
|
|
72
|
+
},
|
|
73
|
+
isPressed: isMousePressed,
|
|
74
|
+
onPressStart
|
|
75
|
+
}}>
|
|
76
|
+
{props.children}
|
|
77
|
+
</MenuTriggerContext.Provider>
|
|
78
|
+
</RootMenuTriggerStateContext.Provider>;
|
|
79
|
+
}
|
|
80
|
+
function SubmenuTrigger(props) {
|
|
81
|
+
const children = () => Array.isArray(props.children) ? props.children : [props.children];
|
|
82
|
+
const trigger = () => children()[0];
|
|
83
|
+
const content = () => children()[1];
|
|
84
|
+
const parentMenuItemContext = useContext(MenuItemContext);
|
|
85
|
+
const state = createMenuTriggerState({
|
|
86
|
+
get isOpen() {
|
|
87
|
+
return props.isOpen;
|
|
88
|
+
},
|
|
89
|
+
get defaultOpen() {
|
|
90
|
+
return props.defaultOpen;
|
|
91
|
+
},
|
|
92
|
+
get onOpenChange() {
|
|
93
|
+
return props.onOpenChange;
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
let triggerRef = null;
|
|
97
|
+
const triggerId = createUniqueId();
|
|
98
|
+
const menuId = createUniqueId();
|
|
99
|
+
let hoverTimeout;
|
|
100
|
+
let hasPointerHover = false;
|
|
101
|
+
const delay = () => props.delay ?? 200;
|
|
102
|
+
const clearHoverTimeout = () => {
|
|
103
|
+
if (hoverTimeout != null) {
|
|
104
|
+
window.clearTimeout(hoverTimeout);
|
|
105
|
+
hoverTimeout = void 0;
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
const openSubmenu = () => {
|
|
109
|
+
clearHoverTimeout();
|
|
110
|
+
state.open();
|
|
111
|
+
};
|
|
112
|
+
const queueOpenSubmenu = () => {
|
|
113
|
+
clearHoverTimeout();
|
|
114
|
+
const open = () => state.open();
|
|
115
|
+
if (typeof queueMicrotask === "function") queueMicrotask(open);
|
|
116
|
+
else Promise.resolve().then(open);
|
|
117
|
+
};
|
|
118
|
+
const scheduleOpen = () => {
|
|
119
|
+
clearHoverTimeout();
|
|
120
|
+
hoverTimeout = window.setTimeout(() => {
|
|
121
|
+
hoverTimeout = void 0;
|
|
122
|
+
state.open();
|
|
123
|
+
}, delay());
|
|
124
|
+
};
|
|
125
|
+
const schedulePointerOpen = (event) => {
|
|
126
|
+
hasPointerHover = true;
|
|
127
|
+
if (event.isTrusted === false) {
|
|
128
|
+
queueOpenSubmenu();
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
scheduleOpen();
|
|
132
|
+
};
|
|
133
|
+
const openFromMouseHover = () => {
|
|
134
|
+
if (state.isOpen()) return;
|
|
135
|
+
if (hasPointerHover) scheduleOpen();
|
|
136
|
+
else queueOpenSubmenu();
|
|
137
|
+
};
|
|
138
|
+
onCleanup(clearHoverTimeout);
|
|
139
|
+
const menuTriggerContext = createMemo(() => ({
|
|
140
|
+
state,
|
|
141
|
+
triggerProps: {},
|
|
142
|
+
menuProps: {
|
|
143
|
+
id: menuId,
|
|
144
|
+
"aria-labelledby": triggerId
|
|
145
|
+
}
|
|
146
|
+
}));
|
|
147
|
+
const popoverTriggerContext = createMemo(() => ({
|
|
148
|
+
state: {
|
|
149
|
+
isOpen: () => state.isOpen(),
|
|
150
|
+
open: () => state.open(),
|
|
151
|
+
close: () => state.close(),
|
|
152
|
+
toggle: () => state.toggle()
|
|
153
|
+
},
|
|
154
|
+
triggerRef: () => triggerRef,
|
|
155
|
+
setTriggerRef: (el) => {
|
|
156
|
+
triggerRef = el;
|
|
157
|
+
},
|
|
158
|
+
triggerId,
|
|
159
|
+
trigger: "SubmenuTrigger"
|
|
160
|
+
}));
|
|
161
|
+
const itemContext = createMemo(() => ({
|
|
162
|
+
closeOnSelect: false,
|
|
163
|
+
onAction: () => openSubmenu(),
|
|
164
|
+
setItemRef: (el) => {
|
|
165
|
+
triggerRef = el;
|
|
166
|
+
},
|
|
167
|
+
props: () => ({
|
|
168
|
+
id: triggerId,
|
|
169
|
+
"aria-haspopup": "menu",
|
|
170
|
+
get "aria-expanded"() {
|
|
171
|
+
return state.isOpen() || void 0;
|
|
172
|
+
},
|
|
173
|
+
get "aria-controls"() {
|
|
174
|
+
return state.isOpen() ? menuId : void 0;
|
|
175
|
+
},
|
|
176
|
+
onPointerEnter: (event) => {
|
|
177
|
+
if (event.pointerType === "touch") return;
|
|
178
|
+
schedulePointerOpen(event);
|
|
179
|
+
},
|
|
180
|
+
onPointerOver: (event) => {
|
|
181
|
+
if (event.pointerType === "touch") return;
|
|
182
|
+
schedulePointerOpen(event);
|
|
183
|
+
},
|
|
184
|
+
onMouseEnter: openFromMouseHover,
|
|
185
|
+
onMouseOver: openFromMouseHover,
|
|
186
|
+
onKeyDown: (event) => {
|
|
187
|
+
if (event.key === "ArrowRight" || event.key === "Enter" || event.key === " ") {
|
|
188
|
+
event.preventDefault();
|
|
189
|
+
openSubmenu();
|
|
190
|
+
} else if (event.key === "ArrowLeft" && state.isOpen()) {
|
|
191
|
+
event.preventDefault();
|
|
192
|
+
state.close();
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
})
|
|
196
|
+
}));
|
|
197
|
+
return <PopoverTriggerContext.Provider value={popoverTriggerContext()}>
|
|
198
|
+
<MenuTriggerContext.Provider value={menuTriggerContext()}>
|
|
199
|
+
<MenuItemContext.Provider value={{
|
|
200
|
+
...parentMenuItemContext,
|
|
201
|
+
...itemContext()
|
|
202
|
+
}}>
|
|
203
|
+
{trigger()}
|
|
204
|
+
</MenuItemContext.Provider>
|
|
205
|
+
{content()}
|
|
206
|
+
</MenuTriggerContext.Provider>
|
|
207
|
+
</PopoverTriggerContext.Provider>;
|
|
208
|
+
}
|
|
209
|
+
function MenuButton(props) {
|
|
210
|
+
const [local, domProps] = splitProps(props, [
|
|
211
|
+
"class",
|
|
212
|
+
"style",
|
|
213
|
+
"slot",
|
|
214
|
+
"isDisabled",
|
|
215
|
+
"children"
|
|
216
|
+
]);
|
|
217
|
+
const context = useContext(MenuTriggerContext);
|
|
218
|
+
if (!context) throw new Error("MenuButton must be used within a MenuTrigger");
|
|
219
|
+
const { state } = context;
|
|
220
|
+
const buttonAria = createButton({
|
|
221
|
+
get isDisabled() {
|
|
222
|
+
return local.isDisabled;
|
|
223
|
+
},
|
|
224
|
+
onPressStart(e) {
|
|
225
|
+
context.onPressStart?.(e);
|
|
226
|
+
},
|
|
227
|
+
onPress() {
|
|
228
|
+
state.toggle();
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
const { isFocused, isFocusVisible, focusProps } = createFocusRing();
|
|
232
|
+
const { isHovered, hoverProps } = createHover({ get isDisabled() {
|
|
233
|
+
return local.isDisabled;
|
|
234
|
+
} });
|
|
235
|
+
const renderValues = createMemo(() => ({
|
|
236
|
+
isOpen: state.isOpen(),
|
|
237
|
+
isFocused: isFocused(),
|
|
238
|
+
isFocusVisible: isFocusVisible(),
|
|
239
|
+
isPressed: context.isPressed?.() || buttonAria.isPressed(),
|
|
240
|
+
isHovered: isHovered(),
|
|
241
|
+
isDisabled: !!local.isDisabled
|
|
242
|
+
}));
|
|
243
|
+
const renderProps = useRenderProps({
|
|
244
|
+
get children() {
|
|
245
|
+
return props.children;
|
|
246
|
+
},
|
|
247
|
+
class: local.class,
|
|
248
|
+
style: local.style,
|
|
249
|
+
defaultClassName: "solidaria-MenuButton"
|
|
250
|
+
}, renderValues);
|
|
251
|
+
const resolvedTriggerProps = () => context.triggerProps;
|
|
252
|
+
const cleanTriggerProps = () => {
|
|
253
|
+
const { ref: _ref1, "aria-haspopup": _ariaHasPopup, "aria-expanded": _ariaExpanded, "aria-controls": _ariaControls, "aria-disabled": _ariaDisabled, ...rest } = resolvedTriggerProps();
|
|
254
|
+
return rest;
|
|
255
|
+
};
|
|
256
|
+
const cleanButtonProps = () => {
|
|
257
|
+
const { ref: _ref2, ...rest } = buttonAria.buttonProps;
|
|
258
|
+
return rest;
|
|
259
|
+
};
|
|
260
|
+
const cleanFocusProps = () => {
|
|
261
|
+
const { ref: _ref3, ...rest } = focusProps;
|
|
262
|
+
return rest;
|
|
263
|
+
};
|
|
264
|
+
const cleanHoverProps = () => {
|
|
265
|
+
const { ref: _ref4, ...rest } = hoverProps;
|
|
266
|
+
return rest;
|
|
267
|
+
};
|
|
268
|
+
return <button {...domProps} {...cleanTriggerProps()} {...cleanButtonProps()} {...cleanFocusProps()} {...cleanHoverProps()} type="button" class={renderProps.class()} style={renderProps.style()} aria-haspopup={resolvedTriggerProps()["aria-haspopup"]} aria-expanded={resolvedTriggerProps()["aria-expanded"]} aria-controls={resolvedTriggerProps()["aria-controls"]} aria-disabled={resolvedTriggerProps()["aria-disabled"]} data-open={state.isOpen() || void 0} data-focused={isFocused() || void 0} data-focus-visible={isFocusVisible() || void 0} data-pressed={context.isPressed?.() || buttonAria.isPressed() || void 0} data-hovered={isHovered() || void 0} data-disabled={local.isDisabled || void 0}>
|
|
269
|
+
{renderProps.renderChildren()}
|
|
270
|
+
</button>;
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* A menu displays a list of actions or options for the user to choose from.
|
|
274
|
+
*/
|
|
275
|
+
function Menu(props) {
|
|
276
|
+
const [local, stateProps, ariaProps] = splitProps(props, [
|
|
277
|
+
"children",
|
|
278
|
+
"class",
|
|
279
|
+
"style",
|
|
280
|
+
"render",
|
|
281
|
+
"slot",
|
|
282
|
+
"renderEmptyState",
|
|
283
|
+
"ref",
|
|
284
|
+
"staticChildren"
|
|
285
|
+
], [
|
|
286
|
+
"items",
|
|
287
|
+
"getKey",
|
|
288
|
+
"getTextValue",
|
|
289
|
+
"getDisabled",
|
|
290
|
+
"disabledKeys",
|
|
291
|
+
"disabledBehavior",
|
|
292
|
+
"selectionMode",
|
|
293
|
+
"selectionBehavior",
|
|
294
|
+
"disallowEmptySelection",
|
|
295
|
+
"selectedKeys",
|
|
296
|
+
"defaultSelectedKeys",
|
|
297
|
+
"onSelectionChange",
|
|
298
|
+
"allowDuplicateSelectionEvents",
|
|
299
|
+
"onAction",
|
|
300
|
+
"onClose",
|
|
301
|
+
"shouldCloseOnSelect",
|
|
302
|
+
"dragAndDropHooks"
|
|
303
|
+
]);
|
|
304
|
+
const triggerContext = useContext(MenuTriggerContext);
|
|
305
|
+
const [menuRef, setMenuRef] = createSignal(null);
|
|
306
|
+
const [staticItems, setStaticItems] = createSignal([]);
|
|
307
|
+
const staticItemMap = /* @__PURE__ */ new Map();
|
|
308
|
+
const sectionSelectionMap = /* @__PURE__ */ new Map();
|
|
309
|
+
const itemCloseMap = /* @__PURE__ */ new Map();
|
|
310
|
+
const usesStaticChildren = () => local.staticChildren != null || stateProps.items == null;
|
|
311
|
+
const syncStaticItems = () => {
|
|
312
|
+
setStaticItems(Array.from(staticItemMap.values()));
|
|
313
|
+
};
|
|
314
|
+
const staticCollectionContext = {
|
|
315
|
+
registerItem(item) {
|
|
316
|
+
const previous = staticItemMap.get(item.id);
|
|
317
|
+
if (previous && previous.textValue === item.textValue && previous.isDisabled === item.isDisabled) return;
|
|
318
|
+
staticItemMap.set(item.id, item);
|
|
319
|
+
syncStaticItems();
|
|
320
|
+
},
|
|
321
|
+
unregisterItem(id) {
|
|
322
|
+
if (staticItemMap.delete(id)) syncStaticItems();
|
|
323
|
+
}
|
|
324
|
+
};
|
|
325
|
+
const sectionSelectionRegistry = {
|
|
326
|
+
registerItem(key, selection) {
|
|
327
|
+
sectionSelectionMap.set(key, selection);
|
|
328
|
+
},
|
|
329
|
+
unregisterItem(key, selection) {
|
|
330
|
+
if (sectionSelectionMap.get(key) === selection) sectionSelectionMap.delete(key);
|
|
331
|
+
},
|
|
332
|
+
selectItem(key, event) {
|
|
333
|
+
const selection = sectionSelectionMap.get(key);
|
|
334
|
+
if (!selection || selection.selectionMode() === "none") return false;
|
|
335
|
+
selection.select(key, event);
|
|
336
|
+
return true;
|
|
337
|
+
}
|
|
338
|
+
};
|
|
339
|
+
const itemCloseRegistry = {
|
|
340
|
+
registerItem(key, shouldCloseOnSelect) {
|
|
341
|
+
itemCloseMap.set(key, shouldCloseOnSelect);
|
|
342
|
+
},
|
|
343
|
+
unregisterItem(key, shouldCloseOnSelect) {
|
|
344
|
+
if (itemCloseMap.get(key) === shouldCloseOnSelect) itemCloseMap.delete(key);
|
|
345
|
+
},
|
|
346
|
+
shouldCloseOnSelect(key) {
|
|
347
|
+
return key == null ? void 0 : itemCloseMap.get(key)?.();
|
|
348
|
+
}
|
|
349
|
+
};
|
|
350
|
+
const handleAction = (key, value) => {
|
|
351
|
+
sectionSelectionRegistry.selectItem(key);
|
|
352
|
+
stateProps.onAction?.(key, usesStaticChildren() ? void 0 : value);
|
|
353
|
+
};
|
|
354
|
+
const flatItems = createMemo(() => {
|
|
355
|
+
return flattenCollectionEntries(stateProps.items ?? []);
|
|
356
|
+
});
|
|
357
|
+
const hasSections = createMemo(() => (stateProps.items ?? []).some((item) => isCollectionSection(item)));
|
|
358
|
+
const state = createMenuState({
|
|
359
|
+
get items() {
|
|
360
|
+
return usesStaticChildren() ? staticItems() : flatItems();
|
|
361
|
+
},
|
|
362
|
+
get getKey() {
|
|
363
|
+
return usesStaticChildren() ? (item) => item.id : stateProps.getKey;
|
|
364
|
+
},
|
|
365
|
+
get getTextValue() {
|
|
366
|
+
return usesStaticChildren() ? (item) => item.textValue ?? String(item.id) : stateProps.getTextValue;
|
|
367
|
+
},
|
|
368
|
+
get getDisabled() {
|
|
369
|
+
return usesStaticChildren() ? (item) => Boolean(item.isDisabled) : stateProps.getDisabled;
|
|
370
|
+
},
|
|
371
|
+
get disabledKeys() {
|
|
372
|
+
return stateProps.disabledKeys;
|
|
373
|
+
},
|
|
374
|
+
get disabledBehavior() {
|
|
375
|
+
return stateProps.disabledBehavior;
|
|
376
|
+
},
|
|
377
|
+
get selectionMode() {
|
|
378
|
+
return stateProps.selectionMode;
|
|
379
|
+
},
|
|
380
|
+
get selectionBehavior() {
|
|
381
|
+
return stateProps.selectionBehavior;
|
|
382
|
+
},
|
|
383
|
+
get disallowEmptySelection() {
|
|
384
|
+
return stateProps.disallowEmptySelection;
|
|
385
|
+
},
|
|
386
|
+
get selectedKeys() {
|
|
387
|
+
return stateProps.selectedKeys;
|
|
388
|
+
},
|
|
389
|
+
get defaultSelectedKeys() {
|
|
390
|
+
return stateProps.defaultSelectedKeys;
|
|
391
|
+
},
|
|
392
|
+
get onSelectionChange() {
|
|
393
|
+
return stateProps.onSelectionChange;
|
|
394
|
+
},
|
|
395
|
+
get allowDuplicateSelectionEvents() {
|
|
396
|
+
return stateProps.allowDuplicateSelectionEvents;
|
|
397
|
+
},
|
|
398
|
+
get onAction() {
|
|
399
|
+
return handleAction;
|
|
400
|
+
},
|
|
401
|
+
get onClose() {
|
|
402
|
+
return stateProps.onClose ?? (() => triggerContext?.state.close());
|
|
403
|
+
}
|
|
404
|
+
});
|
|
405
|
+
const resolveDisabled = () => {
|
|
406
|
+
const disabled = ariaProps.isDisabled;
|
|
407
|
+
if (typeof disabled === "function") return disabled();
|
|
408
|
+
return !!disabled;
|
|
409
|
+
};
|
|
410
|
+
const { menuProps, labelProps } = createMenu({
|
|
411
|
+
get isDisabled() {
|
|
412
|
+
return resolveDisabled();
|
|
413
|
+
},
|
|
414
|
+
get label() {
|
|
415
|
+
return ariaProps.label;
|
|
416
|
+
},
|
|
417
|
+
get onAction() {
|
|
418
|
+
return handleAction;
|
|
419
|
+
},
|
|
420
|
+
get onClose() {
|
|
421
|
+
return stateProps.onClose ?? (() => triggerContext?.state.close());
|
|
422
|
+
},
|
|
423
|
+
get shouldCloseOnSelect() {
|
|
424
|
+
return itemCloseRegistry.shouldCloseOnSelect(state.focusedKey()) ?? stateProps.shouldCloseOnSelect;
|
|
425
|
+
},
|
|
426
|
+
get "aria-label"() {
|
|
427
|
+
return ariaProps["aria-label"];
|
|
428
|
+
},
|
|
429
|
+
get "aria-labelledby"() {
|
|
430
|
+
return ariaProps["aria-labelledby"];
|
|
431
|
+
},
|
|
432
|
+
get "aria-describedby"() {
|
|
433
|
+
return ariaProps["aria-describedby"];
|
|
434
|
+
}
|
|
435
|
+
}, state);
|
|
436
|
+
createScrollIntoViewOnFocus({
|
|
437
|
+
focusedKey: () => state.focusedKey(),
|
|
438
|
+
isActive: () => state.isFocused(),
|
|
439
|
+
ref: () => menuRef()
|
|
440
|
+
});
|
|
441
|
+
const { isFocused, focusProps } = createFocusRing();
|
|
442
|
+
createInteractOutside({
|
|
443
|
+
ref: () => menuRef(),
|
|
444
|
+
onInteractOutside: () => {
|
|
445
|
+
if (triggerContext?.state.isOpen()) triggerContext.state.close();
|
|
446
|
+
},
|
|
447
|
+
get isDisabled() {
|
|
448
|
+
return !triggerContext?.state.isOpen();
|
|
449
|
+
}
|
|
450
|
+
});
|
|
451
|
+
const renderValues = createMemo(() => ({
|
|
452
|
+
isFocused: state.isFocused() || isFocused(),
|
|
453
|
+
isOpen: triggerContext?.state.isOpen() ?? true,
|
|
454
|
+
isEmpty: state.collection().size === 0
|
|
455
|
+
}));
|
|
456
|
+
const renderProps = useRenderProps({
|
|
457
|
+
class: local.class,
|
|
458
|
+
style: local.style,
|
|
459
|
+
defaultClassName: "solidaria-Menu"
|
|
460
|
+
}, renderValues);
|
|
461
|
+
const cleanMenuProps = () => {
|
|
462
|
+
const { ref: _ref1, ...rest } = menuProps;
|
|
463
|
+
return rest;
|
|
464
|
+
};
|
|
465
|
+
const cleanTriggerMenuProps = () => {
|
|
466
|
+
if (!triggerContext) return {};
|
|
467
|
+
const { ref: _ref2, ...rest } = triggerContext.menuProps;
|
|
468
|
+
return rest;
|
|
469
|
+
};
|
|
470
|
+
const cleanFocusProps = () => {
|
|
471
|
+
const { ref: _ref3, ...rest } = focusProps;
|
|
472
|
+
return rest;
|
|
473
|
+
};
|
|
474
|
+
const domProps = createMemo(() => filterDOMProps(ariaProps, { global: true }));
|
|
475
|
+
const cleanLabelProps = () => {
|
|
476
|
+
const { ref: _ref4, ...rest } = labelProps;
|
|
477
|
+
return rest;
|
|
478
|
+
};
|
|
479
|
+
const setResolvedMenuRef = (el) => {
|
|
480
|
+
setMenuRef(el);
|
|
481
|
+
assignRef(local.ref, el);
|
|
482
|
+
};
|
|
483
|
+
const shouldRender = () => triggerContext ? triggerContext.state.isOpen() : true;
|
|
484
|
+
const parentCollectionRenderer = useCollectionRenderer();
|
|
485
|
+
const virtualizer = useVirtualizerContext();
|
|
486
|
+
const getItemNodes = createMemo(() => Array.from(state.collection()).filter((node) => node.type === "item"));
|
|
487
|
+
const getDropTargetByIndex = (index, position) => {
|
|
488
|
+
const node = getItemNodes()[index];
|
|
489
|
+
if (!node) return null;
|
|
490
|
+
return {
|
|
491
|
+
type: "item",
|
|
492
|
+
key: node.key,
|
|
493
|
+
dropPosition: position
|
|
494
|
+
};
|
|
495
|
+
};
|
|
496
|
+
const hasDroppableDnd = createMemo(() => {
|
|
497
|
+
const hooks = stateProps.dragAndDropHooks;
|
|
498
|
+
return Boolean(hooks?.useDroppableCollectionState && hooks.useDroppableCollection && (hooks.dropTargetDelegate || parentCollectionRenderer?.dropTargetDelegate || hooks.ListDropTargetDelegate));
|
|
499
|
+
});
|
|
500
|
+
const hasDraggableDnd = createMemo(() => {
|
|
501
|
+
const hooks = stateProps.dragAndDropHooks;
|
|
502
|
+
return Boolean(hooks?.useDraggableCollectionState && hooks.useDraggableCollection);
|
|
503
|
+
});
|
|
504
|
+
const dragState = createMemo(() => {
|
|
505
|
+
if (!hasDraggableDnd()) return void 0;
|
|
506
|
+
return stateProps.dragAndDropHooks?.useDraggableCollectionState?.({ items: flatItems() });
|
|
507
|
+
});
|
|
508
|
+
const dropState = createMemo(() => {
|
|
509
|
+
if (!hasDroppableDnd()) return void 0;
|
|
510
|
+
return stateProps.dragAndDropHooks?.useDroppableCollectionState?.({});
|
|
511
|
+
});
|
|
512
|
+
const persistedKeys = useDndPersistedKeys({ focusedKey: state.focusedKey }, stateProps.dragAndDropHooks, dropState(), state.collection());
|
|
513
|
+
const virtualRange = createMemo(() => {
|
|
514
|
+
if (!virtualizer || !parentCollectionRenderer?.isVirtualized || hasSections()) return null;
|
|
515
|
+
const dynamicItems = stateProps.items ?? [];
|
|
516
|
+
const baseRange = virtualizer.getVisibleRange(dynamicItems.length);
|
|
517
|
+
const itemNodes = getItemNodes();
|
|
518
|
+
const persistedIndexes = Array.from(persistedKeys()).map((key) => itemNodes.findIndex((node) => node.key === key)).filter((index) => index >= 0);
|
|
519
|
+
const dropTarget = dropState()?.target;
|
|
520
|
+
const normalizedDropKey = getNormalizedDropTargetKey(dropTarget, state.collection());
|
|
521
|
+
const focusedKey = state.focusedKey();
|
|
522
|
+
const focusedIndex = focusedKey != null ? itemNodes.findIndex((node) => node.key === focusedKey) : -1;
|
|
523
|
+
const forceIncludeIndexes = [
|
|
524
|
+
dropTarget?.type === "item" ? itemNodes.findIndex((node) => node.key === dropTarget.key) : -1,
|
|
525
|
+
normalizedDropKey != null ? itemNodes.findIndex((node) => node.key === normalizedDropKey) : -1,
|
|
526
|
+
dropTarget?.type === "item" ? -1 : focusedIndex
|
|
527
|
+
].filter((index) => index >= 0);
|
|
528
|
+
return mergePersistedKeysIntoVirtualRange(baseRange, persistedIndexes, dynamicItems.length, virtualizer, 80, {
|
|
529
|
+
forceIncludeIndexes,
|
|
530
|
+
forceIncludeMaxSpan: 320
|
|
531
|
+
});
|
|
532
|
+
});
|
|
533
|
+
const visibleItems = createMemo(() => {
|
|
534
|
+
const range = virtualRange();
|
|
535
|
+
const items = stateProps.items ?? [];
|
|
536
|
+
if (!range) return items;
|
|
537
|
+
return items.slice(range.start, range.end);
|
|
538
|
+
});
|
|
539
|
+
createEffect(() => {
|
|
540
|
+
if (!hasDraggableDnd()) return;
|
|
541
|
+
const hooks = stateProps.dragAndDropHooks;
|
|
542
|
+
const activeDragState = dragState();
|
|
543
|
+
if (!hooks?.useDraggableCollection || !activeDragState) return;
|
|
544
|
+
hooks.useDraggableCollection({}, activeDragState, () => menuRef());
|
|
545
|
+
});
|
|
546
|
+
const droppableCollection = createMemo(() => {
|
|
547
|
+
if (!hasDroppableDnd()) return void 0;
|
|
548
|
+
const hooks = stateProps.dragAndDropHooks;
|
|
549
|
+
const activeDropState = dropState();
|
|
550
|
+
if (!hooks?.useDroppableCollection || !activeDropState) return void 0;
|
|
551
|
+
const resolveDirection = () => {
|
|
552
|
+
const menuEl = menuRef();
|
|
553
|
+
if (menuEl && typeof window !== "undefined" && typeof window.getComputedStyle === "function") {
|
|
554
|
+
if (window.getComputedStyle(menuEl).direction === "rtl") return "rtl";
|
|
555
|
+
}
|
|
556
|
+
return typeof document !== "undefined" && document.dir === "rtl" ? "rtl" : "ltr";
|
|
557
|
+
};
|
|
558
|
+
const dropTargetDelegate = hooks.dropTargetDelegate ?? parentCollectionRenderer?.dropTargetDelegate ?? (hooks.ListDropTargetDelegate ? new hooks.ListDropTargetDelegate(() => state.collection(), () => menuRef(), {
|
|
559
|
+
layout: "stack",
|
|
560
|
+
orientation: "vertical",
|
|
561
|
+
direction: resolveDirection()
|
|
562
|
+
}) : void 0);
|
|
563
|
+
if (!dropTargetDelegate) return void 0;
|
|
564
|
+
return hooks.useDroppableCollection({
|
|
565
|
+
dropTargetDelegate,
|
|
566
|
+
keyboardDelegate: {
|
|
567
|
+
getFirstKey: () => state.collection().getFirstKey(),
|
|
568
|
+
getLastKey: () => state.collection().getLastKey(),
|
|
569
|
+
getKeyBelow: (key) => state.collection().getKeyAfter(key),
|
|
570
|
+
getKeyAbove: (key) => state.collection().getKeyBefore(key),
|
|
571
|
+
getKeyPageBelow: (key) => state.collection().getKeyAfter(key),
|
|
572
|
+
getKeyPageAbove: (key) => state.collection().getKeyBefore(key)
|
|
573
|
+
}
|
|
574
|
+
}, activeDropState, () => menuRef());
|
|
575
|
+
});
|
|
576
|
+
const isRootDropTarget = createMemo(() => {
|
|
577
|
+
return Boolean(dropState()?.target?.type === "root");
|
|
578
|
+
});
|
|
579
|
+
const dndRenderDropIndicator = createMemo(() => useRenderDropIndicator(stateProps.dragAndDropHooks, dropState()));
|
|
580
|
+
const dndDropIndicator = (index, position) => {
|
|
581
|
+
const target = getDropTargetByIndex(index, position);
|
|
582
|
+
if (!target || target.type !== "item") return void 0;
|
|
583
|
+
return dndRenderDropIndicator()?.(target);
|
|
584
|
+
};
|
|
585
|
+
const sectionedRenderEntries = createMemo(() => {
|
|
586
|
+
let globalIndex = 0;
|
|
587
|
+
return (stateProps.items ?? []).map((entry) => {
|
|
588
|
+
if (isCollectionSection(entry)) return {
|
|
589
|
+
type: "section",
|
|
590
|
+
section: entry,
|
|
591
|
+
items: entry.items.map((item) => ({
|
|
592
|
+
item,
|
|
593
|
+
index: globalIndex++
|
|
594
|
+
}))
|
|
595
|
+
};
|
|
596
|
+
return {
|
|
597
|
+
type: "item",
|
|
598
|
+
item: {
|
|
599
|
+
item: entry,
|
|
600
|
+
index: globalIndex++
|
|
601
|
+
}
|
|
602
|
+
};
|
|
603
|
+
});
|
|
604
|
+
});
|
|
605
|
+
const renderDynamicItem = (item) => typeof local.children === "function" ? local.children(item) : void 0;
|
|
606
|
+
const resolveStaticChild = (child) => {
|
|
607
|
+
return typeof child === "function" ? child() : child;
|
|
608
|
+
};
|
|
609
|
+
const renderStaticChildren = () => {
|
|
610
|
+
const staticChildren = local.staticChildren?.() ?? local.children;
|
|
611
|
+
if (Array.isArray(staticChildren)) return staticChildren.map(resolveStaticChild);
|
|
612
|
+
return resolveStaticChild(staticChildren);
|
|
613
|
+
};
|
|
614
|
+
const collectionRenderer = createMemo(() => ({
|
|
615
|
+
...parentCollectionRenderer,
|
|
616
|
+
renderItem: (item) => renderDynamicItem(item),
|
|
617
|
+
renderDropIndicator: (index, position) => dndDropIndicator(index, position) ?? parentCollectionRenderer?.renderDropIndicator?.(index, position)
|
|
618
|
+
}));
|
|
619
|
+
const menuItemContextValue = createMemo(() => stateProps.shouldCloseOnSelect !== void 0 ? { closeOnSelect: stateProps.shouldCloseOnSelect } : {});
|
|
620
|
+
const menuListChildren = () => <SharedElementTransition>
|
|
621
|
+
{state.collection().size === 0 && !usesStaticChildren() && local.renderEmptyState ? <div role="presentation" data-empty-state>
|
|
622
|
+
<div role="menuitem" style={{ display: "contents" }}>
|
|
623
|
+
{local.renderEmptyState()}
|
|
624
|
+
</div>
|
|
625
|
+
</div> : usesStaticChildren() ? renderStaticChildren() : hasSections() ? <For each={sectionedRenderEntries()}>
|
|
626
|
+
{(entry) => entry.type === "section" ? <div role="presentation" data-section-wrapper>
|
|
627
|
+
<Section class="solidaria-Menu-section">
|
|
628
|
+
{entry.section.title != null && <Header class="solidaria-Menu-sectionHeader">{entry.section.title}</Header>}
|
|
629
|
+
<Group class="solidaria-Menu-sectionGroup">
|
|
630
|
+
<div role="group" aria-label={entry.section["aria-label"]}>
|
|
631
|
+
<For each={entry.items}>
|
|
632
|
+
{(indexedItem) => <>
|
|
633
|
+
{collectionRenderer().renderDropIndicator?.(indexedItem.index, "before")}
|
|
634
|
+
{collectionRenderer().renderDropIndicator?.(indexedItem.index, "on")}
|
|
635
|
+
{renderDynamicItem(indexedItem.item)}
|
|
636
|
+
{collectionRenderer().renderDropIndicator?.(indexedItem.index, "after")}
|
|
637
|
+
</>}
|
|
638
|
+
</For>
|
|
639
|
+
</div>
|
|
640
|
+
</Group>
|
|
641
|
+
</Section>
|
|
642
|
+
</div> : <>
|
|
643
|
+
{collectionRenderer().renderDropIndicator?.(entry.item.index, "before")}
|
|
644
|
+
{collectionRenderer().renderDropIndicator?.(entry.item.index, "on")}
|
|
645
|
+
{renderDynamicItem(entry.item.item)}
|
|
646
|
+
{collectionRenderer().renderDropIndicator?.(entry.item.index, "after")}
|
|
647
|
+
</>}
|
|
648
|
+
</For> : <>
|
|
649
|
+
{virtualRange()?.offsetTop ? <div role="presentation" aria-hidden="true" style={{ height: `${virtualRange().offsetTop}px` }} data-virtualizer-spacer="top" /> : null}
|
|
650
|
+
<For each={visibleItems()}>
|
|
651
|
+
{(item, index) => {
|
|
652
|
+
const itemIndex = () => (virtualRange()?.start ?? 0) + index();
|
|
653
|
+
const beforeIndicator = () => collectionRenderer().renderDropIndicator?.(itemIndex(), "before");
|
|
654
|
+
const onIndicator = () => collectionRenderer().renderDropIndicator?.(itemIndex(), "on");
|
|
655
|
+
const afterIndicator = () => collectionRenderer().renderDropIndicator?.(itemIndex(), "after");
|
|
656
|
+
return <>
|
|
657
|
+
{beforeIndicator()}
|
|
658
|
+
{onIndicator()}
|
|
659
|
+
{renderDynamicItem(item)}
|
|
660
|
+
{afterIndicator()}
|
|
661
|
+
</>;
|
|
662
|
+
}}
|
|
663
|
+
</For>
|
|
664
|
+
{virtualRange()?.offsetBottom ? <div role="presentation" aria-hidden="true" style={{ height: `${virtualRange().offsetBottom}px` }} data-virtualizer-spacer="bottom" /> : null}
|
|
665
|
+
</>}
|
|
666
|
+
</SharedElementTransition>;
|
|
667
|
+
const menuListProps = () => ({
|
|
668
|
+
ref: setResolvedMenuRef,
|
|
669
|
+
...mergeProps$1(domProps(), cleanMenuProps(), cleanTriggerMenuProps(), cleanFocusProps(), droppableCollection()?.collectionProps ?? {}),
|
|
670
|
+
class: renderProps.class(),
|
|
671
|
+
style: renderProps.style(),
|
|
672
|
+
slot: local.slot,
|
|
673
|
+
"data-focused": state.isFocused() || void 0,
|
|
674
|
+
"data-disabled": resolveDisabled() || void 0,
|
|
675
|
+
"data-empty": state.collection().size === 0 || void 0,
|
|
676
|
+
"data-drop-target": isRootDropTarget() || void 0,
|
|
677
|
+
children: menuListChildren()
|
|
678
|
+
});
|
|
679
|
+
const menuContent = () => <MenuContext.Provider value={{
|
|
680
|
+
state,
|
|
681
|
+
isDisabled: resolveDisabled,
|
|
682
|
+
dragAndDropHooks: stateProps.dragAndDropHooks,
|
|
683
|
+
dragState: dragState(),
|
|
684
|
+
dropState: dropState()
|
|
685
|
+
}}>
|
|
686
|
+
<MenuStateContext.Provider value={state}>
|
|
687
|
+
<MenuSectionSelectionRegistryContext.Provider value={sectionSelectionRegistry}>
|
|
688
|
+
<MenuItemCloseRegistryContext.Provider value={itemCloseRegistry}>
|
|
689
|
+
<StaticMenuCollectionContext.Provider value={usesStaticChildren() ? staticCollectionContext : null}>
|
|
690
|
+
<MenuItemContext.Provider value={menuItemContextValue()}>
|
|
691
|
+
<CollectionRendererContext.Provider value={collectionRenderer()}>
|
|
692
|
+
<>
|
|
693
|
+
<Show when={ariaProps.label}>
|
|
694
|
+
<span {...cleanLabelProps()}>{ariaProps.label}</span>
|
|
695
|
+
</Show>
|
|
696
|
+
{local.render ? local.render(menuListProps(), renderValues()) : <div ref={setResolvedMenuRef} {...mergeProps$1(domProps(), cleanMenuProps(), cleanTriggerMenuProps(), cleanFocusProps(), droppableCollection()?.collectionProps ?? {})} class={renderProps.class()} style={renderProps.style()} slot={local.slot} data-focused={state.isFocused() || void 0} data-disabled={resolveDisabled() || void 0} data-empty={state.collection().size === 0 || void 0} data-drop-target={isRootDropTarget() || void 0}>
|
|
697
|
+
{menuListChildren()}
|
|
698
|
+
</div>}
|
|
699
|
+
</>
|
|
700
|
+
</CollectionRendererContext.Provider>
|
|
701
|
+
</MenuItemContext.Provider>
|
|
702
|
+
</StaticMenuCollectionContext.Provider>
|
|
703
|
+
</MenuItemCloseRegistryContext.Provider>
|
|
704
|
+
</MenuSectionSelectionRegistryContext.Provider>
|
|
705
|
+
</MenuStateContext.Provider>
|
|
706
|
+
</MenuContext.Provider>;
|
|
707
|
+
return <Show when={shouldRender()}>
|
|
708
|
+
<Show when={triggerContext} fallback={menuContent()}>
|
|
709
|
+
<FocusScope restoreFocus autoFocus>
|
|
710
|
+
{menuContent()}
|
|
711
|
+
</FocusScope>
|
|
712
|
+
</Show>
|
|
713
|
+
</Show>;
|
|
714
|
+
}
|
|
715
|
+
/**
|
|
716
|
+
* An item in a menu.
|
|
717
|
+
*/
|
|
718
|
+
function MenuItem(props) {
|
|
719
|
+
const [local, ariaProps] = splitProps(props, [
|
|
720
|
+
"class",
|
|
721
|
+
"style",
|
|
722
|
+
"render",
|
|
723
|
+
"slot",
|
|
724
|
+
"id",
|
|
725
|
+
"item",
|
|
726
|
+
"textValue",
|
|
727
|
+
"onAction",
|
|
728
|
+
"href",
|
|
729
|
+
"target",
|
|
730
|
+
"rel",
|
|
731
|
+
"download",
|
|
732
|
+
"onHoverStart",
|
|
733
|
+
"onHoverEnd",
|
|
734
|
+
"onHoverChange",
|
|
735
|
+
"ref"
|
|
736
|
+
]);
|
|
737
|
+
const context = useContext(MenuStateContext);
|
|
738
|
+
if (!context) throw new Error("MenuItem must be used within a Menu");
|
|
739
|
+
const state = context;
|
|
740
|
+
const menuContext = useContext(MenuContext);
|
|
741
|
+
const itemContext = useContext(MenuItemContext);
|
|
742
|
+
const staticCollection = useContext(StaticMenuCollectionContext);
|
|
743
|
+
const sectionSelection = useContext(MenuSectionSelectionContext);
|
|
744
|
+
const sectionSelectionRegistry = useContext(MenuSectionSelectionRegistryContext);
|
|
745
|
+
const itemCloseRegistry = useContext(MenuItemCloseRegistryContext);
|
|
746
|
+
const [ref, setRef] = createSignal(null);
|
|
747
|
+
const contextProps = () => itemContext?.props?.() ?? {};
|
|
748
|
+
const combinedOnAction = () => {
|
|
749
|
+
local.onAction?.();
|
|
750
|
+
itemContext?.onAction?.();
|
|
751
|
+
};
|
|
752
|
+
const itemCloseOnSelect = () => ariaProps.closeOnSelect ?? sectionSelection?.shouldCloseOnSelect() ?? itemContext?.closeOnSelect;
|
|
753
|
+
const activeSectionSelection = () => sectionSelection && sectionSelection.selectionMode() !== "none" ? sectionSelection : null;
|
|
754
|
+
let registeredStaticKey = null;
|
|
755
|
+
let registeredSectionSelectionKey = null;
|
|
756
|
+
let registeredSectionSelection = null;
|
|
757
|
+
let registeredCloseKey = null;
|
|
758
|
+
let registeredCloseAccessor = null;
|
|
759
|
+
const unregisterSectionSelection = () => {
|
|
760
|
+
if (registeredSectionSelectionKey != null && registeredSectionSelection) {
|
|
761
|
+
sectionSelectionRegistry?.unregisterItem(registeredSectionSelectionKey, registeredSectionSelection);
|
|
762
|
+
registeredSectionSelectionKey = null;
|
|
763
|
+
registeredSectionSelection = null;
|
|
764
|
+
}
|
|
765
|
+
};
|
|
766
|
+
createEffect(() => {
|
|
767
|
+
if (!staticCollection) return;
|
|
768
|
+
if (registeredStaticKey != null && registeredStaticKey !== local.id) staticCollection.unregisterItem(registeredStaticKey);
|
|
769
|
+
registeredStaticKey = local.id;
|
|
770
|
+
staticCollection.registerItem({
|
|
771
|
+
id: local.id,
|
|
772
|
+
textValue: local.textValue ?? ariaProps["aria-label"],
|
|
773
|
+
isDisabled: resolveBoolean(ariaProps.isDisabled) || (sectionSelection?.isDisabled(local.id) ?? false)
|
|
774
|
+
});
|
|
775
|
+
});
|
|
776
|
+
onCleanup(() => {
|
|
777
|
+
if (registeredStaticKey != null) staticCollection?.unregisterItem(registeredStaticKey);
|
|
778
|
+
});
|
|
779
|
+
createEffect(() => {
|
|
780
|
+
const selection = activeSectionSelection();
|
|
781
|
+
if (!sectionSelectionRegistry || !selection) {
|
|
782
|
+
unregisterSectionSelection();
|
|
783
|
+
return;
|
|
784
|
+
}
|
|
785
|
+
if (registeredSectionSelectionKey === local.id && registeredSectionSelection === selection) return;
|
|
786
|
+
unregisterSectionSelection();
|
|
787
|
+
registeredSectionSelectionKey = local.id;
|
|
788
|
+
registeredSectionSelection = selection;
|
|
789
|
+
sectionSelectionRegistry.registerItem(local.id, selection);
|
|
790
|
+
});
|
|
791
|
+
onCleanup(unregisterSectionSelection);
|
|
792
|
+
const unregisterItemClose = () => {
|
|
793
|
+
if (registeredCloseKey != null && registeredCloseAccessor) {
|
|
794
|
+
itemCloseRegistry?.unregisterItem(registeredCloseKey, registeredCloseAccessor);
|
|
795
|
+
registeredCloseKey = null;
|
|
796
|
+
registeredCloseAccessor = null;
|
|
797
|
+
}
|
|
798
|
+
};
|
|
799
|
+
createEffect(() => {
|
|
800
|
+
if (!itemCloseRegistry) {
|
|
801
|
+
unregisterItemClose();
|
|
802
|
+
return;
|
|
803
|
+
}
|
|
804
|
+
if (registeredCloseKey === local.id && registeredCloseAccessor === itemCloseOnSelect) return;
|
|
805
|
+
unregisterItemClose();
|
|
806
|
+
registeredCloseKey = local.id;
|
|
807
|
+
registeredCloseAccessor = itemCloseOnSelect;
|
|
808
|
+
itemCloseRegistry.registerItem(local.id, itemCloseOnSelect);
|
|
809
|
+
});
|
|
810
|
+
onCleanup(unregisterItemClose);
|
|
811
|
+
const itemAria = createMenuItem({
|
|
812
|
+
key: local.id,
|
|
813
|
+
get id() {
|
|
814
|
+
return contextProps().id;
|
|
815
|
+
},
|
|
816
|
+
get isDisabled() {
|
|
817
|
+
return Boolean(ariaProps.isDisabled || sectionSelection?.isDisabled(local.id) || menuContext?.isDisabled());
|
|
818
|
+
},
|
|
819
|
+
get "aria-label"() {
|
|
820
|
+
return ariaProps["aria-label"] ?? local.textValue;
|
|
821
|
+
},
|
|
822
|
+
get "aria-controls"() {
|
|
823
|
+
return contextProps()["aria-controls"];
|
|
824
|
+
},
|
|
825
|
+
get "aria-haspopup"() {
|
|
826
|
+
return contextProps()["aria-haspopup"];
|
|
827
|
+
},
|
|
828
|
+
get "aria-expanded"() {
|
|
829
|
+
return contextProps()["aria-expanded"];
|
|
830
|
+
},
|
|
831
|
+
get onAction() {
|
|
832
|
+
return combinedOnAction;
|
|
833
|
+
},
|
|
834
|
+
get closeOnSelect() {
|
|
835
|
+
return itemCloseOnSelect();
|
|
836
|
+
},
|
|
837
|
+
get href() {
|
|
838
|
+
return local.href;
|
|
839
|
+
},
|
|
840
|
+
get target() {
|
|
841
|
+
return local.target;
|
|
842
|
+
},
|
|
843
|
+
get rel() {
|
|
844
|
+
return local.rel;
|
|
845
|
+
},
|
|
846
|
+
get download() {
|
|
847
|
+
return local.download;
|
|
848
|
+
}
|
|
849
|
+
}, state, () => ref());
|
|
850
|
+
const { isHovered, hoverProps } = createHover({
|
|
851
|
+
get isDisabled() {
|
|
852
|
+
return itemAria.isDisabled();
|
|
853
|
+
},
|
|
854
|
+
onHoverStart: local.onHoverStart,
|
|
855
|
+
onHoverEnd: local.onHoverEnd,
|
|
856
|
+
onHoverChange: local.onHoverChange
|
|
857
|
+
});
|
|
858
|
+
const renderValues = createMemo(() => {
|
|
859
|
+
const selection = activeSectionSelection();
|
|
860
|
+
return {
|
|
861
|
+
isSelected: selection?.isSelected(local.id) ?? itemAria.isSelected(),
|
|
862
|
+
selectionMode: selection?.selectionMode() ?? itemAria.selectionMode(),
|
|
863
|
+
isFocused: itemAria.isFocused(),
|
|
864
|
+
isFocusVisible: itemAria.isFocusVisible(),
|
|
865
|
+
isPressed: itemAria.isPressed(),
|
|
866
|
+
isHovered: isHovered(),
|
|
867
|
+
isDisabled: itemAria.isDisabled(),
|
|
868
|
+
hasSubmenu: Boolean(contextProps()["aria-haspopup"]),
|
|
869
|
+
isOpen: contextProps()["aria-expanded"] === true,
|
|
870
|
+
descriptionProps: itemAria.descriptionProps,
|
|
871
|
+
keyboardShortcutProps: itemAria.keyboardShortcutProps
|
|
872
|
+
};
|
|
873
|
+
});
|
|
874
|
+
const renderProps = useRenderProps({
|
|
875
|
+
get children() {
|
|
876
|
+
return props.children;
|
|
877
|
+
},
|
|
878
|
+
class: local.class,
|
|
879
|
+
style: local.style,
|
|
880
|
+
defaultClassName: "solidaria-Menu-item"
|
|
881
|
+
}, renderValues);
|
|
882
|
+
const hasPrimitiveLabel = () => {
|
|
883
|
+
return typeof props.children === "string" || typeof props.children === "number";
|
|
884
|
+
};
|
|
885
|
+
const cleanItemProps = () => {
|
|
886
|
+
const { ref: _ref1, ...rest } = itemAria.menuItemProps;
|
|
887
|
+
if (!hasPrimitiveLabel() && rest["aria-label"] == null) delete rest["aria-labelledby"];
|
|
888
|
+
const selection = activeSectionSelection();
|
|
889
|
+
const selectionMode = selection?.selectionMode();
|
|
890
|
+
if (selectionMode) {
|
|
891
|
+
rest.role = selectionMode === "single" ? "menuitemradio" : selectionMode === "multiple" ? "menuitemcheckbox" : "menuitem";
|
|
892
|
+
if (selectionMode !== "none") rest["aria-checked"] = selection?.isSelected(local.id) ?? false;
|
|
893
|
+
else delete rest["aria-checked"];
|
|
894
|
+
rest["data-selected"] = selection?.isSelected(local.id) || void 0;
|
|
895
|
+
}
|
|
896
|
+
return rest;
|
|
897
|
+
};
|
|
898
|
+
const cleanHoverProps = () => {
|
|
899
|
+
const { ref: _ref2, ...rest } = hoverProps;
|
|
900
|
+
return rest;
|
|
901
|
+
};
|
|
902
|
+
const domProps = createMemo(() => filterDOMProps(ariaProps, { global: true }));
|
|
903
|
+
const draggableItem = createMemo(() => {
|
|
904
|
+
if (!menuContext?.dragAndDropHooks?.useDraggableItem || !menuContext.dragState) return void 0;
|
|
905
|
+
return menuContext.dragAndDropHooks.useDraggableItem({ key: local.id }, menuContext.dragState);
|
|
906
|
+
});
|
|
907
|
+
const droppableItem = createMemo(() => {
|
|
908
|
+
if (!menuContext?.dragAndDropHooks?.useDroppableItem || !menuContext.dropState) return void 0;
|
|
909
|
+
return menuContext.dragAndDropHooks.useDroppableItem({ key: local.id }, menuContext.dropState, () => ref());
|
|
910
|
+
});
|
|
911
|
+
const isLink = () => !!local.href;
|
|
912
|
+
const cleanItemPropsForLink = () => {
|
|
913
|
+
const { href: _href, target: _target, rel: _rel, download: _download, ...rest } = cleanItemProps();
|
|
914
|
+
return rest;
|
|
915
|
+
};
|
|
916
|
+
const linkDomProps = () => {
|
|
917
|
+
const all = cleanItemProps();
|
|
918
|
+
const result = {};
|
|
919
|
+
if (all.href !== void 0) result.href = all.href;
|
|
920
|
+
if (all.target !== void 0) result.target = all.target;
|
|
921
|
+
if (all.rel !== void 0) result.rel = all.rel;
|
|
922
|
+
if (all.download !== void 0) result.download = all.download;
|
|
923
|
+
return result;
|
|
924
|
+
};
|
|
925
|
+
const dataAttrs = () => {
|
|
926
|
+
const selection = activeSectionSelection();
|
|
927
|
+
return {
|
|
928
|
+
"data-focused": itemAria.isFocused() || void 0,
|
|
929
|
+
"data-focus-visible": itemAria.isFocusVisible() || void 0,
|
|
930
|
+
"data-pressed": itemAria.isPressed() || void 0,
|
|
931
|
+
"data-hovered": isHovered() || void 0,
|
|
932
|
+
"data-disabled": itemAria.isDisabled() || void 0,
|
|
933
|
+
"data-selected": (selection?.isSelected(local.id) ?? itemAria.isSelected()) || void 0,
|
|
934
|
+
"data-has-submenu": Boolean(contextProps()["aria-haspopup"]) || void 0,
|
|
935
|
+
"data-open": contextProps()["aria-expanded"] === true || void 0,
|
|
936
|
+
"data-dragging": draggableItem()?.isDragging || void 0,
|
|
937
|
+
"data-drop-target": droppableItem()?.isDropTarget || void 0
|
|
938
|
+
};
|
|
939
|
+
};
|
|
940
|
+
const childContent = () => hasPrimitiveLabel() ? <span {...itemAria.labelProps}>{renderProps.renderChildren()}</span> : renderProps.renderChildren();
|
|
941
|
+
const setResolvedItemRef = (el) => {
|
|
942
|
+
setRef(el);
|
|
943
|
+
itemContext?.setItemRef?.(el);
|
|
944
|
+
if (el) assignRef(local.ref, el);
|
|
945
|
+
};
|
|
946
|
+
const menuItemProps = () => ({
|
|
947
|
+
ref: setResolvedItemRef,
|
|
948
|
+
...mergeProps$1(cleanItemProps(), contextProps(), domProps(), cleanHoverProps(), draggableItem()?.dragProps ?? {}, droppableItem()?.dropProps ?? {}),
|
|
949
|
+
class: renderProps.class(),
|
|
950
|
+
style: renderProps.style(),
|
|
951
|
+
...dataAttrs(),
|
|
952
|
+
children: childContent()
|
|
953
|
+
});
|
|
954
|
+
const linkMenuItemProps = () => ({
|
|
955
|
+
...mergeProps$1(cleanItemPropsForLink(), contextProps(), domProps(), cleanHoverProps(), linkDomProps(), draggableItem()?.dragProps ?? {}, droppableItem()?.dropProps ?? {}),
|
|
956
|
+
class: renderProps.class(),
|
|
957
|
+
style: renderProps.style(),
|
|
958
|
+
...dataAttrs(),
|
|
959
|
+
children: childContent()
|
|
960
|
+
});
|
|
961
|
+
if (local.render && !isLink()) return local.render(menuItemProps(), renderValues());
|
|
962
|
+
return <Show when={isLink()} fallback={<div ref={(el) => {
|
|
963
|
+
setRef(el);
|
|
964
|
+
itemContext?.setItemRef?.(el);
|
|
965
|
+
assignRef(local.ref, el);
|
|
966
|
+
}} {...mergeProps$1(cleanItemProps(), contextProps(), domProps(), cleanHoverProps(), draggableItem()?.dragProps ?? {}, droppableItem()?.dropProps ?? {})} class={renderProps.class()} style={renderProps.style()} {...dataAttrs()}>
|
|
967
|
+
{childContent()}
|
|
968
|
+
</div>}>
|
|
969
|
+
{local.render ? local.render(linkMenuItemProps(), renderValues()) : <a ref={(el) => {
|
|
970
|
+
setRef(el);
|
|
971
|
+
itemContext?.setItemRef?.(el);
|
|
972
|
+
assignRef(local.ref, el);
|
|
973
|
+
}} {...mergeProps$1(cleanItemPropsForLink(), contextProps(), domProps(), cleanHoverProps(), linkDomProps(), draggableItem()?.dragProps ?? {}, droppableItem()?.dropProps ?? {})} class={renderProps.class()} style={renderProps.style()} {...dataAttrs()}>
|
|
974
|
+
{childContent()}
|
|
975
|
+
</a>}
|
|
976
|
+
</Show>;
|
|
977
|
+
}
|
|
978
|
+
/**
|
|
979
|
+
* Section primitive alias for Menu composition parity.
|
|
980
|
+
*/
|
|
981
|
+
function MenuSection(props) {
|
|
982
|
+
const [selectionProps, sectionProps] = splitProps(props, [
|
|
983
|
+
"selectionMode",
|
|
984
|
+
"selectionBehavior",
|
|
985
|
+
"disallowEmptySelection",
|
|
986
|
+
"selectedKeys",
|
|
987
|
+
"defaultSelectedKeys",
|
|
988
|
+
"onSelectionChange",
|
|
989
|
+
"disabledKeys",
|
|
990
|
+
"disabledBehavior",
|
|
991
|
+
"allowDuplicateSelectionEvents",
|
|
992
|
+
"shouldCloseOnSelect"
|
|
993
|
+
]);
|
|
994
|
+
const selectionState = createSelectionState({
|
|
995
|
+
get selectionMode() {
|
|
996
|
+
return selectionProps.selectionMode ?? "none";
|
|
997
|
+
},
|
|
998
|
+
get selectionBehavior() {
|
|
999
|
+
return selectionProps.selectionBehavior;
|
|
1000
|
+
},
|
|
1001
|
+
get disallowEmptySelection() {
|
|
1002
|
+
return selectionProps.disallowEmptySelection;
|
|
1003
|
+
},
|
|
1004
|
+
get selectedKeys() {
|
|
1005
|
+
return selectionProps.selectionMode ? selectionProps.selectedKeys : void 0;
|
|
1006
|
+
},
|
|
1007
|
+
get defaultSelectedKeys() {
|
|
1008
|
+
return selectionProps.selectionMode ? selectionProps.defaultSelectedKeys : void 0;
|
|
1009
|
+
},
|
|
1010
|
+
get onSelectionChange() {
|
|
1011
|
+
return selectionProps.selectionMode ? selectionProps.onSelectionChange : void 0;
|
|
1012
|
+
},
|
|
1013
|
+
get disabledKeys() {
|
|
1014
|
+
return selectionProps.disabledKeys;
|
|
1015
|
+
},
|
|
1016
|
+
get disabledBehavior() {
|
|
1017
|
+
return selectionProps.disabledBehavior;
|
|
1018
|
+
},
|
|
1019
|
+
get allowDuplicateSelectionEvents() {
|
|
1020
|
+
return selectionProps.allowDuplicateSelectionEvents;
|
|
1021
|
+
}
|
|
1022
|
+
});
|
|
1023
|
+
const sectionSelection = {
|
|
1024
|
+
selectionMode: selectionState.selectionMode,
|
|
1025
|
+
isSelected: selectionState.isSelected,
|
|
1026
|
+
isDisabled: selectionState.isDisabled,
|
|
1027
|
+
select(key, event) {
|
|
1028
|
+
selectionState.select(key, event);
|
|
1029
|
+
},
|
|
1030
|
+
shouldCloseOnSelect() {
|
|
1031
|
+
return selectionProps.shouldCloseOnSelect;
|
|
1032
|
+
}
|
|
1033
|
+
};
|
|
1034
|
+
return <MenuSectionSelectionContext.Provider value={sectionSelection}>
|
|
1035
|
+
<Section {...sectionProps} />
|
|
1036
|
+
</MenuSectionSelectionContext.Provider>;
|
|
1037
|
+
}
|
|
1038
|
+
Menu.Item = MenuItem;
|
|
1039
|
+
//#endregion
|
|
1040
|
+
export { Menu, MenuButton, MenuContext, MenuItem, MenuSection, MenuStateContext, MenuTrigger, MenuTriggerContext, RootMenuTriggerStateContext, SubmenuTrigger };
|
|
1041
|
+
|
|
1042
|
+
//# sourceMappingURL=Menu.jsx.map
|