@eodash/eodash 5.1.0 → 5.3.0

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 (133) hide show
  1. package/core/client/components/DashboardLayout.vue +1 -2
  2. package/core/client/components/EodashOverlay.vue +4 -5
  3. package/core/client/components/MobileLayout.vue +42 -21
  4. package/core/client/composables/index.js +54 -60
  5. package/core/client/eodashSTAC/EodashCollection.js +199 -108
  6. package/core/client/eodashSTAC/auth.js +86 -0
  7. package/core/client/eodashSTAC/createLayers.js +234 -4
  8. package/core/client/eodashSTAC/helpers.js +281 -59
  9. package/core/client/eodashSTAC/parquet.js +0 -13
  10. package/core/client/eodashSTAC/triggers.js +1 -1
  11. package/core/client/store/actions.js +14 -0
  12. package/core/client/store/stac.js +46 -8
  13. package/core/client/store/states.js +6 -0
  14. package/core/client/types.ts +206 -3
  15. package/core/client/utils/bands-editor/arithmetic.js +144 -0
  16. package/core/client/utils/bands-editor/colors.js +36 -0
  17. package/core/client/utils/bands-editor/dom.js +196 -0
  18. package/core/client/utils/bands-editor/exampleSchema.json +1320 -0
  19. package/core/client/utils/bands-editor/index.js +68 -0
  20. package/core/client/utils/bands-editor/rgb.js +102 -0
  21. package/core/client/utils/index.js +5 -2
  22. package/core/client/views/Dashboard.vue +1 -1
  23. package/core/client/vite-env.d.ts +122 -0
  24. package/dist/client/{DashboardLayout-ByVs1DrY.js → DashboardLayout-Cq15p4TH.js} +5 -6
  25. package/dist/client/{DynamicWebComponent-C3W7HSQm.js → DynamicWebComponent-Cv-fPRG1.js} +1 -1
  26. package/dist/client/{EodashDatePicker-BIAf1sMT.js → EodashDatePicker-CPlJwEIO.js} +20 -22
  27. package/dist/client/{EodashItemFilter-DPznh8UB.js → EodashItemFilter-Ydebgbjj.js} +46 -31
  28. package/dist/client/EodashLayerControl-COhrkNEs.js +1517 -0
  29. package/dist/client/{EodashLayoutSwitcher-C5qTEffW.js → EodashLayoutSwitcher-pnKhTRZV.js} +4 -4
  30. package/dist/client/EodashMapBtns-Cj0Fx119.js +301 -0
  31. package/dist/client/{EodashStacInfo-CSvvF2jI.js → EodashStacInfo-Dadkg_Nj.js} +1 -1
  32. package/dist/client/EodashTimeSlider-CpoHX0S7.js +53 -0
  33. package/dist/client/{EodashTools-Cv1SXQ5y.js → EodashTools-UGBG7KC9.js} +10 -7
  34. package/dist/client/{ExportState-D-iuwaad.js → ExportState-GtJkAqeZ.js} +145 -121
  35. package/dist/client/{Footer-CyF0zRAk.js → Footer-D3ZPG5c4.js} +1 -1
  36. package/dist/client/{Header-CgD8jDKU.js → Header-z6AK-wpN.js} +2 -3
  37. package/dist/client/MobileLayout-BXNsNftb.js +118 -0
  38. package/dist/client/{PopUp-BsYLvWch.js → PopUp-BbQdjENV.js} +79 -44
  39. package/dist/client/{ProcessList-C2xsLU2_.js → ProcessList-C6VsdsYI.js} +18 -12
  40. package/dist/client/{VImg-OHe8YTs2.js → VImg-CxaMSB99.js} +203 -5
  41. package/dist/client/{VMain-PryTLU4a.js → VMain-Ds7yw0wj.js} +1 -1
  42. package/dist/client/{VTooltip-DZ0fjpB3.js → VTooltip-Cze6CEVh.js} +2 -3
  43. package/dist/client/{WidgetsContainer-B9LBadcC.js → WidgetsContainer-D66bj-JJ.js} +1 -1
  44. package/dist/client/asWebComponent-CWbNRdf9.js +8895 -0
  45. package/dist/client/{async-DkSu_u2K.js → async-BA7oWCMX.js} +69 -5
  46. package/dist/client/easing-CH0-9wR8.js +35 -0
  47. package/dist/client/eo-dash.js +1 -1
  48. package/dist/client/{VOverlay-yUn7p-Uf.js → forwardRefs-BUfxOIo-.js} +308 -28
  49. package/dist/client/{handling-CgmFXkW6.js → handling-DlNTtKB-.js} +27 -6
  50. package/dist/client/{helpers-Dy0Q13tP.js → helpers-CtE0W7iu.js} +595 -278
  51. package/dist/client/{index-skjhlH8u.js → index-CeEZIjO6.js} +26 -13
  52. package/dist/client/{index-Ch_HchK3.js → index-CsKbRDeN.js} +238 -77
  53. package/dist/client/{index-Dqj4tbx2.js → index-D4_NRKrf.js} +2 -2
  54. package/dist/client/index-DeECc3lV.js +571 -0
  55. package/dist/client/material-symbols-outlined.woff2 +0 -0
  56. package/dist/client/material-symbols-rounded.woff2 +0 -0
  57. package/dist/client/material-symbols-sharp.woff2 +0 -0
  58. package/dist/client/material-symbols-subset.woff2 +0 -0
  59. package/dist/client/templates.js +106 -49
  60. package/dist/client/{transition-C98Yn4Vo.js → transition-Byvp3L6Y.js} +1 -1
  61. package/dist/node/cli.js +6 -6
  62. package/dist/types/core/client/eodashSTAC/EodashCollection.d.ts +24 -10
  63. package/dist/types/core/client/eodashSTAC/auth.d.ts +7 -0
  64. package/dist/types/core/client/eodashSTAC/createLayers.d.ts +15 -3
  65. package/dist/types/core/client/eodashSTAC/helpers.d.ts +51 -15
  66. package/dist/types/core/client/plugins/vuetify.d.ts +14 -14
  67. package/dist/types/core/client/store/actions.d.ts +2 -0
  68. package/dist/types/core/client/store/stac.d.ts +16 -7
  69. package/dist/types/core/client/store/states.d.ts +4 -0
  70. package/dist/types/core/client/types.d.ts +171 -3
  71. package/dist/types/core/client/utils/bands-editor/arithmetic.d.ts +8 -0
  72. package/dist/types/core/client/utils/bands-editor/colors.d.ts +15 -0
  73. package/dist/types/core/client/utils/bands-editor/dom.d.ts +42 -0
  74. package/dist/types/core/client/utils/bands-editor/index.d.ts +20 -0
  75. package/dist/types/core/client/utils/bands-editor/rgb.d.ts +15 -0
  76. package/dist/types/core/client/utils/index.d.ts +1 -1
  77. package/dist/types/templates/baseConfig.d.ts +87 -1
  78. package/dist/types/templates/compare.d.ts +0 -25
  79. package/dist/types/templates/expert.d.ts +17 -21
  80. package/dist/types/templates/explore.d.ts +67 -0
  81. package/dist/types/templates/index.d.ts +1 -1
  82. package/dist/types/templates/{light.d.ts → lite.d.ts} +9 -0
  83. package/dist/types/widgets/EodashItemCatalog/index.vue.d.ts +21 -0
  84. package/dist/types/widgets/EodashItemCatalog/methods/filters.d.ts +49 -0
  85. package/dist/types/widgets/EodashItemCatalog/methods/handlers.d.ts +4 -0
  86. package/dist/types/widgets/EodashItemCatalog/methods/map.d.ts +12 -0
  87. package/dist/types/widgets/EodashItemCatalog/types.d.ts +14 -0
  88. package/dist/types/widgets/{EodashMapBtns.vue.d.ts → EodashMap/EodashMapBtns.vue.d.ts} +6 -0
  89. package/dist/types/widgets/EodashMap/index.vue.d.ts +114 -0
  90. package/dist/types/widgets/EodashMap/methods/create-layers-config.d.ts +1 -1
  91. package/dist/types/widgets/EodashMap/methods/index.d.ts +1 -1
  92. package/dist/types/widgets/EodashProcess/methods/async.d.ts +1 -0
  93. package/dist/types/widgets/EodashProcess/methods/custom-endpoints/layers/eoxhub-workspaces-endpoint.d.ts +1 -1
  94. package/dist/types/widgets/EodashTimeSlider.vue.d.ts +7 -0
  95. package/dist/types/widgets/EodashTools.vue.d.ts +10 -10
  96. package/dist/types/widgets/ExportState.vue.d.ts +2 -0
  97. package/package.json +31 -28
  98. package/templates/baseConfig.js +10 -5
  99. package/templates/compare.js +2 -22
  100. package/templates/expert.js +19 -18
  101. package/templates/explore.js +62 -0
  102. package/templates/index.js +1 -1
  103. package/templates/{light.js → lite.js} +11 -2
  104. package/widgets/EodashDatePicker.vue +15 -18
  105. package/widgets/EodashItemCatalog/index.vue +161 -0
  106. package/widgets/EodashItemCatalog/methods/filters.js +216 -0
  107. package/widgets/EodashItemCatalog/methods/handlers.js +50 -0
  108. package/widgets/EodashItemCatalog/methods/map.js +144 -0
  109. package/widgets/EodashItemCatalog/types.ts +15 -0
  110. package/widgets/EodashItemFilter.vue +35 -28
  111. package/widgets/EodashLayerControl.vue +10 -6
  112. package/widgets/EodashLayoutSwitcher.vue +1 -1
  113. package/widgets/EodashMap/EodashMapBtns.vue +278 -0
  114. package/widgets/EodashMap/index.vue +263 -38
  115. package/widgets/EodashMap/methods/create-layers-config.js +9 -6
  116. package/widgets/EodashMap/methods/index.js +27 -13
  117. package/widgets/EodashProcess/ProcessList.vue +13 -1
  118. package/widgets/EodashProcess/index.vue +17 -1
  119. package/widgets/EodashProcess/methods/async.js +22 -1
  120. package/widgets/EodashProcess/methods/custom-endpoints/chart/veda-endpoint.js +25 -3
  121. package/widgets/EodashProcess/methods/handling.js +2 -0
  122. package/widgets/EodashProcess/methods/outputs.js +1 -0
  123. package/widgets/EodashProcess/methods/utils.js +45 -1
  124. package/widgets/EodashTimeSlider.vue +40 -0
  125. package/widgets/EodashTools.vue +7 -3
  126. package/widgets/ExportState.vue +53 -22
  127. package/dist/client/EodashLayerControl-Bhxjw4V2.js +0 -154
  128. package/dist/client/EodashMapBtns-WoGq8MuV.js +0 -173
  129. package/dist/client/MobileLayout-EKQ_kpSh.js +0 -1226
  130. package/dist/client/asWebComponent-By_7_JjS.js +0 -19193
  131. package/dist/client/forwardRefs-BXxrv98s.js +0 -272
  132. package/dist/client/index-BuhOHXKv.js +0 -199
  133. package/widgets/EodashMapBtns.vue +0 -155
@@ -1,1226 +0,0 @@
1
- import { ref, computed, createVNode, mergeProps, createElementVNode, Fragment, normalizeStyle, normalizeClass, shallowRef, watch, provide, toRef, withDirectives, inject, vShow, nextTick, useCssVars, onMounted, createBlock, openBlock, withCtx, createElementBlock, Suspense, createCommentVNode, unref, resolveDynamicComponent, renderList, createTextVNode, toDisplayString } from 'vue';
2
- import { k as keys, g as genericComponent, p as propsFactory, u as useTextColor, a as useRender, V as VBtn, o as omit, m as makeVBtnProps, b as provideTheme, c as useRtl, d as useLocale, e as useGroup, f as makeThemeProps, h as makeTagProps, i as makeComponentProps, j as useProxiedModel, l as useGroupItem, n as makeGroupItemProps, q as convertToUnit, r as useDisplay, s as useResizeObserver, t as useGoTo, I as IN_BROWSER, v as VIcon, w as makeGroupProps, x as makeDisplayProps, y as IconValue, z as focusableChildren, A as useDensity, B as useBackgroundColor, C as provideDefaults, D as makeDensityProps, E as isObject, _ as _export_sfc, F as useDefineTemplate, G as useLayout } from './asWebComponent-By_7_JjS.js';
3
- import { V as VMain } from './VMain-PryTLU4a.js';
4
- import { f as forwardRefs, a as animate, s as standardEasing, u as useLazy, m as makeLazyProps, b as useScopeId } from './forwardRefs-BXxrv98s.js';
5
- import { u as useSsrBoot } from './ssrBoot-Zgc_Ttvi.js';
6
- import { M as MaybeTransition } from './transition-C98Yn4Vo.js';
7
- import { V as VFadeTransition } from './index-BuhOHXKv.js';
8
-
9
- // Utilities
10
- const handleGesture = wrapper => {
11
- const {
12
- touchstartX,
13
- touchendX,
14
- touchstartY,
15
- touchendY
16
- } = wrapper;
17
- const dirRatio = 0.5;
18
- const minDistance = 16;
19
- wrapper.offsetX = touchendX - touchstartX;
20
- wrapper.offsetY = touchendY - touchstartY;
21
- if (Math.abs(wrapper.offsetY) < dirRatio * Math.abs(wrapper.offsetX)) {
22
- wrapper.left && touchendX < touchstartX - minDistance && wrapper.left(wrapper);
23
- wrapper.right && touchendX > touchstartX + minDistance && wrapper.right(wrapper);
24
- }
25
- if (Math.abs(wrapper.offsetX) < dirRatio * Math.abs(wrapper.offsetY)) {
26
- wrapper.up && touchendY < touchstartY - minDistance && wrapper.up(wrapper);
27
- wrapper.down && touchendY > touchstartY + minDistance && wrapper.down(wrapper);
28
- }
29
- };
30
- function touchstart(event, wrapper) {
31
- const touch = event.changedTouches[0];
32
- wrapper.touchstartX = touch.clientX;
33
- wrapper.touchstartY = touch.clientY;
34
- wrapper.start?.({
35
- originalEvent: event,
36
- ...wrapper
37
- });
38
- }
39
- function touchend(event, wrapper) {
40
- const touch = event.changedTouches[0];
41
- wrapper.touchendX = touch.clientX;
42
- wrapper.touchendY = touch.clientY;
43
- wrapper.end?.({
44
- originalEvent: event,
45
- ...wrapper
46
- });
47
- handleGesture(wrapper);
48
- }
49
- function touchmove(event, wrapper) {
50
- const touch = event.changedTouches[0];
51
- wrapper.touchmoveX = touch.clientX;
52
- wrapper.touchmoveY = touch.clientY;
53
- wrapper.move?.({
54
- originalEvent: event,
55
- ...wrapper
56
- });
57
- }
58
- function createHandlers() {
59
- let value = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
60
- const wrapper = {
61
- touchstartX: 0,
62
- touchstartY: 0,
63
- touchendX: 0,
64
- touchendY: 0,
65
- touchmoveX: 0,
66
- touchmoveY: 0,
67
- offsetX: 0,
68
- offsetY: 0,
69
- left: value.left,
70
- right: value.right,
71
- up: value.up,
72
- down: value.down,
73
- start: value.start,
74
- move: value.move,
75
- end: value.end
76
- };
77
- return {
78
- touchstart: e => touchstart(e, wrapper),
79
- touchend: e => touchend(e, wrapper),
80
- touchmove: e => touchmove(e, wrapper)
81
- };
82
- }
83
- function mounted(el, binding) {
84
- const value = binding.value;
85
- const target = value?.parent ? el.parentElement : el;
86
- const options = value?.options ?? {
87
- passive: true
88
- };
89
- const uid = binding.instance?.$.uid; // TODO: use custom uid generator
90
-
91
- if (!target || !uid) return;
92
- const handlers = createHandlers(binding.value);
93
- target._touchHandlers = target._touchHandlers ?? Object.create(null);
94
- target._touchHandlers[uid] = handlers;
95
- keys(handlers).forEach(eventName => {
96
- target.addEventListener(eventName, handlers[eventName], options);
97
- });
98
- }
99
- function unmounted(el, binding) {
100
- const target = binding.value?.parent ? el.parentElement : el;
101
- const uid = binding.instance?.$.uid;
102
- if (!target?._touchHandlers || !uid) return;
103
- const handlers = target._touchHandlers[uid];
104
- keys(handlers).forEach(eventName => {
105
- target.removeEventListener(eventName, handlers[eventName]);
106
- });
107
- delete target._touchHandlers[uid];
108
- }
109
- const Touch = {
110
- mounted,
111
- unmounted
112
- };
113
-
114
- const _style_0 = ".panel[data-v-f4ab4c65]{bottom:var(--2d9a694e);top:var(--4f6792e6);position:absolute;overflow:hidden;width:100%;left:0;z-index:3}.component-container[data-v-f4ab4c65]{height:90%}.close-btn[data-v-f4ab4c65]{height:5%;position:relative}.tabs[data-v-f4ab4c65]{bottom:var(--515e6bda);position:relative;z-index:10}[data-v-f4ab4c65] .bg-surface{backdrop-filter:blur(10px)!important;background-color:rgba(var(--v-theme-surface),var(--v-surface-opacity, .8))!important}";
115
-
116
- // Types
117
-
118
- const VTabsSymbol = Symbol.for('vuetify:v-tabs');
119
-
120
- const makeVTabProps = propsFactory({
121
- fixed: Boolean,
122
- sliderColor: String,
123
- hideSlider: Boolean,
124
- direction: {
125
- type: String,
126
- default: 'horizontal'
127
- },
128
- ...omit(makeVBtnProps({
129
- selectedClass: 'v-tab--selected',
130
- variant: 'text'
131
- }), ['active', 'block', 'flat', 'location', 'position', 'symbol'])
132
- }, 'VTab');
133
- const VTab = genericComponent()({
134
- name: 'VTab',
135
- props: makeVTabProps(),
136
- setup(props, _ref) {
137
- let {
138
- slots,
139
- attrs
140
- } = _ref;
141
- const {
142
- textColorClasses: sliderColorClasses,
143
- textColorStyles: sliderColorStyles
144
- } = useTextColor(() => props.sliderColor);
145
- const rootEl = ref();
146
- const sliderEl = ref();
147
- const isHorizontal = computed(() => props.direction === 'horizontal');
148
- const isSelected = computed(() => rootEl.value?.group?.isSelected.value ?? false);
149
- function updateSlider(_ref2) {
150
- let {
151
- value
152
- } = _ref2;
153
- if (value) {
154
- const prevEl = rootEl.value?.$el.parentElement?.querySelector('.v-tab--selected .v-tab__slider');
155
- const nextEl = sliderEl.value;
156
- if (!prevEl || !nextEl) return;
157
- const color = getComputedStyle(prevEl).color;
158
- const prevBox = prevEl.getBoundingClientRect();
159
- const nextBox = nextEl.getBoundingClientRect();
160
- const xy = isHorizontal.value ? 'x' : 'y';
161
- const XY = isHorizontal.value ? 'X' : 'Y';
162
- const rightBottom = isHorizontal.value ? 'right' : 'bottom';
163
- const widthHeight = isHorizontal.value ? 'width' : 'height';
164
- const prevPos = prevBox[xy];
165
- const nextPos = nextBox[xy];
166
- const delta = prevPos > nextPos ? prevBox[rightBottom] - nextBox[rightBottom] : prevBox[xy] - nextBox[xy];
167
- const origin = Math.sign(delta) > 0 ? isHorizontal.value ? 'right' : 'bottom' : Math.sign(delta) < 0 ? isHorizontal.value ? 'left' : 'top' : 'center';
168
- const size = Math.abs(delta) + (Math.sign(delta) < 0 ? prevBox[widthHeight] : nextBox[widthHeight]);
169
- const scale = size / Math.max(prevBox[widthHeight], nextBox[widthHeight]) || 0;
170
- const initialScale = prevBox[widthHeight] / nextBox[widthHeight] || 0;
171
- const sigma = 1.5;
172
- animate(nextEl, {
173
- backgroundColor: [color, 'currentcolor'],
174
- transform: [`translate${XY}(${delta}px) scale${XY}(${initialScale})`, `translate${XY}(${delta / sigma}px) scale${XY}(${(scale - 1) / sigma + 1})`, 'none'],
175
- transformOrigin: Array(3).fill(origin)
176
- }, {
177
- duration: 225,
178
- easing: standardEasing
179
- });
180
- }
181
- }
182
- useRender(() => {
183
- const btnProps = VBtn.filterProps(props);
184
- return createVNode(VBtn, mergeProps({
185
- "symbol": VTabsSymbol,
186
- "ref": rootEl,
187
- "class": ['v-tab', props.class],
188
- "style": props.style,
189
- "tabindex": isSelected.value ? 0 : -1,
190
- "role": "tab",
191
- "aria-selected": String(isSelected.value),
192
- "active": false
193
- }, btnProps, attrs, {
194
- "block": props.fixed,
195
- "maxWidth": props.fixed ? 300 : undefined,
196
- "onGroup:selected": updateSlider
197
- }), {
198
- ...slots,
199
- default: () => createElementVNode(Fragment, null, [slots.default?.() ?? props.text, !props.hideSlider && createElementVNode("div", {
200
- "ref": sliderEl,
201
- "class": normalizeClass(['v-tab__slider', sliderColorClasses.value]),
202
- "style": normalizeStyle(sliderColorStyles.value)
203
- }, null)])
204
- });
205
- });
206
- return forwardRefs({}, rootEl);
207
- }
208
- });
209
-
210
- const VWindowSymbol = Symbol.for('vuetify:v-window');
211
- const VWindowGroupSymbol = Symbol.for('vuetify:v-window-group');
212
- const makeVWindowProps = propsFactory({
213
- continuous: Boolean,
214
- nextIcon: {
215
- type: [Boolean, String, Function, Object],
216
- default: '$next'
217
- },
218
- prevIcon: {
219
- type: [Boolean, String, Function, Object],
220
- default: '$prev'
221
- },
222
- reverse: Boolean,
223
- showArrows: {
224
- type: [Boolean, String],
225
- validator: v => typeof v === 'boolean' || v === 'hover'
226
- },
227
- verticalArrows: [Boolean, String],
228
- touch: {
229
- type: [Object, Boolean],
230
- default: undefined
231
- },
232
- direction: {
233
- type: String,
234
- default: 'horizontal'
235
- },
236
- modelValue: null,
237
- disabled: Boolean,
238
- selectedClass: {
239
- type: String,
240
- default: 'v-window-item--active'
241
- },
242
- // TODO: mandatory should probably not be exposed but do this for now
243
- mandatory: {
244
- type: [Boolean, String],
245
- default: 'force'
246
- },
247
- ...makeComponentProps(),
248
- ...makeTagProps(),
249
- ...makeThemeProps()
250
- }, 'VWindow');
251
- const VWindow = genericComponent()({
252
- name: 'VWindow',
253
- directives: {
254
- vTouch: Touch
255
- },
256
- props: makeVWindowProps(),
257
- emits: {
258
- 'update:modelValue': value => true
259
- },
260
- setup(props, _ref) {
261
- let {
262
- slots
263
- } = _ref;
264
- const {
265
- themeClasses
266
- } = provideTheme(props);
267
- const {
268
- isRtl
269
- } = useRtl();
270
- const {
271
- t
272
- } = useLocale();
273
- const group = useGroup(props, VWindowGroupSymbol);
274
- const rootRef = ref();
275
- const isRtlReverse = computed(() => isRtl.value ? !props.reverse : props.reverse);
276
- const isReversed = shallowRef(false);
277
- const transition = computed(() => {
278
- const axis = props.direction === 'vertical' ? 'y' : 'x';
279
- const reverse = isRtlReverse.value ? !isReversed.value : isReversed.value;
280
- const direction = reverse ? '-reverse' : '';
281
- return `v-window-${axis}${direction}-transition`;
282
- });
283
- const transitionCount = shallowRef(0);
284
- const transitionHeight = ref(undefined);
285
- const activeIndex = computed(() => {
286
- return group.items.value.findIndex(item => group.selected.value.includes(item.id));
287
- });
288
- watch(activeIndex, (newVal, oldVal) => {
289
- const itemsLength = group.items.value.length;
290
- const lastIndex = itemsLength - 1;
291
- if (itemsLength <= 2) {
292
- isReversed.value = newVal < oldVal;
293
- } else if (newVal === lastIndex && oldVal === 0) {
294
- isReversed.value = true;
295
- } else if (newVal === 0 && oldVal === lastIndex) {
296
- isReversed.value = false;
297
- } else {
298
- isReversed.value = newVal < oldVal;
299
- }
300
- });
301
- provide(VWindowSymbol, {
302
- transition,
303
- isReversed,
304
- transitionCount,
305
- transitionHeight,
306
- rootRef
307
- });
308
- const canMoveBack = toRef(() => props.continuous || activeIndex.value !== 0);
309
- const canMoveForward = toRef(() => props.continuous || activeIndex.value !== group.items.value.length - 1);
310
- function prev() {
311
- canMoveBack.value && group.prev();
312
- }
313
- function next() {
314
- canMoveForward.value && group.next();
315
- }
316
- const arrows = computed(() => {
317
- const arrows = [];
318
- const prevProps = {
319
- icon: isRtl.value ? props.nextIcon : props.prevIcon,
320
- class: `v-window__${isRtlReverse.value ? 'right' : 'left'}`,
321
- onClick: group.prev,
322
- 'aria-label': t('$vuetify.carousel.prev')
323
- };
324
- arrows.push(canMoveBack.value ? slots.prev ? slots.prev({
325
- props: prevProps
326
- }) : createVNode(VBtn, prevProps, null) : createElementVNode("div", null, null));
327
- const nextProps = {
328
- icon: isRtl.value ? props.prevIcon : props.nextIcon,
329
- class: `v-window__${isRtlReverse.value ? 'left' : 'right'}`,
330
- onClick: group.next,
331
- 'aria-label': t('$vuetify.carousel.next')
332
- };
333
- arrows.push(canMoveForward.value ? slots.next ? slots.next({
334
- props: nextProps
335
- }) : createVNode(VBtn, nextProps, null) : createElementVNode("div", null, null));
336
- return arrows;
337
- });
338
- const touchOptions = computed(() => {
339
- if (props.touch === false) return props.touch;
340
- const options = {
341
- left: () => {
342
- isRtlReverse.value ? prev() : next();
343
- },
344
- right: () => {
345
- isRtlReverse.value ? next() : prev();
346
- },
347
- start: _ref2 => {
348
- let {
349
- originalEvent
350
- } = _ref2;
351
- originalEvent.stopPropagation();
352
- }
353
- };
354
- return {
355
- ...options,
356
- ...(props.touch === true ? {} : props.touch)
357
- };
358
- });
359
- useRender(() => withDirectives(createVNode(props.tag, {
360
- "ref": rootRef,
361
- "class": normalizeClass(['v-window', {
362
- 'v-window--show-arrows-on-hover': props.showArrows === 'hover',
363
- 'v-window--vertical-arrows': !!props.verticalArrows
364
- }, themeClasses.value, props.class]),
365
- "style": normalizeStyle(props.style)
366
- }, {
367
- default: () => [createElementVNode("div", {
368
- "class": "v-window__container",
369
- "style": {
370
- height: transitionHeight.value
371
- }
372
- }, [slots.default?.({
373
- group
374
- }), props.showArrows !== false && createElementVNode("div", {
375
- "class": normalizeClass(['v-window__controls', {
376
- 'v-window__controls--left': props.verticalArrows === 'left' || props.verticalArrows === true
377
- }, {
378
- 'v-window__controls--right': props.verticalArrows === 'right'
379
- }])
380
- }, [arrows.value])]), slots.additional?.({
381
- group
382
- })]
383
- }), [[Touch, touchOptions.value]]));
384
- return {
385
- group
386
- };
387
- }
388
- });
389
-
390
- const makeVTabsWindowProps = propsFactory({
391
- ...omit(makeVWindowProps(), ['continuous', 'nextIcon', 'prevIcon', 'showArrows', 'touch', 'mandatory'])
392
- }, 'VTabsWindow');
393
- const VTabsWindow = genericComponent()({
394
- name: 'VTabsWindow',
395
- props: makeVTabsWindowProps(),
396
- emits: {
397
- 'update:modelValue': v => true
398
- },
399
- setup(props, _ref) {
400
- let {
401
- slots
402
- } = _ref;
403
- const group = inject(VTabsSymbol, null);
404
- const _model = useProxiedModel(props, 'modelValue');
405
- const model = computed({
406
- get() {
407
- // Always return modelValue if defined
408
- // or if not within a VTabs group
409
- if (_model.value != null || !group) return _model.value;
410
-
411
- // If inside of a VTabs, find the currently selected
412
- // item by id. Item value may be assigned by its index
413
- return group.items.value.find(item => group.selected.value.includes(item.id))?.value;
414
- },
415
- set(val) {
416
- _model.value = val;
417
- }
418
- });
419
- useRender(() => {
420
- const windowProps = VWindow.filterProps(props);
421
- return createVNode(VWindow, mergeProps({
422
- "_as": "VTabsWindow"
423
- }, windowProps, {
424
- "modelValue": model.value,
425
- "onUpdate:modelValue": $event => model.value = $event,
426
- "class": ['v-tabs-window', props.class],
427
- "style": props.style,
428
- "mandatory": false,
429
- "touch": false
430
- }), slots);
431
- });
432
- return {};
433
- }
434
- });
435
-
436
- const makeVWindowItemProps = propsFactory({
437
- reverseTransition: {
438
- type: [Boolean, String],
439
- default: undefined
440
- },
441
- transition: {
442
- type: [Boolean, String],
443
- default: undefined
444
- },
445
- ...makeComponentProps(),
446
- ...makeGroupItemProps(),
447
- ...makeLazyProps()
448
- }, 'VWindowItem');
449
- const VWindowItem = genericComponent()({
450
- name: 'VWindowItem',
451
- directives: {
452
- vTouch: Touch
453
- },
454
- props: makeVWindowItemProps(),
455
- emits: {
456
- 'group:selected': val => true
457
- },
458
- setup(props, _ref) {
459
- let {
460
- slots
461
- } = _ref;
462
- const window = inject(VWindowSymbol);
463
- const groupItem = useGroupItem(props, VWindowGroupSymbol);
464
- const {
465
- isBooted
466
- } = useSsrBoot();
467
- if (!window || !groupItem) throw new Error('[Vuetify] VWindowItem must be used inside VWindow');
468
- const isTransitioning = shallowRef(false);
469
- const hasTransition = computed(() => isBooted.value && (window.isReversed.value ? props.reverseTransition !== false : props.transition !== false));
470
- function onAfterTransition() {
471
- if (!isTransitioning.value || !window) {
472
- return;
473
- }
474
-
475
- // Finalize transition state.
476
- isTransitioning.value = false;
477
- if (window.transitionCount.value > 0) {
478
- window.transitionCount.value -= 1;
479
-
480
- // Remove container height if we are out of transition.
481
- if (window.transitionCount.value === 0) {
482
- window.transitionHeight.value = undefined;
483
- }
484
- }
485
- }
486
- function onBeforeTransition() {
487
- if (isTransitioning.value || !window) {
488
- return;
489
- }
490
-
491
- // Initialize transition state here.
492
- isTransitioning.value = true;
493
- if (window.transitionCount.value === 0) {
494
- // Set initial height for height transition.
495
- window.transitionHeight.value = convertToUnit(window.rootRef.value?.clientHeight);
496
- }
497
- window.transitionCount.value += 1;
498
- }
499
- function onTransitionCancelled() {
500
- onAfterTransition(); // This should have the same path as normal transition end.
501
- }
502
- function onEnterTransition(el) {
503
- if (!isTransitioning.value) {
504
- return;
505
- }
506
- nextTick(() => {
507
- // Do not set height if no transition or cancelled.
508
- if (!hasTransition.value || !isTransitioning.value || !window) {
509
- return;
510
- }
511
-
512
- // Set transition target height.
513
- window.transitionHeight.value = convertToUnit(el.clientHeight);
514
- });
515
- }
516
- const transition = computed(() => {
517
- const name = window.isReversed.value ? props.reverseTransition : props.transition;
518
- return !hasTransition.value ? false : {
519
- name: typeof name !== 'string' ? window.transition.value : name,
520
- onBeforeEnter: onBeforeTransition,
521
- onAfterEnter: onAfterTransition,
522
- onEnterCancelled: onTransitionCancelled,
523
- onBeforeLeave: onBeforeTransition,
524
- onAfterLeave: onAfterTransition,
525
- onLeaveCancelled: onTransitionCancelled,
526
- onEnter: onEnterTransition
527
- };
528
- });
529
- const {
530
- hasContent
531
- } = useLazy(props, groupItem.isSelected);
532
- useRender(() => createVNode(MaybeTransition, {
533
- "transition": transition.value,
534
- "disabled": !isBooted.value
535
- }, {
536
- default: () => [withDirectives(createElementVNode("div", {
537
- "class": normalizeClass(['v-window-item', groupItem.selectedClass.value, props.class]),
538
- "style": normalizeStyle(props.style)
539
- }, [hasContent.value && slots.default?.()]), [[vShow, groupItem.isSelected.value]])]
540
- }));
541
- return {
542
- groupItem
543
- };
544
- }
545
- });
546
-
547
- const makeVTabsWindowItemProps = propsFactory({
548
- ...makeVWindowItemProps()
549
- }, 'VTabsWindowItem');
550
- const VTabsWindowItem = genericComponent()({
551
- name: 'VTabsWindowItem',
552
- props: makeVTabsWindowItemProps(),
553
- setup(props, _ref) {
554
- let {
555
- slots
556
- } = _ref;
557
- useRender(() => {
558
- const windowItemProps = VWindowItem.filterProps(props);
559
- return createVNode(VWindowItem, mergeProps({
560
- "_as": "VTabsWindowItem"
561
- }, windowItemProps, {
562
- "class": ['v-tabs-window-item', props.class],
563
- "style": props.style
564
- }), slots);
565
- });
566
- return {};
567
- }
568
- });
569
-
570
- function calculateUpdatedTarget(_ref) {
571
- let {
572
- selectedElement,
573
- containerElement,
574
- isRtl,
575
- isHorizontal
576
- } = _ref;
577
- const containerSize = getOffsetSize(isHorizontal, containerElement);
578
- const scrollPosition = getScrollPosition(isHorizontal, isRtl, containerElement);
579
- const childrenSize = getOffsetSize(isHorizontal, selectedElement);
580
- const childrenStartPosition = getOffsetPosition(isHorizontal, selectedElement);
581
- const additionalOffset = childrenSize * 0.4;
582
- if (scrollPosition > childrenStartPosition) {
583
- return childrenStartPosition - additionalOffset;
584
- } else if (scrollPosition + containerSize < childrenStartPosition + childrenSize) {
585
- return childrenStartPosition - containerSize + childrenSize + additionalOffset;
586
- }
587
- return scrollPosition;
588
- }
589
- function calculateCenteredTarget(_ref2) {
590
- let {
591
- selectedElement,
592
- containerElement,
593
- isHorizontal
594
- } = _ref2;
595
- const containerOffsetSize = getOffsetSize(isHorizontal, containerElement);
596
- const childrenOffsetPosition = getOffsetPosition(isHorizontal, selectedElement);
597
- const childrenOffsetSize = getOffsetSize(isHorizontal, selectedElement);
598
- return childrenOffsetPosition - containerOffsetSize / 2 + childrenOffsetSize / 2;
599
- }
600
- function getScrollSize(isHorizontal, element) {
601
- const key = isHorizontal ? 'scrollWidth' : 'scrollHeight';
602
- return element?.[key] || 0;
603
- }
604
- function getClientSize(isHorizontal, element) {
605
- const key = isHorizontal ? 'clientWidth' : 'clientHeight';
606
- return element?.[key] || 0;
607
- }
608
- function getScrollPosition(isHorizontal, rtl, element) {
609
- if (!element) {
610
- return 0;
611
- }
612
- const {
613
- scrollLeft,
614
- offsetWidth,
615
- scrollWidth
616
- } = element;
617
- if (isHorizontal) {
618
- return rtl ? scrollWidth - offsetWidth + scrollLeft : scrollLeft;
619
- }
620
- return element.scrollTop;
621
- }
622
- function getOffsetSize(isHorizontal, element) {
623
- const key = isHorizontal ? 'offsetWidth' : 'offsetHeight';
624
- return element?.[key] || 0;
625
- }
626
- function getOffsetPosition(isHorizontal, element) {
627
- const key = isHorizontal ? 'offsetLeft' : 'offsetTop';
628
- return element?.[key] || 0;
629
- }
630
-
631
- const VSlideGroupSymbol = Symbol.for('vuetify:v-slide-group');
632
- const makeVSlideGroupProps = propsFactory({
633
- centerActive: Boolean,
634
- contentClass: null,
635
- direction: {
636
- type: String,
637
- default: 'horizontal'
638
- },
639
- symbol: {
640
- type: null,
641
- default: VSlideGroupSymbol
642
- },
643
- nextIcon: {
644
- type: IconValue,
645
- default: '$next'
646
- },
647
- prevIcon: {
648
- type: IconValue,
649
- default: '$prev'
650
- },
651
- showArrows: {
652
- type: [Boolean, String],
653
- validator: v => typeof v === 'boolean' || ['always', 'desktop', 'mobile'].includes(v)
654
- },
655
- ...makeComponentProps(),
656
- ...makeDisplayProps({
657
- mobile: null
658
- }),
659
- ...makeTagProps(),
660
- ...makeGroupProps({
661
- selectedClass: 'v-slide-group-item--active'
662
- })
663
- }, 'VSlideGroup');
664
- const VSlideGroup = genericComponent()({
665
- name: 'VSlideGroup',
666
- props: makeVSlideGroupProps(),
667
- emits: {
668
- 'update:modelValue': value => true
669
- },
670
- setup(props, _ref) {
671
- let {
672
- slots
673
- } = _ref;
674
- const {
675
- isRtl
676
- } = useRtl();
677
- const {
678
- displayClasses,
679
- mobile
680
- } = useDisplay(props);
681
- const group = useGroup(props, props.symbol);
682
- const isOverflowing = shallowRef(false);
683
- const scrollOffset = shallowRef(0);
684
- const containerSize = shallowRef(0);
685
- const contentSize = shallowRef(0);
686
- const isHorizontal = computed(() => props.direction === 'horizontal');
687
- const {
688
- resizeRef: containerRef,
689
- contentRect: containerRect
690
- } = useResizeObserver();
691
- const {
692
- resizeRef: contentRef,
693
- contentRect
694
- } = useResizeObserver();
695
- const goTo = useGoTo();
696
- const goToOptions = computed(() => {
697
- return {
698
- container: containerRef.el,
699
- duration: 200,
700
- easing: 'easeOutQuart'
701
- };
702
- });
703
- const firstSelectedIndex = computed(() => {
704
- if (!group.selected.value.length) return -1;
705
- return group.items.value.findIndex(item => item.id === group.selected.value[0]);
706
- });
707
- const lastSelectedIndex = computed(() => {
708
- if (!group.selected.value.length) return -1;
709
- return group.items.value.findIndex(item => item.id === group.selected.value[group.selected.value.length - 1]);
710
- });
711
- if (IN_BROWSER) {
712
- let frame = -1;
713
- watch(() => [group.selected.value, containerRect.value, contentRect.value, isHorizontal.value], () => {
714
- cancelAnimationFrame(frame);
715
- frame = requestAnimationFrame(() => {
716
- if (containerRect.value && contentRect.value) {
717
- const sizeProperty = isHorizontal.value ? 'width' : 'height';
718
- containerSize.value = containerRect.value[sizeProperty];
719
- contentSize.value = contentRect.value[sizeProperty];
720
- isOverflowing.value = containerSize.value + 1 < contentSize.value;
721
- }
722
- if (firstSelectedIndex.value >= 0 && contentRef.el) {
723
- // TODO: Is this too naive? Should we store element references in group composable?
724
- const selectedElement = contentRef.el.children[lastSelectedIndex.value];
725
- scrollToChildren(selectedElement, props.centerActive);
726
- }
727
- });
728
- });
729
- }
730
- const isFocused = shallowRef(false);
731
- function scrollToChildren(children, center) {
732
- let target = 0;
733
- if (center) {
734
- target = calculateCenteredTarget({
735
- containerElement: containerRef.el,
736
- isHorizontal: isHorizontal.value,
737
- selectedElement: children
738
- });
739
- } else {
740
- target = calculateUpdatedTarget({
741
- containerElement: containerRef.el,
742
- isHorizontal: isHorizontal.value,
743
- isRtl: isRtl.value,
744
- selectedElement: children
745
- });
746
- }
747
- scrollToPosition(target);
748
- }
749
- function scrollToPosition(newPosition) {
750
- if (!IN_BROWSER || !containerRef.el) return;
751
- const offsetSize = getOffsetSize(isHorizontal.value, containerRef.el);
752
- const scrollPosition = getScrollPosition(isHorizontal.value, isRtl.value, containerRef.el);
753
- const scrollSize = getScrollSize(isHorizontal.value, containerRef.el);
754
- if (scrollSize <= offsetSize ||
755
- // Prevent scrolling by only a couple of pixels, which doesn't look smooth
756
- Math.abs(newPosition - scrollPosition) < 16) return;
757
- if (isHorizontal.value && isRtl.value && containerRef.el) {
758
- const {
759
- scrollWidth,
760
- offsetWidth: containerWidth
761
- } = containerRef.el;
762
- newPosition = scrollWidth - containerWidth - newPosition;
763
- }
764
- if (isHorizontal.value) {
765
- goTo.horizontal(newPosition, goToOptions.value);
766
- } else {
767
- goTo(newPosition, goToOptions.value);
768
- }
769
- }
770
- function onScroll(e) {
771
- const {
772
- scrollTop,
773
- scrollLeft
774
- } = e.target;
775
- scrollOffset.value = isHorizontal.value ? scrollLeft : scrollTop;
776
- }
777
- function onFocusin(e) {
778
- isFocused.value = true;
779
- if (!isOverflowing.value || !contentRef.el) return;
780
-
781
- // Focused element is likely to be the root of an item, so a
782
- // breadth-first search will probably find it in the first iteration
783
- for (const el of e.composedPath()) {
784
- for (const item of contentRef.el.children) {
785
- if (item === el) {
786
- scrollToChildren(item);
787
- return;
788
- }
789
- }
790
- }
791
- }
792
- function onFocusout(e) {
793
- isFocused.value = false;
794
- }
795
-
796
- // Affix clicks produce onFocus that we have to ignore to avoid extra scrollToChildren
797
- let ignoreFocusEvent = false;
798
- function onFocus(e) {
799
- if (!ignoreFocusEvent && !isFocused.value && !(e.relatedTarget && contentRef.el?.contains(e.relatedTarget))) focus();
800
- ignoreFocusEvent = false;
801
- }
802
- function onFocusAffixes() {
803
- ignoreFocusEvent = true;
804
- }
805
- function onKeydown(e) {
806
- if (!contentRef.el) return;
807
- function toFocus(location) {
808
- e.preventDefault();
809
- focus(location);
810
- }
811
- if (isHorizontal.value) {
812
- if (e.key === 'ArrowRight') {
813
- toFocus(isRtl.value ? 'prev' : 'next');
814
- } else if (e.key === 'ArrowLeft') {
815
- toFocus(isRtl.value ? 'next' : 'prev');
816
- }
817
- } else {
818
- if (e.key === 'ArrowDown') {
819
- toFocus('next');
820
- } else if (e.key === 'ArrowUp') {
821
- toFocus('prev');
822
- }
823
- }
824
- if (e.key === 'Home') {
825
- toFocus('first');
826
- } else if (e.key === 'End') {
827
- toFocus('last');
828
- }
829
- }
830
- function getSiblingElement(el, location) {
831
- if (!el) return undefined;
832
- let sibling = el;
833
- do {
834
- sibling = sibling?.[location === 'next' ? 'nextElementSibling' : 'previousElementSibling'];
835
- } while (sibling?.hasAttribute('disabled'));
836
- return sibling;
837
- }
838
- function focus(location) {
839
- if (!contentRef.el) return;
840
- let el;
841
- if (!location) {
842
- const focusable = focusableChildren(contentRef.el);
843
- el = focusable[0];
844
- } else if (location === 'next') {
845
- el = getSiblingElement(contentRef.el.querySelector(':focus'), location);
846
- if (!el) return focus('first');
847
- } else if (location === 'prev') {
848
- el = getSiblingElement(contentRef.el.querySelector(':focus'), location);
849
- if (!el) return focus('last');
850
- } else if (location === 'first') {
851
- el = contentRef.el.firstElementChild;
852
- if (el?.hasAttribute('disabled')) el = getSiblingElement(el, 'next');
853
- } else if (location === 'last') {
854
- el = contentRef.el.lastElementChild;
855
- if (el?.hasAttribute('disabled')) el = getSiblingElement(el, 'prev');
856
- }
857
- if (el) {
858
- el.focus({
859
- preventScroll: true
860
- });
861
- }
862
- }
863
- function scrollTo(location) {
864
- const direction = isHorizontal.value && isRtl.value ? -1 : 1;
865
- const offsetStep = (location === 'prev' ? -direction : direction) * containerSize.value;
866
- let newPosition = scrollOffset.value + offsetStep;
867
-
868
- // TODO: improve it
869
- if (isHorizontal.value && isRtl.value && containerRef.el) {
870
- const {
871
- scrollWidth,
872
- offsetWidth: containerWidth
873
- } = containerRef.el;
874
- newPosition += scrollWidth - containerWidth;
875
- }
876
- scrollToPosition(newPosition);
877
- }
878
- const slotProps = computed(() => ({
879
- next: group.next,
880
- prev: group.prev,
881
- select: group.select,
882
- isSelected: group.isSelected
883
- }));
884
- const hasAffixes = computed(() => {
885
- switch (props.showArrows) {
886
- // Always show arrows on desktop & mobile
887
- case 'always':
888
- return true;
889
-
890
- // Always show arrows on desktop
891
- case 'desktop':
892
- return !mobile.value;
893
-
894
- // Show arrows on mobile when overflowing.
895
- // This matches the default 2.2 behavior
896
- case true:
897
- return isOverflowing.value || Math.abs(scrollOffset.value) > 0;
898
-
899
- // Always show on mobile
900
- case 'mobile':
901
- return mobile.value || isOverflowing.value || Math.abs(scrollOffset.value) > 0;
902
-
903
- // https://material.io/components/tabs#scrollable-tabs
904
- // Always show arrows when
905
- // overflowed on desktop
906
- default:
907
- return !mobile.value && (isOverflowing.value || Math.abs(scrollOffset.value) > 0);
908
- }
909
- });
910
- const hasPrev = computed(() => {
911
- // 1 pixel in reserve, may be lost after rounding
912
- return Math.abs(scrollOffset.value) > 1;
913
- });
914
- const hasNext = computed(() => {
915
- if (!containerRef.value) return false;
916
- const scrollSize = getScrollSize(isHorizontal.value, containerRef.el);
917
- const clientSize = getClientSize(isHorizontal.value, containerRef.el);
918
- const scrollSizeMax = scrollSize - clientSize;
919
-
920
- // 1 pixel in reserve, may be lost after rounding
921
- return scrollSizeMax - Math.abs(scrollOffset.value) > 1;
922
- });
923
- useRender(() => createVNode(props.tag, {
924
- "class": normalizeClass(['v-slide-group', {
925
- 'v-slide-group--vertical': !isHorizontal.value,
926
- 'v-slide-group--has-affixes': hasAffixes.value,
927
- 'v-slide-group--is-overflowing': isOverflowing.value
928
- }, displayClasses.value, props.class]),
929
- "style": normalizeStyle(props.style),
930
- "tabindex": isFocused.value || group.selected.value.length ? -1 : 0,
931
- "onFocus": onFocus
932
- }, {
933
- default: () => [hasAffixes.value && createElementVNode("div", {
934
- "key": "prev",
935
- "class": normalizeClass(['v-slide-group__prev', {
936
- 'v-slide-group__prev--disabled': !hasPrev.value
937
- }]),
938
- "onMousedown": onFocusAffixes,
939
- "onClick": () => hasPrev.value && scrollTo('prev')
940
- }, [slots.prev?.(slotProps.value) ?? createVNode(VFadeTransition, null, {
941
- default: () => [createVNode(VIcon, {
942
- "icon": isRtl.value ? props.nextIcon : props.prevIcon
943
- }, null)]
944
- })]), createElementVNode("div", {
945
- "key": "container",
946
- "ref": containerRef,
947
- "class": normalizeClass(['v-slide-group__container', props.contentClass]),
948
- "onScroll": onScroll
949
- }, [createElementVNode("div", {
950
- "ref": contentRef,
951
- "class": "v-slide-group__content",
952
- "onFocusin": onFocusin,
953
- "onFocusout": onFocusout,
954
- "onKeydown": onKeydown
955
- }, [slots.default?.(slotProps.value)])]), hasAffixes.value && createElementVNode("div", {
956
- "key": "next",
957
- "class": normalizeClass(['v-slide-group__next', {
958
- 'v-slide-group__next--disabled': !hasNext.value
959
- }]),
960
- "onMousedown": onFocusAffixes,
961
- "onClick": () => hasNext.value && scrollTo('next')
962
- }, [slots.next?.(slotProps.value) ?? createVNode(VFadeTransition, null, {
963
- default: () => [createVNode(VIcon, {
964
- "icon": isRtl.value ? props.prevIcon : props.nextIcon
965
- }, null)]
966
- })])]
967
- }));
968
- return {
969
- selected: group.selected,
970
- scrollTo,
971
- scrollOffset,
972
- focus,
973
- hasPrev,
974
- hasNext
975
- };
976
- }
977
- });
978
-
979
- function parseItems(items) {
980
- if (!items) return [];
981
- return items.map(item => {
982
- if (!isObject(item)) return {
983
- text: item,
984
- value: item
985
- };
986
- return item;
987
- });
988
- }
989
- const makeVTabsProps = propsFactory({
990
- alignTabs: {
991
- type: String,
992
- default: 'start'
993
- },
994
- color: String,
995
- fixedTabs: Boolean,
996
- items: {
997
- type: Array,
998
- default: () => []
999
- },
1000
- stacked: Boolean,
1001
- bgColor: String,
1002
- grow: Boolean,
1003
- height: {
1004
- type: [Number, String],
1005
- default: undefined
1006
- },
1007
- hideSlider: Boolean,
1008
- sliderColor: String,
1009
- ...makeVSlideGroupProps({
1010
- mandatory: 'force',
1011
- selectedClass: 'v-tab-item--selected'
1012
- }),
1013
- ...makeDensityProps(),
1014
- ...makeTagProps()
1015
- }, 'VTabs');
1016
- const VTabs = genericComponent()({
1017
- name: 'VTabs',
1018
- props: makeVTabsProps(),
1019
- emits: {
1020
- 'update:modelValue': v => true
1021
- },
1022
- setup(props, _ref) {
1023
- let {
1024
- attrs,
1025
- slots
1026
- } = _ref;
1027
- const model = useProxiedModel(props, 'modelValue');
1028
- const items = computed(() => parseItems(props.items));
1029
- const {
1030
- densityClasses
1031
- } = useDensity(props);
1032
- const {
1033
- backgroundColorClasses,
1034
- backgroundColorStyles
1035
- } = useBackgroundColor(() => props.bgColor);
1036
- const {
1037
- scopeId
1038
- } = useScopeId();
1039
- provideDefaults({
1040
- VTab: {
1041
- color: toRef(() => props.color),
1042
- direction: toRef(() => props.direction),
1043
- stacked: toRef(() => props.stacked),
1044
- fixed: toRef(() => props.fixedTabs),
1045
- sliderColor: toRef(() => props.sliderColor),
1046
- hideSlider: toRef(() => props.hideSlider)
1047
- }
1048
- });
1049
- useRender(() => {
1050
- const slideGroupProps = VSlideGroup.filterProps(props);
1051
- const hasWindow = !!(slots.window || props.items.length > 0);
1052
- return createElementVNode(Fragment, null, [createVNode(VSlideGroup, mergeProps(slideGroupProps, {
1053
- "modelValue": model.value,
1054
- "onUpdate:modelValue": $event => model.value = $event,
1055
- "class": ['v-tabs', `v-tabs--${props.direction}`, `v-tabs--align-tabs-${props.alignTabs}`, {
1056
- 'v-tabs--fixed-tabs': props.fixedTabs,
1057
- 'v-tabs--grow': props.grow,
1058
- 'v-tabs--stacked': props.stacked
1059
- }, densityClasses.value, backgroundColorClasses.value, props.class],
1060
- "style": [{
1061
- '--v-tabs-height': convertToUnit(props.height)
1062
- }, backgroundColorStyles.value, props.style],
1063
- "role": "tablist",
1064
- "symbol": VTabsSymbol
1065
- }, scopeId, attrs), {
1066
- default: () => [slots.default?.() ?? items.value.map(item => slots.tab?.({
1067
- item
1068
- }) ?? createVNode(VTab, mergeProps(item, {
1069
- "key": item.text,
1070
- "value": item.value
1071
- }), {
1072
- default: slots[`tab.${item.value}`] ? () => slots[`tab.${item.value}`]?.({
1073
- item
1074
- }) : undefined
1075
- }))]
1076
- }), hasWindow && createVNode(VTabsWindow, mergeProps({
1077
- "modelValue": model.value,
1078
- "onUpdate:modelValue": $event => model.value = $event,
1079
- "key": "tabs-window"
1080
- }, scopeId), {
1081
- default: () => [items.value.map(item => slots.item?.({
1082
- item
1083
- }) ?? createVNode(VTabsWindowItem, {
1084
- "value": item.value
1085
- }, {
1086
- default: () => slots[`item.${item.value}`]?.({
1087
- item
1088
- })
1089
- })), slots.window?.()]
1090
- })]);
1091
- });
1092
- return {};
1093
- }
1094
- });
1095
-
1096
- const _hoisted_1 = {
1097
- key: 0,
1098
- id: "overlay",
1099
- class: "pa-2 panel bg-surface"
1100
- };
1101
- const _hoisted_2 = { class: "d-flex py-2 justify-end align-end" };
1102
- const _hoisted_3 = { class: "d-flex flex-column justify-center component-container" };
1103
-
1104
-
1105
- const _sfc_main = {
1106
- __name: 'MobileLayout',
1107
- setup(__props) {
1108
-
1109
- useCssVars(_ctx => ({
1110
- "2d9a694e": (tabsHeightFromBtm.value),
1111
- "4f6792e6": (mainRectTopPx.value),
1112
- "515e6bda": (mainRectBtmPx.value)
1113
- }));
1114
-
1115
- const { bgWidget, importedWidgets } = useDefineTemplate();
1116
- const { mainRect } = useLayout();
1117
-
1118
- const activeIdx = ref(-1);
1119
-
1120
- /** @type {import("vue").Ref<import("vuetify/components").VTabs | null>} */
1121
- const tabs = ref(null);
1122
- const tabsHeightFromBtm = ref("");
1123
- const mainRectTopPx = ref("");
1124
- const mainRectBtmPx = ref("");
1125
-
1126
- onMounted(() => {
1127
- mainRectTopPx.value = mainRect.value.top + "px";
1128
- mainRectBtmPx.value = (mainRect.value.bottom || 48) + "px";
1129
- tabsHeightFromBtm.value =
1130
- mainRect.value.bottom + (tabs.value?.$el?.clientHeight ?? 48) + "px";
1131
- });
1132
-
1133
- return (_ctx, _cache) => {
1134
-
1135
-
1136
-
1137
-
1138
-
1139
- return (openBlock(), createBlock(VMain, { class: "overflow-hidden" }, {
1140
- default: withCtx(() => [
1141
- (openBlock(), createBlock(Suspense, { suspensible: "" }, {
1142
- default: withCtx(() => [
1143
- (unref(bgWidget)?.component)
1144
- ? (openBlock(), createBlock(resolveDynamicComponent(unref(bgWidget).component), mergeProps({
1145
- id: "bg-widget",
1146
- key: unref(bgWidget).id
1147
- }, unref(bgWidget).props), null, 16 /* FULL_PROPS */))
1148
- : createCommentVNode("v-if", true)
1149
- ]),
1150
- _: 1 /* STABLE */
1151
- })),
1152
- (openBlock(true), createElementBlock(Fragment, null, renderList(unref(importedWidgets), (importedWidget, idx) => {
1153
- return (openBlock(), createElementBlock(Fragment, { key: idx }, [
1154
- (importedWidget.value.component)
1155
- ? withDirectives((openBlock(), createElementBlock("div", _hoisted_1, [
1156
- createElementVNode("div", _hoisted_2, [
1157
- createVNode(VBtn, {
1158
- icon: "",
1159
- variant: "text",
1160
- class: "close-btn",
1161
- onClick: _cache[0] || (_cache[0] = $event => (activeIdx.value = -1))
1162
- }, {
1163
- default: withCtx(() => _cache[2] || (_cache[2] = [
1164
- createTextVNode("✕", -1 /* CACHED */)
1165
- ])),
1166
- _: 1 /* STABLE */,
1167
- __: [2]
1168
- })
1169
- ]),
1170
- (openBlock(), createBlock(Suspense, { suspensible: "" }, {
1171
- default: withCtx(() => [
1172
- withDirectives(createElementVNode("div", _hoisted_3, [
1173
- (openBlock(), createBlock(resolveDynamicComponent(importedWidget.value.component), mergeProps({
1174
- key: importedWidget.value.id
1175
- }, { ref_for: true }, importedWidget.value.props), null, 16 /* FULL_PROPS */))
1176
- ], 512 /* NEED_PATCH */), [
1177
- [vShow, activeIdx.value === idx]
1178
- ])
1179
- ]),
1180
- _: 2 /* DYNAMIC */
1181
- }, 1024 /* DYNAMIC_SLOTS */))
1182
- ], 512 /* NEED_PATCH */)), [
1183
- [vShow, activeIdx.value === idx]
1184
- ])
1185
- : createCommentVNode("v-if", true)
1186
- ], 64 /* STABLE_FRAGMENT */))
1187
- }), 128 /* KEYED_FRAGMENT */)),
1188
- createVNode(VTabs, {
1189
- ref_key: "tabs",
1190
- ref: tabs,
1191
- "align-tabs": "center",
1192
- "bg-color": "surface",
1193
- class: "tabs",
1194
- "show-arrows": "",
1195
- modelValue: activeIdx.value,
1196
- "onUpdate:modelValue": _cache[1] || (_cache[1] = $event => ((activeIdx).value = $event))
1197
- }, {
1198
- default: withCtx(() => [
1199
- (openBlock(true), createElementBlock(Fragment, null, renderList(unref(importedWidgets), (importedWidget, idx) => {
1200
- return (openBlock(), createElementBlock(Fragment, { key: idx }, [
1201
- (importedWidget.value.component)
1202
- ? (openBlock(), createBlock(VTab, {
1203
- key: 0,
1204
- value: idx
1205
- }, {
1206
- default: withCtx(() => [
1207
- createTextVNode(toDisplayString(importedWidget.value.title), 1 /* TEXT */)
1208
- ]),
1209
- _: 2 /* DYNAMIC */
1210
- }, 1032 /* PROPS, DYNAMIC_SLOTS */, ["value"]))
1211
- : createCommentVNode("v-if", true)
1212
- ], 64 /* STABLE_FRAGMENT */))
1213
- }), 128 /* KEYED_FRAGMENT */))
1214
- ]),
1215
- _: 1 /* STABLE */
1216
- }, 8 /* PROPS */, ["modelValue"])
1217
- ]),
1218
- _: 1 /* STABLE */
1219
- }))
1220
- }
1221
- }
1222
-
1223
- };
1224
- const MobileLayout = /*#__PURE__*/_export_sfc(_sfc_main, [['styles',[_style_0]],['__scopeId',"data-v-f4ab4c65"]]);
1225
-
1226
- export { MobileLayout as default };