@eodash/eodash 5.0.0-alpha.2.8 → 5.0.0-processing

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 (138) hide show
  1. package/README.md +1 -1
  2. package/core/client/App.vue +13 -1
  3. package/core/client/asWebComponent.js +13 -3
  4. package/core/client/components/DashboardLayout.vue +6 -2
  5. package/core/client/composables/DefineEodash.js +1 -1
  6. package/core/client/composables/EodashMap.js +349 -0
  7. package/core/client/composables/EodashProcess.js +575 -0
  8. package/core/client/composables/index.js +107 -24
  9. package/core/client/eodash.js +83 -10
  10. package/core/client/plugins/axios.js +8 -0
  11. package/core/client/plugins/index.js +2 -1
  12. package/core/client/store/Actions.js +63 -12
  13. package/core/client/store/States.js +19 -0
  14. package/core/client/store/stac.js +98 -8
  15. package/core/client/types.d.ts +25 -18
  16. package/core/client/utils/createLayers.js +313 -0
  17. package/core/client/utils/eodashSTAC.js +320 -170
  18. package/core/client/utils/helpers.js +369 -9
  19. package/core/client/utils/keys.js +2 -0
  20. package/core/client/utils/states.js +17 -0
  21. package/core/client/views/Dashboard.vue +17 -46
  22. package/core/client/vite-env.d.ts +1 -9
  23. package/dist/client/DashboardLayout-CVMJ4l8M.js +87 -0
  24. package/dist/client/DynamicWebComponent-Cv8n457T.js +88 -0
  25. package/dist/client/EodashDatePicker-VVkiPmpc.js +394 -0
  26. package/dist/client/EodashItemFilter-CugWNQ86.js +194 -0
  27. package/dist/client/EodashLayerControl-53WghA8G.js +110 -0
  28. package/dist/client/EodashMap-CQnOePpy.js +486 -0
  29. package/dist/client/EodashMapBtns-uaRwFtfB.js +66 -0
  30. package/dist/client/EodashProcess-cF0unIy8.js +1477 -0
  31. package/dist/client/ExportState-BT8MLAW7.js +644 -0
  32. package/dist/client/Footer-C6GUG84G.js +141 -0
  33. package/dist/client/Header-D2dtCWp8.js +437 -0
  34. package/dist/client/IframeWrapper-BgM9aU8f.js +28 -0
  35. package/dist/client/MobileLayout-BAo8Wr8T.js +1210 -0
  36. package/dist/client/PopUp-Bm01q7Ko.js +389 -0
  37. package/dist/client/VImg-B8AbetCE.js +384 -0
  38. package/dist/client/VMain-DnGlQUyr.js +43 -0
  39. package/dist/client/VOverlay-B8Qj7LRG.js +1453 -0
  40. package/dist/client/WidgetsContainer-CwXRRLS1.js +83 -0
  41. package/dist/client/asWebComponent-DUUoR7MZ.js +11621 -0
  42. package/dist/client/eo-dash.js +2 -6
  43. package/dist/client/forwardRefs-CZJhEAKW.js +245 -0
  44. package/dist/client/index-DlIO7sJ3.js +199 -0
  45. package/dist/client/ssrBoot-BP7SYRyC.js +22 -0
  46. package/dist/client/style.css +2 -2
  47. package/dist/client/transition-BiR8wMn1.js +37 -0
  48. package/dist/node/cli.js +4 -4
  49. package/dist/node/types.d.ts +2 -0
  50. package/dist/types/core/client/App.vue.d.ts +7 -0
  51. package/dist/types/core/client/asWebComponent.d.ts +9 -0
  52. package/dist/types/core/client/components/DashboardLayout.vue.d.ts +2 -0
  53. package/dist/types/core/client/components/DynamicWebComponent.vue.d.ts +18 -0
  54. package/dist/types/core/client/components/ErrorAlert.vue.d.ts +2 -0
  55. package/dist/types/core/client/components/Footer.vue.d.ts +2 -0
  56. package/dist/types/core/client/components/Header.vue.d.ts +2 -0
  57. package/dist/types/core/client/components/IframeWrapper.vue.d.ts +7 -0
  58. package/dist/types/core/client/components/Loading.vue.d.ts +2 -0
  59. package/dist/types/core/client/components/MobileLayout.vue.d.ts +2 -0
  60. package/dist/types/core/client/composables/DefineEodash.d.ts +2 -0
  61. package/dist/types/core/client/composables/DefineTemplate.d.ts +15 -0
  62. package/dist/types/core/client/composables/DefineWidgets.d.ts +14 -0
  63. package/dist/types/core/client/composables/EodashMap.d.ts +5 -0
  64. package/dist/types/core/client/composables/index.d.ts +30 -0
  65. package/dist/types/core/client/eodash.d.ts +8 -0
  66. package/dist/types/core/client/main.d.ts +2 -0
  67. package/dist/types/core/client/plugins/axios.d.ts +2 -0
  68. package/dist/types/core/client/plugins/index.d.ts +3 -0
  69. package/dist/types/core/client/plugins/vuetify.d.ts +82 -0
  70. package/dist/types/core/client/render.d.ts +1 -0
  71. package/dist/types/core/client/store/Actions.d.ts +12 -0
  72. package/dist/types/core/client/store/States.d.ts +22 -0
  73. package/dist/types/core/client/store/index.d.ts +2 -0
  74. package/dist/types/core/client/store/stac.d.ts +25 -0
  75. package/dist/types/core/client/types.d.ts +279 -0
  76. package/dist/types/core/client/utils/createLayers.d.ts +45 -0
  77. package/dist/types/core/client/utils/eodashSTAC.d.ts +82 -0
  78. package/dist/types/core/client/utils/helpers.d.ts +84 -0
  79. package/dist/types/core/client/utils/index.d.ts +2 -0
  80. package/dist/types/core/client/utils/keys.d.ts +6 -0
  81. package/dist/types/core/client/utils/states.d.ts +14 -0
  82. package/dist/types/core/client/views/Dashboard.vue.d.ts +9 -0
  83. package/dist/types/widgets/EodashDatePicker.vue.d.ts +7 -0
  84. package/dist/types/widgets/EodashItemFilter.vue.d.ts +42 -0
  85. package/dist/types/widgets/EodashLayerControl.vue.d.ts +11 -0
  86. package/dist/types/widgets/EodashLayoutSwitcher.vue.d.ts +9 -0
  87. package/dist/types/widgets/EodashMap.vue.d.ts +7 -0
  88. package/dist/types/widgets/EodashMapBtns.vue.d.ts +11 -0
  89. package/dist/types/widgets/EodashStacInfo.vue.d.ts +21 -0
  90. package/dist/types/widgets/EodashTools.vue.d.ts +15 -0
  91. package/dist/types/widgets/ExportState.vue.d.ts +7 -0
  92. package/dist/types/widgets/PopUp.vue.d.ts +22 -0
  93. package/dist/types/widgets/WidgetsContainer.vue.d.ts +7 -0
  94. package/package.json +58 -37
  95. package/widgets/EodashDatePicker.vue +128 -100
  96. package/widgets/EodashItemFilter.vue +149 -47
  97. package/widgets/EodashLayerControl.vue +98 -0
  98. package/widgets/EodashMap.vue +98 -122
  99. package/widgets/EodashMapBtns.vue +24 -7
  100. package/widgets/EodashProcess.vue +151 -0
  101. package/widgets/ExportState.vue +15 -11
  102. package/core/client/SuspensedDashboard.ce.vue +0 -105
  103. package/dist/client/DashboardLayout-CKOExc7r.js +0 -156
  104. package/dist/client/DynamicWebComponent-m1Zbbw6n.js +0 -57
  105. package/dist/client/EodashDatePicker-CGdJRGZJ.js +0 -252
  106. package/dist/client/EodashItemFilter-BjM_LHaE.js +0 -63
  107. package/dist/client/EodashMap-61UMC8sv.js +0 -86917
  108. package/dist/client/EodashMapBtns-DVITfAFx.js +0 -36
  109. package/dist/client/ExportState-DhpK09GR.js +0 -558
  110. package/dist/client/Footer-CIwjaddz.js +0 -115
  111. package/dist/client/Header-BcM-pZFi.js +0 -350
  112. package/dist/client/IframeWrapper-CAe6HPqe.js +0 -19
  113. package/dist/client/MobileLayout-DcZOQX8r.js +0 -945
  114. package/dist/client/PopUp-DCaITceG.js +0 -300
  115. package/dist/client/VImg-C-I_7puM.js +0 -291
  116. package/dist/client/VMain-Cd3P0YTG.js +0 -39
  117. package/dist/client/VOverlay-AcvFgk39.js +0 -967
  118. package/dist/client/WidgetsContainer-B0-q0EMO.js +0 -129
  119. package/dist/client/_commonjsHelpers-DaMA6jEr.js +0 -8
  120. package/dist/client/asWebComponent-zuKR9I1w.js +0 -20361
  121. package/dist/client/basedecoder-DHcBySSe-BmCFNFnw.js +0 -88
  122. package/dist/client/decoder-CP4lv0Kb-DdKalImK.js +0 -10
  123. package/dist/client/deflate-BXt-9JA_-CWfClgpK.js +0 -10
  124. package/dist/client/eodashSTAC-DGB50vNk.js +0 -2788
  125. package/dist/client/eox-itemfilter-TaBxgqq_.js +0 -7565
  126. package/dist/client/eox-stacinfo-l7ALSV90.js +0 -13969
  127. package/dist/client/forwardRefs-BnxE4iKQ.js +0 -185
  128. package/dist/client/index-hSIi5Ygk.js +0 -153
  129. package/dist/client/jpeg-BAgeD1d3-oeHbFPUL.js +0 -514
  130. package/dist/client/lerc-DzVumYtB-cTUap6k_.js +0 -1027
  131. package/dist/client/lzw-LAGDNbSC-DkP96qO9.js +0 -84
  132. package/dist/client/packbits-BlDR4Kj5-C66n1-zr.js +0 -24
  133. package/dist/client/pako.esm-CB1uQYY0-DB0PYm1P.js +0 -1081
  134. package/dist/client/raw-CMGvRjfu-BRi6E4i1.js +0 -9
  135. package/dist/client/ssrBoot-D3KF5Thc.js +0 -17
  136. package/dist/client/transition-D3a4tiJv.js +0 -34
  137. package/dist/client/webfontloader-qotgY98I.js +0 -435
  138. package/dist/client/webimage-BM_pbLN3-L2cGWK5l.js +0 -19
@@ -0,0 +1,1453 @@
1
+ import { ref, watch, onScopeDispose, computed, nextTick, watchEffect, effectScope, inject, mergeProps, shallowRef, onMounted, reactive, provide, readonly, toRaw, warn, toRef, onBeforeUnmount, createVNode, Fragment, Teleport, withDirectives, vShow, resolveDirective, Transition } from 'vue';
2
+ import { aD as isOn, aE as eventName, p as propsFactory, x as IN_BROWSER, W as useToggleScope, aF as destructComputed, aG as parseAnchor, aH as flipSide, aI as flipAlign, aJ as flipCorner, Z as consoleError, aK as getAxis, q as convertToUnit, S as clamp, aL as defer, aC as getCurrentInstance, aM as templateRef, aN as matchesSelector, t as useDisplay, b as makeComponentProps, J as makeDimensionProps, d as makeThemeProps, g as genericComponent, j as useProxiedModel, e as provideTheme, f as useRtl, C as useBackgroundColor, K as useDimension, aO as useRouter, a as useRender, aP as useBackButton } from './asWebComponent-DUUoR7MZ.js';
3
+ import { g as getTargetBox, B as Box, e as getOverflow, n as nullifyTransforms, m as makeLazyProps, u as useLazy, b as useScopeId, a as animate, s as standardEasing } from './forwardRefs-CZJhEAKW.js';
4
+ import { m as makeTransitionProps, M as MaybeTransition } from './transition-BiR8wMn1.js';
5
+
6
+ // Utilities
7
+ const handlers = new WeakMap();
8
+ function bindProps(el, props) {
9
+ Object.keys(props).forEach(k => {
10
+ if (isOn(k)) {
11
+ const name = eventName(k);
12
+ const handler = handlers.get(el);
13
+ if (props[k] == null) {
14
+ handler?.forEach(v => {
15
+ const [n, fn] = v;
16
+ if (n === name) {
17
+ el.removeEventListener(name, fn);
18
+ handler.delete(v);
19
+ }
20
+ });
21
+ } else if (!handler || ![...handler]?.some(v => v[0] === name && v[1] === props[k])) {
22
+ el.addEventListener(name, props[k]);
23
+ const _handler = handler || new Set();
24
+ _handler.add([name, props[k]]);
25
+ if (!handlers.has(el)) handlers.set(el, _handler);
26
+ }
27
+ } else {
28
+ if (props[k] == null) {
29
+ el.removeAttribute(k);
30
+ } else {
31
+ el.setAttribute(k, props[k]);
32
+ }
33
+ }
34
+ });
35
+ }
36
+ function unbindProps(el, props) {
37
+ Object.keys(props).forEach(k => {
38
+ if (isOn(k)) {
39
+ const name = eventName(k);
40
+ const handler = handlers.get(el);
41
+ handler?.forEach(v => {
42
+ const [n, fn] = v;
43
+ if (n === name) {
44
+ el.removeEventListener(name, fn);
45
+ handler.delete(v);
46
+ }
47
+ });
48
+ } else {
49
+ el.removeAttribute(k);
50
+ }
51
+ });
52
+ }
53
+
54
+ /**
55
+ * Returns:
56
+ * - 'null' if the node is not attached to the DOM
57
+ * - the root node (HTMLDocument | ShadowRoot) otherwise
58
+ */
59
+ function attachedRoot(node) {
60
+ /* istanbul ignore next */
61
+ if (typeof node.getRootNode !== 'function') {
62
+ // Shadow DOM not supported (IE11), lets find the root of this node
63
+ while (node.parentNode) node = node.parentNode;
64
+
65
+ // The root parent is the document if the node is attached to the DOM
66
+ if (node !== document) return null;
67
+ return document;
68
+ }
69
+ const root = node.getRootNode();
70
+
71
+ // The composed root node is the document if the node is attached to the DOM
72
+ if (root !== document && root.getRootNode({
73
+ composed: true
74
+ }) !== document) return null;
75
+ return root;
76
+ }
77
+
78
+ function getScrollParent(el) {
79
+ let includeHidden = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
80
+ while (el) {
81
+ if (includeHidden ? isPotentiallyScrollable(el) : hasScrollbar(el)) return el;
82
+ el = el.parentElement;
83
+ }
84
+ return document.scrollingElement;
85
+ }
86
+ function getScrollParents(el, stopAt) {
87
+ const elements = [];
88
+ if (stopAt && el && !stopAt.contains(el)) return elements;
89
+ while (el) {
90
+ if (hasScrollbar(el)) elements.push(el);
91
+ if (el === stopAt) break;
92
+ el = el.parentElement;
93
+ }
94
+ return elements;
95
+ }
96
+ function hasScrollbar(el) {
97
+ if (!el || el.nodeType !== Node.ELEMENT_NODE) return false;
98
+ const style = window.getComputedStyle(el);
99
+ return style.overflowY === 'scroll' || style.overflowY === 'auto' && el.scrollHeight > el.clientHeight;
100
+ }
101
+ function isPotentiallyScrollable(el) {
102
+ if (!el || el.nodeType !== Node.ELEMENT_NODE) return false;
103
+ const style = window.getComputedStyle(el);
104
+ return ['scroll', 'auto'].includes(style.overflowY);
105
+ }
106
+
107
+ function isFixedPosition(el) {
108
+ while (el) {
109
+ if (window.getComputedStyle(el).position === 'fixed') {
110
+ return true;
111
+ }
112
+ el = el.offsetParent;
113
+ }
114
+ return false;
115
+ }
116
+
117
+ // Utilities
118
+ function defaultConditional() {
119
+ return true;
120
+ }
121
+ function checkEvent(e, el, binding) {
122
+ // The include element callbacks below can be expensive
123
+ // so we should avoid calling them when we're not active.
124
+ // Explicitly check for false to allow fallback compatibility
125
+ // with non-toggleable components
126
+ if (!e || checkIsActive(e, binding) === false) return false;
127
+
128
+ // If we're clicking inside the shadowroot, then the app root doesn't get the same
129
+ // level of introspection as to _what_ we're clicking. We want to check to see if
130
+ // our target is the shadowroot parent container, and if it is, ignore.
131
+ const root = attachedRoot(el);
132
+ if (typeof ShadowRoot !== 'undefined' && root instanceof ShadowRoot && root.host === e.target) return false;
133
+
134
+ // Check if additional elements were passed to be included in check
135
+ // (click must be outside all included elements, if any)
136
+ const elements = (typeof binding.value === 'object' && binding.value.include || (() => []))();
137
+ // Add the root element for the component this directive was defined on
138
+ elements.push(el);
139
+
140
+ // Check if it's a click outside our elements, and then if our callback returns true.
141
+ // Non-toggleable components should take action in their callback and return falsy.
142
+ // Toggleable can return true if it wants to deactivate.
143
+ // Note that, because we're in the capture phase, this callback will occur before
144
+ // the bubbling click event on any outside elements.
145
+ return !elements.some(el => el?.contains(e.target));
146
+ }
147
+ function checkIsActive(e, binding) {
148
+ const isActive = typeof binding.value === 'object' && binding.value.closeConditional || defaultConditional;
149
+ return isActive(e);
150
+ }
151
+ function directive(e, el, binding) {
152
+ const handler = typeof binding.value === 'function' ? binding.value : binding.value.handler;
153
+
154
+ // Clicks in the Shadow DOM change their target while using setTimeout, so the original target is saved here
155
+ e.shadowTarget = e.target;
156
+ el._clickOutside.lastMousedownWasOutside && checkEvent(e, el, binding) && setTimeout(() => {
157
+ checkIsActive(e, binding) && handler && handler(e);
158
+ }, 0);
159
+ }
160
+ function handleShadow(el, callback) {
161
+ const root = attachedRoot(el);
162
+ callback(document);
163
+ if (typeof ShadowRoot !== 'undefined' && root instanceof ShadowRoot) {
164
+ callback(root);
165
+ }
166
+ }
167
+ const ClickOutside = {
168
+ // [data-app] may not be found
169
+ // if using bind, inserted makes
170
+ // sure that the root element is
171
+ // available, iOS does not support
172
+ // clicks on body
173
+ mounted(el, binding) {
174
+ const onClick = e => directive(e, el, binding);
175
+ const onMousedown = e => {
176
+ el._clickOutside.lastMousedownWasOutside = checkEvent(e, el, binding);
177
+ };
178
+ handleShadow(el, app => {
179
+ app.addEventListener('click', onClick, true);
180
+ app.addEventListener('mousedown', onMousedown, true);
181
+ });
182
+ if (!el._clickOutside) {
183
+ el._clickOutside = {
184
+ lastMousedownWasOutside: false
185
+ };
186
+ }
187
+ el._clickOutside[binding.instance.$.uid] = {
188
+ onClick,
189
+ onMousedown
190
+ };
191
+ },
192
+ beforeUnmount(el, binding) {
193
+ if (!el._clickOutside) return;
194
+ handleShadow(el, app => {
195
+ if (!app || !el._clickOutside?.[binding.instance.$.uid]) return;
196
+ const {
197
+ onClick,
198
+ onMousedown
199
+ } = el._clickOutside[binding.instance.$.uid];
200
+ app.removeEventListener('click', onClick, true);
201
+ app.removeEventListener('mousedown', onMousedown, true);
202
+ });
203
+ delete el._clickOutside[binding.instance.$.uid];
204
+ }
205
+ };
206
+
207
+ // Types
208
+
209
+ /** Convert a point in local space to viewport space */
210
+ function elementToViewport(point, offset) {
211
+ return {
212
+ x: point.x + offset.x,
213
+ y: point.y + offset.y
214
+ };
215
+ }
216
+
217
+ /** Get the difference between two points */
218
+ function getOffset(a, b) {
219
+ return {
220
+ x: a.x - b.x,
221
+ y: a.y - b.y
222
+ };
223
+ }
224
+
225
+ /** Convert an anchor object to a point in local space */
226
+ function anchorToPoint(anchor, box) {
227
+ if (anchor.side === 'top' || anchor.side === 'bottom') {
228
+ const {
229
+ side,
230
+ align
231
+ } = anchor;
232
+ const x = align === 'left' ? 0 : align === 'center' ? box.width / 2 : align === 'right' ? box.width : align;
233
+ const y = side === 'top' ? 0 : side === 'bottom' ? box.height : side;
234
+ return elementToViewport({
235
+ x,
236
+ y
237
+ }, box);
238
+ } else if (anchor.side === 'left' || anchor.side === 'right') {
239
+ const {
240
+ side,
241
+ align
242
+ } = anchor;
243
+ const x = side === 'left' ? 0 : side === 'right' ? box.width : side;
244
+ const y = align === 'top' ? 0 : align === 'center' ? box.height / 2 : align === 'bottom' ? box.height : align;
245
+ return elementToViewport({
246
+ x,
247
+ y
248
+ }, box);
249
+ }
250
+ return elementToViewport({
251
+ x: box.width / 2,
252
+ y: box.height / 2
253
+ }, box);
254
+ }
255
+
256
+ // Composables
257
+ const locationStrategies = {
258
+ static: staticLocationStrategy,
259
+ // specific viewport position, usually centered
260
+ connected: connectedLocationStrategy // connected to a certain element
261
+ };
262
+ const makeLocationStrategyProps = propsFactory({
263
+ locationStrategy: {
264
+ type: [String, Function],
265
+ default: 'static',
266
+ validator: val => typeof val === 'function' || val in locationStrategies
267
+ },
268
+ location: {
269
+ type: String,
270
+ default: 'bottom'
271
+ },
272
+ origin: {
273
+ type: String,
274
+ default: 'auto'
275
+ },
276
+ offset: [Number, String, Array]
277
+ }, 'VOverlay-location-strategies');
278
+ function useLocationStrategies(props, data) {
279
+ const contentStyles = ref({});
280
+ const updateLocation = ref();
281
+ if (IN_BROWSER) {
282
+ useToggleScope(() => !!(data.isActive.value && props.locationStrategy), reset => {
283
+ watch(() => props.locationStrategy, reset);
284
+ onScopeDispose(() => {
285
+ window.removeEventListener('resize', onResize);
286
+ updateLocation.value = undefined;
287
+ });
288
+ window.addEventListener('resize', onResize, {
289
+ passive: true
290
+ });
291
+ if (typeof props.locationStrategy === 'function') {
292
+ updateLocation.value = props.locationStrategy(data, props, contentStyles)?.updateLocation;
293
+ } else {
294
+ updateLocation.value = locationStrategies[props.locationStrategy](data, props, contentStyles)?.updateLocation;
295
+ }
296
+ });
297
+ }
298
+ function onResize(e) {
299
+ updateLocation.value?.(e);
300
+ }
301
+ return {
302
+ contentStyles,
303
+ updateLocation
304
+ };
305
+ }
306
+ function staticLocationStrategy() {
307
+ // TODO
308
+ }
309
+
310
+ /** Get size of element ignoring max-width/max-height */
311
+ function getIntrinsicSize(el, isRtl) {
312
+ // const scrollables = new Map<Element, [number, number]>()
313
+ // el.querySelectorAll('*').forEach(el => {
314
+ // const x = el.scrollLeft
315
+ // const y = el.scrollTop
316
+ // if (x || y) {
317
+ // scrollables.set(el, [x, y])
318
+ // }
319
+ // })
320
+
321
+ // const initialMaxWidth = el.style.maxWidth
322
+ // const initialMaxHeight = el.style.maxHeight
323
+ // el.style.removeProperty('max-width')
324
+ // el.style.removeProperty('max-height')
325
+
326
+ /* eslint-disable-next-line sonarjs/prefer-immediate-return */
327
+ const contentBox = nullifyTransforms(el);
328
+ if (isRtl) {
329
+ contentBox.x += parseFloat(el.style.right || 0);
330
+ } else {
331
+ contentBox.x -= parseFloat(el.style.left || 0);
332
+ }
333
+ contentBox.y -= parseFloat(el.style.top || 0);
334
+
335
+ // el.style.maxWidth = initialMaxWidth
336
+ // el.style.maxHeight = initialMaxHeight
337
+ // scrollables.forEach((position, el) => {
338
+ // el.scrollTo(...position)
339
+ // })
340
+
341
+ return contentBox;
342
+ }
343
+ function connectedLocationStrategy(data, props, contentStyles) {
344
+ const activatorFixed = Array.isArray(data.target.value) || isFixedPosition(data.target.value);
345
+ if (activatorFixed) {
346
+ Object.assign(contentStyles.value, {
347
+ position: 'fixed',
348
+ top: 0,
349
+ [data.isRtl.value ? 'right' : 'left']: 0
350
+ });
351
+ }
352
+ const {
353
+ preferredAnchor,
354
+ preferredOrigin
355
+ } = destructComputed(() => {
356
+ const parsedAnchor = parseAnchor(props.location, data.isRtl.value);
357
+ const parsedOrigin = props.origin === 'overlap' ? parsedAnchor : props.origin === 'auto' ? flipSide(parsedAnchor) : parseAnchor(props.origin, data.isRtl.value);
358
+
359
+ // Some combinations of props may produce an invalid origin
360
+ if (parsedAnchor.side === parsedOrigin.side && parsedAnchor.align === flipAlign(parsedOrigin).align) {
361
+ return {
362
+ preferredAnchor: flipCorner(parsedAnchor),
363
+ preferredOrigin: flipCorner(parsedOrigin)
364
+ };
365
+ } else {
366
+ return {
367
+ preferredAnchor: parsedAnchor,
368
+ preferredOrigin: parsedOrigin
369
+ };
370
+ }
371
+ });
372
+ const [minWidth, minHeight, maxWidth, maxHeight] = ['minWidth', 'minHeight', 'maxWidth', 'maxHeight'].map(key => {
373
+ return computed(() => {
374
+ const val = parseFloat(props[key]);
375
+ return isNaN(val) ? Infinity : val;
376
+ });
377
+ });
378
+ const offset = computed(() => {
379
+ if (Array.isArray(props.offset)) {
380
+ return props.offset;
381
+ }
382
+ if (typeof props.offset === 'string') {
383
+ const offset = props.offset.split(' ').map(parseFloat);
384
+ if (offset.length < 2) offset.push(0);
385
+ return offset;
386
+ }
387
+ return typeof props.offset === 'number' ? [props.offset, 0] : [0, 0];
388
+ });
389
+ let observe = false;
390
+ const observer = new ResizeObserver(() => {
391
+ if (observe) updateLocation();
392
+ });
393
+ watch([data.target, data.contentEl], (_ref, _ref2) => {
394
+ let [newTarget, newContentEl] = _ref;
395
+ let [oldTarget, oldContentEl] = _ref2;
396
+ if (oldTarget && !Array.isArray(oldTarget)) observer.unobserve(oldTarget);
397
+ if (newTarget && !Array.isArray(newTarget)) observer.observe(newTarget);
398
+ if (oldContentEl) observer.unobserve(oldContentEl);
399
+ if (newContentEl) observer.observe(newContentEl);
400
+ }, {
401
+ immediate: true
402
+ });
403
+ onScopeDispose(() => {
404
+ observer.disconnect();
405
+ });
406
+
407
+ // eslint-disable-next-line max-statements
408
+ function updateLocation() {
409
+ observe = false;
410
+ requestAnimationFrame(() => observe = true);
411
+ if (!data.target.value || !data.contentEl.value) return;
412
+ const targetBox = getTargetBox(data.target.value);
413
+ const contentBox = getIntrinsicSize(data.contentEl.value, data.isRtl.value);
414
+ const scrollParents = getScrollParents(data.contentEl.value);
415
+ const viewportMargin = 12;
416
+ if (!scrollParents.length) {
417
+ scrollParents.push(document.documentElement);
418
+ if (!(data.contentEl.value.style.top && data.contentEl.value.style.left)) {
419
+ contentBox.x -= parseFloat(document.documentElement.style.getPropertyValue('--v-body-scroll-x') || 0);
420
+ contentBox.y -= parseFloat(document.documentElement.style.getPropertyValue('--v-body-scroll-y') || 0);
421
+ }
422
+ }
423
+ const viewport = scrollParents.reduce((box, el) => {
424
+ const rect = el.getBoundingClientRect();
425
+ const scrollBox = new Box({
426
+ x: el === document.documentElement ? 0 : rect.x,
427
+ y: el === document.documentElement ? 0 : rect.y,
428
+ width: el.clientWidth,
429
+ height: el.clientHeight
430
+ });
431
+ if (box) {
432
+ return new Box({
433
+ x: Math.max(box.left, scrollBox.left),
434
+ y: Math.max(box.top, scrollBox.top),
435
+ width: Math.min(box.right, scrollBox.right) - Math.max(box.left, scrollBox.left),
436
+ height: Math.min(box.bottom, scrollBox.bottom) - Math.max(box.top, scrollBox.top)
437
+ });
438
+ }
439
+ return scrollBox;
440
+ }, undefined);
441
+ viewport.x += viewportMargin;
442
+ viewport.y += viewportMargin;
443
+ viewport.width -= viewportMargin * 2;
444
+ viewport.height -= viewportMargin * 2;
445
+ let placement = {
446
+ anchor: preferredAnchor.value,
447
+ origin: preferredOrigin.value
448
+ };
449
+ function checkOverflow(_placement) {
450
+ const box = new Box(contentBox);
451
+ const targetPoint = anchorToPoint(_placement.anchor, targetBox);
452
+ const contentPoint = anchorToPoint(_placement.origin, box);
453
+ let {
454
+ x,
455
+ y
456
+ } = getOffset(targetPoint, contentPoint);
457
+ switch (_placement.anchor.side) {
458
+ case 'top':
459
+ y -= offset.value[0];
460
+ break;
461
+ case 'bottom':
462
+ y += offset.value[0];
463
+ break;
464
+ case 'left':
465
+ x -= offset.value[0];
466
+ break;
467
+ case 'right':
468
+ x += offset.value[0];
469
+ break;
470
+ }
471
+ switch (_placement.anchor.align) {
472
+ case 'top':
473
+ y -= offset.value[1];
474
+ break;
475
+ case 'bottom':
476
+ y += offset.value[1];
477
+ break;
478
+ case 'left':
479
+ x -= offset.value[1];
480
+ break;
481
+ case 'right':
482
+ x += offset.value[1];
483
+ break;
484
+ }
485
+ box.x += x;
486
+ box.y += y;
487
+ box.width = Math.min(box.width, maxWidth.value);
488
+ box.height = Math.min(box.height, maxHeight.value);
489
+ const overflows = getOverflow(box, viewport);
490
+ return {
491
+ overflows,
492
+ x,
493
+ y
494
+ };
495
+ }
496
+ let x = 0;
497
+ let y = 0;
498
+ const available = {
499
+ x: 0,
500
+ y: 0
501
+ };
502
+ const flipped = {
503
+ x: false,
504
+ y: false
505
+ };
506
+ let resets = -1;
507
+ while (true) {
508
+ if (resets++ > 10) {
509
+ consoleError('Infinite loop detected in connectedLocationStrategy');
510
+ break;
511
+ }
512
+ const {
513
+ x: _x,
514
+ y: _y,
515
+ overflows
516
+ } = checkOverflow(placement);
517
+ x += _x;
518
+ y += _y;
519
+ contentBox.x += _x;
520
+ contentBox.y += _y;
521
+
522
+ // flip
523
+ {
524
+ const axis = getAxis(placement.anchor);
525
+ const hasOverflowX = overflows.x.before || overflows.x.after;
526
+ const hasOverflowY = overflows.y.before || overflows.y.after;
527
+ let reset = false;
528
+ ['x', 'y'].forEach(key => {
529
+ if (key === 'x' && hasOverflowX && !flipped.x || key === 'y' && hasOverflowY && !flipped.y) {
530
+ const newPlacement = {
531
+ anchor: {
532
+ ...placement.anchor
533
+ },
534
+ origin: {
535
+ ...placement.origin
536
+ }
537
+ };
538
+ const flip = key === 'x' ? axis === 'y' ? flipAlign : flipSide : axis === 'y' ? flipSide : flipAlign;
539
+ newPlacement.anchor = flip(newPlacement.anchor);
540
+ newPlacement.origin = flip(newPlacement.origin);
541
+ const {
542
+ overflows: newOverflows
543
+ } = checkOverflow(newPlacement);
544
+ if (newOverflows[key].before <= overflows[key].before && newOverflows[key].after <= overflows[key].after || newOverflows[key].before + newOverflows[key].after < (overflows[key].before + overflows[key].after) / 2) {
545
+ placement = newPlacement;
546
+ reset = flipped[key] = true;
547
+ }
548
+ }
549
+ });
550
+ if (reset) continue;
551
+ }
552
+
553
+ // shift
554
+ if (overflows.x.before) {
555
+ x += overflows.x.before;
556
+ contentBox.x += overflows.x.before;
557
+ }
558
+ if (overflows.x.after) {
559
+ x -= overflows.x.after;
560
+ contentBox.x -= overflows.x.after;
561
+ }
562
+ if (overflows.y.before) {
563
+ y += overflows.y.before;
564
+ contentBox.y += overflows.y.before;
565
+ }
566
+ if (overflows.y.after) {
567
+ y -= overflows.y.after;
568
+ contentBox.y -= overflows.y.after;
569
+ }
570
+
571
+ // size
572
+ {
573
+ const overflows = getOverflow(contentBox, viewport);
574
+ available.x = viewport.width - overflows.x.before - overflows.x.after;
575
+ available.y = viewport.height - overflows.y.before - overflows.y.after;
576
+ x += overflows.x.before;
577
+ contentBox.x += overflows.x.before;
578
+ y += overflows.y.before;
579
+ contentBox.y += overflows.y.before;
580
+ }
581
+ break;
582
+ }
583
+ const axis = getAxis(placement.anchor);
584
+ Object.assign(contentStyles.value, {
585
+ '--v-overlay-anchor-origin': `${placement.anchor.side} ${placement.anchor.align}`,
586
+ transformOrigin: `${placement.origin.side} ${placement.origin.align}`,
587
+ // transform: `translate(${pixelRound(x)}px, ${pixelRound(y)}px)`,
588
+ top: convertToUnit(pixelRound(y)),
589
+ left: data.isRtl.value ? undefined : convertToUnit(pixelRound(x)),
590
+ right: data.isRtl.value ? convertToUnit(pixelRound(-x)) : undefined,
591
+ minWidth: convertToUnit(axis === 'y' ? Math.min(minWidth.value, targetBox.width) : minWidth.value),
592
+ maxWidth: convertToUnit(pixelCeil(clamp(available.x, minWidth.value === Infinity ? 0 : minWidth.value, maxWidth.value))),
593
+ maxHeight: convertToUnit(pixelCeil(clamp(available.y, minHeight.value === Infinity ? 0 : minHeight.value, maxHeight.value)))
594
+ });
595
+ return {
596
+ available,
597
+ contentBox
598
+ };
599
+ }
600
+ watch(() => [preferredAnchor.value, preferredOrigin.value, props.offset, props.minWidth, props.minHeight, props.maxWidth, props.maxHeight], () => updateLocation());
601
+ nextTick(() => {
602
+ const result = updateLocation();
603
+
604
+ // TODO: overflowing content should only require a single updateLocation call
605
+ // Icky hack to make sure the content is positioned consistently
606
+ if (!result) return;
607
+ const {
608
+ available,
609
+ contentBox
610
+ } = result;
611
+ if (contentBox.height > available.y) {
612
+ requestAnimationFrame(() => {
613
+ updateLocation();
614
+ requestAnimationFrame(() => {
615
+ updateLocation();
616
+ });
617
+ });
618
+ }
619
+ });
620
+ return {
621
+ updateLocation
622
+ };
623
+ }
624
+ function pixelRound(val) {
625
+ return Math.round(val * devicePixelRatio) / devicePixelRatio;
626
+ }
627
+ function pixelCeil(val) {
628
+ return Math.ceil(val * devicePixelRatio) / devicePixelRatio;
629
+ }
630
+
631
+ let clean = true;
632
+ const frames = [];
633
+
634
+ /**
635
+ * Schedule a task to run in an animation frame on its own
636
+ * This is useful for heavy tasks that may cause jank if all ran together
637
+ */
638
+ function requestNewFrame(cb) {
639
+ if (!clean || frames.length) {
640
+ frames.push(cb);
641
+ run();
642
+ } else {
643
+ clean = false;
644
+ cb();
645
+ run();
646
+ }
647
+ }
648
+ let raf = -1;
649
+ function run() {
650
+ cancelAnimationFrame(raf);
651
+ raf = requestAnimationFrame(() => {
652
+ const frame = frames.shift();
653
+ if (frame) frame();
654
+ if (frames.length) run();else clean = true;
655
+ });
656
+ }
657
+
658
+ // Utilities
659
+ const scrollStrategies = {
660
+ none: null,
661
+ close: closeScrollStrategy,
662
+ block: blockScrollStrategy,
663
+ reposition: repositionScrollStrategy
664
+ };
665
+ const makeScrollStrategyProps = propsFactory({
666
+ scrollStrategy: {
667
+ type: [String, Function],
668
+ default: 'block',
669
+ validator: val => typeof val === 'function' || val in scrollStrategies
670
+ }
671
+ }, 'VOverlay-scroll-strategies');
672
+ function useScrollStrategies(props, data) {
673
+ if (!IN_BROWSER) return;
674
+ let scope;
675
+ watchEffect(async () => {
676
+ scope?.stop();
677
+ if (!(data.isActive.value && props.scrollStrategy)) return;
678
+ scope = effectScope();
679
+ await new Promise(resolve => setTimeout(resolve));
680
+ scope.active && scope.run(() => {
681
+ if (typeof props.scrollStrategy === 'function') {
682
+ props.scrollStrategy(data, props, scope);
683
+ } else {
684
+ scrollStrategies[props.scrollStrategy]?.(data, props, scope);
685
+ }
686
+ });
687
+ });
688
+ onScopeDispose(() => {
689
+ scope?.stop();
690
+ });
691
+ }
692
+ function closeScrollStrategy(data) {
693
+ function onScroll(e) {
694
+ data.isActive.value = false;
695
+ }
696
+ bindScroll(data.targetEl.value ?? data.contentEl.value, onScroll);
697
+ }
698
+ function blockScrollStrategy(data, props) {
699
+ const offsetParent = data.root.value?.offsetParent;
700
+ const scrollElements = [...new Set([...getScrollParents(data.targetEl.value, props.contained ? offsetParent : undefined), ...getScrollParents(data.contentEl.value, props.contained ? offsetParent : undefined)])].filter(el => !el.classList.contains('v-overlay-scroll-blocked'));
701
+ const scrollbarWidth = window.innerWidth - document.documentElement.offsetWidth;
702
+ const scrollableParent = (el => hasScrollbar(el) && el)(offsetParent || document.documentElement);
703
+ if (scrollableParent) {
704
+ data.root.value.classList.add('v-overlay--scroll-blocked');
705
+ }
706
+ scrollElements.forEach((el, i) => {
707
+ el.style.setProperty('--v-body-scroll-x', convertToUnit(-el.scrollLeft));
708
+ el.style.setProperty('--v-body-scroll-y', convertToUnit(-el.scrollTop));
709
+ if (el !== document.documentElement) {
710
+ el.style.setProperty('--v-scrollbar-offset', convertToUnit(scrollbarWidth));
711
+ }
712
+ el.classList.add('v-overlay-scroll-blocked');
713
+ });
714
+ onScopeDispose(() => {
715
+ scrollElements.forEach((el, i) => {
716
+ const x = parseFloat(el.style.getPropertyValue('--v-body-scroll-x'));
717
+ const y = parseFloat(el.style.getPropertyValue('--v-body-scroll-y'));
718
+ const scrollBehavior = el.style.scrollBehavior;
719
+ el.style.scrollBehavior = 'auto';
720
+ el.style.removeProperty('--v-body-scroll-x');
721
+ el.style.removeProperty('--v-body-scroll-y');
722
+ el.style.removeProperty('--v-scrollbar-offset');
723
+ el.classList.remove('v-overlay-scroll-blocked');
724
+ el.scrollLeft = -x;
725
+ el.scrollTop = -y;
726
+ el.style.scrollBehavior = scrollBehavior;
727
+ });
728
+ if (scrollableParent) {
729
+ data.root.value.classList.remove('v-overlay--scroll-blocked');
730
+ }
731
+ });
732
+ }
733
+ function repositionScrollStrategy(data, props, scope) {
734
+ let slow = false;
735
+ let raf = -1;
736
+ let ric = -1;
737
+ function update(e) {
738
+ requestNewFrame(() => {
739
+ const start = performance.now();
740
+ data.updateLocation.value?.(e);
741
+ const time = performance.now() - start;
742
+ slow = time / (1000 / 60) > 2;
743
+ });
744
+ }
745
+ ric = (typeof requestIdleCallback === 'undefined' ? cb => cb() : requestIdleCallback)(() => {
746
+ scope.run(() => {
747
+ bindScroll(data.targetEl.value ?? data.contentEl.value, e => {
748
+ if (slow) {
749
+ // If the position calculation is slow,
750
+ // defer updates until scrolling is finished.
751
+ // Browsers usually fire one scroll event per frame so
752
+ // we just wait until we've got two frames without an event
753
+ cancelAnimationFrame(raf);
754
+ raf = requestAnimationFrame(() => {
755
+ raf = requestAnimationFrame(() => {
756
+ update(e);
757
+ });
758
+ });
759
+ } else {
760
+ update(e);
761
+ }
762
+ });
763
+ });
764
+ });
765
+ onScopeDispose(() => {
766
+ typeof cancelIdleCallback !== 'undefined' && cancelIdleCallback(ric);
767
+ cancelAnimationFrame(raf);
768
+ });
769
+ }
770
+
771
+ /** @private */
772
+ function bindScroll(el, onScroll) {
773
+ const scrollElements = [document, ...getScrollParents(el)];
774
+ scrollElements.forEach(el => {
775
+ el.addEventListener('scroll', onScroll, {
776
+ passive: true
777
+ });
778
+ });
779
+ onScopeDispose(() => {
780
+ scrollElements.forEach(el => {
781
+ el.removeEventListener('scroll', onScroll);
782
+ });
783
+ });
784
+ }
785
+
786
+ // Types
787
+
788
+ const VMenuSymbol = Symbol.for('vuetify:v-menu');
789
+
790
+ // Utilities
791
+ // Composables
792
+ const makeDelayProps = propsFactory({
793
+ closeDelay: [Number, String],
794
+ openDelay: [Number, String]
795
+ }, 'delay');
796
+ function useDelay(props, cb) {
797
+ let clearDelay = () => {};
798
+ function runDelay(isOpening) {
799
+ clearDelay?.();
800
+ const delay = Number(isOpening ? props.openDelay : props.closeDelay);
801
+ return new Promise(resolve => {
802
+ clearDelay = defer(delay, () => {
803
+ cb?.(isOpening);
804
+ resolve(isOpening);
805
+ });
806
+ });
807
+ }
808
+ function runOpenDelay() {
809
+ return runDelay(true);
810
+ }
811
+ function runCloseDelay() {
812
+ return runDelay(false);
813
+ }
814
+ return {
815
+ clearDelay,
816
+ runOpenDelay,
817
+ runCloseDelay
818
+ };
819
+ }
820
+
821
+ // Components
822
+ const makeActivatorProps = propsFactory({
823
+ target: [String, Object],
824
+ activator: [String, Object],
825
+ activatorProps: {
826
+ type: Object,
827
+ default: () => ({})
828
+ },
829
+ openOnClick: {
830
+ type: Boolean,
831
+ default: undefined
832
+ },
833
+ openOnHover: Boolean,
834
+ openOnFocus: {
835
+ type: Boolean,
836
+ default: undefined
837
+ },
838
+ closeOnContentClick: Boolean,
839
+ ...makeDelayProps()
840
+ }, 'VOverlay-activator');
841
+ function useActivator(props, _ref) {
842
+ let {
843
+ isActive,
844
+ isTop,
845
+ contentEl
846
+ } = _ref;
847
+ const vm = getCurrentInstance('useActivator');
848
+ const activatorEl = ref();
849
+ let isHovered = false;
850
+ let isFocused = false;
851
+ let firstEnter = true;
852
+ const openOnFocus = computed(() => props.openOnFocus || props.openOnFocus == null && props.openOnHover);
853
+ const openOnClick = computed(() => props.openOnClick || props.openOnClick == null && !props.openOnHover && !openOnFocus.value);
854
+ const {
855
+ runOpenDelay,
856
+ runCloseDelay
857
+ } = useDelay(props, value => {
858
+ if (value === (props.openOnHover && isHovered || openOnFocus.value && isFocused) && !(props.openOnHover && isActive.value && !isTop.value)) {
859
+ if (isActive.value !== value) {
860
+ firstEnter = true;
861
+ }
862
+ isActive.value = value;
863
+ }
864
+ });
865
+ const cursorTarget = ref();
866
+ const availableEvents = {
867
+ onClick: e => {
868
+ e.stopPropagation();
869
+ activatorEl.value = e.currentTarget || e.target;
870
+ if (!isActive.value) {
871
+ cursorTarget.value = [e.clientX, e.clientY];
872
+ }
873
+ isActive.value = !isActive.value;
874
+ },
875
+ onMouseenter: e => {
876
+ if (e.sourceCapabilities?.firesTouchEvents) return;
877
+ isHovered = true;
878
+ activatorEl.value = e.currentTarget || e.target;
879
+ runOpenDelay();
880
+ },
881
+ onMouseleave: e => {
882
+ isHovered = false;
883
+ runCloseDelay();
884
+ },
885
+ onFocus: e => {
886
+ if (matchesSelector(e.target, ':focus-visible') === false) return;
887
+ isFocused = true;
888
+ e.stopPropagation();
889
+ activatorEl.value = e.currentTarget || e.target;
890
+ runOpenDelay();
891
+ },
892
+ onBlur: e => {
893
+ isFocused = false;
894
+ e.stopPropagation();
895
+ runCloseDelay();
896
+ }
897
+ };
898
+ const activatorEvents = computed(() => {
899
+ const events = {};
900
+ if (openOnClick.value) {
901
+ events.onClick = availableEvents.onClick;
902
+ }
903
+ if (props.openOnHover) {
904
+ events.onMouseenter = availableEvents.onMouseenter;
905
+ events.onMouseleave = availableEvents.onMouseleave;
906
+ }
907
+ if (openOnFocus.value) {
908
+ events.onFocus = availableEvents.onFocus;
909
+ events.onBlur = availableEvents.onBlur;
910
+ }
911
+ return events;
912
+ });
913
+ const contentEvents = computed(() => {
914
+ const events = {};
915
+ if (props.openOnHover) {
916
+ events.onMouseenter = () => {
917
+ isHovered = true;
918
+ runOpenDelay();
919
+ };
920
+ events.onMouseleave = () => {
921
+ isHovered = false;
922
+ runCloseDelay();
923
+ };
924
+ }
925
+ if (openOnFocus.value) {
926
+ events.onFocusin = () => {
927
+ isFocused = true;
928
+ runOpenDelay();
929
+ };
930
+ events.onFocusout = () => {
931
+ isFocused = false;
932
+ runCloseDelay();
933
+ };
934
+ }
935
+ if (props.closeOnContentClick) {
936
+ const menu = inject(VMenuSymbol, null);
937
+ events.onClick = () => {
938
+ isActive.value = false;
939
+ menu?.closeParents();
940
+ };
941
+ }
942
+ return events;
943
+ });
944
+ const scrimEvents = computed(() => {
945
+ const events = {};
946
+ if (props.openOnHover) {
947
+ events.onMouseenter = () => {
948
+ if (firstEnter) {
949
+ isHovered = true;
950
+ firstEnter = false;
951
+ runOpenDelay();
952
+ }
953
+ };
954
+ events.onMouseleave = () => {
955
+ isHovered = false;
956
+ runCloseDelay();
957
+ };
958
+ }
959
+ return events;
960
+ });
961
+ watch(isTop, val => {
962
+ if (val && (props.openOnHover && !isHovered && (!openOnFocus.value || !isFocused) || openOnFocus.value && !isFocused && (!props.openOnHover || !isHovered)) && !contentEl.value?.contains(document.activeElement)) {
963
+ isActive.value = false;
964
+ }
965
+ });
966
+ watch(isActive, val => {
967
+ if (!val) {
968
+ setTimeout(() => {
969
+ cursorTarget.value = undefined;
970
+ });
971
+ }
972
+ }, {
973
+ flush: 'post'
974
+ });
975
+ const activatorRef = templateRef();
976
+ watchEffect(() => {
977
+ if (!activatorRef.value) return;
978
+ nextTick(() => {
979
+ activatorEl.value = activatorRef.el;
980
+ });
981
+ });
982
+ const targetRef = templateRef();
983
+ const target = computed(() => {
984
+ if (props.target === 'cursor' && cursorTarget.value) return cursorTarget.value;
985
+ if (targetRef.value) return targetRef.el;
986
+ return getTarget(props.target, vm) || activatorEl.value;
987
+ });
988
+ const targetEl = computed(() => {
989
+ return Array.isArray(target.value) ? undefined : target.value;
990
+ });
991
+ let scope;
992
+ watch(() => !!props.activator, val => {
993
+ if (val && IN_BROWSER) {
994
+ scope = effectScope();
995
+ scope.run(() => {
996
+ _useActivator(props, vm, {
997
+ activatorEl,
998
+ activatorEvents
999
+ });
1000
+ });
1001
+ } else if (scope) {
1002
+ scope.stop();
1003
+ }
1004
+ }, {
1005
+ flush: 'post',
1006
+ immediate: true
1007
+ });
1008
+ onScopeDispose(() => {
1009
+ scope?.stop();
1010
+ });
1011
+ return {
1012
+ activatorEl,
1013
+ activatorRef,
1014
+ target,
1015
+ targetEl,
1016
+ targetRef,
1017
+ activatorEvents,
1018
+ contentEvents,
1019
+ scrimEvents
1020
+ };
1021
+ }
1022
+ function _useActivator(props, vm, _ref2) {
1023
+ let {
1024
+ activatorEl,
1025
+ activatorEvents
1026
+ } = _ref2;
1027
+ watch(() => props.activator, (val, oldVal) => {
1028
+ if (oldVal && val !== oldVal) {
1029
+ const activator = getActivator(oldVal);
1030
+ activator && unbindActivatorProps(activator);
1031
+ }
1032
+ if (val) {
1033
+ nextTick(() => bindActivatorProps());
1034
+ }
1035
+ }, {
1036
+ immediate: true
1037
+ });
1038
+ watch(() => props.activatorProps, () => {
1039
+ bindActivatorProps();
1040
+ });
1041
+ onScopeDispose(() => {
1042
+ unbindActivatorProps();
1043
+ });
1044
+ function bindActivatorProps() {
1045
+ let el = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getActivator();
1046
+ let _props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : props.activatorProps;
1047
+ if (!el) return;
1048
+ bindProps(el, mergeProps(activatorEvents.value, _props));
1049
+ }
1050
+ function unbindActivatorProps() {
1051
+ let el = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : getActivator();
1052
+ let _props = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : props.activatorProps;
1053
+ if (!el) return;
1054
+ unbindProps(el, mergeProps(activatorEvents.value, _props));
1055
+ }
1056
+ function getActivator() {
1057
+ let selector = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : props.activator;
1058
+ const activator = getTarget(selector, vm);
1059
+
1060
+ // The activator should only be a valid element (Ignore comments and text nodes)
1061
+ activatorEl.value = activator?.nodeType === Node.ELEMENT_NODE ? activator : undefined;
1062
+ return activatorEl.value;
1063
+ }
1064
+ }
1065
+ function getTarget(selector, vm) {
1066
+ if (!selector) return;
1067
+ let target;
1068
+ if (selector === 'parent') {
1069
+ let el = vm?.proxy?.$el?.parentNode;
1070
+ while (el?.hasAttribute('data-no-activator')) {
1071
+ el = el.parentNode;
1072
+ }
1073
+ target = el;
1074
+ } else if (typeof selector === 'string') {
1075
+ // Selector
1076
+ target = document.querySelector(selector);
1077
+ } else if ('$el' in selector) {
1078
+ // Component (ref)
1079
+ target = selector.$el;
1080
+ } else {
1081
+ // HTMLElement | Element | [x, y]
1082
+ target = selector;
1083
+ }
1084
+ return target;
1085
+ }
1086
+
1087
+ // Composables
1088
+ function useHydration() {
1089
+ if (!IN_BROWSER) return shallowRef(false);
1090
+ const {
1091
+ ssr
1092
+ } = useDisplay();
1093
+ if (ssr) {
1094
+ const isMounted = shallowRef(false);
1095
+ onMounted(() => {
1096
+ isMounted.value = true;
1097
+ });
1098
+ return isMounted;
1099
+ } else {
1100
+ return shallowRef(true);
1101
+ }
1102
+ }
1103
+
1104
+ // Composables
1105
+ const StackSymbol = Symbol.for('vuetify:stack');
1106
+ const globalStack = reactive([]);
1107
+ function useStack(isActive, zIndex, disableGlobalStack) {
1108
+ const vm = getCurrentInstance('useStack');
1109
+ const createStackEntry = !disableGlobalStack;
1110
+ const parent = inject(StackSymbol, undefined);
1111
+ const stack = reactive({
1112
+ activeChildren: new Set()
1113
+ });
1114
+ provide(StackSymbol, stack);
1115
+ const _zIndex = shallowRef(+zIndex.value);
1116
+ useToggleScope(isActive, () => {
1117
+ const lastZIndex = globalStack.at(-1)?.[1];
1118
+ _zIndex.value = lastZIndex ? lastZIndex + 10 : +zIndex.value;
1119
+ if (createStackEntry) {
1120
+ globalStack.push([vm.uid, _zIndex.value]);
1121
+ }
1122
+ parent?.activeChildren.add(vm.uid);
1123
+ onScopeDispose(() => {
1124
+ if (createStackEntry) {
1125
+ const idx = toRaw(globalStack).findIndex(v => v[0] === vm.uid);
1126
+ globalStack.splice(idx, 1);
1127
+ }
1128
+ parent?.activeChildren.delete(vm.uid);
1129
+ });
1130
+ });
1131
+ const globalTop = shallowRef(true);
1132
+ if (createStackEntry) {
1133
+ watchEffect(() => {
1134
+ const _isTop = globalStack.at(-1)?.[0] === vm.uid;
1135
+ setTimeout(() => globalTop.value = _isTop);
1136
+ });
1137
+ }
1138
+ const localTop = computed(() => !stack.activeChildren.size);
1139
+ return {
1140
+ globalTop: readonly(globalTop),
1141
+ localTop,
1142
+ stackStyles: computed(() => ({
1143
+ zIndex: _zIndex.value
1144
+ }))
1145
+ };
1146
+ }
1147
+
1148
+ // Utilities
1149
+ function useTeleport(target) {
1150
+ const teleportTarget = computed(() => {
1151
+ const _target = target();
1152
+ if (_target === true || !IN_BROWSER) return undefined;
1153
+ const targetElement = _target === false ? document.body : typeof _target === 'string' ? document.querySelector(_target) : _target;
1154
+ if (targetElement == null) {
1155
+ warn(`Unable to locate target ${_target}`);
1156
+ return undefined;
1157
+ }
1158
+ let container = [...targetElement.children].find(el => el.matches('.v-overlay-container'));
1159
+ if (!container) {
1160
+ container = document.createElement('div');
1161
+ container.className = 'v-overlay-container';
1162
+ targetElement.appendChild(container);
1163
+ }
1164
+ return container;
1165
+ });
1166
+ return {
1167
+ teleportTarget
1168
+ };
1169
+ }
1170
+
1171
+ function Scrim(props) {
1172
+ const {
1173
+ modelValue,
1174
+ color,
1175
+ ...rest
1176
+ } = props;
1177
+ return createVNode(Transition, {
1178
+ "name": "fade-transition",
1179
+ "appear": true
1180
+ }, {
1181
+ default: () => [props.modelValue && createVNode("div", mergeProps({
1182
+ "class": ['v-overlay__scrim', props.color.backgroundColorClasses.value],
1183
+ "style": props.color.backgroundColorStyles.value
1184
+ }, rest), null)]
1185
+ });
1186
+ }
1187
+ const makeVOverlayProps = propsFactory({
1188
+ absolute: Boolean,
1189
+ attach: [Boolean, String, Object],
1190
+ closeOnBack: {
1191
+ type: Boolean,
1192
+ default: true
1193
+ },
1194
+ contained: Boolean,
1195
+ contentClass: null,
1196
+ contentProps: null,
1197
+ disabled: Boolean,
1198
+ opacity: [Number, String],
1199
+ noClickAnimation: Boolean,
1200
+ modelValue: Boolean,
1201
+ persistent: Boolean,
1202
+ scrim: {
1203
+ type: [Boolean, String],
1204
+ default: true
1205
+ },
1206
+ zIndex: {
1207
+ type: [Number, String],
1208
+ default: 2000
1209
+ },
1210
+ ...makeActivatorProps(),
1211
+ ...makeComponentProps(),
1212
+ ...makeDimensionProps(),
1213
+ ...makeLazyProps(),
1214
+ ...makeLocationStrategyProps(),
1215
+ ...makeScrollStrategyProps(),
1216
+ ...makeThemeProps(),
1217
+ ...makeTransitionProps()
1218
+ }, 'VOverlay');
1219
+ const VOverlay = genericComponent()({
1220
+ name: 'VOverlay',
1221
+ directives: {
1222
+ ClickOutside
1223
+ },
1224
+ inheritAttrs: false,
1225
+ props: {
1226
+ _disableGlobalStack: Boolean,
1227
+ ...makeVOverlayProps()
1228
+ },
1229
+ emits: {
1230
+ 'click:outside': e => true,
1231
+ 'update:modelValue': value => true,
1232
+ afterEnter: () => true,
1233
+ afterLeave: () => true
1234
+ },
1235
+ setup(props, _ref) {
1236
+ let {
1237
+ slots,
1238
+ attrs,
1239
+ emit
1240
+ } = _ref;
1241
+ const vm = getCurrentInstance('VOverlay');
1242
+ const root = ref();
1243
+ const scrimEl = ref();
1244
+ const contentEl = ref();
1245
+ const model = useProxiedModel(props, 'modelValue');
1246
+ const isActive = computed({
1247
+ get: () => model.value,
1248
+ set: v => {
1249
+ if (!(v && props.disabled)) model.value = v;
1250
+ }
1251
+ });
1252
+ const {
1253
+ themeClasses
1254
+ } = provideTheme(props);
1255
+ const {
1256
+ rtlClasses,
1257
+ isRtl
1258
+ } = useRtl();
1259
+ const {
1260
+ hasContent,
1261
+ onAfterLeave: _onAfterLeave
1262
+ } = useLazy(props, isActive);
1263
+ const scrimColor = useBackgroundColor(computed(() => {
1264
+ return typeof props.scrim === 'string' ? props.scrim : null;
1265
+ }));
1266
+ const {
1267
+ globalTop,
1268
+ localTop,
1269
+ stackStyles
1270
+ } = useStack(isActive, toRef(props, 'zIndex'), props._disableGlobalStack);
1271
+ const {
1272
+ activatorEl,
1273
+ activatorRef,
1274
+ target,
1275
+ targetEl,
1276
+ targetRef,
1277
+ activatorEvents,
1278
+ contentEvents,
1279
+ scrimEvents
1280
+ } = useActivator(props, {
1281
+ isActive,
1282
+ isTop: localTop,
1283
+ contentEl
1284
+ });
1285
+ const {
1286
+ teleportTarget
1287
+ } = useTeleport(() => {
1288
+ const target = props.attach || props.contained;
1289
+ if (target) return target;
1290
+ const rootNode = activatorEl?.value?.getRootNode() || vm.proxy?.$el?.getRootNode();
1291
+ if (rootNode instanceof ShadowRoot) return rootNode;
1292
+ return false;
1293
+ });
1294
+ const {
1295
+ dimensionStyles
1296
+ } = useDimension(props);
1297
+ const isMounted = useHydration();
1298
+ const {
1299
+ scopeId
1300
+ } = useScopeId();
1301
+ watch(() => props.disabled, v => {
1302
+ if (v) isActive.value = false;
1303
+ });
1304
+ const {
1305
+ contentStyles,
1306
+ updateLocation
1307
+ } = useLocationStrategies(props, {
1308
+ isRtl,
1309
+ contentEl,
1310
+ target,
1311
+ isActive
1312
+ });
1313
+ useScrollStrategies(props, {
1314
+ root,
1315
+ contentEl,
1316
+ targetEl,
1317
+ isActive,
1318
+ updateLocation
1319
+ });
1320
+ function onClickOutside(e) {
1321
+ emit('click:outside', e);
1322
+ if (!props.persistent) isActive.value = false;else animateClick();
1323
+ }
1324
+ function closeConditional(e) {
1325
+ return isActive.value && globalTop.value && (
1326
+ // If using scrim, only close if clicking on it rather than anything opened on top
1327
+ !props.scrim || e.target === scrimEl.value || e instanceof MouseEvent && e.shadowTarget === scrimEl.value);
1328
+ }
1329
+ IN_BROWSER && watch(isActive, val => {
1330
+ if (val) {
1331
+ window.addEventListener('keydown', onKeydown);
1332
+ } else {
1333
+ window.removeEventListener('keydown', onKeydown);
1334
+ }
1335
+ }, {
1336
+ immediate: true
1337
+ });
1338
+ onBeforeUnmount(() => {
1339
+ if (!IN_BROWSER) return;
1340
+ window.removeEventListener('keydown', onKeydown);
1341
+ });
1342
+ function onKeydown(e) {
1343
+ if (e.key === 'Escape' && globalTop.value) {
1344
+ if (!props.persistent) {
1345
+ isActive.value = false;
1346
+ if (contentEl.value?.contains(document.activeElement)) {
1347
+ activatorEl.value?.focus();
1348
+ }
1349
+ } else animateClick();
1350
+ }
1351
+ }
1352
+ const router = useRouter();
1353
+ useToggleScope(() => props.closeOnBack, () => {
1354
+ useBackButton(router, next => {
1355
+ if (globalTop.value && isActive.value) {
1356
+ next(false);
1357
+ if (!props.persistent) isActive.value = false;else animateClick();
1358
+ } else {
1359
+ next();
1360
+ }
1361
+ });
1362
+ });
1363
+ const top = ref();
1364
+ watch(() => isActive.value && (props.absolute || props.contained) && teleportTarget.value == null, val => {
1365
+ if (val) {
1366
+ const scrollParent = getScrollParent(root.value);
1367
+ if (scrollParent && scrollParent !== document.scrollingElement) {
1368
+ top.value = scrollParent.scrollTop;
1369
+ }
1370
+ }
1371
+ });
1372
+
1373
+ // Add a quick "bounce" animation to the content
1374
+ function animateClick() {
1375
+ if (props.noClickAnimation) return;
1376
+ contentEl.value && animate(contentEl.value, [{
1377
+ transformOrigin: 'center'
1378
+ }, {
1379
+ transform: 'scale(1.03)'
1380
+ }, {
1381
+ transformOrigin: 'center'
1382
+ }], {
1383
+ duration: 150,
1384
+ easing: standardEasing
1385
+ });
1386
+ }
1387
+ function onAfterEnter() {
1388
+ emit('afterEnter');
1389
+ }
1390
+ function onAfterLeave() {
1391
+ _onAfterLeave();
1392
+ emit('afterLeave');
1393
+ }
1394
+ useRender(() => createVNode(Fragment, null, [slots.activator?.({
1395
+ isActive: isActive.value,
1396
+ targetRef,
1397
+ props: mergeProps({
1398
+ ref: activatorRef
1399
+ }, activatorEvents.value, props.activatorProps)
1400
+ }), isMounted.value && hasContent.value && createVNode(Teleport, {
1401
+ "disabled": !teleportTarget.value,
1402
+ "to": teleportTarget.value
1403
+ }, {
1404
+ default: () => [createVNode("div", mergeProps({
1405
+ "class": ['v-overlay', {
1406
+ 'v-overlay--absolute': props.absolute || props.contained,
1407
+ 'v-overlay--active': isActive.value,
1408
+ 'v-overlay--contained': props.contained
1409
+ }, themeClasses.value, rtlClasses.value, props.class],
1410
+ "style": [stackStyles.value, {
1411
+ '--v-overlay-opacity': props.opacity,
1412
+ top: convertToUnit(top.value)
1413
+ }, props.style],
1414
+ "ref": root
1415
+ }, scopeId, attrs), [createVNode(Scrim, mergeProps({
1416
+ "color": scrimColor,
1417
+ "modelValue": isActive.value && !!props.scrim,
1418
+ "ref": scrimEl
1419
+ }, scrimEvents.value), null), createVNode(MaybeTransition, {
1420
+ "appear": true,
1421
+ "persisted": true,
1422
+ "transition": props.transition,
1423
+ "target": target.value,
1424
+ "onAfterEnter": onAfterEnter,
1425
+ "onAfterLeave": onAfterLeave
1426
+ }, {
1427
+ default: () => [withDirectives(createVNode("div", mergeProps({
1428
+ "ref": contentEl,
1429
+ "class": ['v-overlay__content', props.contentClass],
1430
+ "style": [dimensionStyles.value, contentStyles.value]
1431
+ }, contentEvents.value, props.contentProps), [slots.default?.({
1432
+ isActive
1433
+ })]), [[vShow, isActive.value], [resolveDirective("click-outside"), {
1434
+ handler: onClickOutside,
1435
+ closeConditional,
1436
+ include: () => [activatorEl.value]
1437
+ }]])]
1438
+ })])]
1439
+ })]));
1440
+ return {
1441
+ activatorEl,
1442
+ scrimEl,
1443
+ target,
1444
+ animateClick,
1445
+ contentEl,
1446
+ globalTop,
1447
+ localTop,
1448
+ updateLocation
1449
+ };
1450
+ }
1451
+ });
1452
+
1453
+ export { VOverlay as V, makeVOverlayProps as m };