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.
Files changed (127) hide show
  1. package/dist/_plugin-vue_export-helper.js +1 -11
  2. package/dist/accordion.css +112 -0
  3. package/dist/accordion.js +360 -0
  4. package/dist/accordion.js.map +1 -0
  5. package/dist/badge.css +169 -0
  6. package/dist/badge.js +103 -0
  7. package/dist/badge.js.map +1 -0
  8. package/dist/bem.js +11 -0
  9. package/dist/bem.js.map +1 -0
  10. package/dist/button-group.css +8 -8
  11. package/dist/button-group.js +2 -1
  12. package/dist/button-group.js.map +1 -1
  13. package/dist/button.js +3 -2
  14. package/dist/button.js.map +1 -1
  15. package/dist/card.js +2 -1
  16. package/dist/card.js.map +1 -1
  17. package/dist/checkbox.js +2 -1
  18. package/dist/checkbox.js.map +1 -1
  19. package/dist/collapse.css +32 -0
  20. package/dist/collapse.js +68 -0
  21. package/dist/collapse.js.map +1 -0
  22. package/dist/components/accordion/accordion-item.d.ts +40 -0
  23. package/dist/components/accordion/accordion.d.ts +23 -0
  24. package/dist/components/accordion/index.d.ts +4 -0
  25. package/dist/components/accordion/index.js +2 -0
  26. package/dist/components/accordion/types.d.ts +100 -0
  27. package/dist/components/accordion/useAccordion.d.ts +3 -0
  28. package/dist/components/badge/badge.d.ts +25 -0
  29. package/dist/components/badge/index.d.ts +3 -0
  30. package/dist/components/badge/index.js +2 -0
  31. package/dist/components/badge/types.d.ts +16 -0
  32. package/dist/components/badge/useBadgeColor.d.ts +8 -0
  33. package/dist/components/collapse/collapse.d.ts +36 -0
  34. package/dist/components/collapse/index.d.ts +3 -0
  35. package/dist/components/collapse/index.js +3 -0
  36. package/dist/components/collapse/types.d.ts +76 -0
  37. package/dist/components/collapse/useCollapse.d.ts +2 -0
  38. package/dist/components/dropdown-menu/dropdown-menu-items.d.ts +16 -0
  39. package/dist/components/dropdown-menu/dropdown-menu-utils.d.ts +23 -0
  40. package/dist/components/dropdown-menu/dropdown-menu.d.ts +26 -0
  41. package/dist/components/dropdown-menu/index.d.ts +3 -0
  42. package/dist/components/dropdown-menu/index.js +2 -0
  43. package/dist/components/dropdown-menu/types.d.ts +104 -0
  44. package/dist/components/dropdown-menu/useDropdownMenu.d.ts +32 -0
  45. package/dist/components/dropdown-menu/useDropdownMenuDisclosure.d.ts +30 -0
  46. package/dist/components/dropdown-menu/useDropdownMenuDom.d.ts +28 -0
  47. package/dist/components/dropdown-menu/useDropdownMenuHoverIntent.d.ts +24 -0
  48. package/dist/components/dropdown-menu/useDropdownMenuInteractions.d.ts +51 -0
  49. package/dist/components/dropdown-menu/useDropdownMenuNavigation.d.ts +16 -0
  50. package/dist/components/dropdown-menu/useDropdownMenuRenderItems.d.ts +25 -0
  51. package/dist/components/dropdown-menu/useDropdownSubmenus.d.ts +18 -0
  52. package/dist/components/field/field.d.ts +2 -2
  53. package/dist/components/field/useField.d.ts +16 -0
  54. package/dist/components/input/useInput.d.ts +8 -0
  55. package/dist/components/modal/index.d.ts +2 -0
  56. package/dist/components/modal/index.js +2 -0
  57. package/dist/components/modal/modal.d.ts +42 -0
  58. package/dist/components/modal/types.d.ts +32 -0
  59. package/dist/components/modal/useModal.d.ts +29 -0
  60. package/dist/components/overlay/index.d.ts +2 -0
  61. package/dist/components/overlay/index.js +2 -0
  62. package/dist/components/overlay/overlay.d.ts +19 -0
  63. package/dist/components/overlay/types.d.ts +12 -0
  64. package/dist/components/overlay/useOverlay.d.ts +7 -0
  65. package/dist/components/popover/index.d.ts +2 -0
  66. package/dist/components/popover/index.js +2 -0
  67. package/dist/components/popover/popover.d.ts +43 -0
  68. package/dist/components/popover/types.d.ts +40 -0
  69. package/dist/components/popover/usePopover.d.ts +20 -0
  70. package/dist/components/tabs/index.d.ts +6 -0
  71. package/dist/components/tabs/index.js +2 -0
  72. package/dist/components/tabs/tabs-content.d.ts +24 -0
  73. package/dist/components/tabs/tabs-list.d.ts +26 -0
  74. package/dist/components/tabs/tabs-trigger.d.ts +29 -0
  75. package/dist/components/tabs/tabs.d.ts +31 -0
  76. package/dist/components/tabs/types.d.ts +160 -0
  77. package/dist/components/tabs/useTabs.d.ts +5 -0
  78. package/dist/dropdown-menu.css +159 -0
  79. package/dist/dropdown-menu.js +903 -0
  80. package/dist/dropdown-menu.js.map +1 -0
  81. package/dist/field.css +8 -8
  82. package/dist/field.js +68 -50
  83. package/dist/field.js.map +1 -1
  84. package/dist/icon-button.css +1 -1
  85. package/dist/icon-button.js +3 -2
  86. package/dist/icon-button.js.map +1 -1
  87. package/dist/index.d.ts +8 -0
  88. package/dist/index.js +12 -1
  89. package/dist/input.css +25 -25
  90. package/dist/input.js +57 -38
  91. package/dist/input.js.map +1 -1
  92. package/dist/modal.css +134 -0
  93. package/dist/modal.js +433 -0
  94. package/dist/modal.js.map +1 -0
  95. package/dist/overlay.css +28 -0
  96. package/dist/overlay.js +84 -0
  97. package/dist/overlay.js.map +1 -0
  98. package/dist/popover.css +75 -0
  99. package/dist/popover.js +367 -0
  100. package/dist/popover.js.map +1 -0
  101. package/dist/progress.js +2 -1
  102. package/dist/progress.js.map +1 -1
  103. package/dist/radio.js +4 -9
  104. package/dist/radio.js.map +1 -1
  105. package/dist/select.js +8 -37
  106. package/dist/select.js.map +1 -1
  107. package/dist/slider.js +2 -1
  108. package/dist/slider.js.map +1 -1
  109. package/dist/switch.js +2 -1
  110. package/dist/switch.js.map +1 -1
  111. package/dist/tabs.css +279 -0
  112. package/dist/tabs.js +515 -0
  113. package/dist/tabs.js.map +1 -0
  114. package/dist/textarea.js +2 -1
  115. package/dist/textarea.js.map +1 -1
  116. package/dist/tooltip.js +2 -1
  117. package/dist/tooltip.js.map +1 -1
  118. package/dist/useClickOutside.js +26 -0
  119. package/dist/useClickOutside.js.map +1 -0
  120. package/dist/useCollapse.js +94 -0
  121. package/dist/useCollapse.js.map +1 -0
  122. package/dist/useRequiredInject.js +11 -0
  123. package/dist/useRequiredInject.js.map +1 -0
  124. package/dist/x.js +14 -0
  125. package/dist/x.js.map +1 -0
  126. package/package.json +35 -3
  127. 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