ropav 0.0.10 → 0.0.11

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 (227) hide show
  1. package/README.md +6 -0
  2. package/dist/accordion.css +115 -111
  3. package/dist/accordion.js +60 -16
  4. package/dist/alert.css +110 -108
  5. package/dist/alert.js +48 -26
  6. package/dist/aspect-ratio.css +17 -15
  7. package/dist/aspect-ratio.js +20 -6
  8. package/dist/avatar.css +98 -96
  9. package/dist/avatar.js +27 -16
  10. package/dist/badge.css +95 -93
  11. package/dist/badge.js +29 -16
  12. package/dist/base.css +672 -671
  13. package/dist/button-group.css +39 -37
  14. package/dist/button-group.js +23 -12
  15. package/dist/button-link.css +160 -158
  16. package/dist/button-link.js +43 -24
  17. package/dist/button.css +160 -158
  18. package/dist/button.js +37 -19
  19. package/dist/card.css +109 -107
  20. package/dist/card.js +42 -17
  21. package/dist/checkbox.css +139 -137
  22. package/dist/checkbox.js +79 -28
  23. package/dist/collapse.css +29 -27
  24. package/dist/collapse.js +44 -10
  25. package/dist/color-input.css +137 -107
  26. package/dist/color-input.js +86 -17
  27. package/dist/color-picker.css +309 -303
  28. package/dist/color-picker.js +147 -54
  29. package/dist/color-picker2.js +9 -1
  30. package/dist/color-swatch.css +48 -46
  31. package/dist/color-swatch.js +15 -11
  32. package/dist/color-swatch2.js +4 -0
  33. package/dist/components/accordion/accordion-item.d.ts +13 -1
  34. package/dist/components/accordion/index.d.ts +2 -1
  35. package/dist/components/accordion/index.js +2 -2
  36. package/dist/components/accordion/types.d.ts +9 -4
  37. package/dist/components/alert/alert.d.ts +2 -2
  38. package/dist/components/alert/index.d.ts +2 -2
  39. package/dist/components/alert/index.js +2 -2
  40. package/dist/components/alert/types.d.ts +4 -1
  41. package/dist/components/aspect-ratio/index.d.ts +2 -1
  42. package/dist/components/aspect-ratio/index.js +2 -2
  43. package/dist/components/aspect-ratio/types.d.ts +4 -1
  44. package/dist/components/avatar/index.d.ts +2 -2
  45. package/dist/components/avatar/index.js +2 -2
  46. package/dist/components/avatar/types.d.ts +4 -1
  47. package/dist/components/badge/index.d.ts +2 -2
  48. package/dist/components/badge/index.js +2 -2
  49. package/dist/components/badge/types.d.ts +4 -1
  50. package/dist/components/button/index.d.ts +2 -1
  51. package/dist/components/button/index.js +2 -2
  52. package/dist/components/button/types.d.ts +4 -1
  53. package/dist/components/button-group/index.d.ts +2 -1
  54. package/dist/components/button-group/index.js +2 -2
  55. package/dist/components/button-group/types.d.ts +4 -1
  56. package/dist/components/button-link/index.d.ts +2 -1
  57. package/dist/components/button-link/index.js +2 -2
  58. package/dist/components/button-link/types.d.ts +4 -1
  59. package/dist/components/card/index.d.ts +2 -1
  60. package/dist/components/card/index.js +2 -2
  61. package/dist/components/card/types.d.ts +5 -1
  62. package/dist/components/checkbox/checkbox.d.ts +4 -1
  63. package/dist/components/checkbox/index.d.ts +2 -1
  64. package/dist/components/checkbox/index.js +2 -2
  65. package/dist/components/checkbox/types.d.ts +6 -1
  66. package/dist/components/checkbox/useCheckbox.d.ts +2 -0
  67. package/dist/components/collapse/collapse.d.ts +2 -2
  68. package/dist/components/collapse/index.d.ts +2 -1
  69. package/dist/components/collapse/index.js +2 -2
  70. package/dist/components/collapse/types.d.ts +9 -2
  71. package/dist/components/color-input/index.d.ts +2 -1
  72. package/dist/components/color-input/index.js +2 -2
  73. package/dist/components/color-input/types.d.ts +4 -1
  74. package/dist/components/color-picker/index.d.ts +2 -2
  75. package/dist/components/color-picker/index.js +2 -2
  76. package/dist/components/color-picker/types.d.ts +13 -1
  77. package/dist/components/color-swatch/index.d.ts +2 -1
  78. package/dist/components/color-swatch/index.js +2 -1
  79. package/dist/components/color-swatch/types.d.ts +4 -1
  80. package/dist/components/dropdown-menu/dropdown-menu-primitives.d.ts +724 -0
  81. package/dist/components/dropdown-menu/dropdown-menu.d.ts +3 -3
  82. package/dist/components/dropdown-menu/index.d.ts +53 -1
  83. package/dist/components/dropdown-menu/index.js +2 -2
  84. package/dist/components/dropdown-menu/types.d.ts +142 -6
  85. package/dist/components/dropdown-menu/useDropdownMenu.d.ts +11 -3
  86. package/dist/components/dropdown-menu/useDropdownMenuDisclosure.d.ts +5 -3
  87. package/dist/components/dropdown-menu/useDropdownMenuDom.d.ts +2 -1
  88. package/dist/components/dropdown-menu/useDropdownMenuInteractions.d.ts +4 -4
  89. package/dist/components/dropdown-menu/useDropdownMenuPortalPosition.d.ts +19 -0
  90. package/dist/components/dropdown-menu/useDropdownMenuRenderItems.d.ts +14 -2
  91. package/dist/components/field/index.d.ts +2 -1
  92. package/dist/components/field/index.js +2 -2
  93. package/dist/components/field/types.d.ts +4 -1
  94. package/dist/components/floating/index.d.ts +1 -0
  95. package/dist/components/floating/index.js +0 -0
  96. package/dist/components/floating/types.d.ts +31 -0
  97. package/dist/components/floating/useFloatingPosition.d.ts +38 -0
  98. package/dist/components/focus-trap/focus-trap.d.ts +31 -0
  99. package/dist/components/focus-trap/index.d.ts +4 -0
  100. package/dist/components/focus-trap/index.js +3 -0
  101. package/dist/components/focus-trap/types.d.ts +41 -0
  102. package/dist/components/focus-trap/useFocusTrap.d.ts +2 -0
  103. package/dist/components/icon-button/index.d.ts +2 -1
  104. package/dist/components/icon-button/index.js +2 -1
  105. package/dist/components/icon-button/types.d.ts +4 -1
  106. package/dist/components/input/index.d.ts +2 -1
  107. package/dist/components/input/index.js +2 -1
  108. package/dist/components/input/types.d.ts +4 -1
  109. package/dist/components/modal/index.d.ts +2 -1
  110. package/dist/components/modal/index.js +2 -2
  111. package/dist/components/modal/types.d.ts +8 -1
  112. package/dist/components/number-input/index.d.ts +2 -1
  113. package/dist/components/number-input/index.js +2 -2
  114. package/dist/components/number-input/types.d.ts +4 -1
  115. package/dist/components/overlay/index.d.ts +2 -1
  116. package/dist/components/overlay/index.js +2 -1
  117. package/dist/components/overlay/types.d.ts +4 -1
  118. package/dist/components/popover/index.d.ts +2 -2
  119. package/dist/components/popover/index.js +2 -2
  120. package/dist/components/popover/popover.d.ts +2 -2
  121. package/dist/components/popover/types.d.ts +20 -11
  122. package/dist/components/popover/usePopover.d.ts +9 -1
  123. package/dist/components/progress/index.d.ts +2 -2
  124. package/dist/components/progress/index.js +2 -2
  125. package/dist/components/progress/types.d.ts +4 -1
  126. package/dist/components/radio/index.d.ts +2 -1
  127. package/dist/components/radio/index.js +2 -2
  128. package/dist/components/radio/radio.d.ts +8 -3
  129. package/dist/components/radio/types.d.ts +20 -3
  130. package/dist/components/radio/useRadio.d.ts +9 -4
  131. package/dist/components/select/index.d.ts +2 -1
  132. package/dist/components/select/index.js +2 -2
  133. package/dist/components/select/types.d.ts +4 -1
  134. package/dist/components/select/useSelect.d.ts +2 -1
  135. package/dist/components/slider/index.d.ts +2 -2
  136. package/dist/components/slider/index.js +2 -2
  137. package/dist/components/slider/range-slider-tooltip.d.ts +3 -0
  138. package/dist/components/slider/range-slider.d.ts +4 -1
  139. package/dist/components/slider/slider.d.ts +4 -1
  140. package/dist/components/slider/sliderCore.d.ts +4 -4
  141. package/dist/components/slider/types.d.ts +12 -2
  142. package/dist/components/slider/useRangeSlider.d.ts +1 -1
  143. package/dist/components/slider/useSlider.d.ts +1 -1
  144. package/dist/components/switch/index.d.ts +2 -1
  145. package/dist/components/switch/index.js +2 -2
  146. package/dist/components/switch/switch.d.ts +4 -1
  147. package/dist/components/switch/types.d.ts +6 -1
  148. package/dist/components/switch/useSwitch.d.ts +2 -0
  149. package/dist/components/tabs/index.d.ts +2 -1
  150. package/dist/components/tabs/index.js +2 -2
  151. package/dist/components/tabs/types.d.ts +13 -4
  152. package/dist/components/teleport-provider/index.d.ts +2 -0
  153. package/dist/components/teleport-provider/index.js +2 -0
  154. package/dist/components/teleport-provider/teleport-provider.d.ts +21 -0
  155. package/dist/components/teleport-provider/types.d.ts +4 -0
  156. package/dist/components/teleport-provider/useTeleportTarget.d.ts +5 -0
  157. package/dist/components/textarea/index.d.ts +2 -1
  158. package/dist/components/textarea/index.js +2 -2
  159. package/dist/components/textarea/textarea.d.ts +4 -1
  160. package/dist/components/textarea/types.d.ts +6 -1
  161. package/dist/components/textarea/useTextarea.d.ts +1 -0
  162. package/dist/components/toast/index.d.ts +2 -2
  163. package/dist/components/toast/index.js +2 -2
  164. package/dist/components/toast/toast.d.ts +2 -2
  165. package/dist/components/toast/types.d.ts +10 -6
  166. package/dist/components/tooltip/index.d.ts +2 -1
  167. package/dist/components/tooltip/index.js +2 -1
  168. package/dist/components/tooltip/tooltip.d.ts +2 -2
  169. package/dist/components/tooltip/types.d.ts +13 -12
  170. package/dist/components/tooltip/useTooltip.d.ts +13 -3
  171. package/dist/dropdown-menu.css +191 -107
  172. package/dist/dropdown-menu.js +1582 -81
  173. package/dist/field.css +41 -39
  174. package/dist/field.js +40 -16
  175. package/dist/focus-trap.js +80 -0
  176. package/dist/icon-button.css +193 -189
  177. package/dist/icon-button.js +23 -18
  178. package/dist/icon-button2.js +8 -0
  179. package/dist/index.d.ts +4 -0
  180. package/dist/index.js +36 -32
  181. package/dist/input.css +122 -120
  182. package/dist/input.js +47 -34
  183. package/dist/input2.js +9 -0
  184. package/dist/legacy-unlayered.css +5461 -0
  185. package/dist/modal.css +129 -127
  186. package/dist/modal.js +160 -200
  187. package/dist/number-input.css +87 -85
  188. package/dist/number-input.js +61 -17
  189. package/dist/overlay.css +26 -24
  190. package/dist/overlay.js +17 -9
  191. package/dist/overlay2.js +4 -0
  192. package/dist/popover.css +140 -107
  193. package/dist/popover.js +288 -193
  194. package/dist/popover2.js +6 -1
  195. package/dist/progress.css +101 -99
  196. package/dist/progress.js +50 -28
  197. package/dist/radio.css +114 -105
  198. package/dist/radio.js +154 -56
  199. package/dist/select.css +244 -242
  200. package/dist/select.js +92 -47
  201. package/dist/slider.css +1109 -1031
  202. package/dist/slider.js +330 -163
  203. package/dist/styles-api.d.ts +22 -0
  204. package/dist/styles-api.js +49 -0
  205. package/dist/switch.css +120 -108
  206. package/dist/switch.js +89 -33
  207. package/dist/tabs.css +286 -278
  208. package/dist/tabs.js +60 -21
  209. package/dist/teleport-provider.js +15 -0
  210. package/dist/textarea.css +132 -130
  211. package/dist/textarea.js +69 -27
  212. package/dist/toast.css +229 -225
  213. package/dist/toast.js +102 -42
  214. package/dist/tooltip.css +137 -107
  215. package/dist/tooltip.js +180 -228
  216. package/dist/tooltip2.js +8 -0
  217. package/dist/useClickOutside.js +1 -1
  218. package/dist/useFloatingPosition.js +1284 -0
  219. package/dist/useFocusTrap.js +130 -0
  220. package/dist/useTeleportTarget.js +29 -0
  221. package/docs/public-styles-api.md +133 -0
  222. package/docs/public-tokens.md +545 -0
  223. package/package.json +29 -5
  224. package/src/styles/_tokens.scss +33 -28
  225. package/src/styles/_utilities.scss +11 -9
  226. package/src/styles/styles-manifest.json +4125 -0
  227. package/dist/rafScheduler.js +0 -34
@@ -1,7 +1,1251 @@
1
1
  import './dropdown-menu.css';
2
2
  import { t as bem } from "./bem.js";
3
+ import { n as useStylesApi, t as presence } from "./styles-api.js";
4
+ import { t as useRequiredInject } from "./useRequiredInject.js";
5
+ import { n as useFloatingPosition, r as useFloatingTarget, t as isElementReference } from "./useFloatingPosition.js";
6
+ import { n as useTeleportTarget, t as provideTeleportTarget } from "./useTeleportTarget.js";
3
7
  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";
8
+ import { Teleport, VaporTeleport, VaporTransition, computed, createComponent, createIf, createSlot, createTemplateRefSetter, defineComponent, defineVaporComponent, extend, h, markRaw, mergeProps, nextTick, onBeforeUnmount, onMounted, onUnmounted, provide, ref, renderEffect, setAttr, setDynamicProps, setInsertionState, setStaticTemplateRef, setStyle, setText, shallowRef, template, toDisplayString, txt, unref, useId, watch } from "vue";
9
+ //#region src/components/dropdown-menu/dropdown-menu-primitives.ts
10
+ var rootKey = Symbol("dropdown-menu-root");
11
+ var menuKey = Symbol("dropdown-menu-content");
12
+ var subKey = Symbol("dropdown-menu-sub");
13
+ var radioGroupKey = Symbol("dropdown-menu-radio-group");
14
+ var checkedKey = Symbol("dropdown-menu-checked");
15
+ var openLayers = [];
16
+ function optionalAttr(value) {
17
+ return value || void 0;
18
+ }
19
+ function getFocusTarget(options) {
20
+ if (typeof options === "string") return options;
21
+ return options?.focus ?? "first";
22
+ }
23
+ function toHTMLElement(value) {
24
+ if (typeof HTMLElement !== "undefined" && value instanceof HTMLElement) return value;
25
+ const element = value?.$el;
26
+ return typeof HTMLElement !== "undefined" && element instanceof HTMLElement ? element : null;
27
+ }
28
+ function createPointRect(point) {
29
+ return {
30
+ x: point.x,
31
+ y: point.y,
32
+ left: point.x,
33
+ right: point.x,
34
+ top: point.y,
35
+ bottom: point.y,
36
+ width: 0,
37
+ height: 0,
38
+ toJSON: () => ({})
39
+ };
40
+ }
41
+ function createVirtualAnchor(point) {
42
+ return { getBoundingClientRect: () => createPointRect(point) };
43
+ }
44
+ function createCustomEvent(type, detail, originalEvent) {
45
+ const target = originalEvent.target;
46
+ return new (((target instanceof Node ? target.ownerDocument?.defaultView : null)?.CustomEvent) ?? CustomEvent)(type, {
47
+ bubbles: false,
48
+ cancelable: true,
49
+ detail
50
+ });
51
+ }
52
+ function createSelectEvent(originalEvent, value) {
53
+ return createCustomEvent("dropdown-menu-select", {
54
+ originalEvent,
55
+ value
56
+ }, originalEvent);
57
+ }
58
+ function createOutsideEvent(originalEvent) {
59
+ return createCustomEvent("dropdown-menu-interact-outside", { originalEvent }, originalEvent);
60
+ }
61
+ function sortItems(items) {
62
+ return [...items].sort((left, right) => {
63
+ const leftElement = left.element();
64
+ const rightElement = right.element();
65
+ if (!leftElement || !rightElement || leftElement === rightElement) return 0;
66
+ const position = leftElement.compareDocumentPosition(rightElement);
67
+ if (position & Node.DOCUMENT_POSITION_FOLLOWING) return -1;
68
+ if (position & Node.DOCUMENT_POSITION_PRECEDING) return 1;
69
+ return 0;
70
+ });
71
+ }
72
+ function getPlacementSide(placement) {
73
+ return placement.split("-")[0];
74
+ }
75
+ function getOpenDirection(sub) {
76
+ return getPlacementSide(sub.actualPlacement.value) === "left" ? "ArrowLeft" : "ArrowRight";
77
+ }
78
+ function getCloseDirection(menu) {
79
+ return getPlacementSide(menu.actualPlacement.value) === "left" ? "ArrowRight" : "ArrowLeft";
80
+ }
81
+ function addOpenLayer(root) {
82
+ const index = openLayers.indexOf(root);
83
+ if (index >= 0) openLayers.splice(index, 1);
84
+ openLayers.push(root);
85
+ }
86
+ function removeOpenLayer(root) {
87
+ const index = openLayers.indexOf(root);
88
+ if (index >= 0) openLayers.splice(index, 1);
89
+ }
90
+ function isTopLayer(root) {
91
+ return openLayers[openLayers.length - 1] === root;
92
+ }
93
+ function blockDocumentClick(event) {
94
+ if (event.cancelable) event.preventDefault();
95
+ event.stopPropagation();
96
+ document.removeEventListener("click", blockDocumentClick, true);
97
+ }
98
+ function blockNextDocumentClick() {
99
+ if (typeof document === "undefined") return;
100
+ document.addEventListener("click", blockDocumentClick, true);
101
+ window.setTimeout(() => document.removeEventListener("click", blockDocumentClick, true), 1e3);
102
+ }
103
+ function createMenuContext(options) {
104
+ const items = shallowRef([]);
105
+ const activeId = ref(null);
106
+ const submenus = /* @__PURE__ */ new Set();
107
+ function getEnabledItems() {
108
+ return sortItems(items.value).filter((item) => !item.disabled());
109
+ }
110
+ function registerItem(item) {
111
+ items.value = [...items.value.filter((current) => current.id !== item.id), item];
112
+ if ((options.parentSub?.isOpen.value ?? options.root.isOpen.value) && activeId.value == null && !item.disabled()) {
113
+ activeId.value = item.id;
114
+ nextTick(() => {
115
+ options.element.value?.focus();
116
+ item.element()?.scrollIntoView?.({ block: "nearest" });
117
+ });
118
+ }
119
+ }
120
+ function unregisterItem(id) {
121
+ items.value = items.value.filter((item) => item.id !== id);
122
+ if (activeId.value === id) activeId.value = null;
123
+ }
124
+ function registerSub(sub) {
125
+ submenus.add(sub);
126
+ }
127
+ function unregisterSub(sub) {
128
+ submenus.delete(sub);
129
+ }
130
+ function closeSubmenus(except) {
131
+ for (const submenu of submenus) if (submenu !== except) submenu.close(false);
132
+ }
133
+ function setActive(id) {
134
+ const item = items.value.find((current) => current.id === id);
135
+ if (!item || item.disabled()) return;
136
+ activeId.value = id;
137
+ nextTick(() => item.element()?.scrollIntoView?.({ block: "nearest" }));
138
+ }
139
+ function focus(target = "first") {
140
+ const enabledItems = getEnabledItems();
141
+ const item = target === "last" ? enabledItems[enabledItems.length - 1] : enabledItems[0];
142
+ if (!item) {
143
+ activeId.value = null;
144
+ options.element.value?.focus();
145
+ return false;
146
+ }
147
+ activeId.value = item.id;
148
+ options.element.value?.focus();
149
+ item.element()?.scrollIntoView?.({ block: "nearest" });
150
+ return true;
151
+ }
152
+ function focusElement() {
153
+ options.element.value?.focus();
154
+ }
155
+ function move(direction) {
156
+ const enabledItems = getEnabledItems();
157
+ if (enabledItems.length === 0) return;
158
+ const currentIndex = enabledItems.findIndex((item) => item.id === activeId.value);
159
+ const item = enabledItems[((currentIndex < 0 ? direction === 1 ? -1 : 0 : currentIndex) + direction + enabledItems.length) % enabledItems.length];
160
+ if (item) setActive(item.id);
161
+ }
162
+ function onHorizontalKeydown(event, active) {
163
+ if (options.parentSub && event.key === getCloseDirection(context)) {
164
+ event.preventDefault();
165
+ event.stopPropagation();
166
+ options.parentSub.close(true);
167
+ return;
168
+ }
169
+ if (!active?.submenu || event.key !== getOpenDirection(active.submenu)) return;
170
+ event.preventDefault();
171
+ event.stopPropagation();
172
+ active.submenu.open("first");
173
+ }
174
+ function onKeydown(event) {
175
+ const active = items.value.find((item) => item.id === activeId.value);
176
+ switch (event.key) {
177
+ case "ArrowDown":
178
+ event.preventDefault();
179
+ event.stopPropagation();
180
+ move(1);
181
+ break;
182
+ case "ArrowUp":
183
+ event.preventDefault();
184
+ event.stopPropagation();
185
+ move(-1);
186
+ break;
187
+ case "Home":
188
+ event.preventDefault();
189
+ event.stopPropagation();
190
+ focus("first");
191
+ break;
192
+ case "End":
193
+ event.preventDefault();
194
+ event.stopPropagation();
195
+ focus("last");
196
+ break;
197
+ case "ArrowRight":
198
+ case "ArrowLeft":
199
+ onHorizontalKeydown(event, active);
200
+ break;
201
+ case "Enter":
202
+ case " ":
203
+ event.preventDefault();
204
+ event.stopPropagation();
205
+ active?.activate(event);
206
+ break;
207
+ case "Escape":
208
+ event.preventDefault();
209
+ event.stopPropagation();
210
+ options.onEscape(event);
211
+ break;
212
+ case "Tab":
213
+ options.root.close({ returnFocus: false });
214
+ break;
215
+ }
216
+ }
217
+ const context = {
218
+ root: options.root,
219
+ element: options.element,
220
+ activeId,
221
+ actualPlacement: options.actualPlacement,
222
+ parentSub: options.parentSub,
223
+ registerItem,
224
+ unregisterItem,
225
+ registerSub,
226
+ unregisterSub,
227
+ closeSubmenus,
228
+ setActive,
229
+ isActive: (id) => activeId.value === id,
230
+ focus,
231
+ focusElement,
232
+ onKeydown
233
+ };
234
+ return context;
235
+ }
236
+ function primitiveAsProp(defaultValue) {
237
+ return {
238
+ type: [
239
+ String,
240
+ Object,
241
+ Function
242
+ ],
243
+ default: defaultValue
244
+ };
245
+ }
246
+ var DropdownMenuRoot = defineComponent({
247
+ name: "RpDropdownMenuRoot",
248
+ props: {
249
+ id: String,
250
+ open: {
251
+ type: Boolean,
252
+ default: void 0
253
+ },
254
+ defaultOpen: {
255
+ type: Boolean,
256
+ default: false
257
+ },
258
+ disabled: {
259
+ type: Boolean,
260
+ default: false
261
+ },
262
+ modal: {
263
+ type: Boolean,
264
+ default: true
265
+ },
266
+ target: {
267
+ type: [String, Object],
268
+ default: null
269
+ },
270
+ virtualAnchor: {
271
+ type: Object,
272
+ default: null
273
+ }
274
+ },
275
+ emits: ["update:open"],
276
+ setup(props, { emit, expose, slots }) {
277
+ const generatedId = useId();
278
+ const id = computed(() => props.id ?? `${generatedId}-dropdown-menu`);
279
+ const uncontrolledOpen = ref(props.defaultOpen);
280
+ const isOpen = computed(() => props.open ?? uncontrolledOpen.value);
281
+ const disabled = computed(() => props.disabled);
282
+ const modal = computed(() => props.modal);
283
+ const trigger = ref(null);
284
+ const triggerId = ref();
285
+ const contentId = ref();
286
+ const activeReference = shallowRef(null);
287
+ const { reference: configuredReference } = useFloatingTarget(() => props.target ?? props.virtualAnchor, trigger);
288
+ const reference = computed(() => activeReference.value ?? configuredReference.value);
289
+ const pendingFocus = ref("first");
290
+ const inside = /* @__PURE__ */ new Set();
291
+ let returnFocusElement = null;
292
+ function setOpen(value) {
293
+ if (value && disabled.value) return;
294
+ const previous = isOpen.value;
295
+ if (props.open === void 0) uncontrolledOpen.value = value;
296
+ if (previous !== value) emit("update:open", value);
297
+ }
298
+ function rememberFocus() {
299
+ if (typeof document === "undefined" || returnFocusElement) return;
300
+ const activeElement = document.activeElement;
301
+ if (activeElement instanceof HTMLElement) returnFocusElement = activeElement;
302
+ }
303
+ function open(options) {
304
+ if (disabled.value) return;
305
+ rememberFocus();
306
+ pendingFocus.value = getFocusTarget(options);
307
+ setOpen(true);
308
+ }
309
+ function focusReturnTarget() {
310
+ const target = returnFocusElement ?? trigger.value;
311
+ nextTick(() => target?.focus());
312
+ }
313
+ function close(options = {}) {
314
+ setOpen(false);
315
+ pendingFocus.value = false;
316
+ if (options.focusTrigger || options.returnFocus) focusReturnTarget();
317
+ }
318
+ function toggle() {
319
+ if (isOpen.value) close({ returnFocus: true });
320
+ else open();
321
+ }
322
+ function openAt(point, options) {
323
+ activeReference.value = createVirtualAnchor(point);
324
+ open(options);
325
+ }
326
+ function setTrigger(element, nextId) {
327
+ if (trigger.value && trigger.value !== element) inside.delete(trigger.value);
328
+ trigger.value = element;
329
+ triggerId.value = nextId;
330
+ if (element) inside.add(element);
331
+ }
332
+ const context = {
333
+ id,
334
+ isOpen,
335
+ disabled,
336
+ modal,
337
+ trigger,
338
+ triggerId,
339
+ contentId,
340
+ reference,
341
+ pendingFocus,
342
+ open,
343
+ close,
344
+ toggle,
345
+ openAt,
346
+ setTrigger,
347
+ setReference(nextReference) {
348
+ activeReference.value = nextReference;
349
+ },
350
+ setReturnFocus(element) {
351
+ returnFocusElement = element;
352
+ },
353
+ registerInside(element) {
354
+ inside.add(element);
355
+ },
356
+ unregisterInside(element) {
357
+ inside.delete(element);
358
+ },
359
+ isInside(target) {
360
+ return target instanceof Node && [...inside].some((element) => element.contains(target));
361
+ }
362
+ };
363
+ const slotProps = computed(() => ({
364
+ isOpen: isOpen.value,
365
+ open,
366
+ close,
367
+ toggle,
368
+ openAt
369
+ }));
370
+ watch(disabled, (value) => {
371
+ if (value) close();
372
+ });
373
+ watch(isOpen, (value) => {
374
+ if (value) addOpenLayer(context);
375
+ else removeOpenLayer(context);
376
+ }, { immediate: true });
377
+ onBeforeUnmount(() => removeOpenLayer(context));
378
+ provide(rootKey, context);
379
+ expose({
380
+ open,
381
+ close,
382
+ toggle,
383
+ openAt
384
+ });
385
+ return () => slots.default?.(slotProps.value);
386
+ }
387
+ });
388
+ var DropdownMenuTrigger = defineComponent({
389
+ name: "RpDropdownMenuTrigger",
390
+ inheritAttrs: false,
391
+ props: {
392
+ id: String,
393
+ as: primitiveAsProp("button"),
394
+ disabled: {
395
+ type: Boolean,
396
+ default: false
397
+ }
398
+ },
399
+ setup(props, { attrs, slots }) {
400
+ const root = useRequiredInject(rootKey, "RpDropdownMenuTrigger");
401
+ const generatedId = useId();
402
+ const id = computed(() => props.id ?? `${generatedId}-trigger`);
403
+ const element = ref(null);
404
+ const isDisabled = computed(() => root.disabled.value || props.disabled);
405
+ function setElement(value) {
406
+ element.value = toHTMLElement(value);
407
+ root.setTrigger(element.value, id.value);
408
+ }
409
+ function openWithReference(focus = "first") {
410
+ root.setReference(element.value);
411
+ root.setReturnFocus(element.value);
412
+ root.open({ focus });
413
+ }
414
+ function onClick(event) {
415
+ if (event.defaultPrevented || isDisabled.value) return;
416
+ root.setReference(element.value);
417
+ root.setReturnFocus(element.value);
418
+ root.toggle();
419
+ }
420
+ function onKeydown(event) {
421
+ if (isDisabled.value) return;
422
+ if (event.key === "ArrowUp") {
423
+ event.preventDefault();
424
+ openWithReference("last");
425
+ } else if ([
426
+ "Enter",
427
+ " ",
428
+ "ArrowDown"
429
+ ].includes(event.key)) {
430
+ event.preventDefault();
431
+ openWithReference("first");
432
+ } else if (event.key === "Escape") root.close({ focusTrigger: true });
433
+ }
434
+ onBeforeUnmount(() => root.setTrigger(null));
435
+ return () => {
436
+ const as = props.as ?? "button";
437
+ return h(as, mergeProps(attrs, {
438
+ id: id.value,
439
+ ref: setElement,
440
+ type: as === "button" ? "button" : void 0,
441
+ disabled: as === "button" ? optionalAttr(isDisabled.value) : void 0,
442
+ "aria-controls": root.contentId.value,
443
+ "aria-expanded": root.isOpen.value,
444
+ "aria-haspopup": "menu",
445
+ "aria-disabled": as === "button" ? void 0 : optionalAttr(isDisabled.value),
446
+ "data-state": root.isOpen.value ? "open" : "closed",
447
+ "data-disabled": optionalAttr(isDisabled.value),
448
+ onClick,
449
+ onKeydown
450
+ }), slots.default?.({ isOpen: root.isOpen.value }));
451
+ };
452
+ }
453
+ });
454
+ var DropdownMenuContextTrigger = defineComponent({
455
+ name: "RpDropdownMenuContextTrigger",
456
+ inheritAttrs: false,
457
+ props: {
458
+ id: String,
459
+ as: primitiveAsProp("span"),
460
+ disabled: {
461
+ type: Boolean,
462
+ default: false
463
+ },
464
+ longPressDelay: {
465
+ type: Number,
466
+ default: 700
467
+ },
468
+ longPressTolerance: {
469
+ type: Number,
470
+ default: 10
471
+ }
472
+ },
473
+ setup(props, { attrs, slots }) {
474
+ const root = useRequiredInject(rootKey, "RpDropdownMenuContextTrigger");
475
+ const generatedId = useId();
476
+ const id = computed(() => props.id ?? `${generatedId}-context-trigger`);
477
+ const element = ref(null);
478
+ const isDisabled = computed(() => root.disabled.value || props.disabled);
479
+ let timer;
480
+ let pointerId;
481
+ let startPoint;
482
+ let longPressOpened = false;
483
+ let suppressUntil = 0;
484
+ function setElement(value) {
485
+ const previous = element.value;
486
+ if (previous) root.unregisterInside(previous);
487
+ element.value = toHTMLElement(value);
488
+ if (element.value) root.registerInside(element.value);
489
+ if (!root.triggerId.value) root.triggerId.value = id.value;
490
+ }
491
+ function clearLongPress() {
492
+ if (timer) clearTimeout(timer);
493
+ timer = void 0;
494
+ pointerId = void 0;
495
+ startPoint = void 0;
496
+ element.value?.ownerDocument.defaultView?.removeEventListener("scroll", clearLongPress, true);
497
+ }
498
+ function openAt(point) {
499
+ root.setReturnFocus(element.value);
500
+ root.openAt(point);
501
+ }
502
+ function onContextmenu(event) {
503
+ if (isDisabled.value) return;
504
+ event.preventDefault();
505
+ if (Date.now() < suppressUntil) return;
506
+ openAt({
507
+ x: event.clientX,
508
+ y: event.clientY
509
+ });
510
+ }
511
+ function onKeydown(event) {
512
+ if (isDisabled.value) return;
513
+ if (event.key !== "ContextMenu" && !(event.shiftKey && event.key === "F10")) return;
514
+ event.preventDefault();
515
+ const rect = element.value?.getBoundingClientRect();
516
+ openAt({
517
+ x: rect?.left ?? 0,
518
+ y: rect?.bottom ?? 0
519
+ });
520
+ }
521
+ function onPointerdown(event) {
522
+ if (isDisabled.value || event.pointerType !== "touch" && event.pointerType !== "pen") return;
523
+ clearLongPress();
524
+ pointerId = event.pointerId;
525
+ startPoint = {
526
+ x: event.clientX,
527
+ y: event.clientY
528
+ };
529
+ longPressOpened = false;
530
+ (element.value?.ownerDocument.defaultView)?.addEventListener("scroll", clearLongPress, true);
531
+ timer = setTimeout(() => {
532
+ if (!startPoint) return;
533
+ longPressOpened = true;
534
+ suppressUntil = Date.now() + 1e3;
535
+ openAt(startPoint);
536
+ timer = void 0;
537
+ }, props.longPressDelay);
538
+ }
539
+ function onPointermove(event) {
540
+ if (event.pointerId !== pointerId || !startPoint) return;
541
+ if (Math.hypot(event.clientX - startPoint.x, event.clientY - startPoint.y) > props.longPressTolerance) clearLongPress();
542
+ }
543
+ function finishPointer(event) {
544
+ if (event.pointerId !== pointerId) return;
545
+ if (longPressOpened) event.preventDefault();
546
+ clearLongPress();
547
+ }
548
+ function onClick(event) {
549
+ if (Date.now() >= suppressUntil) return;
550
+ event.preventDefault();
551
+ event.stopPropagation();
552
+ }
553
+ onBeforeUnmount(() => {
554
+ clearLongPress();
555
+ if (element.value) root.unregisterInside(element.value);
556
+ if (root.triggerId.value === id.value) root.triggerId.value = void 0;
557
+ });
558
+ return () => h(props.as ?? "span", mergeProps(attrs, {
559
+ id: id.value,
560
+ ref: setElement,
561
+ "aria-controls": root.contentId.value,
562
+ "aria-expanded": root.isOpen.value,
563
+ "aria-haspopup": "menu",
564
+ "aria-disabled": optionalAttr(isDisabled.value),
565
+ "data-state": root.isOpen.value ? "open" : "closed",
566
+ "data-disabled": optionalAttr(isDisabled.value),
567
+ onClick,
568
+ onContextmenu,
569
+ onKeydown,
570
+ onPointerdown,
571
+ onPointermove,
572
+ onPointerup: finishPointer,
573
+ onPointercancel: finishPointer
574
+ }), slots.default?.({ isOpen: root.isOpen.value }));
575
+ }
576
+ });
577
+ var DropdownMenuPortal = defineComponent({
578
+ name: "RpDropdownMenuPortal",
579
+ props: {
580
+ to: {
581
+ type: [String, Object],
582
+ default: void 0
583
+ },
584
+ teleportTo: {
585
+ type: [String, Object],
586
+ default: void 0
587
+ },
588
+ teleport: {
589
+ type: Boolean,
590
+ default: true
591
+ },
592
+ disabled: {
593
+ type: Boolean,
594
+ default: false
595
+ }
596
+ },
597
+ setup(props, { slots }) {
598
+ const teleportTo = provideTeleportTarget({ get teleportTo() {
599
+ return props.to ?? props.teleportTo;
600
+ } });
601
+ return () => h(Teleport, {
602
+ to: teleportTo.value,
603
+ disabled: props.disabled || !props.teleport
604
+ }, slots.default?.());
605
+ }
606
+ });
607
+ function createContentComponent(submenu) {
608
+ return defineComponent({
609
+ name: submenu ? "RpDropdownMenuSubContent" : "RpDropdownMenuContent",
610
+ inheritAttrs: false,
611
+ props: {
612
+ id: String,
613
+ as: primitiveAsProp("div"),
614
+ placement: {
615
+ type: String,
616
+ default: submenu ? "right-start" : "bottom-start"
617
+ },
618
+ offset: {
619
+ type: [Number, Object],
620
+ default: void 0
621
+ },
622
+ strategy: {
623
+ type: String,
624
+ default: "absolute"
625
+ },
626
+ flip: {
627
+ type: Boolean,
628
+ default: true
629
+ },
630
+ shift: {
631
+ type: Boolean,
632
+ default: true
633
+ },
634
+ collisionPadding: {
635
+ type: [Number, Object],
636
+ default: 8
637
+ },
638
+ arrow: {
639
+ type: Boolean,
640
+ default: false
641
+ },
642
+ avoidCollisions: {
643
+ type: Boolean,
644
+ default: true
645
+ },
646
+ forceMount: {
647
+ type: Boolean,
648
+ default: false
649
+ },
650
+ ariaLabel: String,
651
+ ariaLabelledby: String,
652
+ ariaDescribedby: String
653
+ },
654
+ emits: [
655
+ "escapeKeyDown",
656
+ "pointerDownOutside",
657
+ "focusOutside",
658
+ "interactOutside"
659
+ ],
660
+ setup(props, { attrs, emit, slots }) {
661
+ const root = useRequiredInject(rootKey, submenu ? "RpDropdownMenuSubContent" : "RpDropdownMenuContent");
662
+ const sub = submenu ? useRequiredInject(subKey, "RpDropdownMenuSubContent") : void 0;
663
+ const generatedId = useId();
664
+ const id = computed(() => props.id ?? `${generatedId}-${submenu ? "submenu" : "menu"}`);
665
+ const element = ref(null);
666
+ const arrowElement = ref(null);
667
+ const actualPlacement = ref(props.placement);
668
+ const isOpen = computed(() => sub ? sub.isOpen.value : root.isOpen.value);
669
+ const reference = computed(() => sub ? sub.trigger.value : root.reference.value);
670
+ const teleportTo = useTeleportTarget(() => void 0);
671
+ const menu = createMenuContext({
672
+ root,
673
+ element,
674
+ actualPlacement,
675
+ parentSub: sub,
676
+ onEscape(event) {
677
+ const customEvent = createCustomEvent("dropdown-menu-escape-key-down", { originalEvent: event }, event);
678
+ emit("escapeKeyDown", customEvent);
679
+ if (customEvent.defaultPrevented) return;
680
+ if (sub) sub.close(true);
681
+ else root.close({ returnFocus: true });
682
+ }
683
+ });
684
+ const floating = useFloatingPosition({
685
+ reference,
686
+ floating: element,
687
+ arrow: arrowElement,
688
+ open: isOpen,
689
+ placement: () => props.placement,
690
+ strategy: () => props.strategy,
691
+ offset: () => props.offset,
692
+ flip: () => props.avoidCollisions !== false && props.flip,
693
+ shift: () => props.avoidCollisions !== false && props.shift,
694
+ collisionPadding: () => props.collisionPadding,
695
+ arrowEnabled: () => !submenu && props.arrow,
696
+ restartKey: () => teleportTo.value
697
+ });
698
+ watch(floating.actualPlacement, (value) => {
699
+ actualPlacement.value = value;
700
+ }, { immediate: true });
701
+ const shouldRender = computed(() => props.forceMount || isOpen.value);
702
+ provide(menuKey, menu);
703
+ if (sub) sub.menu = menu;
704
+ function setElement(value) {
705
+ const previous = element.value;
706
+ if (previous) root.unregisterInside(previous);
707
+ element.value = toHTMLElement(value);
708
+ if (element.value) root.registerInside(element.value);
709
+ }
710
+ function emitOutside(type, originalEvent) {
711
+ const outsideEvent = createOutsideEvent(originalEvent);
712
+ if (type === "pointer") emit("pointerDownOutside", outsideEvent);
713
+ else emit("focusOutside", outsideEvent);
714
+ emit("interactOutside", outsideEvent);
715
+ return outsideEvent;
716
+ }
717
+ function onDocumentPointer(event) {
718
+ if (!isTopLayer(root) || root.isInside(event.target)) return;
719
+ const outsideEvent = emitOutside("pointer", event);
720
+ if (root.modal.value) {
721
+ if (event.cancelable) event.preventDefault();
722
+ event.stopPropagation();
723
+ if (event.type === "pointerdown") blockNextDocumentClick();
724
+ }
725
+ if (!outsideEvent.defaultPrevented) root.close({ returnFocus: root.modal.value });
726
+ }
727
+ function onDocumentFocus(event) {
728
+ if (!isTopLayer(root) || root.isInside(event.target)) return;
729
+ const outsideEvent = emitOutside("focus", event);
730
+ if (root.modal.value) {
731
+ if (event.cancelable) event.preventDefault();
732
+ event.stopPropagation();
733
+ }
734
+ if (!outsideEvent.defaultPrevented) root.close({ returnFocus: root.modal.value });
735
+ else if (root.modal.value) nextTick(menu.focusElement);
736
+ }
737
+ function setDocumentListeners(active) {
738
+ if (submenu || typeof document === "undefined") return;
739
+ const method = active ? "addEventListener" : "removeEventListener";
740
+ document[method]("pointerdown", onDocumentPointer, true);
741
+ document[method]("click", onDocumentPointer, true);
742
+ document[method]("focusin", onDocumentFocus, true);
743
+ }
744
+ watch(isOpen, (open) => {
745
+ setDocumentListeners(open);
746
+ if (!open) {
747
+ menu.activeId.value = null;
748
+ menu.closeSubmenus();
749
+ return;
750
+ }
751
+ nextTick(() => {
752
+ const focus = sub ? sub.pendingFocus.value : root.pendingFocus.value;
753
+ menu.focus(focus || "first");
754
+ });
755
+ }, {
756
+ flush: "post",
757
+ immediate: true
758
+ });
759
+ onMounted(() => {
760
+ if (sub) sub.contentId.value = id.value;
761
+ else root.contentId.value = id.value;
762
+ if (isOpen.value) menu.focus((sub ? sub.pendingFocus.value : root.pendingFocus.value) || "first");
763
+ });
764
+ onBeforeUnmount(() => {
765
+ setDocumentListeners(false);
766
+ if (element.value) root.unregisterInside(element.value);
767
+ if (sub) sub.menu = null;
768
+ else if (root.contentId.value === id.value) root.contentId.value = void 0;
769
+ });
770
+ return () => {
771
+ if (!shouldRender.value) return null;
772
+ const placement = floating.actualPlacement.value.split("-");
773
+ const className = submenu ? bem("rp-dropdown-menu__submenu", {
774
+ compound: true,
775
+ open: isOpen.value
776
+ }) : bem("rp-dropdown-menu__content", {
777
+ compound: true,
778
+ open: isOpen.value
779
+ });
780
+ return h(props.as ?? "div", mergeProps(attrs, {
781
+ id: id.value,
782
+ ref: setElement,
783
+ role: "menu",
784
+ tabindex: -1,
785
+ hidden: optionalAttr(!isOpen.value),
786
+ class: className,
787
+ style: [floating.floatingStyle.value, !isOpen.value ? { display: "none" } : void 0],
788
+ "aria-label": props.ariaLabel,
789
+ "aria-labelledby": props.ariaLabelledby ?? (submenu ? void 0 : root.triggerId.value),
790
+ "aria-describedby": props.ariaDescribedby,
791
+ "aria-activedescendant": menu.activeId.value ?? void 0,
792
+ "data-state": isOpen.value ? "open" : "closed",
793
+ "data-placement": floating.actualPlacement.value,
794
+ "data-side": placement[0],
795
+ "data-align": placement[1] ?? "center",
796
+ onKeydown: menu.onKeydown
797
+ }), [!submenu && props.arrow ? h("span", {
798
+ ref: arrowElement,
799
+ class: "rp-dropdown-menu__arrow",
800
+ "data-side": placement[0],
801
+ style: floating.arrowStyle.value,
802
+ "aria-hidden": "true"
803
+ }) : null, slots.default?.({
804
+ isOpen: isOpen.value,
805
+ placement: floating.actualPlacement.value,
806
+ close: () => sub ? sub.close(true) : root.close({ returnFocus: true })
807
+ })]);
808
+ };
809
+ }
810
+ });
811
+ }
812
+ var DropdownMenuContent = createContentComponent(false);
813
+ var DropdownMenuSubContent = createContentComponent(true);
814
+ function usePrimitiveItem(componentName, props, emit, options) {
815
+ const menu = useRequiredInject(menuKey, componentName);
816
+ const generatedId = useId();
817
+ const id = computed(() => props.id ?? `${generatedId}-item`);
818
+ const element = ref(null);
819
+ const isDisabled = computed(() => Boolean(menu.root.disabled.value || props.disabled));
820
+ const focused = computed(() => menu.isActive(id.value));
821
+ function activate(originalEvent) {
822
+ if (isDisabled.value) return;
823
+ const selectEvent = createSelectEvent(originalEvent, props.value);
824
+ emit("select", selectEvent);
825
+ options.afterSelect?.();
826
+ if (!selectEvent.defaultPrevented && (props.closeOnSelect ?? options.defaultCloseOnSelect)) menu.root.close({ returnFocus: true });
827
+ }
828
+ const registration = {
829
+ get id() {
830
+ return id.value;
831
+ },
832
+ element: () => element.value,
833
+ disabled: () => isDisabled.value,
834
+ activate
835
+ };
836
+ menu.registerItem(registration);
837
+ watch(id, (nextId, previousId) => {
838
+ menu.unregisterItem(previousId);
839
+ menu.registerItem(registration);
840
+ if (menu.activeId.value === previousId) menu.activeId.value = nextId;
841
+ });
842
+ onBeforeUnmount(() => menu.unregisterItem(id.value));
843
+ function setElement(value) {
844
+ element.value = toHTMLElement(value);
845
+ }
846
+ function onPointerenter() {
847
+ if (isDisabled.value) return;
848
+ menu.closeSubmenus();
849
+ menu.setActive(id.value);
850
+ }
851
+ return {
852
+ menu,
853
+ id,
854
+ element,
855
+ isDisabled,
856
+ focused,
857
+ activate,
858
+ setElement,
859
+ render(attrs, slots) {
860
+ const as = props.as ?? "button";
861
+ return h(as, mergeProps(attrs, {
862
+ id: id.value,
863
+ ref: setElement,
864
+ type: as === "button" ? "button" : void 0,
865
+ role: options.role ?? "menuitem",
866
+ tabindex: -1,
867
+ disabled: as === "button" ? optionalAttr(isDisabled.value) : void 0,
868
+ "aria-disabled": optionalAttr(isDisabled.value),
869
+ "aria-checked": options.checked?.value,
870
+ "data-disabled": optionalAttr(isDisabled.value),
871
+ "data-focused": optionalAttr(focused.value),
872
+ "data-highlighted": optionalAttr(focused.value),
873
+ "data-state": options.checked ? options.checked.value === "mixed" ? "indeterminate" : options.checked.value ? "checked" : "unchecked" : void 0,
874
+ class: bem("rp-dropdown-menu__item", {
875
+ focused: focused.value,
876
+ disabled: isDisabled.value,
877
+ destructive: props.destructive
878
+ }),
879
+ onClick: (event) => {
880
+ if (!event.defaultPrevented) activate(event);
881
+ },
882
+ onMouseenter: onPointerenter
883
+ }), slots.default?.({
884
+ focused: focused.value,
885
+ disabled: isDisabled.value,
886
+ select: () => activate(new Event("select"))
887
+ }));
888
+ }
889
+ };
890
+ }
891
+ var DropdownMenuItem$1 = defineComponent({
892
+ name: "RpDropdownMenuItem",
893
+ inheritAttrs: false,
894
+ props: {
895
+ id: String,
896
+ as: primitiveAsProp("button"),
897
+ value: [String, Number],
898
+ disabled: {
899
+ type: Boolean,
900
+ default: false
901
+ },
902
+ destructive: {
903
+ type: Boolean,
904
+ default: false
905
+ },
906
+ closeOnSelect: {
907
+ type: Boolean,
908
+ default: true
909
+ }
910
+ },
911
+ emits: ["select"],
912
+ setup(props, { attrs, emit, slots }) {
913
+ const item = usePrimitiveItem("RpDropdownMenuItem", props, emit, { defaultCloseOnSelect: true });
914
+ return () => item.render(attrs, slots);
915
+ }
916
+ });
917
+ var DropdownMenuSeparator = defineComponent({
918
+ name: "RpDropdownMenuSeparator",
919
+ inheritAttrs: false,
920
+ props: {
921
+ id: String,
922
+ as: primitiveAsProp("div"),
923
+ orientation: {
924
+ type: String,
925
+ default: "horizontal"
926
+ }
927
+ },
928
+ setup(props, { attrs }) {
929
+ useRequiredInject(menuKey, "RpDropdownMenuSeparator");
930
+ return () => h(props.as ?? "div", mergeProps(attrs, {
931
+ id: props.id,
932
+ role: "separator",
933
+ "aria-orientation": props.orientation,
934
+ class: "rp-dropdown-menu__separator",
935
+ "data-orientation": props.orientation
936
+ }));
937
+ }
938
+ });
939
+ var DropdownMenuLabel = defineComponent({
940
+ name: "RpDropdownMenuLabel",
941
+ inheritAttrs: false,
942
+ props: {
943
+ id: String,
944
+ as: primitiveAsProp("div")
945
+ },
946
+ setup(props, { attrs, slots }) {
947
+ useRequiredInject(menuKey, "RpDropdownMenuLabel");
948
+ return () => h(props.as ?? "div", mergeProps(attrs, {
949
+ id: props.id,
950
+ role: "presentation",
951
+ class: "rp-dropdown-menu__group-label"
952
+ }), slots.default?.());
953
+ }
954
+ });
955
+ var DropdownMenuCheckboxItem = defineComponent({
956
+ name: "RpDropdownMenuCheckboxItem",
957
+ inheritAttrs: false,
958
+ props: {
959
+ id: String,
960
+ as: primitiveAsProp("button"),
961
+ modelValue: {
962
+ type: [Boolean, String],
963
+ default: void 0
964
+ },
965
+ defaultValue: {
966
+ type: [Boolean, String],
967
+ default: false
968
+ },
969
+ disabled: {
970
+ type: Boolean,
971
+ default: false
972
+ },
973
+ destructive: {
974
+ type: Boolean,
975
+ default: false
976
+ },
977
+ closeOnSelect: {
978
+ type: Boolean,
979
+ default: false
980
+ }
981
+ },
982
+ emits: ["select", "update:modelValue"],
983
+ setup(props, { attrs, emit, slots }) {
984
+ const uncontrolled = ref(props.defaultValue);
985
+ const value = computed(() => props.modelValue ?? uncontrolled.value);
986
+ const checked = computed(() => value.value === "indeterminate" ? "mixed" : value.value);
987
+ const state = computed(() => value.value === "indeterminate" ? "indeterminate" : value.value ? "checked" : "unchecked");
988
+ function toggleChecked() {
989
+ const nextValue = value.value === "indeterminate" ? true : !value.value;
990
+ if (props.modelValue === void 0) uncontrolled.value = nextValue;
991
+ emit("update:modelValue", nextValue);
992
+ }
993
+ provide(checkedKey, {
994
+ state,
995
+ checked: computed(() => value.value !== false)
996
+ });
997
+ const item = usePrimitiveItem("RpDropdownMenuCheckboxItem", props, emit, {
998
+ role: "menuitemcheckbox",
999
+ checked,
1000
+ defaultCloseOnSelect: false,
1001
+ afterSelect: toggleChecked
1002
+ });
1003
+ return () => item.render(attrs, slots);
1004
+ }
1005
+ });
1006
+ var DropdownMenuRadioGroup = defineComponent({
1007
+ name: "RpDropdownMenuRadioGroup",
1008
+ inheritAttrs: false,
1009
+ props: {
1010
+ id: String,
1011
+ as: primitiveAsProp("div"),
1012
+ modelValue: {
1013
+ type: [String, Number],
1014
+ default: void 0
1015
+ },
1016
+ defaultValue: {
1017
+ type: [String, Number],
1018
+ default: null
1019
+ },
1020
+ ariaLabel: String,
1021
+ ariaLabelledby: String
1022
+ },
1023
+ emits: ["update:modelValue"],
1024
+ setup(props, { attrs, emit, slots }) {
1025
+ useRequiredInject(menuKey, "RpDropdownMenuRadioGroup");
1026
+ const uncontrolled = ref(props.defaultValue);
1027
+ const value = computed(() => props.modelValue === void 0 ? uncontrolled.value : props.modelValue);
1028
+ function select(nextValue) {
1029
+ if (value.value === nextValue) return;
1030
+ if (props.modelValue === void 0) uncontrolled.value = nextValue;
1031
+ emit("update:modelValue", nextValue);
1032
+ }
1033
+ provide(radioGroupKey, {
1034
+ value,
1035
+ select
1036
+ });
1037
+ return () => h(props.as ?? "div", mergeProps(attrs, {
1038
+ id: props.id,
1039
+ role: "group",
1040
+ class: "rp-dropdown-menu__radio-group",
1041
+ "aria-label": props.ariaLabel,
1042
+ "aria-labelledby": props.ariaLabelledby
1043
+ }), slots.default?.({ value: value.value }));
1044
+ }
1045
+ });
1046
+ var DropdownMenuRadioItem = defineComponent({
1047
+ name: "RpDropdownMenuRadioItem",
1048
+ inheritAttrs: false,
1049
+ props: {
1050
+ id: String,
1051
+ as: primitiveAsProp("button"),
1052
+ value: {
1053
+ type: [String, Number],
1054
+ required: true
1055
+ },
1056
+ disabled: {
1057
+ type: Boolean,
1058
+ default: false
1059
+ },
1060
+ destructive: {
1061
+ type: Boolean,
1062
+ default: false
1063
+ },
1064
+ closeOnSelect: {
1065
+ type: Boolean,
1066
+ default: false
1067
+ }
1068
+ },
1069
+ emits: ["select"],
1070
+ setup(props, { attrs, emit, slots }) {
1071
+ const group = useRequiredInject(radioGroupKey, "RpDropdownMenuRadioItem");
1072
+ const isChecked = computed(() => group.value.value === props.value);
1073
+ const checked = computed(() => isChecked.value);
1074
+ provide(checkedKey, {
1075
+ state: computed(() => isChecked.value ? "checked" : "unchecked"),
1076
+ checked: isChecked
1077
+ });
1078
+ const item = usePrimitiveItem("RpDropdownMenuRadioItem", props, emit, {
1079
+ role: "menuitemradio",
1080
+ checked,
1081
+ defaultCloseOnSelect: false,
1082
+ afterSelect: () => group.select(props.value)
1083
+ });
1084
+ return () => item.render(attrs, slots);
1085
+ }
1086
+ });
1087
+ var DropdownMenuItemIndicator = defineComponent({
1088
+ name: "RpDropdownMenuItemIndicator",
1089
+ inheritAttrs: false,
1090
+ props: {
1091
+ as: primitiveAsProp("span"),
1092
+ forceMount: {
1093
+ type: Boolean,
1094
+ default: false
1095
+ }
1096
+ },
1097
+ setup(props, { attrs, slots }) {
1098
+ const context = useRequiredInject(checkedKey, "RpDropdownMenuItemIndicator");
1099
+ return () => {
1100
+ if (!props.forceMount && !context.checked.value) return null;
1101
+ return h(props.as ?? "span", mergeProps(attrs, {
1102
+ class: "rp-dropdown-menu__indicator",
1103
+ "data-state": context.state.value,
1104
+ "aria-hidden": true
1105
+ }), slots.default?.({
1106
+ state: context.state.value,
1107
+ checked: context.checked.value
1108
+ }));
1109
+ };
1110
+ }
1111
+ });
1112
+ var DropdownMenuSub = defineComponent({
1113
+ name: "RpDropdownMenuSub",
1114
+ props: {
1115
+ open: {
1116
+ type: Boolean,
1117
+ default: void 0
1118
+ },
1119
+ defaultOpen: {
1120
+ type: Boolean,
1121
+ default: false
1122
+ }
1123
+ },
1124
+ emits: ["update:open"],
1125
+ setup(props, { emit, slots }) {
1126
+ const parentMenu = useRequiredInject(menuKey, "RpDropdownMenuSub");
1127
+ const uncontrolled = ref(props.defaultOpen);
1128
+ const isOpen = computed(() => props.open ?? uncontrolled.value);
1129
+ const trigger = ref(null);
1130
+ const contentId = ref();
1131
+ const actualPlacement = ref("right-start");
1132
+ const pendingFocus = ref(false);
1133
+ function setOpen(value) {
1134
+ const previous = isOpen.value;
1135
+ if (props.open === void 0) uncontrolled.value = value;
1136
+ if (previous !== value) emit("update:open", value);
1137
+ }
1138
+ const context = {
1139
+ isOpen,
1140
+ trigger,
1141
+ contentId,
1142
+ actualPlacement,
1143
+ pendingFocus,
1144
+ menu: null,
1145
+ open(focus = "first") {
1146
+ parentMenu.closeSubmenus(context);
1147
+ pendingFocus.value = focus;
1148
+ setOpen(true);
1149
+ if (focus) nextTick(() => context.menu?.focus(focus));
1150
+ },
1151
+ close(focusParent = false) {
1152
+ setOpen(false);
1153
+ pendingFocus.value = false;
1154
+ context.menu?.closeSubmenus();
1155
+ if (focusParent) {
1156
+ parentMenu.setActive(trigger.value?.id ?? "");
1157
+ parentMenu.focusElement();
1158
+ }
1159
+ }
1160
+ };
1161
+ parentMenu.registerSub(context);
1162
+ provide(subKey, context);
1163
+ watch(parentMenu.root.isOpen, (open) => {
1164
+ if (!open) context.close(false);
1165
+ });
1166
+ onBeforeUnmount(() => parentMenu.unregisterSub(context));
1167
+ return () => slots.default?.({
1168
+ isOpen: isOpen.value,
1169
+ open: context.open,
1170
+ close: context.close
1171
+ });
1172
+ }
1173
+ });
1174
+ var DropdownMenuSubTrigger = defineComponent({
1175
+ name: "RpDropdownMenuSubTrigger",
1176
+ inheritAttrs: false,
1177
+ props: {
1178
+ id: String,
1179
+ as: primitiveAsProp("button"),
1180
+ disabled: {
1181
+ type: Boolean,
1182
+ default: false
1183
+ }
1184
+ },
1185
+ setup(props, { attrs, slots }) {
1186
+ const menu = useRequiredInject(menuKey, "RpDropdownMenuSubTrigger");
1187
+ const sub = useRequiredInject(subKey, "RpDropdownMenuSubTrigger");
1188
+ const generatedId = useId();
1189
+ const id = computed(() => props.id ?? `${generatedId}-sub-trigger`);
1190
+ const isDisabled = computed(() => menu.root.disabled.value || props.disabled);
1191
+ const focused = computed(() => menu.isActive(id.value));
1192
+ const registration = {
1193
+ get id() {
1194
+ return id.value;
1195
+ },
1196
+ element: () => sub.trigger.value,
1197
+ disabled: () => isDisabled.value,
1198
+ activate: () => sub.open("first"),
1199
+ submenu: sub
1200
+ };
1201
+ menu.registerItem(registration);
1202
+ onBeforeUnmount(() => menu.unregisterItem(id.value));
1203
+ function setElement(value) {
1204
+ sub.trigger.value = toHTMLElement(value);
1205
+ }
1206
+ function onMouseenter() {
1207
+ if (isDisabled.value) return;
1208
+ menu.setActive(id.value);
1209
+ sub.open(false);
1210
+ }
1211
+ return () => {
1212
+ const as = props.as ?? "button";
1213
+ return h(as, mergeProps(attrs, {
1214
+ id: id.value,
1215
+ ref: setElement,
1216
+ type: as === "button" ? "button" : void 0,
1217
+ role: "menuitem",
1218
+ tabindex: -1,
1219
+ disabled: as === "button" ? optionalAttr(isDisabled.value) : void 0,
1220
+ "aria-disabled": optionalAttr(isDisabled.value),
1221
+ "aria-haspopup": "menu",
1222
+ "aria-expanded": sub.isOpen.value,
1223
+ "aria-controls": sub.contentId.value,
1224
+ "data-disabled": optionalAttr(isDisabled.value),
1225
+ "data-focused": optionalAttr(focused.value),
1226
+ "data-highlighted": optionalAttr(focused.value),
1227
+ "data-state": sub.isOpen.value ? "open" : "closed",
1228
+ class: bem("rp-dropdown-menu__item", {
1229
+ focused: focused.value,
1230
+ disabled: isDisabled.value,
1231
+ submenu: true,
1232
+ open: sub.isOpen.value
1233
+ }),
1234
+ onClick: (event) => {
1235
+ if (!event.defaultPrevented && !isDisabled.value) sub.open("first");
1236
+ },
1237
+ onMouseenter
1238
+ }), slots.default?.({
1239
+ focused: focused.value,
1240
+ disabled: isDisabled.value,
1241
+ isOpen: sub.isOpen.value,
1242
+ open: sub.open,
1243
+ close: sub.close
1244
+ }));
1245
+ };
1246
+ }
1247
+ });
1248
+ //#endregion
5
1249
  //#region ~icons/lucide/chevron-right
6
1250
  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
1251
  function render(_ctx) {
@@ -116,7 +1360,11 @@ var DropdownMenuItemRow = defineComponent({
116
1360
  return () => {
117
1361
  const currentPath = path.value;
118
1362
  const hasSubmenu = hasItemSubmenu(props.item);
119
- const children = [h("button", props.context.getItemProps(props.item, currentPath, props.focused, props.disabled, props.submenuOpen), props.renderItem(props.context.getItemSlotProps(props.item, currentPath, props.focused, props.disabled, props.submenuOpen)))];
1363
+ const itemProps = props.context.getItemProps(props.item, currentPath, props.focused, props.disabled, props.submenuOpen);
1364
+ const children = [h("button", {
1365
+ ...itemProps,
1366
+ ...props.context.getPublicPartAttrs?.("item", { class: itemProps.class })
1367
+ }, props.renderItem(props.context.getItemSlotProps(props.item, currentPath, props.focused, props.disabled, props.submenuOpen)))];
120
1368
  if (hasSubmenu && props.submenuOpen) children.push(h(DropdownMenuSubmenu, {
121
1369
  context: props.context,
122
1370
  item: props.item,
@@ -177,12 +1425,38 @@ var DropdownMenuSubmenu = defineComponent({
177
1425
  renderItem: renderItemProp
178
1426
  },
179
1427
  setup(props) {
180
- return () => h("div", props.context.getSubmenuProps(props.item, props.path, true), [h(DropdownMenuItemsList, {
181
- context: props.context,
182
- items: props.item.children ?? [],
183
- parentPath: props.path,
184
- renderItem: props.renderItem
185
- })]);
1428
+ const element = ref(null);
1429
+ const floating = useFloatingPosition({
1430
+ reference: computed(() => props.context.getItemElement(props.path)),
1431
+ floating: element,
1432
+ open: computed(() => props.context.isSubmenuOpen(props.path)),
1433
+ placement: props.context.getSubmenuPlacement,
1434
+ strategy: props.context.getStrategy,
1435
+ offset: () => 4,
1436
+ flip: props.context.getFlip,
1437
+ shift: props.context.getShift,
1438
+ collisionPadding: props.context.getCollisionPadding,
1439
+ arrowEnabled: () => false
1440
+ });
1441
+ return () => {
1442
+ const submenuProps = props.context.getSubmenuProps(props.item, props.path, true);
1443
+ return h("div", {
1444
+ ...submenuProps,
1445
+ ...props.context.getPublicPartAttrs?.("submenu", {
1446
+ class: submenuProps.class,
1447
+ style: floating.floatingStyle.value
1448
+ }),
1449
+ ref: element,
1450
+ "data-state": "open",
1451
+ "data-placement": floating.actualPlacement.value.split("-")[0],
1452
+ "data-side": floating.actualPlacement.value.split("-")[0]
1453
+ }, [h(DropdownMenuItemsList, {
1454
+ context: props.context,
1455
+ items: props.item.children ?? [],
1456
+ parentPath: props.path,
1457
+ renderItem: props.renderItem
1458
+ })]);
1459
+ };
186
1460
  }
187
1461
  });
188
1462
  var dropdown_menu_items_default = defineComponent({
@@ -205,7 +1479,7 @@ var dropdown_menu_items_default = defineComponent({
205
1479
  });
206
1480
  //#endregion
207
1481
  //#region src/components/dropdown-menu/useDropdownMenuDisclosure.ts
208
- function useDropdownMenuDisclosure({ props, emit, rootRef, uncontrolledOpen, isDisabled, isOpen, isVisible, focusedPath, resetFocus, resetSubmenus, resetHoverIntent, focusItem, focusMenu, focusTrigger }) {
1482
+ function useDropdownMenuDisclosure({ props, emit, rootRef, menuRef, targetRef, uncontrolledOpen, isDisabled, isOpen, isVisible, focusedPath, resetFocus, resetSubmenus, resetHoverIntent, focusItem, focusMenu, focusTrigger }) {
209
1483
  function setOpen(nextOpen) {
210
1484
  if (nextOpen && isDisabled.value) return;
211
1485
  const previousOpen = isOpen.value;
@@ -243,7 +1517,17 @@ function useDropdownMenuDisclosure({ props, emit, rootRef, uncontrolledOpen, isD
243
1517
  focusMenu();
244
1518
  } else resetMenuFocus();
245
1519
  });
246
- useClickOutside(rootRef, isVisible, () => close());
1520
+ useClickOutside([
1521
+ rootRef,
1522
+ menuRef,
1523
+ targetRef
1524
+ ], isVisible, (event) => {
1525
+ if (props.modal) {
1526
+ event.preventDefault();
1527
+ event.stopPropagation();
1528
+ }
1529
+ close({ focusTrigger: Boolean(props.modal) });
1530
+ });
247
1531
  return {
248
1532
  open,
249
1533
  close,
@@ -253,13 +1537,17 @@ function useDropdownMenuDisclosure({ props, emit, rootRef, uncontrolledOpen, isD
253
1537
  }
254
1538
  //#endregion
255
1539
  //#region src/components/dropdown-menu/useDropdownMenuDom.ts
256
- function useDropdownMenuDom({ menuId, rootRef, menuRef, placement, focusedPath }) {
1540
+ function useDropdownMenuDom({ menuId, rootRef, menuRef, targetRef, placement, focusedPath }) {
257
1541
  const activeDescendantId = computed(() => focusedPath.value.length === 0 ? void 0 : getItemId(focusedPath.value));
258
1542
  function focusMenu() {
259
1543
  nextTick(() => menuRef.value?.focus());
260
1544
  }
261
1545
  function focusTrigger() {
262
1546
  nextTick(() => {
1547
+ if (targetRef.value instanceof HTMLElement) {
1548
+ targetRef.value.focus();
1549
+ return;
1550
+ }
263
1551
  (rootRef.value?.querySelector("[aria-haspopup=\"menu\"]"))?.focus();
264
1552
  });
265
1553
  }
@@ -457,15 +1745,22 @@ function useDropdownMenuInteractions({ props, emit, isDisabled, focusedPath, ope
457
1745
  function activateItem(item, path, event) {
458
1746
  if (item.disabled) return;
459
1747
  if (hasItemSubmenu(item)) {
460
- openSubmenu(path, DEFAULT_FOCUS_TARGET, event ? getEventPoint(event) : void 0);
1748
+ openSubmenu(path, DEFAULT_FOCUS_TARGET, event instanceof MouseEvent ? getEventPoint(event) : void 0);
461
1749
  return;
462
1750
  }
463
- selectItem(item);
1751
+ selectItem(item, event);
464
1752
  }
465
- function selectItem(item) {
1753
+ function selectItem(item, originalEvent = new Event("select")) {
466
1754
  if (item.disabled) return;
467
- emit.select?.(item);
468
- if (props.closeOnSelect !== false) disclosure.close({ focusTrigger: true });
1755
+ const event = new CustomEvent("dropdown-menu-select", {
1756
+ cancelable: true,
1757
+ detail: {
1758
+ originalEvent,
1759
+ value: item.value
1760
+ }
1761
+ });
1762
+ emit.select?.(item, event);
1763
+ if (!event.defaultPrevented && props.closeOnSelect !== false) disclosure.close({ focusTrigger: true });
469
1764
  }
470
1765
  function closeSubmenusAfter(menuPath) {
471
1766
  submenus.closeSubmenusAfter(menuPath);
@@ -497,10 +1792,10 @@ function useDropdownMenuInteractions({ props, emit, isDisabled, focusedPath, ope
497
1792
  const path = normalizePath(indexOrPath);
498
1793
  hoverIntent.handleItemHover(item, path, event, commitHoveredItem);
499
1794
  }
500
- function selectFocusedItem() {
1795
+ function selectFocusedItem(event) {
501
1796
  const item = getItemAtPath(focusedPath.value);
502
1797
  if (!item) return;
503
- activateItem(item, focusedPath.value);
1798
+ activateItem(item, focusedPath.value, event);
504
1799
  }
505
1800
  function moveFocusedItem(direction) {
506
1801
  const menuPath = moveFocus(direction);
@@ -553,7 +1848,7 @@ function useDropdownMenuInteractions({ props, emit, isDisabled, focusedPath, ope
553
1848
  case "Enter":
554
1849
  case " ":
555
1850
  event.preventDefault();
556
- selectFocusedItem();
1851
+ selectFocusedItem(event);
557
1852
  break;
558
1853
  case "Escape":
559
1854
  event.preventDefault();
@@ -655,8 +1950,31 @@ function useDropdownMenuNavigation(items) {
655
1950
  };
656
1951
  }
657
1952
  //#endregion
1953
+ //#region src/components/dropdown-menu/useDropdownMenuPortalPosition.ts
1954
+ function useDropdownMenuPortalPosition(options) {
1955
+ const floating = useFloatingPosition({
1956
+ reference: options.reference,
1957
+ floating: options.menuRef,
1958
+ arrow: options.arrowRef,
1959
+ open: options.isVisible,
1960
+ placement: () => options.placement.value,
1961
+ strategy: () => options.props.strategy ?? "absolute",
1962
+ offset: () => options.props.offset,
1963
+ flip: () => options.props.flip !== false,
1964
+ shift: () => options.props.shift !== false,
1965
+ collisionPadding: () => options.props.collisionPadding ?? 8,
1966
+ arrowEnabled: () => Boolean(options.props.arrow),
1967
+ restartKey: options.restartKey
1968
+ });
1969
+ return {
1970
+ actualPlacement: floating.actualPlacement,
1971
+ arrowStyle: floating.arrowStyle,
1972
+ contentStyle: floating.floatingStyle
1973
+ };
1974
+ }
1975
+ //#endregion
658
1976
  //#region src/components/dropdown-menu/useDropdownMenuRenderItems.ts
659
- function useDropdownMenuRenderItems({ items, getItemId, getSubmenuId, getMenuActiveDescendant, isItemFocused, isSubmenuOpen, activateItem, focusHoveredItem, selectItem, openSubmenu, closeSubmenu, close }) {
1977
+ function useDropdownMenuRenderItems({ props, actualPlacement, items, getItemId, getSubmenuId, getMenuActiveDescendant, getItemElement, isItemFocused, isSubmenuOpen, activateItem, focusHoveredItem, selectItem, openSubmenu, closeSubmenu, close }) {
660
1978
  const renderedItems = computed(() => getRenderedItems(items.value));
661
1979
  function getRenderedItems(dropdownItems, parentPath = []) {
662
1980
  return dropdownItems.map((item, index) => {
@@ -697,9 +2015,9 @@ function useDropdownMenuRenderItems({ items, getItemId, getSubmenuId, getMenuAct
697
2015
  "aria-expanded": hasSubmenu ? resolvedSubmenuOpen : void 0,
698
2016
  "aria-haspopup": hasSubmenu ? "menu" : void 0,
699
2017
  "aria-disabled": disabled || void 0,
700
- "data-disabled": disabled || void 0,
701
- "data-focused": focused || void 0,
702
- "data-submenu": hasSubmenu || void 0,
2018
+ "data-disabled": disabled ? "" : void 0,
2019
+ "data-highlighted": focused ? "" : void 0,
2020
+ "data-submenu": hasSubmenu ? "" : void 0,
703
2021
  onClick: (event) => activateItem(item, path, event),
704
2022
  onMouseenter: (event) => focusHoveredItem(item, path, event)
705
2023
  };
@@ -742,7 +2060,13 @@ function useDropdownMenuRenderItems({ items, getItemId, getSubmenuId, getMenuAct
742
2060
  isSubmenuOpen,
743
2061
  getItemProps,
744
2062
  getSubmenuProps,
745
- getItemSlotProps
2063
+ getItemSlotProps,
2064
+ getItemElement,
2065
+ getSubmenuPlacement: () => actualPlacement.value.endsWith("end") ? "left-start" : "right-start",
2066
+ getStrategy: () => props.strategy ?? "absolute",
2067
+ getFlip: () => props.flip !== false,
2068
+ getShift: () => props.shift !== false,
2069
+ getCollisionPadding: () => props.collisionPadding ?? 8
746
2070
  },
747
2071
  getItemProps,
748
2072
  getItemSlotProps
@@ -794,16 +2118,32 @@ function useDropdownSubmenus({ focusedPath, getItemAtPath, focusItem }) {
794
2118
  function useDropdownMenu(props, emit = {}) {
795
2119
  const rootRef = ref(null);
796
2120
  const menuRef = ref(null);
2121
+ const arrowRef = ref(null);
797
2122
  const uncontrolledOpen = ref(false);
798
2123
  const generatedId = useId();
799
2124
  const menuId = computed(() => props.id ?? `${generatedId}-menu`);
800
2125
  const placement = computed(() => props.placement ?? "bottom-start");
2126
+ const requestedTeleportTarget = computed(() => props.portalTo ?? props.teleportTo);
2127
+ const teleportTo = useTeleportTarget(() => requestedTeleportTarget.value);
2128
+ const shouldTeleport = computed(() => props.portal ?? props.teleport !== false);
2129
+ const { isExplicitTarget, reference, resolvedTarget } = useFloatingTarget(() => props.target, rootRef);
2130
+ const targetElement = computed(() => isElementReference(resolvedTarget.value) ? resolvedTarget.value : null);
801
2131
  const visibleItems = computed(() => props.items ?? []);
802
2132
  const isDisabled = computed(() => Boolean(props.disabled));
803
2133
  const isOpen = computed(() => props.open ?? uncontrolledOpen.value);
804
2134
  const isVisible = computed(() => isOpen.value && !isDisabled.value);
805
2135
  const contentHasSubmenu = computed(() => hasNestedItems(visibleItems.value));
806
2136
  const isEmpty = computed(() => visibleItems.value.length === 0);
2137
+ const { actualPlacement, arrowStyle, contentStyle } = useDropdownMenuPortalPosition({
2138
+ props,
2139
+ reference,
2140
+ menuRef,
2141
+ arrowRef,
2142
+ isVisible,
2143
+ placement,
2144
+ restartKey: () => [shouldTeleport.value, teleportTo.value]
2145
+ });
2146
+ const placementSide = computed(() => actualPlacement.value.split("-")[0]);
807
2147
  const { focusedPath, focusedIndex, getItemAtPath, focusItem, resetFocus, isItemFocused, moveFocus } = useDropdownMenuNavigation(visibleItems);
808
2148
  const submenus = useDropdownSubmenus({
809
2149
  focusedPath,
@@ -815,7 +2155,8 @@ function useDropdownMenu(props, emit = {}) {
815
2155
  menuId,
816
2156
  rootRef,
817
2157
  menuRef,
818
- placement,
2158
+ targetRef: targetElement,
2159
+ placement: actualPlacement,
819
2160
  focusedPath
820
2161
  });
821
2162
  const hoverIntent = useDropdownMenuHoverIntent({
@@ -827,6 +2168,8 @@ function useDropdownMenu(props, emit = {}) {
827
2168
  props,
828
2169
  emit,
829
2170
  rootRef,
2171
+ menuRef,
2172
+ targetRef: targetElement,
830
2173
  uncontrolledOpen,
831
2174
  isDisabled,
832
2175
  isOpen,
@@ -855,7 +2198,8 @@ function useDropdownMenu(props, emit = {}) {
855
2198
  isSubmenuOpeningLeft
856
2199
  });
857
2200
  const rootClass = computed(() => bem("rp-dropdown-menu", {
858
- [`placement-${placement.value}`]: true,
2201
+ [`placement-${actualPlacement.value}`]: true,
2202
+ target: isExplicitTarget.value,
859
2203
  open: isVisible.value,
860
2204
  disabled: isDisabled.value
861
2205
  }));
@@ -886,10 +2230,13 @@ function useDropdownMenu(props, emit = {}) {
886
2230
  toggle
887
2231
  }));
888
2232
  const { renderedItems, renderContext, getItemProps, getItemSlotProps } = useDropdownMenuRenderItems({
2233
+ props,
2234
+ actualPlacement,
889
2235
  items: visibleItems,
890
2236
  getItemId,
891
2237
  getSubmenuId,
892
2238
  getMenuActiveDescendant,
2239
+ getItemElement,
893
2240
  isItemFocused,
894
2241
  isSubmenuOpen,
895
2242
  activateItem,
@@ -899,9 +2246,49 @@ function useDropdownMenu(props, emit = {}) {
899
2246
  closeSubmenu,
900
2247
  close
901
2248
  });
2249
+ watch([isExplicitTarget, targetElement], ([explicit, target], _previous, onCleanup) => {
2250
+ if (!explicit || !target) return;
2251
+ target.addEventListener("click", onTriggerClick);
2252
+ target.addEventListener("keydown", onTriggerKeydown);
2253
+ onCleanup(() => {
2254
+ target.removeEventListener("click", onTriggerClick);
2255
+ target.removeEventListener("keydown", onTriggerKeydown);
2256
+ });
2257
+ }, { flush: "sync" });
2258
+ watch([
2259
+ isExplicitTarget,
2260
+ targetElement,
2261
+ menuId,
2262
+ isVisible,
2263
+ isDisabled
2264
+ ], ([explicit, target, id, visible, disabled], _previous, onCleanup) => {
2265
+ if (!explicit || !target) return;
2266
+ const snapshot = new Map([
2267
+ "aria-controls",
2268
+ "aria-expanded",
2269
+ "aria-haspopup",
2270
+ "aria-disabled"
2271
+ ].map((attribute) => [attribute, target.getAttribute(attribute)]));
2272
+ if (disabled) {
2273
+ target.removeAttribute("aria-controls");
2274
+ target.removeAttribute("aria-expanded");
2275
+ target.removeAttribute("aria-haspopup");
2276
+ target.setAttribute("aria-disabled", "true");
2277
+ } else {
2278
+ target.setAttribute("aria-controls", id);
2279
+ target.setAttribute("aria-expanded", String(visible));
2280
+ target.setAttribute("aria-haspopup", "menu");
2281
+ target.removeAttribute("aria-disabled");
2282
+ }
2283
+ onCleanup(() => {
2284
+ for (const [attribute, value] of snapshot) if (value == null) target.removeAttribute(attribute);
2285
+ else target.setAttribute(attribute, value);
2286
+ });
2287
+ }, { flush: "sync" });
902
2288
  return {
903
2289
  rootRef,
904
2290
  menuRef,
2291
+ arrowRef,
905
2292
  menuId,
906
2293
  isVisible,
907
2294
  isEmpty,
@@ -913,6 +2300,13 @@ function useDropdownMenu(props, emit = {}) {
913
2300
  activeDescendantId,
914
2301
  rootClass,
915
2302
  contentClass,
2303
+ contentStyle,
2304
+ arrowStyle,
2305
+ actualPlacement,
2306
+ placementSide,
2307
+ isTargetMode: isExplicitTarget,
2308
+ teleportTo,
2309
+ shouldTeleport,
916
2310
  triggerProps,
917
2311
  contentProps,
918
2312
  slotProps,
@@ -931,22 +2325,22 @@ function useDropdownMenu(props, emit = {}) {
931
2325
  }
932
2326
  //#endregion
933
2327
  //#region src/components/dropdown-menu/dropdown-menu.vue?vue&type=script&setup=true&vapor=true&lang.ts
934
- var t0 = template("No actions", 2);
935
- var t1 = template("<div class=rp-dropdown-menu__empty>");
936
- var t2 = template("<span class=rp-dropdown-menu__label> </span>");
937
- var t3 = template("<kbd class=rp-dropdown-menu__shortcut> ");
938
- var t4 = template("<span class=rp-dropdown-menu__submenu-icon aria-hidden=true>");
939
- var t5 = template("<div>");
2328
+ var t0 = template("<span class=rp-dropdown-menu__arrow aria-hidden=true>");
2329
+ var t1 = template("No actions", 2);
2330
+ var t2 = template("<div>");
2331
+ var t3 = template("<span> </span>");
2332
+ var t4 = template("<kbd> ");
2333
+ var t5 = template("<span>");
940
2334
  var t6 = template("<span>", 1);
941
2335
  //#endregion
942
2336
  //#region src/components/dropdown-menu/dropdown-menu.vue
943
2337
  var dropdown_menu_default = /* @__PURE__ */ defineVaporComponent({
944
2338
  name: "RpDropdownMenu",
2339
+ inheritAttrs: false,
945
2340
  __name: "dropdown-menu",
946
2341
  props: {
947
2342
  id: {},
948
2343
  items: { default: () => [] },
949
- placement: { default: "bottom-start" },
950
2344
  open: {
951
2345
  type: Boolean,
952
2346
  default: void 0
@@ -959,64 +2353,171 @@ var dropdown_menu_default = /* @__PURE__ */ defineVaporComponent({
959
2353
  type: Boolean,
960
2354
  default: true
961
2355
  },
962
- ariaLabel: {}
2356
+ ariaLabel: {},
2357
+ modal: {
2358
+ type: Boolean,
2359
+ default: false
2360
+ },
2361
+ portal: {
2362
+ type: Boolean,
2363
+ default: void 0
2364
+ },
2365
+ portalTo: {},
2366
+ target: {},
2367
+ placement: { default: "bottom-start" },
2368
+ strategy: { default: "absolute" },
2369
+ offset: {},
2370
+ flip: {
2371
+ type: Boolean,
2372
+ default: true
2373
+ },
2374
+ shift: {
2375
+ type: Boolean,
2376
+ default: true
2377
+ },
2378
+ collisionPadding: { default: 8 },
2379
+ arrow: {
2380
+ type: Boolean,
2381
+ default: false
2382
+ },
2383
+ teleport: {
2384
+ type: Boolean,
2385
+ default: true
2386
+ },
2387
+ teleportTo: {},
2388
+ classNames: {},
2389
+ styles: {}
963
2390
  },
964
2391
  emits: ["update:open", "select"],
965
2392
  setup(__props, { emit: __emit }) {
966
2393
  const props = __props;
967
2394
  const emit = __emit;
968
- const { rootRef, menuRef, isVisible, isEmpty, visibleItems, renderContext, rootClass, contentClass, contentProps, slotProps } = useDropdownMenu(props, {
2395
+ const { rootRef, menuRef, arrowRef, isVisible, isEmpty, visibleItems, renderContext, rootClass, contentClass, contentStyle, arrowStyle, placementSide, isTargetMode, teleportTo, shouldTeleport, contentProps, slotProps } = useDropdownMenu(props, {
969
2396
  openChange: (open) => emit("update:open", open),
970
- select: (item) => emit("select", item)
2397
+ select: (item, event) => emit("select", item, event)
2398
+ });
2399
+ const { getPartAttrs, getRootAttrs } = useStylesApi(props, "root");
2400
+ const state = computed(() => isVisible.value ? "open" : "closed");
2401
+ const rootAttrs = computed(() => getRootAttrs({
2402
+ class: rootClass.value,
2403
+ "data-state": state.value,
2404
+ "data-disabled": presence(props.disabled)
2405
+ }));
2406
+ const publicSlotProps = computed(() => {
2407
+ const partAttrs = getPartAttrs("trigger");
2408
+ return {
2409
+ ...slotProps.value,
2410
+ triggerProps: {
2411
+ ...slotProps.value.triggerProps,
2412
+ ...props.classNames?.trigger !== void 0 ? { class: partAttrs.class } : {},
2413
+ ...props.styles?.trigger !== void 0 ? { style: partAttrs.style } : {},
2414
+ "data-state": state.value,
2415
+ "data-disabled": presence(props.disabled)
2416
+ }
2417
+ };
971
2418
  });
2419
+ const publicContentProps = computed(() => ({
2420
+ ...contentProps.value,
2421
+ ...getPartAttrs("content", {
2422
+ class: contentClass.value,
2423
+ style: contentStyle.value
2424
+ }),
2425
+ "data-state": state.value,
2426
+ "data-placement": placementSide.value
2427
+ }));
2428
+ const publicRenderContext = computed(() => ({
2429
+ ...renderContext,
2430
+ getPublicPartAttrs: getPartAttrs
2431
+ }));
972
2432
  const _setTemplateRef = createTemplateRefSetter();
973
- const n23 = t6();
974
- renderEffect(() => setClass(n23, unref(rootClass)));
975
- setInsertionState(n23, null, 0);
976
- createSlot("default", { $: [() => unref(slotProps)] });
977
- setInsertionState(n23, null, 1);
978
- createComponent(VaporTransition, { name: "rp-dropdown-menu-content" }, extend(() => {
979
- return createIf(() => unref(isVisible), () => {
980
- const n21 = t5();
981
- renderEffect(() => setDynamicProps(n21, [{ class: unref(contentClass) }, unref(contentProps)]));
982
- setInsertionState(n21, null, 0);
983
- createIf(() => unref(isEmpty), () => {
984
- const n8 = t1();
985
- setInsertionState(n8, null, 0);
986
- createSlot("empty", null, () => {
987
- return t0();
2433
+ const n29 = t6();
2434
+ renderEffect(() => setDynamicProps(n29, [rootAttrs.value]));
2435
+ setInsertionState(n29, null, 0);
2436
+ createIf(() => !unref(isTargetMode), () => {
2437
+ return createSlot("default", { $: [() => publicSlotProps.value] });
2438
+ });
2439
+ setInsertionState(n29, null, 1);
2440
+ createComponent(VaporTeleport, {
2441
+ to: () => unref(teleportTo),
2442
+ disabled: () => !unref(shouldTeleport)
2443
+ }, () => {
2444
+ return createComponent(VaporTransition, { name: "rp-dropdown-menu-content" }, extend(() => {
2445
+ return createIf(() => unref(isVisible), () => {
2446
+ const n26 = t2();
2447
+ renderEffect(() => setDynamicProps(n26, [publicContentProps.value, { "data-side": unref(placementSide) }]));
2448
+ setInsertionState(n26, null, 0);
2449
+ createIf(() => __props.arrow, () => {
2450
+ const n7 = t0();
2451
+ _setTemplateRef(n7, arrowRef, null, "arrowRef");
2452
+ renderEffect(() => {
2453
+ setAttr(n7, "data-side", unref(placementSide));
2454
+ setStyle(n7, unref(arrowStyle));
2455
+ });
2456
+ return n7;
988
2457
  });
989
- return n8;
990
- });
991
- setInsertionState(n21, null, 1);
992
- createComponent(unref(dropdown_menu_items_default), {
993
- items: () => unref(visibleItems),
994
- context: () => unref(renderContext)
995
- }, { "item": extend((itemSlotProps) => {
996
- return [createSlot("item", { $: [() => itemSlotProps] }, () => {
997
- const n11 = t2();
998
- const x11 = txt(n11);
999
- renderEffect(() => setText(x11, toDisplayString(itemSlotProps.item.label)));
1000
- return [n11, createIf(() => itemSlotProps.item.shortcut, () => {
1001
- const n14 = t3();
1002
- const x14 = txt(n14);
1003
- renderEffect(() => setText(x14, toDisplayString(itemSlotProps.item.shortcut)));
1004
- return n14;
2458
+ setInsertionState(n26, null, 1);
2459
+ createIf(() => unref(isEmpty), () => {
2460
+ const n13 = t2();
2461
+ renderEffect(() => setDynamicProps(n13, [unref(getPartAttrs)("empty", { class: "rp-dropdown-menu__empty" })]));
2462
+ setInsertionState(n13, null, 0);
2463
+ createSlot("empty", null, () => {
2464
+ return t1();
2465
+ });
2466
+ return n13;
2467
+ });
2468
+ setInsertionState(n26, null, 2);
2469
+ createComponent(unref(dropdown_menu_items_default), {
2470
+ items: () => unref(visibleItems),
2471
+ context: () => publicRenderContext.value
2472
+ }, { "item": extend((itemSlotProps) => {
2473
+ return [createSlot("item", { $: [() => itemSlotProps] }, () => {
2474
+ const n16 = t3();
2475
+ const x16 = txt(n16);
2476
+ renderEffect(() => {
2477
+ setDynamicProps(n16, [unref(getPartAttrs)("label", { class: "rp-dropdown-menu__label" })]);
2478
+ setText(x16, toDisplayString(itemSlotProps.item.label));
2479
+ });
2480
+ return [n16, createIf(() => itemSlotProps.item.shortcut, () => {
2481
+ const n19 = t4();
2482
+ const x19 = txt(n19);
2483
+ renderEffect(() => {
2484
+ setDynamicProps(n19, [unref(getPartAttrs)("shortcut", { class: "rp-dropdown-menu__shortcut" })]);
2485
+ setText(x19, toDisplayString(itemSlotProps.item.shortcut));
2486
+ });
2487
+ return n19;
2488
+ }, null, 129)];
2489
+ }), createIf(() => itemSlotProps.hasSubmenu, () => {
2490
+ const n23 = t5();
2491
+ renderEffect(() => setDynamicProps(n23, [unref(getPartAttrs)("submenuIndicator", { class: "rp-dropdown-menu__submenu-icon" }), { "aria-hidden": "true" }]));
2492
+ setInsertionState(n23, null, 0);
2493
+ createComponent(unref(chevron_right_default));
2494
+ return n23;
1005
2495
  }, null, 129)];
1006
- }), createIf(() => itemSlotProps.hasSubmenu, () => {
1007
- const n18 = t4();
1008
- setInsertionState(n18, null, 0);
1009
- createComponent(unref(chevron_right_default));
1010
- return n18;
1011
- }, null, 129)];
1012
- }, { _: 8 }) });
1013
- _setTemplateRef(n21, menuRef, null, "menuRef");
1014
- return n21;
1015
- }, null, 129);
1016
- }, { _: 8 }));
1017
- setStaticTemplateRef(n23, rootRef, null, "rootRef");
1018
- return n23;
2496
+ }, { _: 8 }) });
2497
+ _setTemplateRef(n26, menuRef, null, "menuRef");
2498
+ return n26;
2499
+ }, null, 129);
2500
+ }, { _: 8 }));
2501
+ });
2502
+ setStaticTemplateRef(n29, rootRef, null, "rootRef");
2503
+ return n29;
1019
2504
  }
1020
2505
  });
1021
2506
  //#endregion
1022
- export { useDropdownMenu as n, dropdown_menu_default as t };
2507
+ //#region src/components/dropdown-menu/types.ts
2508
+ var dropdownMenuParts = [
2509
+ "root",
2510
+ "trigger",
2511
+ "content",
2512
+ "item",
2513
+ "label",
2514
+ "shortcut",
2515
+ "submenu",
2516
+ "submenuIndicator",
2517
+ "empty"
2518
+ ];
2519
+ //#endregion
2520
+ //#region src/components/dropdown-menu/index.ts
2521
+ var DropdownMenuItem = DropdownMenuItem$1;
2522
+ //#endregion
2523
+ export { DropdownMenuSubTrigger as _, DropdownMenuCheckboxItem as a, DropdownMenuItemIndicator as c, DropdownMenuRadioGroup as d, DropdownMenuRadioItem as f, DropdownMenuSubContent as g, DropdownMenuSub as h, useDropdownMenu as i, DropdownMenuLabel as l, DropdownMenuSeparator as m, dropdownMenuParts as n, DropdownMenuContent as o, DropdownMenuRoot as p, dropdown_menu_default as r, DropdownMenuContextTrigger as s, DropdownMenuItem as t, DropdownMenuPortal as u, DropdownMenuTrigger as v };