ropav 0.0.9 → 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 (289) 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 +91 -17
  27. package/dist/color-picker.css +309 -303
  28. package/dist/color-picker.js +250 -77
  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 +16 -4
  34. package/dist/components/accordion/accordion.d.ts +1 -1
  35. package/dist/components/accordion/index.d.ts +5 -4
  36. package/dist/components/accordion/index.js +2 -2
  37. package/dist/components/accordion/types.d.ts +10 -5
  38. package/dist/components/accordion/useAccordion.d.ts +1 -1
  39. package/dist/components/alert/alert.d.ts +3 -3
  40. package/dist/components/alert/index.d.ts +3 -3
  41. package/dist/components/alert/index.js +2 -2
  42. package/dist/components/alert/types.d.ts +5 -2
  43. package/dist/components/alert/useAlertColor.d.ts +1 -1
  44. package/dist/components/aspect-ratio/aspect-ratio.d.ts +1 -1
  45. package/dist/components/aspect-ratio/index.d.ts +3 -2
  46. package/dist/components/aspect-ratio/index.js +2 -2
  47. package/dist/components/aspect-ratio/types.d.ts +4 -1
  48. package/dist/components/avatar/avatar.d.ts +1 -1
  49. package/dist/components/avatar/index.d.ts +3 -3
  50. package/dist/components/avatar/index.js +2 -2
  51. package/dist/components/avatar/types.d.ts +5 -2
  52. package/dist/components/avatar/useAvatarColor.d.ts +1 -1
  53. package/dist/components/badge/badge.d.ts +1 -1
  54. package/dist/components/badge/index.d.ts +3 -3
  55. package/dist/components/badge/index.js +2 -2
  56. package/dist/components/badge/types.d.ts +5 -2
  57. package/dist/components/badge/useBadgeColor.d.ts +1 -1
  58. package/dist/components/button/button.d.ts +1 -1
  59. package/dist/components/button/index.d.ts +3 -2
  60. package/dist/components/button/index.js +2 -2
  61. package/dist/components/button/types.d.ts +5 -2
  62. package/dist/components/button/useButtonColor.d.ts +1 -1
  63. package/dist/components/button-group/button-group.d.ts +1 -1
  64. package/dist/components/button-group/index.d.ts +3 -2
  65. package/dist/components/button-group/index.js +2 -2
  66. package/dist/components/button-group/types.d.ts +4 -1
  67. package/dist/components/button-link/button-link.d.ts +1 -1
  68. package/dist/components/button-link/index.d.ts +3 -2
  69. package/dist/components/button-link/index.js +2 -2
  70. package/dist/components/button-link/types.d.ts +5 -2
  71. package/dist/components/card/card.d.ts +1 -1
  72. package/dist/components/card/index.d.ts +3 -2
  73. package/dist/components/card/index.js +2 -2
  74. package/dist/components/card/types.d.ts +5 -1
  75. package/dist/components/checkbox/checkbox.d.ts +5 -2
  76. package/dist/components/checkbox/index.d.ts +3 -2
  77. package/dist/components/checkbox/index.js +2 -2
  78. package/dist/components/checkbox/types.d.ts +7 -2
  79. package/dist/components/checkbox/useCheckbox.d.ts +4 -2
  80. package/dist/components/collapse/collapse.d.ts +2 -2
  81. package/dist/components/collapse/index.d.ts +4 -3
  82. package/dist/components/collapse/index.js +2 -2
  83. package/dist/components/collapse/types.d.ts +9 -2
  84. package/dist/components/collapse/useCollapse.d.ts +1 -1
  85. package/dist/components/color-input/color-input.d.ts +1 -1
  86. package/dist/components/color-input/index.d.ts +3 -2
  87. package/dist/components/color-input/index.js +2 -2
  88. package/dist/components/color-input/types.d.ts +8 -4
  89. package/dist/components/color-input/useColorInput.d.ts +5 -5
  90. package/dist/components/color-input/useColorInputEyeDropper.d.ts +1 -1
  91. package/dist/components/color-input/useColorInputPopover.d.ts +2 -2
  92. package/dist/components/color-input/useColorInputValue.d.ts +1 -1
  93. package/dist/components/color-picker/color-picker-saturation.d.ts +1 -1
  94. package/dist/components/color-picker/color-picker-slider.d.ts +1 -1
  95. package/dist/components/color-picker/color-picker-utils.d.ts +1 -1
  96. package/dist/components/color-picker/color-picker.d.ts +1 -1
  97. package/dist/components/color-picker/index.d.ts +3 -3
  98. package/dist/components/color-picker/index.js +2 -2
  99. package/dist/components/color-picker/types.d.ts +13 -1
  100. package/dist/components/color-picker/useColorPickerDrag.d.ts +7 -2
  101. package/dist/components/color-picker/useColorPickerSwatches.d.ts +1 -1
  102. package/dist/components/color-picker/useColorPickerValue.d.ts +2 -2
  103. package/dist/components/color-swatch/color-swatch.d.ts +1 -1
  104. package/dist/components/color-swatch/index.d.ts +3 -2
  105. package/dist/components/color-swatch/index.js +2 -1
  106. package/dist/components/color-swatch/types.d.ts +4 -1
  107. package/dist/components/dropdown-menu/dropdown-menu-items.d.ts +15 -6
  108. package/dist/components/dropdown-menu/dropdown-menu-primitives.d.ts +724 -0
  109. package/dist/components/dropdown-menu/dropdown-menu-utils.d.ts +1 -1
  110. package/dist/components/dropdown-menu/dropdown-menu.d.ts +3 -3
  111. package/dist/components/dropdown-menu/index.d.ts +55 -3
  112. package/dist/components/dropdown-menu/index.js +2 -2
  113. package/dist/components/dropdown-menu/types.d.ts +142 -6
  114. package/dist/components/dropdown-menu/useDropdownMenu.d.ts +21 -12
  115. package/dist/components/dropdown-menu/useDropdownMenuDisclosure.d.ts +6 -4
  116. package/dist/components/dropdown-menu/useDropdownMenuDom.d.ts +4 -3
  117. package/dist/components/dropdown-menu/useDropdownMenuHoverIntent.d.ts +2 -2
  118. package/dist/components/dropdown-menu/useDropdownMenuInteractions.d.ts +5 -5
  119. package/dist/components/dropdown-menu/useDropdownMenuNavigation.d.ts +3 -3
  120. package/dist/components/dropdown-menu/useDropdownMenuPortalPosition.d.ts +19 -0
  121. package/dist/components/dropdown-menu/useDropdownMenuRenderItems.d.ts +25 -5
  122. package/dist/components/dropdown-menu/useDropdownSubmenus.d.ts +3 -3
  123. package/dist/components/field/field.d.ts +2 -2
  124. package/dist/components/field/index.d.ts +3 -2
  125. package/dist/components/field/index.js +2 -2
  126. package/dist/components/field/types.d.ts +4 -1
  127. package/dist/components/field/useField.d.ts +1 -1
  128. package/dist/components/floating/index.d.ts +1 -0
  129. package/dist/components/floating/index.js +0 -0
  130. package/dist/components/floating/types.d.ts +31 -0
  131. package/dist/components/floating/useFloatingPosition.d.ts +38 -0
  132. package/dist/components/focus-trap/focus-trap.d.ts +31 -0
  133. package/dist/components/focus-trap/index.d.ts +4 -0
  134. package/dist/components/focus-trap/index.js +3 -0
  135. package/dist/components/focus-trap/types.d.ts +41 -0
  136. package/dist/components/focus-trap/useFocusTrap.d.ts +2 -0
  137. package/dist/components/icon-button/icon-button.d.ts +1 -1
  138. package/dist/components/icon-button/index.d.ts +3 -2
  139. package/dist/components/icon-button/index.js +2 -1
  140. package/dist/components/icon-button/types.d.ts +5 -2
  141. package/dist/components/input/index.d.ts +3 -2
  142. package/dist/components/input/index.js +2 -1
  143. package/dist/components/input/input.d.ts +1 -1
  144. package/dist/components/input/types.d.ts +4 -1
  145. package/dist/components/input/useInput.d.ts +2 -2
  146. package/dist/components/modal/index.d.ts +3 -2
  147. package/dist/components/modal/index.js +2 -2
  148. package/dist/components/modal/modal.d.ts +1 -1
  149. package/dist/components/modal/types.d.ts +9 -2
  150. package/dist/components/modal/useModal.d.ts +1 -1
  151. package/dist/components/number-input/index.d.ts +3 -2
  152. package/dist/components/number-input/index.js +2 -2
  153. package/dist/components/number-input/number-input.d.ts +1 -1
  154. package/dist/components/number-input/types.d.ts +5 -2
  155. package/dist/components/number-input/useNumberInput.d.ts +2 -2
  156. package/dist/components/overlay/index.d.ts +3 -2
  157. package/dist/components/overlay/index.js +2 -1
  158. package/dist/components/overlay/overlay.d.ts +1 -1
  159. package/dist/components/overlay/types.d.ts +4 -1
  160. package/dist/components/overlay/useOverlay.d.ts +1 -1
  161. package/dist/components/popover/index.d.ts +3 -3
  162. package/dist/components/popover/index.js +2 -2
  163. package/dist/components/popover/popover.d.ts +2 -2
  164. package/dist/components/popover/types.d.ts +21 -11
  165. package/dist/components/popover/usePopover.d.ts +11 -2
  166. package/dist/components/progress/index.d.ts +3 -3
  167. package/dist/components/progress/index.js +2 -2
  168. package/dist/components/progress/progress.d.ts +1 -1
  169. package/dist/components/progress/types.d.ts +5 -2
  170. package/dist/components/progress/useProgress.d.ts +2 -2
  171. package/dist/components/radio/index.d.ts +4 -3
  172. package/dist/components/radio/index.js +2 -2
  173. package/dist/components/radio/radio-group.d.ts +1 -1
  174. package/dist/components/radio/radio.d.ts +9 -4
  175. package/dist/components/radio/types.d.ts +21 -4
  176. package/dist/components/radio/useRadio.d.ts +10 -5
  177. package/dist/components/select/index.d.ts +3 -2
  178. package/dist/components/select/index.js +2 -2
  179. package/dist/components/select/select.d.ts +1 -1
  180. package/dist/components/select/types.d.ts +4 -1
  181. package/dist/components/select/useSelect.d.ts +4 -3
  182. package/dist/components/slider/index.d.ts +4 -4
  183. package/dist/components/slider/index.js +2 -2
  184. package/dist/components/slider/range-slider-tooltip.d.ts +37 -0
  185. package/dist/components/slider/range-slider.d.ts +8 -13
  186. package/dist/components/slider/slider.d.ts +5 -2
  187. package/dist/components/slider/sliderCore.d.ts +35 -0
  188. package/dist/components/slider/types.d.ts +14 -7
  189. package/dist/components/slider/useRangeSlider.d.ts +5 -7
  190. package/dist/components/slider/useRangeSliderPointer.d.ts +19 -0
  191. package/dist/components/slider/useRangeSliderTooltipCollision.d.ts +31 -2
  192. package/dist/components/slider/useRangeSliderTooltipState.d.ts +23 -0
  193. package/dist/components/slider/useSlider.d.ts +11 -15
  194. package/dist/components/switch/index.d.ts +3 -2
  195. package/dist/components/switch/index.js +2 -2
  196. package/dist/components/switch/switch.d.ts +5 -2
  197. package/dist/components/switch/types.d.ts +7 -2
  198. package/dist/components/switch/useSwitch.d.ts +4 -2
  199. package/dist/components/tabs/index.d.ts +7 -6
  200. package/dist/components/tabs/index.js +2 -2
  201. package/dist/components/tabs/tabs-content.d.ts +2 -2
  202. package/dist/components/tabs/tabs-list.d.ts +4 -4
  203. package/dist/components/tabs/tabs-trigger.d.ts +5 -5
  204. package/dist/components/tabs/tabs.d.ts +5 -5
  205. package/dist/components/tabs/types.d.ts +13 -4
  206. package/dist/components/tabs/useTabs.d.ts +1 -1
  207. package/dist/components/teleport-provider/index.d.ts +2 -0
  208. package/dist/components/teleport-provider/index.js +2 -0
  209. package/dist/components/teleport-provider/teleport-provider.d.ts +21 -0
  210. package/dist/components/teleport-provider/types.d.ts +4 -0
  211. package/dist/components/teleport-provider/useTeleportTarget.d.ts +5 -0
  212. package/dist/components/textarea/index.d.ts +3 -2
  213. package/dist/components/textarea/index.js +2 -2
  214. package/dist/components/textarea/textarea.d.ts +5 -2
  215. package/dist/components/textarea/types.d.ts +6 -1
  216. package/dist/components/textarea/useTextarea.d.ts +3 -2
  217. package/dist/components/toast/defaults.d.ts +7 -0
  218. package/dist/components/toast/index.d.ts +7 -0
  219. package/dist/components/toast/index.js +2 -0
  220. package/dist/components/toast/toast-provider.d.ts +21 -0
  221. package/dist/components/toast/toast-viewport.d.ts +34 -0
  222. package/dist/components/toast/toast.d.ts +31 -0
  223. package/dist/components/toast/types.d.ts +110 -0
  224. package/dist/components/toast/useToast.d.ts +4 -0
  225. package/dist/components/toast/useToastColor.d.ts +3 -0
  226. package/dist/components/toast/useToastState.d.ts +2 -0
  227. package/dist/components/tooltip/index.d.ts +3 -2
  228. package/dist/components/tooltip/index.js +2 -1
  229. package/dist/components/tooltip/tooltip.d.ts +2 -2
  230. package/dist/components/tooltip/types.d.ts +14 -13
  231. package/dist/components/tooltip/useTooltip.d.ts +15 -3
  232. package/dist/dropdown-menu.css +191 -107
  233. package/dist/dropdown-menu.js +1729 -107
  234. package/dist/field.css +41 -39
  235. package/dist/field.js +40 -16
  236. package/dist/focus-trap.js +80 -0
  237. package/dist/icon-button.css +193 -189
  238. package/dist/icon-button.js +23 -18
  239. package/dist/icon-button2.js +8 -0
  240. package/dist/index.d.ts +35 -30
  241. package/dist/index.js +36 -31
  242. package/dist/input.css +122 -120
  243. package/dist/input.js +47 -34
  244. package/dist/input2.js +9 -0
  245. package/dist/legacy-unlayered.css +5461 -0
  246. package/dist/modal.css +129 -127
  247. package/dist/modal.js +160 -200
  248. package/dist/number-input.css +87 -85
  249. package/dist/number-input.js +61 -17
  250. package/dist/overlay.css +26 -24
  251. package/dist/overlay.js +17 -9
  252. package/dist/overlay2.js +4 -0
  253. package/dist/popover.css +140 -107
  254. package/dist/popover.js +295 -189
  255. package/dist/popover2.js +6 -1
  256. package/dist/progress.css +101 -99
  257. package/dist/progress.js +50 -28
  258. package/dist/radio.css +114 -105
  259. package/dist/radio.js +154 -56
  260. package/dist/select.css +244 -242
  261. package/dist/select.js +92 -47
  262. package/dist/slider.css +1109 -904
  263. package/dist/slider.js +1118 -923
  264. package/dist/styles-api.d.ts +22 -0
  265. package/dist/styles-api.js +49 -0
  266. package/dist/switch.css +120 -108
  267. package/dist/switch.js +89 -33
  268. package/dist/tabs.css +286 -278
  269. package/dist/tabs.js +60 -21
  270. package/dist/teleport-provider.js +15 -0
  271. package/dist/textarea.css +132 -130
  272. package/dist/textarea.js +77 -29
  273. package/dist/toast.css +236 -0
  274. package/dist/toast.js +739 -0
  275. package/dist/tooltip.css +137 -107
  276. package/dist/tooltip.js +182 -223
  277. package/dist/tooltip2.js +8 -0
  278. package/dist/useClickOutside.js +1 -1
  279. package/dist/useFloatingPosition.js +1284 -0
  280. package/dist/useFocusTrap.js +130 -0
  281. package/dist/useTeleportTarget.js +29 -0
  282. package/dist/utils/componentColors.d.ts +60 -0
  283. package/docs/public-styles-api.md +133 -0
  284. package/docs/public-tokens.md +545 -0
  285. package/package.json +44 -12
  286. package/src/styles/_tokens.scss +33 -28
  287. package/src/styles/_utilities.scss +11 -9
  288. package/src/styles/styles-manifest.json +4125 -0
  289. package/dist/components/slider/useRangeSliderTooltipTransition.d.ts +0 -4
package/dist/popover.js CHANGED
@@ -1,7 +1,11 @@
1
1
  import './popover.css';
2
2
  import { t as bem } from "./bem.js";
3
+ import { n as useStylesApi, t as presence } from "./styles-api.js";
3
4
  import { t as _plugin_vue_export_helper_default } from "./_plugin-vue_export-helper.js";
4
- import { VaporTransition, applyVShow, computed, createComponent, createIf, createSlot, defineVaporComponent, extend, isRef, onMounted, ref, renderEffect, setAttr, setClass, setInsertionState, setProp, setStaticTemplateRef, setStyle, template, unref, useId, useSlots, watch } from "vue";
5
+ import { t as useFocusTrap } from "./useFocusTrap.js";
6
+ import { n as useFloatingPosition, r as useFloatingTarget, t as isElementReference } from "./useFloatingPosition.js";
7
+ import { n as useTeleportTarget } from "./useTeleportTarget.js";
8
+ import { VaporTeleport, VaporTransition, applyVShow, computed, createComponent, createIf, createInvoker, createSlot, createTemplateRefSetter, defineVaporComponent, delegateEvents, extend, isRef, nextTick, ref, renderEffect, setAttr, setDynamicProps, setInsertionState, setStaticTemplateRef, setStyle, template, unref, useAttrs, useId, useSlots, watch } from "vue";
5
9
  //#region src/components/popover/usePopover.ts
6
10
  var DEFAULT_PLACEMENT = "bottom";
7
11
  var DEFAULT_ROLE = "dialog";
@@ -10,51 +14,14 @@ var TARGET_ATTRIBUTES = [
10
14
  "aria-expanded",
11
15
  "aria-haspopup"
12
16
  ];
13
- function isHTMLElement(value) {
14
- return typeof HTMLElement !== "undefined" && value instanceof HTMLElement;
15
- }
16
- function getTargetPosition(rect, placement) {
17
- const centerX = rect.left + rect.width / 2;
18
- const centerY = rect.top + rect.height / 2;
19
- const [side, alignment = "center"] = placement.split("-");
20
- const alignedX = alignment === "start" ? rect.left : alignment === "end" ? rect.right : centerX;
21
- const alignedY = alignment === "start" ? rect.top : alignment === "end" ? rect.bottom : centerY;
22
- switch (side) {
23
- case "right": return {
24
- x: rect.right,
25
- y: alignedY
26
- };
27
- case "bottom": return {
28
- x: alignedX,
29
- y: rect.bottom
30
- };
31
- case "left": return {
32
- x: rect.left,
33
- y: alignedY
34
- };
35
- default: return {
36
- x: alignedX,
37
- y: rect.top
38
- };
39
- }
40
- }
41
- function setPixelVar(style, variable, value) {
42
- if (value != null) style[variable] = `${value}px`;
43
- }
44
- function styleOrUndefined(style) {
45
- return Object.keys(style).length > 0 ? style : void 0;
46
- }
47
- function resolveOffsetStyle(offset) {
48
- if (offset == null) return void 0;
49
- const style = {};
50
- if (typeof offset === "number") {
51
- setPixelVar(style, "--_rp-popover-main-axis-offset", offset);
52
- return style;
53
- }
54
- setPixelVar(style, "--_rp-popover-main-axis-offset", offset.mainAxis);
55
- setPixelVar(style, "--_rp-popover-cross-axis-offset", offset.crossAxis);
56
- return styleOrUndefined(style);
57
- }
17
+ var TABBABLE_SELECTOR = [
18
+ "a[href]",
19
+ "button:not([disabled])",
20
+ "input:not([disabled])",
21
+ "select:not([disabled])",
22
+ "textarea:not([disabled])",
23
+ "[tabindex]:not([tabindex=\"-1\"])"
24
+ ].join(",");
58
25
  function addIdReference(currentValue, id) {
59
26
  const ids = (currentValue ?? "").split(/\s+/).filter(Boolean);
60
27
  if (!ids.includes(id)) ids.push(id);
@@ -77,51 +44,72 @@ function applyTargetAttributes(element, snapshot, options) {
77
44
  element.setAttribute("aria-expanded", String(options.expanded));
78
45
  element.setAttribute("aria-haspopup", options.role);
79
46
  }
80
- function resolveTargetElement(target) {
81
- if (!target) return null;
82
- if (typeof target !== "string") return isHTMLElement(target) ? target : null;
83
- if (typeof document === "undefined") return null;
84
- try {
85
- const element = document.querySelector(target);
86
- return isHTMLElement(element) ? element : null;
87
- } catch {
88
- return null;
89
- }
47
+ function isFocusTrapContainer(value) {
48
+ return typeof HTMLElement !== "undefined" && value instanceof HTMLElement || typeof SVGElement !== "undefined" && value instanceof SVGElement;
49
+ }
50
+ function resolveOffsetStyle(offset) {
51
+ if (offset == null) return void 0;
52
+ if (typeof offset === "number") return { "--_rp-popover-main-axis-offset": `${offset}px` };
53
+ const style = {};
54
+ if (offset.mainAxis != null) style["--_rp-popover-main-axis-offset"] = `${offset.mainAxis}px`;
55
+ if (offset.crossAxis != null) style["--_rp-popover-cross-axis-offset"] = `${offset.crossAxis}px`;
56
+ return Object.keys(style).length > 0 ? style : void 0;
90
57
  }
91
58
  function usePopover(props, emitOpenChange) {
92
59
  const slots = useSlots();
60
+ const attrs = useAttrs();
93
61
  const generatedId = useId();
94
62
  const rootRef = ref(null);
95
- const targetElement = ref(null);
96
- const targetPosition = ref(null);
63
+ const contentRef = ref(null);
64
+ const arrowRef = ref(null);
97
65
  const uncontrolledOpen = ref(false);
98
66
  const popoverId = computed(() => props.id ?? `${generatedId}-popover`);
99
67
  const placement = computed(() => props.placement ?? DEFAULT_PLACEMENT);
100
68
  const popoverRole = computed(() => props.role ?? DEFAULT_ROLE);
101
- const isTargetMode = computed(() => props.target != null && props.target !== "");
102
- const hasContent = computed(() => Boolean(slots.content || isTargetMode.value && slots.default));
69
+ const teleportTo = useTeleportTarget(() => props.teleportTo);
70
+ const { isExplicitTarget, reference, resolvedTarget } = useFloatingTarget(() => props.target, rootRef);
71
+ const targetElement = computed(() => isElementReference(resolvedTarget.value) ? resolvedTarget.value : null);
72
+ const hasContent = computed(() => Boolean(slots.content || isExplicitTarget.value && slots.default));
103
73
  const isDisabled = computed(() => Boolean(props.disabled || !hasContent.value));
104
74
  const isOpen = computed(() => props.open ?? uncontrolledOpen.value);
105
75
  const isVisible = computed(() => isOpen.value && !isDisabled.value);
106
- const shouldRenderContent = computed(() => !isDisabled.value);
107
- const shouldWireTarget = computed(() => isTargetMode.value && !isDisabled.value);
76
+ const shouldRenderContent = computed(() => !isDisabled.value && (Boolean(props.keepMounted) || isVisible.value));
77
+ const shouldShowContent = computed(() => !props.keepMounted || isVisible.value);
108
78
  const ariaLabel = computed(() => props.ariaLabel || void 0);
109
79
  const ariaLabelledby = computed(() => props.ariaLabelledby || void 0);
110
80
  const ariaDescribedby = computed(() => props.ariaDescribedby || void 0);
81
+ const focusTrapContainers = computed(() => {
82
+ const content = contentRef.value;
83
+ if (!content) return null;
84
+ const trigger = targetElement.value ?? rootRef.value;
85
+ return isFocusTrapContainer(trigger) ? [trigger, content] : content;
86
+ });
87
+ const floating = useFloatingPosition({
88
+ reference,
89
+ floating: contentRef,
90
+ arrow: arrowRef,
91
+ open: isVisible,
92
+ placement: () => placement.value,
93
+ strategy: () => props.strategy ?? "absolute",
94
+ offset: () => props.offset,
95
+ flip: () => props.flip !== false,
96
+ shift: () => props.shift !== false,
97
+ collisionPadding: () => props.collisionPadding ?? 8,
98
+ arrowEnabled: () => Boolean(props.arrow),
99
+ restartKey: () => teleportTo.value
100
+ });
101
+ const placementSide = computed(() => floating.actualPlacement.value.split("-")[0]);
111
102
  const rootClass = computed(() => bem("rp-popover", {
112
- [`placement-${placement.value}`]: true,
113
- target: isTargetMode.value,
103
+ [`placement-${floating.actualPlacement.value}`]: true,
104
+ target: isExplicitTarget.value,
114
105
  open: isVisible.value,
115
- disabled: props.disabled
106
+ disabled: props.disabled,
107
+ arrow: props.arrow
108
+ }));
109
+ const contentStyle = computed(() => ({
110
+ ...floating.floatingStyle.value,
111
+ ...resolveOffsetStyle(props.offset)
116
112
  }));
117
- const contentStyle = computed(() => {
118
- const style = { ...resolveOffsetStyle(props.offset) };
119
- if (isTargetMode.value && targetPosition.value) {
120
- setPixelVar(style, "--_rp-popover-target-x", targetPosition.value.x);
121
- setPixelVar(style, "--_rp-popover-target-y", targetPosition.value.y);
122
- }
123
- return styleOrUndefined(style);
124
- });
125
113
  const triggerProps = computed(() => ({
126
114
  "aria-controls": isDisabled.value ? void 0 : popoverId.value,
127
115
  "aria-expanded": isDisabled.value ? void 0 : isVisible.value,
@@ -139,18 +127,37 @@ function usePopover(props, emitOpenChange) {
139
127
  triggerProps: triggerProps.value,
140
128
  ...contentSlotProps.value
141
129
  }));
130
+ let shouldReturnFocus = props.returnFocus !== false;
131
+ const focusTrap = useFocusTrap(focusTrapContainers, {
132
+ ...props.focusTrapOptions,
133
+ initialFocus: () => {
134
+ const initialFocus = props.initialFocus;
135
+ return isRef(initialFocus) ? initialFocus.value ?? void 0 : initialFocus ?? void 0;
136
+ },
137
+ fallbackFocus: () => contentRef.value,
138
+ returnFocusOnDeactivate: props.returnFocus !== false,
139
+ escapeDeactivates: false,
140
+ allowOutsideClick: true
141
+ });
142
142
  function setOpen(nextOpen) {
143
143
  const previousOpen = isOpen.value;
144
144
  if (props.open === void 0) uncontrolledOpen.value = nextOpen;
145
145
  if (previousOpen !== nextOpen) emitOpenChange?.(nextOpen);
146
146
  }
147
147
  function openPopover() {
148
- if (isDisabled.value) return;
149
- updateTargetPosition();
150
- setOpen(true);
148
+ if (!isDisabled.value) setOpen(true);
151
149
  }
152
150
  function closePopover() {
151
+ shouldReturnFocus = props.returnFocus !== false;
152
+ setOpen(false);
153
+ }
154
+ function closePopoverWithoutReturnFocus() {
155
+ shouldReturnFocus = false;
156
+ if (props.trapFocus) focusTrap.deactivate({ returnFocus: false });
153
157
  setOpen(false);
158
+ nextTick(() => {
159
+ if (props.trapFocus && isVisible.value) focusTrap.activate();
160
+ });
154
161
  }
155
162
  function togglePopover() {
156
163
  if (isVisible.value) closePopover();
@@ -164,139 +171,152 @@ function usePopover(props, emitOpenChange) {
164
171
  event.stopPropagation();
165
172
  closePopover();
166
173
  }
167
- function onTargetClick() {
168
- togglePopover();
169
- }
170
- function readTarget() {
171
- return isRef(props.target) ? props.target.value : props.target;
172
- }
173
- function updateTargetPosition() {
174
- if (!isTargetMode.value || !targetElement.value) {
175
- targetPosition.value = null;
176
- return;
177
- }
178
- targetPosition.value = getTargetPosition(targetElement.value.getBoundingClientRect(), placement.value);
179
- }
180
174
  function isEventInsidePopover(event) {
181
175
  const eventTarget = event.target;
182
176
  if (typeof Node === "undefined" || !(eventTarget instanceof Node)) return false;
183
- return Boolean(rootRef.value?.contains(eventTarget) || targetElement.value?.contains(eventTarget));
177
+ return Boolean(rootRef.value?.contains(eventTarget) || contentRef.value?.contains(eventTarget) || targetElement.value?.contains(eventTarget));
178
+ }
179
+ function onCompositeFocusout(event) {
180
+ const nextTarget = event.relatedTarget;
181
+ if (nextTarget instanceof Node && (rootRef.value?.contains(nextTarget) || contentRef.value?.contains(nextTarget) || targetElement.value?.contains(nextTarget))) return;
182
+ const listener = attrs.onFocusout;
183
+ const listeners = Array.isArray(listener) ? listener : [listener];
184
+ for (const current of listeners) if (typeof current === "function") current(event);
184
185
  }
185
186
  function onDocumentClick(event) {
186
187
  if (props.closeOnOutsideClick === false || isEventInsidePopover(event)) return;
187
- closePopover();
188
+ closePopoverWithoutReturnFocus();
189
+ }
190
+ function onDocumentPointerDown(event) {
191
+ if (!props.trapFocus) return;
192
+ if (props.closeOnOutsideClick === false || isEventInsidePopover(event)) return;
193
+ closePopoverWithoutReturnFocus();
188
194
  }
189
195
  function onDocumentKeydown(event) {
196
+ if (props.trapFocus && event.key === "Tab") {
197
+ const containers = [targetElement.value ?? rootRef.value, contentRef.value];
198
+ const tabbables = [];
199
+ for (const container of containers) {
200
+ if (!container) continue;
201
+ if (container instanceof HTMLElement && container.matches(TABBABLE_SELECTOR)) tabbables.push(container);
202
+ tabbables.push(...container.querySelectorAll(TABBABLE_SELECTOR));
203
+ }
204
+ const active = event.target;
205
+ const first = tabbables[0];
206
+ const last = tabbables[tabbables.length - 1];
207
+ if (event.shiftKey && active === first && last) {
208
+ event.preventDefault();
209
+ last.focus();
210
+ return;
211
+ }
212
+ if (!event.shiftKey && active === last && first) {
213
+ event.preventDefault();
214
+ first.focus();
215
+ return;
216
+ }
217
+ }
190
218
  if (props.closeOnEscape === false || event.key !== "Escape") return;
191
219
  closePopover();
192
220
  }
193
- function syncTargetElement() {
194
- const nextTarget = isTargetMode.value ? resolveTargetElement(readTarget()) : null;
195
- if (targetElement.value !== nextTarget) targetElement.value = nextTarget;
196
- if (!nextTarget) {
197
- targetPosition.value = null;
198
- return;
199
- }
200
- if (isVisible.value) updateTargetPosition();
201
- }
202
221
  watch(isDisabled, (disabled) => {
203
222
  if (disabled) closePopover();
204
223
  });
205
- watch(() => readTarget(), () => syncTargetElement(), { flush: "post" });
206
- watch([shouldWireTarget, targetElement], ([shouldWire, target], _previous, onCleanup) => {
207
- if (!shouldWire || !target) return;
208
- target.addEventListener("click", onTargetClick);
209
- onCleanup(() => {
210
- target.removeEventListener("click", onTargetClick);
211
- });
224
+ watch([isVisible, () => props.trapFocus], ([visible, trapFocus]) => {
225
+ if (visible && trapFocus) {
226
+ shouldReturnFocus = props.returnFocus !== false;
227
+ focusTrap.activate();
228
+ return;
229
+ }
230
+ focusTrap.deactivate({ returnFocus: shouldReturnFocus && props.returnFocus !== false });
231
+ shouldReturnFocus = props.returnFocus !== false;
232
+ }, {
233
+ flush: "post",
234
+ immediate: true
235
+ });
236
+ watch([isExplicitTarget, targetElement], ([explicit, target], _previous, onCleanup) => {
237
+ if (!explicit || !target) return;
238
+ target.addEventListener("click", onTriggerClick);
239
+ onCleanup(() => target.removeEventListener("click", onTriggerClick));
212
240
  }, { flush: "sync" });
213
241
  watch([
214
- shouldWireTarget,
242
+ isExplicitTarget,
215
243
  targetElement,
216
244
  popoverId,
217
245
  popoverRole,
218
- isVisible
219
- ], ([shouldWire, target], _previous, onCleanup) => {
220
- if (!shouldWire || !target) return;
246
+ isVisible,
247
+ isDisabled
248
+ ], ([explicit, target, id, role, visible, disabled], _previous, onCleanup) => {
249
+ if (!explicit || !target || disabled) return;
221
250
  const snapshot = snapshotAttributes(target);
222
251
  applyTargetAttributes(target, snapshot, {
223
- id: popoverId.value,
224
- expanded: isVisible.value,
225
- role: popoverRole.value
226
- });
227
- onCleanup(() => {
228
- restoreAttributes(target, snapshot);
229
- });
230
- }, { flush: "sync" });
231
- watch([
232
- isVisible,
233
- isTargetMode,
234
- targetElement
235
- ], ([visible, targetMode, target], _previous, onCleanup) => {
236
- if (!visible || !targetMode || !target || typeof window === "undefined") return;
237
- window.addEventListener("resize", updateTargetPosition);
238
- window.addEventListener("scroll", updateTargetPosition, true);
239
- onCleanup(() => {
240
- window.removeEventListener("resize", updateTargetPosition);
241
- window.removeEventListener("scroll", updateTargetPosition, true);
252
+ id,
253
+ expanded: visible,
254
+ role
242
255
  });
256
+ onCleanup(() => restoreAttributes(target, snapshot));
243
257
  }, { flush: "sync" });
244
258
  watch(isVisible, (visible, _previous, onCleanup) => {
245
259
  if (!visible || typeof document === "undefined") return;
246
260
  document.addEventListener("click", onDocumentClick, true);
261
+ document.addEventListener("mousedown", onDocumentPointerDown, true);
262
+ document.addEventListener("touchstart", onDocumentPointerDown, true);
247
263
  document.addEventListener("keydown", onDocumentKeydown);
248
264
  onCleanup(() => {
249
265
  document.removeEventListener("click", onDocumentClick, true);
266
+ document.removeEventListener("mousedown", onDocumentPointerDown, true);
267
+ document.removeEventListener("touchstart", onDocumentPointerDown, true);
250
268
  document.removeEventListener("keydown", onDocumentKeydown);
251
269
  });
252
270
  }, {
253
271
  flush: "sync",
254
272
  immediate: true
255
273
  });
256
- watch([
257
- targetElement,
258
- placement,
259
- isVisible
260
- ], () => {
261
- if (isVisible.value) updateTargetPosition();
262
- }, { flush: "sync" });
263
- onMounted(syncTargetElement);
264
274
  return {
265
275
  rootRef,
276
+ contentRef,
277
+ arrowRef,
266
278
  popoverId,
267
279
  isOpen,
280
+ isDisabled,
268
281
  isVisible,
269
- isTargetMode,
282
+ isTargetMode: isExplicitTarget,
270
283
  popoverRole,
271
284
  ariaLabel,
272
285
  ariaLabelledby,
273
286
  ariaDescribedby,
274
287
  shouldRenderContent,
288
+ shouldShowContent,
275
289
  rootClass,
276
290
  contentStyle,
277
291
  triggerProps,
278
292
  slotProps,
279
293
  contentSlotProps,
294
+ actualPlacement: floating.actualPlacement,
295
+ placementSide,
296
+ arrowStyle: floating.arrowStyle,
297
+ teleportTo,
280
298
  openPopover,
281
299
  closePopover,
282
300
  togglePopover,
283
- onTriggerKeydown
301
+ onTriggerKeydown,
302
+ onCompositeFocusout
284
303
  };
285
304
  }
286
305
  //#endregion
287
306
  //#region src/components/popover/popover.vue?vue&type=script&setup=true&vapor=true&lang.ts
288
- var t0 = template("<section data-v-fd62ef9b class=rp-popover__content>");
289
- var t1 = template("<span data-v-fd62ef9b>", 1);
307
+ var t0 = template("<span data-v-8af57bff class=rp-popover__arrow aria-hidden=true>");
308
+ var t1 = template("<section data-v-8af57bff>");
309
+ var t2 = template("<span data-v-8af57bff>", 1);
310
+ delegateEvents("focusout");
290
311
  //#endregion
291
312
  //#region src/components/popover/popover.vue
292
313
  var popover_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE__ */ defineVaporComponent({
293
314
  name: "RpPopover",
315
+ inheritAttrs: false,
294
316
  __name: "popover",
295
317
  props: {
296
318
  id: {},
297
- target: {},
298
- placement: { default: "bottom" },
299
- offset: {},
319
+ contentClass: {},
300
320
  open: {
301
321
  type: Boolean,
302
322
  default: void 0
@@ -316,65 +336,151 @@ var popover_default = /*#__PURE__*/ _plugin_vue_export_helper_default(/* @__PURE
316
336
  closeOnEscape: {
317
337
  type: Boolean,
318
338
  default: true
319
- }
339
+ },
340
+ keepMounted: {
341
+ type: Boolean,
342
+ default: false
343
+ },
344
+ trapFocus: {
345
+ type: Boolean,
346
+ default: false
347
+ },
348
+ initialFocus: { default: null },
349
+ returnFocus: {
350
+ type: Boolean,
351
+ default: true
352
+ },
353
+ focusTrapOptions: { default: () => ({}) },
354
+ target: {},
355
+ placement: { default: "bottom" },
356
+ strategy: { default: "absolute" },
357
+ offset: {},
358
+ flip: {
359
+ type: Boolean,
360
+ default: true
361
+ },
362
+ shift: {
363
+ type: Boolean,
364
+ default: true
365
+ },
366
+ collisionPadding: { default: 8 },
367
+ arrow: {
368
+ type: Boolean,
369
+ default: false
370
+ },
371
+ teleport: {
372
+ type: Boolean,
373
+ default: true
374
+ },
375
+ teleportTo: {},
376
+ classNames: {},
377
+ styles: {}
320
378
  },
321
379
  emits: ["update:open"],
322
380
  setup(__props, { emit: __emit }) {
323
381
  const props = __props;
324
382
  const emit = __emit;
325
- const { rootRef, popoverId, isVisible, isTargetMode, popoverRole, ariaLabel, ariaLabelledby, ariaDescribedby, shouldRenderContent, rootClass, contentStyle, slotProps, contentSlotProps } = usePopover(props, (open) => {
383
+ const { rootRef, contentRef, arrowRef, popoverId, isDisabled, isTargetMode, popoverRole, ariaLabel, ariaLabelledby, ariaDescribedby, shouldRenderContent, shouldShowContent, rootClass, contentStyle, slotProps, contentSlotProps, actualPlacement, placementSide, arrowStyle, teleportTo, onCompositeFocusout } = usePopover(props, (open) => {
326
384
  emit("update:open", open);
327
385
  });
328
- const n12 = t1();
329
- renderEffect(() => setClass(n12, unref(rootClass)));
330
- setInsertionState(n12, null, 0);
386
+ const { getPartAttrs, getRootAttrs } = useStylesApi(props, "root");
387
+ const publicRootAttrs = computed(() => getRootAttrs({
388
+ class: rootClass.value,
389
+ onFocusout: onCompositeFocusout,
390
+ "data-state": slotProps.value.isOpen ? "open" : "closed",
391
+ "data-disabled": presence(isDisabled.value)
392
+ }, {}, ["onFocusout"]));
393
+ const styledTriggerProps = computed(() => {
394
+ const partAttrs = getPartAttrs("trigger");
395
+ return {
396
+ ...slotProps.value.triggerProps,
397
+ ...props.classNames?.trigger !== void 0 ? { class: partAttrs.class } : {},
398
+ ...props.styles?.trigger !== void 0 ? { style: partAttrs.style } : {},
399
+ "data-state": slotProps.value.isOpen ? "open" : "closed",
400
+ "data-disabled": presence(isDisabled.value)
401
+ };
402
+ });
403
+ const contentAttrs = computed(() => ({
404
+ ...getPartAttrs("content", {
405
+ class: "rp-popover__content",
406
+ compatibilityClass: props.contentClass,
407
+ style: contentStyle.value
408
+ }),
409
+ "data-state": slotProps.value.isOpen ? "open" : "closed",
410
+ "data-placement": actualPlacement.value
411
+ }));
412
+ const _setTemplateRef = createTemplateRefSetter();
413
+ const n16 = t2();
414
+ renderEffect(() => setDynamicProps(n16, [publicRootAttrs.value]));
415
+ setInsertionState(n16, null, 0);
331
416
  createIf(() => !unref(isTargetMode), () => {
332
417
  return createSlot("default", {
333
- triggerProps: () => unref(slotProps).triggerProps,
418
+ triggerProps: () => styledTriggerProps.value,
334
419
  isOpen: () => unref(slotProps).isOpen,
335
420
  open: () => unref(slotProps).open,
336
421
  close: () => unref(slotProps).close,
337
422
  toggle: () => unref(slotProps).toggle
338
423
  }, null, 1);
339
424
  });
340
- setInsertionState(n12, null, 1);
341
- createComponent(VaporTransition, {
342
- name: "rp-popover-content",
343
- persisted: ""
344
- }, extend(() => {
345
- return createIf(() => unref(shouldRenderContent), () => {
346
- const n10 = t0();
347
- renderEffect(() => {
348
- setProp(n10, "id", unref(popoverId));
349
- setProp(n10, "role", unref(popoverRole));
350
- setAttr(n10, "aria-label", unref(ariaLabel));
351
- setAttr(n10, "aria-labelledby", unref(ariaLabelledby));
352
- setAttr(n10, "aria-describedby", unref(ariaDescribedby));
353
- setStyle(n10, unref(contentStyle));
354
- });
355
- setInsertionState(n10, null, 0);
356
- createSlot("content", {
357
- isOpen: () => unref(contentSlotProps).isOpen,
358
- open: () => unref(contentSlotProps).open,
359
- close: () => unref(contentSlotProps).close,
360
- toggle: () => unref(contentSlotProps).toggle
361
- }, () => {
362
- return createIf(() => unref(isTargetMode), () => {
363
- return createSlot("default", {
364
- isOpen: () => unref(contentSlotProps).isOpen,
365
- open: () => unref(contentSlotProps).open,
366
- close: () => unref(contentSlotProps).close,
367
- toggle: () => unref(contentSlotProps).toggle
368
- }, null, 1);
369
- }, null, 129);
370
- }, 1);
371
- applyVShow(n10, () => unref(isVisible));
372
- return n10;
373
- }, null, 129);
374
- }, { _: 8 }));
375
- setStaticTemplateRef(n12, rootRef, null, "rootRef");
376
- return n12;
425
+ setInsertionState(n16, null, 1);
426
+ createComponent(VaporTeleport, {
427
+ to: () => unref(teleportTo),
428
+ disabled: () => !__props.teleport
429
+ }, () => {
430
+ return createComponent(VaporTransition, {
431
+ name: "rp-popover-content",
432
+ persisted: ""
433
+ }, extend(() => {
434
+ return createIf(() => unref(shouldRenderContent), () => {
435
+ const n13 = t1();
436
+ renderEffect(() => setDynamicProps(n13, [
437
+ { id: unref(popoverId) },
438
+ contentAttrs.value,
439
+ {
440
+ role: unref(popoverRole),
441
+ "aria-label": unref(ariaLabel),
442
+ "aria-labelledby": unref(ariaLabelledby),
443
+ "aria-describedby": unref(ariaDescribedby),
444
+ "data-side": unref(placementSide),
445
+ tabindex: __props.trapFocus ? -1 : void 0
446
+ }
447
+ ]));
448
+ setInsertionState(n13, null, 0);
449
+ createSlot("content", {
450
+ isOpen: () => unref(contentSlotProps).isOpen,
451
+ open: () => unref(contentSlotProps).open,
452
+ close: () => unref(contentSlotProps).close,
453
+ toggle: () => unref(contentSlotProps).toggle
454
+ }, () => {
455
+ return createIf(() => unref(isTargetMode), () => {
456
+ return createSlot("default", {
457
+ isOpen: () => unref(contentSlotProps).isOpen,
458
+ open: () => unref(contentSlotProps).open,
459
+ close: () => unref(contentSlotProps).close,
460
+ toggle: () => unref(contentSlotProps).toggle
461
+ }, null, 1);
462
+ }, null, 129);
463
+ }, 1);
464
+ setInsertionState(n13, null, 1);
465
+ createIf(() => __props.arrow, () => {
466
+ const n12 = t0();
467
+ _setTemplateRef(n12, arrowRef, null, "arrowRef");
468
+ renderEffect(() => {
469
+ setAttr(n12, "data-side", unref(placementSide));
470
+ setStyle(n12, unref(arrowStyle));
471
+ });
472
+ return n12;
473
+ });
474
+ applyVShow(n13, () => unref(shouldShowContent));
475
+ n13.$evtfocusout = createInvoker((e) => unref(onCompositeFocusout)(e));
476
+ _setTemplateRef(n13, contentRef, null, "contentRef");
477
+ return n13;
478
+ }, null, 129);
479
+ }, { _: 8 }));
480
+ });
481
+ setStaticTemplateRef(n16, rootRef, null, "rootRef");
482
+ return n16;
377
483
  }
378
- }), [["__scopeId", "data-v-fd62ef9b"]]);
484
+ }), [["__scopeId", "data-v-8af57bff"]]);
379
485
  //#endregion
380
486
  export { popover_default as t };
package/dist/popover2.js CHANGED
@@ -13,5 +13,10 @@ var popoverPlacements = [
13
13
  "left",
14
14
  "left-end"
15
15
  ];
16
+ var popoverParts = [
17
+ "root",
18
+ "trigger",
19
+ "content"
20
+ ];
16
21
  //#endregion
17
- export { popoverPlacements as t };
22
+ export { popoverPlacements as n, popoverParts as t };