ropav 0.0.6 → 0.0.7
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/_plugin-vue_export-helper.js +1 -11
- package/dist/accordion.css +112 -0
- package/dist/accordion.js +360 -0
- package/dist/accordion.js.map +1 -0
- package/dist/badge.css +169 -0
- package/dist/badge.js +103 -0
- package/dist/badge.js.map +1 -0
- package/dist/bem.js +11 -0
- package/dist/bem.js.map +1 -0
- package/dist/button-group.css +8 -8
- package/dist/button-group.js +2 -1
- package/dist/button-group.js.map +1 -1
- package/dist/button.js +3 -2
- package/dist/button.js.map +1 -1
- package/dist/card.js +2 -1
- package/dist/card.js.map +1 -1
- package/dist/checkbox.js +2 -1
- package/dist/checkbox.js.map +1 -1
- package/dist/collapse.css +32 -0
- package/dist/collapse.js +68 -0
- package/dist/collapse.js.map +1 -0
- package/dist/components/accordion/accordion-item.d.ts +40 -0
- package/dist/components/accordion/accordion.d.ts +23 -0
- package/dist/components/accordion/index.d.ts +4 -0
- package/dist/components/accordion/index.js +2 -0
- package/dist/components/accordion/types.d.ts +100 -0
- package/dist/components/accordion/useAccordion.d.ts +3 -0
- package/dist/components/badge/badge.d.ts +25 -0
- package/dist/components/badge/index.d.ts +3 -0
- package/dist/components/badge/index.js +2 -0
- package/dist/components/badge/types.d.ts +16 -0
- package/dist/components/badge/useBadgeColor.d.ts +8 -0
- package/dist/components/collapse/collapse.d.ts +36 -0
- package/dist/components/collapse/index.d.ts +3 -0
- package/dist/components/collapse/index.js +3 -0
- package/dist/components/collapse/types.d.ts +76 -0
- package/dist/components/collapse/useCollapse.d.ts +2 -0
- package/dist/components/dropdown-menu/dropdown-menu-items.d.ts +16 -0
- package/dist/components/dropdown-menu/dropdown-menu-utils.d.ts +23 -0
- package/dist/components/dropdown-menu/dropdown-menu.d.ts +26 -0
- package/dist/components/dropdown-menu/index.d.ts +3 -0
- package/dist/components/dropdown-menu/index.js +2 -0
- package/dist/components/dropdown-menu/types.d.ts +104 -0
- package/dist/components/dropdown-menu/useDropdownMenu.d.ts +32 -0
- package/dist/components/dropdown-menu/useDropdownMenuDisclosure.d.ts +30 -0
- package/dist/components/dropdown-menu/useDropdownMenuDom.d.ts +28 -0
- package/dist/components/dropdown-menu/useDropdownMenuHoverIntent.d.ts +24 -0
- package/dist/components/dropdown-menu/useDropdownMenuInteractions.d.ts +51 -0
- package/dist/components/dropdown-menu/useDropdownMenuNavigation.d.ts +16 -0
- package/dist/components/dropdown-menu/useDropdownMenuRenderItems.d.ts +25 -0
- package/dist/components/dropdown-menu/useDropdownSubmenus.d.ts +18 -0
- package/dist/components/field/field.d.ts +2 -2
- package/dist/components/field/useField.d.ts +16 -0
- package/dist/components/input/useInput.d.ts +8 -0
- package/dist/components/modal/index.d.ts +2 -0
- package/dist/components/modal/index.js +2 -0
- package/dist/components/modal/modal.d.ts +42 -0
- package/dist/components/modal/types.d.ts +32 -0
- package/dist/components/modal/useModal.d.ts +29 -0
- package/dist/components/overlay/index.d.ts +2 -0
- package/dist/components/overlay/index.js +2 -0
- package/dist/components/overlay/overlay.d.ts +19 -0
- package/dist/components/overlay/types.d.ts +12 -0
- package/dist/components/overlay/useOverlay.d.ts +7 -0
- package/dist/components/popover/index.d.ts +2 -0
- package/dist/components/popover/index.js +2 -0
- package/dist/components/popover/popover.d.ts +43 -0
- package/dist/components/popover/types.d.ts +40 -0
- package/dist/components/popover/usePopover.d.ts +20 -0
- package/dist/components/tabs/index.d.ts +6 -0
- package/dist/components/tabs/index.js +2 -0
- package/dist/components/tabs/tabs-content.d.ts +24 -0
- package/dist/components/tabs/tabs-list.d.ts +26 -0
- package/dist/components/tabs/tabs-trigger.d.ts +29 -0
- package/dist/components/tabs/tabs.d.ts +31 -0
- package/dist/components/tabs/types.d.ts +160 -0
- package/dist/components/tabs/useTabs.d.ts +5 -0
- package/dist/dropdown-menu.css +159 -0
- package/dist/dropdown-menu.js +903 -0
- package/dist/dropdown-menu.js.map +1 -0
- package/dist/field.css +8 -8
- package/dist/field.js +68 -50
- package/dist/field.js.map +1 -1
- package/dist/icon-button.css +1 -1
- package/dist/icon-button.js +3 -2
- package/dist/icon-button.js.map +1 -1
- package/dist/index.d.ts +8 -0
- package/dist/index.js +12 -1
- package/dist/input.css +25 -25
- package/dist/input.js +57 -38
- package/dist/input.js.map +1 -1
- package/dist/modal.css +134 -0
- package/dist/modal.js +433 -0
- package/dist/modal.js.map +1 -0
- package/dist/overlay.css +28 -0
- package/dist/overlay.js +84 -0
- package/dist/overlay.js.map +1 -0
- package/dist/popover.css +75 -0
- package/dist/popover.js +367 -0
- package/dist/popover.js.map +1 -0
- package/dist/progress.js +2 -1
- package/dist/progress.js.map +1 -1
- package/dist/radio.js +4 -9
- package/dist/radio.js.map +1 -1
- package/dist/select.js +8 -37
- package/dist/select.js.map +1 -1
- package/dist/slider.js +2 -1
- package/dist/slider.js.map +1 -1
- package/dist/switch.js +2 -1
- package/dist/switch.js.map +1 -1
- package/dist/tabs.css +279 -0
- package/dist/tabs.js +515 -0
- package/dist/tabs.js.map +1 -0
- package/dist/textarea.js +2 -1
- package/dist/textarea.js.map +1 -1
- package/dist/tooltip.js +2 -1
- package/dist/tooltip.js.map +1 -1
- package/dist/useClickOutside.js +26 -0
- package/dist/useClickOutside.js.map +1 -0
- package/dist/useCollapse.js +94 -0
- package/dist/useCollapse.js.map +1 -0
- package/dist/useRequiredInject.js +11 -0
- package/dist/useRequiredInject.js.map +1 -0
- package/dist/x.js +14 -0
- package/dist/x.js.map +1 -0
- package/package.json +35 -3
- package/dist/_plugin-vue_export-helper.js.map +0 -1
|
@@ -0,0 +1,903 @@
|
|
|
1
|
+
import './dropdown-menu.css';
|
|
2
|
+
import { t as bem } from "./bem.js";
|
|
3
|
+
import { t as useClickOutside } from "./useClickOutside.js";
|
|
4
|
+
import { VaporTransition, computed, createComponent, createIf, createSlot, createTemplateRefSetter, defineComponent, defineVaporComponent, extend, h, markRaw, nextTick, onUnmounted, ref, renderEffect, setClass, setDynamicProps, setInsertionState, setStaticTemplateRef, setText, template, toDisplayString, txt, unref, useId, watch } from "vue";
|
|
5
|
+
//#region ~icons/lucide/chevron-right
|
|
6
|
+
var t0$1 = template("<svg viewBox=\"0 0 24 24\"width=1.2em height=1.2em><path fill=none stroke=currentColor stroke-linecap=round stroke-linejoin=round stroke-width=2 d=\"m9 18l6-6l-6-6\">", 3, 1);
|
|
7
|
+
function render(_ctx) {
|
|
8
|
+
return t0$1();
|
|
9
|
+
}
|
|
10
|
+
var chevron_right_default = markRaw(defineVaporComponent({
|
|
11
|
+
name: "lucide-chevron-right",
|
|
12
|
+
render
|
|
13
|
+
}));
|
|
14
|
+
//#endregion
|
|
15
|
+
//#region src/components/dropdown-menu/dropdown-menu-items.ts
|
|
16
|
+
var dropdown_menu_items_default = defineComponent({
|
|
17
|
+
name: "RpDropdownMenuItems",
|
|
18
|
+
props: { items: {
|
|
19
|
+
type: Array,
|
|
20
|
+
required: true
|
|
21
|
+
} },
|
|
22
|
+
setup(props, { slots }) {
|
|
23
|
+
function renderItems(items) {
|
|
24
|
+
return items.map((renderedItem) => {
|
|
25
|
+
const children = [h("button", renderedItem.props, slots.item?.(renderedItem.slotProps))];
|
|
26
|
+
if (renderedItem.hasSubmenu && renderedItem.submenuOpen) children.push(h("div", renderedItem.submenuProps, renderItems(renderedItem.children)));
|
|
27
|
+
return h("div", {
|
|
28
|
+
key: renderedItem.key,
|
|
29
|
+
class: "rp-dropdown-menu__item-wrap",
|
|
30
|
+
role: "none"
|
|
31
|
+
}, children);
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
return () => renderItems(props.items);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
var DEFAULT_FOCUS_TARGET = "first";
|
|
38
|
+
function getOpenFocusTarget(options) {
|
|
39
|
+
if (typeof options === "string") return options;
|
|
40
|
+
return options?.focus ?? "first";
|
|
41
|
+
}
|
|
42
|
+
function getItemClass(item, focused, disabled, hasSubmenu, submenuOpen) {
|
|
43
|
+
return bem("rp-dropdown-menu__item", {
|
|
44
|
+
focused,
|
|
45
|
+
disabled,
|
|
46
|
+
destructive: item.destructive,
|
|
47
|
+
submenu: hasSubmenu,
|
|
48
|
+
open: submenuOpen
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
function hasItemSubmenu(item) {
|
|
52
|
+
return (item.children?.length ?? 0) > 0;
|
|
53
|
+
}
|
|
54
|
+
function hasNestedItems(items) {
|
|
55
|
+
return items.some((item) => hasItemSubmenu(item) || hasNestedItems(item.children ?? []));
|
|
56
|
+
}
|
|
57
|
+
function getPathKey(path) {
|
|
58
|
+
return path.length === 0 ? "root" : path.join("-");
|
|
59
|
+
}
|
|
60
|
+
function getParentPath(path) {
|
|
61
|
+
return path.slice(0, -1);
|
|
62
|
+
}
|
|
63
|
+
function arePathsEqual(a, b) {
|
|
64
|
+
return a.length === b.length && a.every((part, index) => part === b[index]);
|
|
65
|
+
}
|
|
66
|
+
function isPathPrefix(prefix, path) {
|
|
67
|
+
return prefix.length <= path.length && prefix.every((part, index) => part === path[index]);
|
|
68
|
+
}
|
|
69
|
+
function normalizePath(indexOrPath) {
|
|
70
|
+
return Array.isArray(indexOrPath) ? indexOrPath : [indexOrPath];
|
|
71
|
+
}
|
|
72
|
+
function getEventPoint(event) {
|
|
73
|
+
return {
|
|
74
|
+
x: event.clientX,
|
|
75
|
+
y: event.clientY
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
function hasMeasuredRect(rect) {
|
|
79
|
+
return rect.width > 0 || rect.height > 0;
|
|
80
|
+
}
|
|
81
|
+
function isPointInRect(point, rect, padding = 0) {
|
|
82
|
+
return point.x >= rect.left - padding && point.x <= rect.right + padding && point.y >= rect.top - padding && point.y <= rect.bottom + padding;
|
|
83
|
+
}
|
|
84
|
+
function getEnabledIndexes(items) {
|
|
85
|
+
return items.map((item, index) => item.disabled ? -1 : index).filter((index) => index >= 0);
|
|
86
|
+
}
|
|
87
|
+
function getNextEnabledIndex(items, index, direction) {
|
|
88
|
+
const enabledIndexes = getEnabledIndexes(items);
|
|
89
|
+
if (enabledIndexes.length === 0) return void 0;
|
|
90
|
+
if (direction === 1) return enabledIndexes.find((candidate) => candidate > index) ?? enabledIndexes[0];
|
|
91
|
+
for (let i = enabledIndexes.length - 1; i >= 0; i -= 1) {
|
|
92
|
+
const candidate = enabledIndexes[i];
|
|
93
|
+
if (candidate < index) return candidate;
|
|
94
|
+
}
|
|
95
|
+
return enabledIndexes[enabledIndexes.length - 1];
|
|
96
|
+
}
|
|
97
|
+
//#endregion
|
|
98
|
+
//#region src/components/dropdown-menu/useDropdownMenuDisclosure.ts
|
|
99
|
+
function useDropdownMenuDisclosure({ props, emit, rootRef, uncontrolledOpen, isDisabled, isOpen, isVisible, focusedPath, resetFocus, resetSubmenus, resetHoverIntent, focusItem, focusMenu, focusTrigger }) {
|
|
100
|
+
function setOpen(nextOpen) {
|
|
101
|
+
if (nextOpen && isDisabled.value) return;
|
|
102
|
+
const previousOpen = isOpen.value;
|
|
103
|
+
if (props.open === void 0) uncontrolledOpen.value = nextOpen;
|
|
104
|
+
if (previousOpen !== nextOpen) emit.openChange?.(nextOpen);
|
|
105
|
+
}
|
|
106
|
+
function resetMenuFocus() {
|
|
107
|
+
resetFocus();
|
|
108
|
+
resetSubmenus();
|
|
109
|
+
resetHoverIntent();
|
|
110
|
+
}
|
|
111
|
+
function open(options) {
|
|
112
|
+
if (isDisabled.value) return;
|
|
113
|
+
setOpen(true);
|
|
114
|
+
focusItem(getOpenFocusTarget(options));
|
|
115
|
+
resetSubmenus();
|
|
116
|
+
resetHoverIntent();
|
|
117
|
+
focusMenu();
|
|
118
|
+
}
|
|
119
|
+
function close(options = {}) {
|
|
120
|
+
setOpen(false);
|
|
121
|
+
resetMenuFocus();
|
|
122
|
+
if (options.focusTrigger) focusTrigger();
|
|
123
|
+
}
|
|
124
|
+
function toggle() {
|
|
125
|
+
if (isVisible.value) close({ focusTrigger: true });
|
|
126
|
+
else open();
|
|
127
|
+
}
|
|
128
|
+
watch(isDisabled, (disabled) => {
|
|
129
|
+
if (disabled) close();
|
|
130
|
+
});
|
|
131
|
+
watch(isVisible, (visible) => {
|
|
132
|
+
if (visible) {
|
|
133
|
+
if (focusedPath.value.length === 0) focusItem(DEFAULT_FOCUS_TARGET);
|
|
134
|
+
focusMenu();
|
|
135
|
+
} else resetMenuFocus();
|
|
136
|
+
});
|
|
137
|
+
useClickOutside(rootRef, isVisible, () => close());
|
|
138
|
+
return {
|
|
139
|
+
open,
|
|
140
|
+
close,
|
|
141
|
+
toggle,
|
|
142
|
+
resetMenuFocus
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
//#endregion
|
|
146
|
+
//#region src/components/dropdown-menu/useDropdownMenuDom.ts
|
|
147
|
+
function useDropdownMenuDom({ menuId, rootRef, menuRef, placement, focusedPath }) {
|
|
148
|
+
const activeDescendantId = computed(() => focusedPath.value.length === 0 ? void 0 : getItemId(focusedPath.value));
|
|
149
|
+
function focusMenu() {
|
|
150
|
+
nextTick(() => menuRef.value?.focus());
|
|
151
|
+
}
|
|
152
|
+
function focusTrigger() {
|
|
153
|
+
nextTick(() => {
|
|
154
|
+
(rootRef.value?.querySelector("[aria-haspopup=\"menu\"]"))?.focus();
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
function getItemId(indexOrPath) {
|
|
158
|
+
return `${menuId.value}-item-${getPathKey(normalizePath(indexOrPath))}`;
|
|
159
|
+
}
|
|
160
|
+
function getSubmenuId(path) {
|
|
161
|
+
return `${menuId.value}-submenu-${getPathKey(path)}`;
|
|
162
|
+
}
|
|
163
|
+
function getItemElement(path) {
|
|
164
|
+
return document.getElementById(getItemId(path));
|
|
165
|
+
}
|
|
166
|
+
function getSubmenuElement(path) {
|
|
167
|
+
return document.getElementById(getSubmenuId(path));
|
|
168
|
+
}
|
|
169
|
+
function isSubmenuOpeningLeft(path) {
|
|
170
|
+
const submenuRect = getSubmenuElement(path)?.getBoundingClientRect();
|
|
171
|
+
const itemRect = getItemElement(path)?.getBoundingClientRect();
|
|
172
|
+
if (submenuRect && itemRect && hasMeasuredRect(submenuRect) && hasMeasuredRect(itemRect)) return submenuRect.right <= itemRect.left;
|
|
173
|
+
return placement.value.endsWith("end");
|
|
174
|
+
}
|
|
175
|
+
function getMenuActiveDescendant(menuPath) {
|
|
176
|
+
return arePathsEqual(getParentPath(focusedPath.value), menuPath) ? getItemId(focusedPath.value) : void 0;
|
|
177
|
+
}
|
|
178
|
+
watch(focusedPath, (path) => {
|
|
179
|
+
if (path.length === 0) return;
|
|
180
|
+
const targetPath = [...path];
|
|
181
|
+
nextTick(() => {
|
|
182
|
+
if (!arePathsEqual(targetPath, focusedPath.value)) return;
|
|
183
|
+
getItemElement(targetPath)?.scrollIntoView?.({ block: "nearest" });
|
|
184
|
+
});
|
|
185
|
+
});
|
|
186
|
+
return {
|
|
187
|
+
activeDescendantId,
|
|
188
|
+
focusMenu,
|
|
189
|
+
focusTrigger,
|
|
190
|
+
getItemId,
|
|
191
|
+
getSubmenuId,
|
|
192
|
+
getItemElement,
|
|
193
|
+
getSubmenuElement,
|
|
194
|
+
isSubmenuOpeningLeft,
|
|
195
|
+
getMenuActiveDescendant
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
//#endregion
|
|
199
|
+
//#region src/components/dropdown-menu/useDropdownMenuHoverIntent.ts
|
|
200
|
+
var SAFE_TRIANGLE_PADDING = 2;
|
|
201
|
+
var SAFE_TRIANGLE_ORIGIN_OFFSET = 2;
|
|
202
|
+
var SAFE_TRIANGLE_TIMEOUT = 400;
|
|
203
|
+
function getTriangleArea(a, b, c) {
|
|
204
|
+
return Math.abs((a.x * (b.y - c.y) + b.x * (c.y - a.y) + c.x * (a.y - b.y)) / 2);
|
|
205
|
+
}
|
|
206
|
+
function isPointInTriangle(point, triangle) {
|
|
207
|
+
const [a, b, c] = triangle;
|
|
208
|
+
const area = getTriangleArea(a, b, c);
|
|
209
|
+
const area1 = getTriangleArea(point, b, c);
|
|
210
|
+
const area2 = getTriangleArea(a, point, c);
|
|
211
|
+
const area3 = getTriangleArea(a, b, point);
|
|
212
|
+
return Math.abs(area - (area1 + area2 + area3)) < .5;
|
|
213
|
+
}
|
|
214
|
+
function clamp(value, min, max) {
|
|
215
|
+
return Math.min(Math.max(value, min), max);
|
|
216
|
+
}
|
|
217
|
+
function clampPointToRect(point, rect) {
|
|
218
|
+
return {
|
|
219
|
+
x: clamp(point.x, rect.left, rect.right),
|
|
220
|
+
y: clamp(point.y, rect.top, rect.bottom)
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
function getDropdownMenuSafeTriangle({ itemRect, submenuRect, origin }) {
|
|
224
|
+
const measuredItemRect = itemRect && hasMeasuredRect(itemRect) ? itemRect : null;
|
|
225
|
+
const opensRight = !measuredItemRect || submenuRect.left >= measuredItemRect.right;
|
|
226
|
+
const edgeX = opensRight ? submenuRect.left : submenuRect.right;
|
|
227
|
+
const boundedOrigin = measuredItemRect ? clampPointToRect(origin, measuredItemRect) : origin;
|
|
228
|
+
return [
|
|
229
|
+
{
|
|
230
|
+
x: boundedOrigin.x + (opensRight ? -2 : SAFE_TRIANGLE_ORIGIN_OFFSET),
|
|
231
|
+
y: boundedOrigin.y
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
x: edgeX,
|
|
235
|
+
y: submenuRect.top - SAFE_TRIANGLE_PADDING
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
x: edgeX,
|
|
239
|
+
y: submenuRect.bottom + SAFE_TRIANGLE_PADDING
|
|
240
|
+
}
|
|
241
|
+
];
|
|
242
|
+
}
|
|
243
|
+
function useDropdownMenuHoverIntent({ openSubmenuPath, getItemElement, getSubmenuElement }) {
|
|
244
|
+
const safeTriangleOrigin = ref(null);
|
|
245
|
+
let latestPointerPoint = null;
|
|
246
|
+
let pendingHover = null;
|
|
247
|
+
let pendingHoverTimer;
|
|
248
|
+
function clearPendingHover() {
|
|
249
|
+
pendingHover = null;
|
|
250
|
+
if (pendingHoverTimer !== void 0) {
|
|
251
|
+
window.clearTimeout(pendingHoverTimer);
|
|
252
|
+
pendingHoverTimer = void 0;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
function resetHoverIntent() {
|
|
256
|
+
safeTriangleOrigin.value = null;
|
|
257
|
+
latestPointerPoint = null;
|
|
258
|
+
clearPendingHover();
|
|
259
|
+
}
|
|
260
|
+
function getFallbackTriangleOrigin(path) {
|
|
261
|
+
const itemRect = getItemElement(path)?.getBoundingClientRect();
|
|
262
|
+
if (!itemRect) return null;
|
|
263
|
+
const submenuRect = getSubmenuElement(path)?.getBoundingClientRect();
|
|
264
|
+
return {
|
|
265
|
+
x: !submenuRect || submenuRect.left >= itemRect.right ? itemRect.right : itemRect.left,
|
|
266
|
+
y: itemRect.top + itemRect.height / 2
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
function trackSubmenuOpen(path, point) {
|
|
270
|
+
safeTriangleOrigin.value = point ?? getFallbackTriangleOrigin(path);
|
|
271
|
+
clearPendingHover();
|
|
272
|
+
}
|
|
273
|
+
function isPointInCurrentSubmenu(point) {
|
|
274
|
+
if (openSubmenuPath.value.length === 0) return false;
|
|
275
|
+
const submenuRect = getSubmenuElement(openSubmenuPath.value)?.getBoundingClientRect();
|
|
276
|
+
return submenuRect ? isPointInRect(point, submenuRect, SAFE_TRIANGLE_PADDING) : false;
|
|
277
|
+
}
|
|
278
|
+
function getSafeTriangle(path) {
|
|
279
|
+
const submenuRect = getSubmenuElement(path)?.getBoundingClientRect();
|
|
280
|
+
const itemRect = getItemElement(path)?.getBoundingClientRect();
|
|
281
|
+
const origin = safeTriangleOrigin.value ?? getFallbackTriangleOrigin(path);
|
|
282
|
+
if (!submenuRect || !origin) return null;
|
|
283
|
+
return getDropdownMenuSafeTriangle({
|
|
284
|
+
itemRect: itemRect ?? null,
|
|
285
|
+
submenuRect,
|
|
286
|
+
origin
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
function updateSafeTriangleOrigin(point) {
|
|
290
|
+
if (openSubmenuPath.value.length === 0) return;
|
|
291
|
+
const itemRect = getItemElement(openSubmenuPath.value)?.getBoundingClientRect();
|
|
292
|
+
if (itemRect && isPointInRect(point, itemRect)) safeTriangleOrigin.value = point;
|
|
293
|
+
}
|
|
294
|
+
function shouldDelayHover(path, point) {
|
|
295
|
+
if (openSubmenuPath.value.length === 0) return false;
|
|
296
|
+
if (arePathsEqual(path, openSubmenuPath.value)) return false;
|
|
297
|
+
if (isPathPrefix(openSubmenuPath.value, path)) return false;
|
|
298
|
+
if (isPointInCurrentSubmenu(point)) return true;
|
|
299
|
+
const triangle = getSafeTriangle(openSubmenuPath.value);
|
|
300
|
+
return triangle ? isPointInTriangle(point, triangle) : false;
|
|
301
|
+
}
|
|
302
|
+
function delayHoveredItem(item, path, commit) {
|
|
303
|
+
pendingHover = {
|
|
304
|
+
item,
|
|
305
|
+
path
|
|
306
|
+
};
|
|
307
|
+
if (pendingHoverTimer !== void 0) window.clearTimeout(pendingHoverTimer);
|
|
308
|
+
pendingHoverTimer = window.setTimeout(() => {
|
|
309
|
+
if (!pendingHover) return;
|
|
310
|
+
const nextHover = pendingHover;
|
|
311
|
+
if (latestPointerPoint && isPointInCurrentSubmenu(latestPointerPoint)) {
|
|
312
|
+
clearPendingHover();
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
commit(nextHover.item, nextHover.path);
|
|
316
|
+
}, SAFE_TRIANGLE_TIMEOUT);
|
|
317
|
+
}
|
|
318
|
+
function handleItemHover(item, path, event, commit) {
|
|
319
|
+
const point = event ? getEventPoint(event) : void 0;
|
|
320
|
+
latestPointerPoint = point ?? latestPointerPoint;
|
|
321
|
+
if (point && shouldDelayHover(path, point)) {
|
|
322
|
+
delayHoveredItem(item, path, commit);
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
commit(item, path, point);
|
|
326
|
+
}
|
|
327
|
+
function handleMenuMousemove(event, commit) {
|
|
328
|
+
const point = getEventPoint(event);
|
|
329
|
+
latestPointerPoint = point;
|
|
330
|
+
updateSafeTriangleOrigin(point);
|
|
331
|
+
if (!pendingHover) return;
|
|
332
|
+
if (shouldDelayHover(pendingHover.path, point)) return;
|
|
333
|
+
const nextHover = pendingHover;
|
|
334
|
+
commit(nextHover.item, nextHover.path, point);
|
|
335
|
+
}
|
|
336
|
+
onUnmounted(clearPendingHover);
|
|
337
|
+
return {
|
|
338
|
+
clearPendingHover,
|
|
339
|
+
resetHoverIntent,
|
|
340
|
+
trackSubmenuOpen,
|
|
341
|
+
handleItemHover,
|
|
342
|
+
handleMenuMousemove
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
//#endregion
|
|
346
|
+
//#region src/components/dropdown-menu/useDropdownMenuInteractions.ts
|
|
347
|
+
function useDropdownMenuInteractions({ props, emit, isDisabled, focusedPath, openSubmenuPath, getItemAtPath, focusItem, moveFocus, submenus, hoverIntent, disclosure, isSubmenuOpeningLeft }) {
|
|
348
|
+
function activateItem(item, path, event) {
|
|
349
|
+
if (item.disabled) return;
|
|
350
|
+
if (hasItemSubmenu(item)) {
|
|
351
|
+
openSubmenu(path, DEFAULT_FOCUS_TARGET, event ? getEventPoint(event) : void 0);
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
selectItem(item);
|
|
355
|
+
}
|
|
356
|
+
function selectItem(item) {
|
|
357
|
+
if (item.disabled) return;
|
|
358
|
+
emit.select?.(item);
|
|
359
|
+
if (props.closeOnSelect !== false) disclosure.close({ focusTrigger: true });
|
|
360
|
+
}
|
|
361
|
+
function closeSubmenusAfter(menuPath) {
|
|
362
|
+
submenus.closeSubmenusAfter(menuPath);
|
|
363
|
+
hoverIntent.resetHoverIntent();
|
|
364
|
+
}
|
|
365
|
+
function openSubmenu(path, focus = DEFAULT_FOCUS_TARGET, point) {
|
|
366
|
+
const opened = submenus.openSubmenu(path, focus);
|
|
367
|
+
if (opened) hoverIntent.trackSubmenuOpen(path, point);
|
|
368
|
+
return opened;
|
|
369
|
+
}
|
|
370
|
+
function closeSubmenu(path) {
|
|
371
|
+
const closed = submenus.closeSubmenu(path);
|
|
372
|
+
if (closed) hoverIntent.resetHoverIntent();
|
|
373
|
+
return closed;
|
|
374
|
+
}
|
|
375
|
+
function closeCurrentSubmenu() {
|
|
376
|
+
const closed = submenus.closeCurrentSubmenu();
|
|
377
|
+
if (closed) hoverIntent.resetHoverIntent();
|
|
378
|
+
return closed;
|
|
379
|
+
}
|
|
380
|
+
function commitHoveredItem(item, path, point) {
|
|
381
|
+
hoverIntent.clearPendingHover();
|
|
382
|
+
focusedPath.value = [...path];
|
|
383
|
+
if (hasItemSubmenu(item)) openSubmenu(path, false, point);
|
|
384
|
+
else closeSubmenusAfter(getParentPath(path));
|
|
385
|
+
}
|
|
386
|
+
function focusHoveredItem(item, indexOrPath, event) {
|
|
387
|
+
if (item.disabled) return;
|
|
388
|
+
const path = normalizePath(indexOrPath);
|
|
389
|
+
hoverIntent.handleItemHover(item, path, event, commitHoveredItem);
|
|
390
|
+
}
|
|
391
|
+
function selectFocusedItem() {
|
|
392
|
+
const item = getItemAtPath(focusedPath.value);
|
|
393
|
+
if (!item) return;
|
|
394
|
+
activateItem(item, focusedPath.value);
|
|
395
|
+
}
|
|
396
|
+
function moveFocusedItem(direction) {
|
|
397
|
+
const menuPath = moveFocus(direction);
|
|
398
|
+
if (menuPath) closeSubmenusAfter(menuPath);
|
|
399
|
+
}
|
|
400
|
+
function onTriggerClick() {
|
|
401
|
+
disclosure.toggle();
|
|
402
|
+
}
|
|
403
|
+
function onTriggerKeydown(event) {
|
|
404
|
+
if (isDisabled.value) return;
|
|
405
|
+
switch (event.key) {
|
|
406
|
+
case "Enter":
|
|
407
|
+
case " ":
|
|
408
|
+
case "ArrowDown":
|
|
409
|
+
event.preventDefault();
|
|
410
|
+
disclosure.open();
|
|
411
|
+
break;
|
|
412
|
+
case "ArrowUp":
|
|
413
|
+
event.preventDefault();
|
|
414
|
+
disclosure.open({ focus: "last" });
|
|
415
|
+
break;
|
|
416
|
+
case "Escape":
|
|
417
|
+
disclosure.close({ focusTrigger: true });
|
|
418
|
+
break;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
function onMenuKeydown(event) {
|
|
422
|
+
hoverIntent.resetHoverIntent();
|
|
423
|
+
switch (event.key) {
|
|
424
|
+
case "ArrowDown":
|
|
425
|
+
event.preventDefault();
|
|
426
|
+
moveFocusedItem(1);
|
|
427
|
+
break;
|
|
428
|
+
case "ArrowUp":
|
|
429
|
+
event.preventDefault();
|
|
430
|
+
moveFocusedItem(-1);
|
|
431
|
+
break;
|
|
432
|
+
case "Home":
|
|
433
|
+
event.preventDefault();
|
|
434
|
+
focusItem("first", getParentPath(focusedPath.value));
|
|
435
|
+
break;
|
|
436
|
+
case "End":
|
|
437
|
+
event.preventDefault();
|
|
438
|
+
focusItem("last", getParentPath(focusedPath.value));
|
|
439
|
+
break;
|
|
440
|
+
case "ArrowRight":
|
|
441
|
+
case "ArrowLeft":
|
|
442
|
+
onMenuHorizontalKeydown(event);
|
|
443
|
+
break;
|
|
444
|
+
case "Enter":
|
|
445
|
+
case " ":
|
|
446
|
+
event.preventDefault();
|
|
447
|
+
selectFocusedItem();
|
|
448
|
+
break;
|
|
449
|
+
case "Escape":
|
|
450
|
+
event.preventDefault();
|
|
451
|
+
if (!closeCurrentSubmenu()) disclosure.close({ focusTrigger: true });
|
|
452
|
+
break;
|
|
453
|
+
case "Tab":
|
|
454
|
+
disclosure.close();
|
|
455
|
+
break;
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
function onMenuHorizontalKeydown(event) {
|
|
459
|
+
const isRight = event.key === "ArrowRight";
|
|
460
|
+
const currentMenuPath = getParentPath(focusedPath.value);
|
|
461
|
+
const closePath = focusedPath.value.length > 1 ? currentMenuPath : arePathsEqual(focusedPath.value, openSubmenuPath.value) ? focusedPath.value : void 0;
|
|
462
|
+
if (closePath && isRight === isSubmenuOpeningLeft(closePath)) {
|
|
463
|
+
event.preventDefault();
|
|
464
|
+
closeSubmenu(closePath);
|
|
465
|
+
return;
|
|
466
|
+
}
|
|
467
|
+
const item = getItemAtPath(focusedPath.value);
|
|
468
|
+
if (!item || item.disabled || !hasItemSubmenu(item)) return;
|
|
469
|
+
if (isRight === isSubmenuOpeningLeft(focusedPath.value)) return;
|
|
470
|
+
event.preventDefault();
|
|
471
|
+
openSubmenu(focusedPath.value);
|
|
472
|
+
}
|
|
473
|
+
function onMenuMousemove(event) {
|
|
474
|
+
hoverIntent.handleMenuMousemove(event, commitHoveredItem);
|
|
475
|
+
}
|
|
476
|
+
function onMenuMouseleave() {
|
|
477
|
+
hoverIntent.resetHoverIntent();
|
|
478
|
+
}
|
|
479
|
+
return {
|
|
480
|
+
activateItem,
|
|
481
|
+
selectItem,
|
|
482
|
+
openSubmenu,
|
|
483
|
+
closeSubmenu,
|
|
484
|
+
focusHoveredItem,
|
|
485
|
+
onTriggerClick,
|
|
486
|
+
onTriggerKeydown,
|
|
487
|
+
onMenuKeydown,
|
|
488
|
+
onMenuMousemove,
|
|
489
|
+
onMenuMouseleave
|
|
490
|
+
};
|
|
491
|
+
}
|
|
492
|
+
//#endregion
|
|
493
|
+
//#region src/components/dropdown-menu/useDropdownMenuNavigation.ts
|
|
494
|
+
function useDropdownMenuNavigation(items) {
|
|
495
|
+
const focusedPath = ref([]);
|
|
496
|
+
const focusedIndex = computed(() => focusedPath.value[0] ?? -1);
|
|
497
|
+
function getItemsAtPath(path) {
|
|
498
|
+
let currentItems = items.value;
|
|
499
|
+
for (const index of path) {
|
|
500
|
+
const item = currentItems[index];
|
|
501
|
+
if (!item) return [];
|
|
502
|
+
currentItems = item.children ?? [];
|
|
503
|
+
}
|
|
504
|
+
return currentItems;
|
|
505
|
+
}
|
|
506
|
+
function getItemAtPath(path) {
|
|
507
|
+
if (path.length === 0) return void 0;
|
|
508
|
+
return getItemsAtPath(getParentPath(path))[path[path.length - 1]];
|
|
509
|
+
}
|
|
510
|
+
function focusItem(target, menuPath = []) {
|
|
511
|
+
const enabledIndexes = getEnabledIndexes(getItemsAtPath(menuPath));
|
|
512
|
+
const index = target === "last" ? enabledIndexes[enabledIndexes.length - 1] : enabledIndexes[0];
|
|
513
|
+
if (index === void 0) {
|
|
514
|
+
if (menuPath.length === 0) focusedPath.value = [];
|
|
515
|
+
return false;
|
|
516
|
+
}
|
|
517
|
+
focusedPath.value = [...menuPath, index];
|
|
518
|
+
return true;
|
|
519
|
+
}
|
|
520
|
+
function resetFocus() {
|
|
521
|
+
focusedPath.value = [];
|
|
522
|
+
}
|
|
523
|
+
function isItemFocused(indexOrPath) {
|
|
524
|
+
return arePathsEqual(normalizePath(indexOrPath), focusedPath.value);
|
|
525
|
+
}
|
|
526
|
+
function moveFocus(direction) {
|
|
527
|
+
const menuPath = getParentPath(focusedPath.value);
|
|
528
|
+
const itemsAtPath = getItemsAtPath(menuPath);
|
|
529
|
+
const nextIndex = getNextEnabledIndex(itemsAtPath, focusedPath.value.length === 0 ? direction === 1 ? -1 : itemsAtPath.length : focusedPath.value[focusedPath.value.length - 1], direction);
|
|
530
|
+
if (nextIndex === void 0) {
|
|
531
|
+
focusedPath.value = [];
|
|
532
|
+
return;
|
|
533
|
+
}
|
|
534
|
+
focusedPath.value = [...menuPath, nextIndex];
|
|
535
|
+
return menuPath;
|
|
536
|
+
}
|
|
537
|
+
return {
|
|
538
|
+
focusedPath,
|
|
539
|
+
focusedIndex,
|
|
540
|
+
getItemsAtPath,
|
|
541
|
+
getItemAtPath,
|
|
542
|
+
focusItem,
|
|
543
|
+
resetFocus,
|
|
544
|
+
isItemFocused,
|
|
545
|
+
moveFocus
|
|
546
|
+
};
|
|
547
|
+
}
|
|
548
|
+
//#endregion
|
|
549
|
+
//#region src/components/dropdown-menu/useDropdownMenuRenderItems.ts
|
|
550
|
+
function useDropdownMenuRenderItems({ items, getItemId, getSubmenuId, getMenuActiveDescendant, isItemFocused, isSubmenuOpen, activateItem, focusHoveredItem, selectItem, openSubmenu, closeSubmenu, close }) {
|
|
551
|
+
const renderedItems = computed(() => getRenderedItems(items.value));
|
|
552
|
+
function getRenderedItems(dropdownItems, parentPath = []) {
|
|
553
|
+
return dropdownItems.map((item, index) => {
|
|
554
|
+
const path = [...parentPath, index];
|
|
555
|
+
const level = parentPath.length;
|
|
556
|
+
const focused = isItemFocused(path);
|
|
557
|
+
const disabled = Boolean(item.disabled);
|
|
558
|
+
const hasSubmenu = hasItemSubmenu(item);
|
|
559
|
+
const submenuOpen = hasSubmenu && isSubmenuOpen(path);
|
|
560
|
+
return {
|
|
561
|
+
item,
|
|
562
|
+
index,
|
|
563
|
+
key: `${getPathKey(path)}:${String(item.value)}`,
|
|
564
|
+
path,
|
|
565
|
+
level,
|
|
566
|
+
focused,
|
|
567
|
+
disabled,
|
|
568
|
+
hasSubmenu,
|
|
569
|
+
submenuOpen,
|
|
570
|
+
props: getItemProps(item, path, focused, disabled),
|
|
571
|
+
submenuProps: hasSubmenu ? getSubmenuProps(item, path) : void 0,
|
|
572
|
+
slotProps: getItemSlotProps(item, path, focused, disabled),
|
|
573
|
+
children: hasSubmenu ? getRenderedItems(item.children ?? [], path) : []
|
|
574
|
+
};
|
|
575
|
+
});
|
|
576
|
+
}
|
|
577
|
+
function getItemProps(item, indexOrPath, focused = isItemFocused(indexOrPath), disabled = Boolean(item.disabled)) {
|
|
578
|
+
const path = normalizePath(indexOrPath);
|
|
579
|
+
const hasSubmenu = hasItemSubmenu(item);
|
|
580
|
+
const submenuOpen = hasSubmenu && isSubmenuOpen(path);
|
|
581
|
+
return {
|
|
582
|
+
id: getItemId(path),
|
|
583
|
+
type: "button",
|
|
584
|
+
role: "menuitem",
|
|
585
|
+
tabindex: -1,
|
|
586
|
+
class: getItemClass(item, focused, disabled, hasSubmenu, submenuOpen),
|
|
587
|
+
"aria-controls": hasSubmenu ? getSubmenuId(path) : void 0,
|
|
588
|
+
"aria-expanded": hasSubmenu ? submenuOpen : void 0,
|
|
589
|
+
"aria-haspopup": hasSubmenu ? "menu" : void 0,
|
|
590
|
+
"aria-disabled": disabled || void 0,
|
|
591
|
+
"data-disabled": disabled || void 0,
|
|
592
|
+
"data-focused": focused || void 0,
|
|
593
|
+
"data-submenu": hasSubmenu || void 0,
|
|
594
|
+
onClick: (event) => activateItem(item, path, event),
|
|
595
|
+
onMouseenter: (event) => focusHoveredItem(item, path, event)
|
|
596
|
+
};
|
|
597
|
+
}
|
|
598
|
+
function getSubmenuProps(item, path) {
|
|
599
|
+
return {
|
|
600
|
+
id: getSubmenuId(path),
|
|
601
|
+
role: "menu",
|
|
602
|
+
class: bem("rp-dropdown-menu__submenu", {
|
|
603
|
+
open: isSubmenuOpen(path),
|
|
604
|
+
"has-submenu": hasNestedItems(item.children ?? [])
|
|
605
|
+
}),
|
|
606
|
+
"aria-label": item.label,
|
|
607
|
+
"aria-activedescendant": getMenuActiveDescendant(path)
|
|
608
|
+
};
|
|
609
|
+
}
|
|
610
|
+
function getItemSlotProps(item, indexOrPath, focused = isItemFocused(indexOrPath), disabled = Boolean(item.disabled)) {
|
|
611
|
+
const path = normalizePath(indexOrPath);
|
|
612
|
+
const hasSubmenu = hasItemSubmenu(item);
|
|
613
|
+
return {
|
|
614
|
+
item,
|
|
615
|
+
index: path[path.length - 1] ?? -1,
|
|
616
|
+
path,
|
|
617
|
+
level: path.length - 1,
|
|
618
|
+
focused,
|
|
619
|
+
disabled,
|
|
620
|
+
hasSubmenu,
|
|
621
|
+
isSubmenuOpen: hasSubmenu && isSubmenuOpen(path),
|
|
622
|
+
select: () => selectItem(item),
|
|
623
|
+
openSubmenu: (focus = DEFAULT_FOCUS_TARGET) => openSubmenu(path, focus),
|
|
624
|
+
closeSubmenu: () => closeSubmenu(path),
|
|
625
|
+
close
|
|
626
|
+
};
|
|
627
|
+
}
|
|
628
|
+
return {
|
|
629
|
+
renderedItems,
|
|
630
|
+
getItemProps,
|
|
631
|
+
getItemSlotProps
|
|
632
|
+
};
|
|
633
|
+
}
|
|
634
|
+
//#endregion
|
|
635
|
+
//#region src/components/dropdown-menu/useDropdownSubmenus.ts
|
|
636
|
+
function useDropdownSubmenus({ focusedPath, getItemAtPath, focusItem }) {
|
|
637
|
+
const openSubmenuPath = ref([]);
|
|
638
|
+
function resetSubmenus() {
|
|
639
|
+
openSubmenuPath.value = [];
|
|
640
|
+
}
|
|
641
|
+
function isSubmenuOpen(path) {
|
|
642
|
+
return path.length > 0 && isPathPrefix(path, openSubmenuPath.value);
|
|
643
|
+
}
|
|
644
|
+
function closeSubmenusAfter(menuPath) {
|
|
645
|
+
openSubmenuPath.value = [...menuPath];
|
|
646
|
+
}
|
|
647
|
+
function openSubmenu(path, focus = DEFAULT_FOCUS_TARGET) {
|
|
648
|
+
const item = getItemAtPath(path);
|
|
649
|
+
if (!item || item.disabled || !hasItemSubmenu(item)) return false;
|
|
650
|
+
openSubmenuPath.value = [...path];
|
|
651
|
+
if (focus && !focusItem(focus, path)) focusedPath.value = [...path];
|
|
652
|
+
return true;
|
|
653
|
+
}
|
|
654
|
+
function closeSubmenu(path) {
|
|
655
|
+
if (!isSubmenuOpen(path)) return false;
|
|
656
|
+
openSubmenuPath.value = getParentPath(path);
|
|
657
|
+
if (isPathPrefix(path, focusedPath.value) && focusedPath.value.length > path.length) focusedPath.value = [...path];
|
|
658
|
+
return true;
|
|
659
|
+
}
|
|
660
|
+
function closeCurrentSubmenu() {
|
|
661
|
+
const path = focusedPath.value.length > 1 ? getParentPath(focusedPath.value) : focusedPath.value;
|
|
662
|
+
if (path.length === 0 || !isSubmenuOpen(path)) return false;
|
|
663
|
+
return closeSubmenu(path);
|
|
664
|
+
}
|
|
665
|
+
return {
|
|
666
|
+
openSubmenuPath,
|
|
667
|
+
resetSubmenus,
|
|
668
|
+
isSubmenuOpen,
|
|
669
|
+
closeSubmenusAfter,
|
|
670
|
+
openSubmenu,
|
|
671
|
+
closeSubmenu,
|
|
672
|
+
closeCurrentSubmenu
|
|
673
|
+
};
|
|
674
|
+
}
|
|
675
|
+
//#endregion
|
|
676
|
+
//#region src/components/dropdown-menu/useDropdownMenu.ts
|
|
677
|
+
function useDropdownMenu(props, emit = {}) {
|
|
678
|
+
const rootRef = ref(null);
|
|
679
|
+
const menuRef = ref(null);
|
|
680
|
+
const uncontrolledOpen = ref(false);
|
|
681
|
+
const generatedId = useId();
|
|
682
|
+
const menuId = computed(() => props.id ?? `${generatedId}-menu`);
|
|
683
|
+
const placement = computed(() => props.placement ?? "bottom-start");
|
|
684
|
+
const visibleItems = computed(() => props.items ?? []);
|
|
685
|
+
const isDisabled = computed(() => Boolean(props.disabled));
|
|
686
|
+
const isOpen = computed(() => props.open ?? uncontrolledOpen.value);
|
|
687
|
+
const isVisible = computed(() => isOpen.value && !isDisabled.value);
|
|
688
|
+
const contentHasSubmenu = computed(() => hasNestedItems(visibleItems.value));
|
|
689
|
+
const isEmpty = computed(() => visibleItems.value.length === 0);
|
|
690
|
+
const { focusedPath, focusedIndex, getItemAtPath, focusItem, resetFocus, isItemFocused, moveFocus } = useDropdownMenuNavigation(visibleItems);
|
|
691
|
+
const submenus = useDropdownSubmenus({
|
|
692
|
+
focusedPath,
|
|
693
|
+
getItemAtPath,
|
|
694
|
+
focusItem
|
|
695
|
+
});
|
|
696
|
+
const { openSubmenuPath, isSubmenuOpen } = submenus;
|
|
697
|
+
const { activeDescendantId, focusMenu, focusTrigger, getItemId, getSubmenuId, getItemElement, getSubmenuElement, isSubmenuOpeningLeft, getMenuActiveDescendant } = useDropdownMenuDom({
|
|
698
|
+
menuId,
|
|
699
|
+
rootRef,
|
|
700
|
+
menuRef,
|
|
701
|
+
placement,
|
|
702
|
+
focusedPath
|
|
703
|
+
});
|
|
704
|
+
const hoverIntent = useDropdownMenuHoverIntent({
|
|
705
|
+
openSubmenuPath,
|
|
706
|
+
getItemElement,
|
|
707
|
+
getSubmenuElement
|
|
708
|
+
});
|
|
709
|
+
const disclosure = useDropdownMenuDisclosure({
|
|
710
|
+
props,
|
|
711
|
+
emit,
|
|
712
|
+
rootRef,
|
|
713
|
+
uncontrolledOpen,
|
|
714
|
+
isDisabled,
|
|
715
|
+
isOpen,
|
|
716
|
+
isVisible,
|
|
717
|
+
focusedPath,
|
|
718
|
+
resetFocus,
|
|
719
|
+
resetSubmenus: submenus.resetSubmenus,
|
|
720
|
+
resetHoverIntent: hoverIntent.resetHoverIntent,
|
|
721
|
+
focusItem,
|
|
722
|
+
focusMenu,
|
|
723
|
+
focusTrigger
|
|
724
|
+
});
|
|
725
|
+
const { open, close, toggle } = disclosure;
|
|
726
|
+
const { activateItem, selectItem, openSubmenu, closeSubmenu, focusHoveredItem, onTriggerClick, onTriggerKeydown, onMenuKeydown, onMenuMousemove, onMenuMouseleave } = useDropdownMenuInteractions({
|
|
727
|
+
props,
|
|
728
|
+
emit,
|
|
729
|
+
isDisabled,
|
|
730
|
+
focusedPath,
|
|
731
|
+
openSubmenuPath,
|
|
732
|
+
getItemAtPath,
|
|
733
|
+
focusItem,
|
|
734
|
+
moveFocus,
|
|
735
|
+
submenus,
|
|
736
|
+
hoverIntent,
|
|
737
|
+
disclosure,
|
|
738
|
+
isSubmenuOpeningLeft
|
|
739
|
+
});
|
|
740
|
+
const rootClass = computed(() => bem("rp-dropdown-menu", {
|
|
741
|
+
[`placement-${placement.value}`]: true,
|
|
742
|
+
open: isVisible.value,
|
|
743
|
+
disabled: isDisabled.value
|
|
744
|
+
}));
|
|
745
|
+
const contentClass = computed(() => bem("rp-dropdown-menu__content", { "has-submenu": contentHasSubmenu.value }));
|
|
746
|
+
const triggerProps = computed(() => ({
|
|
747
|
+
"aria-controls": isDisabled.value ? void 0 : menuId.value,
|
|
748
|
+
"aria-expanded": isDisabled.value ? void 0 : isVisible.value,
|
|
749
|
+
"aria-haspopup": "menu",
|
|
750
|
+
disabled: isDisabled.value || void 0,
|
|
751
|
+
onClick: onTriggerClick,
|
|
752
|
+
onKeydown: onTriggerKeydown
|
|
753
|
+
}));
|
|
754
|
+
const contentProps = computed(() => ({
|
|
755
|
+
id: menuId.value,
|
|
756
|
+
role: "menu",
|
|
757
|
+
tabindex: -1,
|
|
758
|
+
"aria-label": props.ariaLabel || void 0,
|
|
759
|
+
"aria-activedescendant": activeDescendantId.value,
|
|
760
|
+
onKeydown: onMenuKeydown,
|
|
761
|
+
onMousemove: onMenuMousemove,
|
|
762
|
+
onMouseleave: onMenuMouseleave
|
|
763
|
+
}));
|
|
764
|
+
const slotProps = computed(() => ({
|
|
765
|
+
triggerProps: triggerProps.value,
|
|
766
|
+
isOpen: isVisible.value,
|
|
767
|
+
open,
|
|
768
|
+
close,
|
|
769
|
+
toggle
|
|
770
|
+
}));
|
|
771
|
+
const { renderedItems, getItemProps, getItemSlotProps } = useDropdownMenuRenderItems({
|
|
772
|
+
items: visibleItems,
|
|
773
|
+
getItemId,
|
|
774
|
+
getSubmenuId,
|
|
775
|
+
getMenuActiveDescendant,
|
|
776
|
+
isItemFocused,
|
|
777
|
+
isSubmenuOpen,
|
|
778
|
+
activateItem,
|
|
779
|
+
focusHoveredItem,
|
|
780
|
+
selectItem,
|
|
781
|
+
openSubmenu,
|
|
782
|
+
closeSubmenu,
|
|
783
|
+
close
|
|
784
|
+
});
|
|
785
|
+
return {
|
|
786
|
+
rootRef,
|
|
787
|
+
menuRef,
|
|
788
|
+
menuId,
|
|
789
|
+
isVisible,
|
|
790
|
+
isEmpty,
|
|
791
|
+
visibleItems,
|
|
792
|
+
renderedItems,
|
|
793
|
+
focusedIndex,
|
|
794
|
+
focusedPath,
|
|
795
|
+
activeDescendantId,
|
|
796
|
+
rootClass,
|
|
797
|
+
contentClass,
|
|
798
|
+
triggerProps,
|
|
799
|
+
contentProps,
|
|
800
|
+
slotProps,
|
|
801
|
+
open,
|
|
802
|
+
close,
|
|
803
|
+
toggle,
|
|
804
|
+
selectItem,
|
|
805
|
+
openSubmenu,
|
|
806
|
+
closeSubmenu,
|
|
807
|
+
onItemMouseenter: focusHoveredItem,
|
|
808
|
+
onTriggerKeydown,
|
|
809
|
+
onMenuKeydown,
|
|
810
|
+
getItemProps,
|
|
811
|
+
getItemSlotProps
|
|
812
|
+
};
|
|
813
|
+
}
|
|
814
|
+
//#endregion
|
|
815
|
+
//#region src/components/dropdown-menu/dropdown-menu.vue?vue&type=script&setup=true&vapor=true&lang.ts
|
|
816
|
+
var t0 = template("No actions", 2);
|
|
817
|
+
var t1 = template("<div class=rp-dropdown-menu__empty>");
|
|
818
|
+
var t2 = template("<span class=rp-dropdown-menu__label> </span>");
|
|
819
|
+
var t3 = template("<kbd class=rp-dropdown-menu__shortcut> ");
|
|
820
|
+
var t4 = template("<span class=rp-dropdown-menu__submenu-icon aria-hidden=true>");
|
|
821
|
+
var t5 = template("<div>");
|
|
822
|
+
var t6 = template("<span>", 1);
|
|
823
|
+
//#endregion
|
|
824
|
+
//#region src/components/dropdown-menu/dropdown-menu.vue
|
|
825
|
+
var dropdown_menu_default = /* @__PURE__ */ defineVaporComponent({
|
|
826
|
+
name: "RpDropdownMenu",
|
|
827
|
+
__name: "dropdown-menu",
|
|
828
|
+
props: {
|
|
829
|
+
id: {},
|
|
830
|
+
items: { default: () => [] },
|
|
831
|
+
placement: { default: "bottom-start" },
|
|
832
|
+
open: {
|
|
833
|
+
type: Boolean,
|
|
834
|
+
default: void 0
|
|
835
|
+
},
|
|
836
|
+
disabled: {
|
|
837
|
+
type: Boolean,
|
|
838
|
+
default: false
|
|
839
|
+
},
|
|
840
|
+
closeOnSelect: {
|
|
841
|
+
type: Boolean,
|
|
842
|
+
default: true
|
|
843
|
+
},
|
|
844
|
+
ariaLabel: {}
|
|
845
|
+
},
|
|
846
|
+
emits: ["update:open", "select"],
|
|
847
|
+
setup(__props, { emit: __emit }) {
|
|
848
|
+
const props = __props;
|
|
849
|
+
const emit = __emit;
|
|
850
|
+
const { rootRef, menuRef, isVisible, isEmpty, renderedItems, rootClass, contentClass, contentProps, slotProps } = useDropdownMenu(props, {
|
|
851
|
+
openChange: (open) => emit("update:open", open),
|
|
852
|
+
select: (item) => emit("select", item)
|
|
853
|
+
});
|
|
854
|
+
const _setTemplateRef = createTemplateRefSetter();
|
|
855
|
+
const n23 = t6();
|
|
856
|
+
renderEffect(() => setClass(n23, unref(rootClass)));
|
|
857
|
+
setInsertionState(n23, null, 0);
|
|
858
|
+
createSlot("default", { $: [() => unref(slotProps)] });
|
|
859
|
+
setInsertionState(n23, null, 1);
|
|
860
|
+
createComponent(VaporTransition, { name: "rp-dropdown-menu-content" }, extend(() => {
|
|
861
|
+
return createIf(() => unref(isVisible), () => {
|
|
862
|
+
const n21 = t5();
|
|
863
|
+
renderEffect(() => setDynamicProps(n21, [{ class: unref(contentClass) }, unref(contentProps)]));
|
|
864
|
+
setInsertionState(n21, null, 0);
|
|
865
|
+
createIf(() => unref(isEmpty), () => {
|
|
866
|
+
const n8 = t1();
|
|
867
|
+
setInsertionState(n8, null, 0);
|
|
868
|
+
createSlot("empty", null, () => {
|
|
869
|
+
return t0();
|
|
870
|
+
});
|
|
871
|
+
return n8;
|
|
872
|
+
});
|
|
873
|
+
setInsertionState(n21, null, 1);
|
|
874
|
+
createComponent(unref(dropdown_menu_items_default), { items: () => unref(renderedItems) }, { "item": extend((itemSlotProps) => {
|
|
875
|
+
return [createSlot("item", { $: [() => itemSlotProps] }, () => {
|
|
876
|
+
const n11 = t2();
|
|
877
|
+
const x11 = txt(n11);
|
|
878
|
+
renderEffect(() => setText(x11, toDisplayString(itemSlotProps.item.label)));
|
|
879
|
+
return [n11, createIf(() => itemSlotProps.item.shortcut, () => {
|
|
880
|
+
const n14 = t3();
|
|
881
|
+
const x14 = txt(n14);
|
|
882
|
+
renderEffect(() => setText(x14, toDisplayString(itemSlotProps.item.shortcut)));
|
|
883
|
+
return n14;
|
|
884
|
+
}, null, 129)];
|
|
885
|
+
}), createIf(() => itemSlotProps.hasSubmenu, () => {
|
|
886
|
+
const n18 = t4();
|
|
887
|
+
setInsertionState(n18, null, 0);
|
|
888
|
+
createComponent(unref(chevron_right_default));
|
|
889
|
+
return n18;
|
|
890
|
+
}, null, 129)];
|
|
891
|
+
}, { _: 8 }) });
|
|
892
|
+
_setTemplateRef(n21, menuRef, null, "menuRef");
|
|
893
|
+
return n21;
|
|
894
|
+
}, null, 129);
|
|
895
|
+
}, { _: 8 }));
|
|
896
|
+
setStaticTemplateRef(n23, rootRef, null, "rootRef");
|
|
897
|
+
return n23;
|
|
898
|
+
}
|
|
899
|
+
});
|
|
900
|
+
//#endregion
|
|
901
|
+
export { useDropdownMenu as n, dropdown_menu_default as t };
|
|
902
|
+
|
|
903
|
+
//# sourceMappingURL=dropdown-menu.js.map
|