@vuetify/nightly 3.9.2-master.2025-07-23 → 3.9.2-master.2025-07-25
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.
- package/CHANGELOG.md +15 -3
- package/dist/_component-variables-labs.sass +3 -1
- package/dist/json/attributes.json +4029 -3617
- package/dist/json/importMap-labs.json +38 -14
- package/dist/json/importMap.json +148 -148
- package/dist/json/tags.json +133 -0
- package/dist/json/web-types.json +13484 -11867
- package/dist/vuetify-labs.cjs +1525 -126
- package/dist/vuetify-labs.css +5448 -5007
- package/dist/vuetify-labs.d.ts +7670 -974
- package/dist/vuetify-labs.esm.js +1526 -127
- package/dist/vuetify-labs.esm.js.map +1 -1
- package/dist/vuetify-labs.js +1525 -126
- package/dist/vuetify-labs.min.css +2 -2
- package/dist/vuetify.cjs +74 -34
- package/dist/vuetify.cjs.map +1 -1
- package/dist/vuetify.css +3415 -3415
- package/dist/vuetify.d.ts +86 -61
- package/dist/vuetify.esm.js +74 -34
- package/dist/vuetify.esm.js.map +1 -1
- package/dist/vuetify.js +74 -34
- package/dist/vuetify.js.map +1 -1
- package/dist/vuetify.min.css +2 -2
- package/dist/vuetify.min.js +976 -977
- package/dist/vuetify.min.js.map +1 -1
- package/lib/components/VBottomSheet/VBottomSheet.d.ts +6 -6
- package/lib/components/VDialog/VDialog.d.ts +6 -6
- package/lib/components/VOverlay/VOverlay.js +1 -0
- package/lib/components/VOverlay/VOverlay.js.map +1 -1
- package/lib/components/VOverlay/locationStrategies.js +16 -10
- package/lib/components/VOverlay/locationStrategies.js.map +1 -1
- package/lib/components/VOverlay/scrollStrategies.d.ts +1 -0
- package/lib/components/VOverlay/scrollStrategies.js +6 -4
- package/lib/components/VOverlay/scrollStrategies.js.map +1 -1
- package/lib/components/VRangeSlider/VRangeSlider.d.ts +13 -0
- package/lib/components/VSlider/VSlider.d.ts +13 -0
- package/lib/components/VSlider/VSlider.js +3 -1
- package/lib/components/VSlider/VSlider.js.map +1 -1
- package/lib/components/VSlider/VSliderThumb.d.ts +13 -0
- package/lib/components/VSlider/VSliderThumb.js +2 -0
- package/lib/components/VSlider/VSliderThumb.js.map +1 -1
- package/lib/components/VSlider/slider.d.ts +6 -0
- package/lib/components/VSlider/slider.js +2 -0
- package/lib/components/VSlider/slider.js.map +1 -1
- package/lib/components/index.js +2 -2
- package/lib/components/index.js.map +1 -1
- package/lib/composables/goto.d.ts +3 -2
- package/lib/composables/goto.js +2 -16
- package/lib/composables/goto.js.map +1 -1
- package/lib/composables/reveal.d.ts +36 -0
- package/lib/composables/reveal.js +30 -0
- package/lib/composables/reveal.js.map +1 -0
- package/lib/entry-bundler.js +1 -1
- package/lib/framework.d.ts +142 -133
- package/lib/framework.js +1 -1
- package/lib/iconsets/fa.js +9 -1
- package/lib/iconsets/fa.js.map +1 -1
- package/lib/iconsets/fa4.js +9 -1
- package/lib/iconsets/fa4.js.map +1 -1
- package/lib/iconsets/md.js +9 -1
- package/lib/iconsets/md.js.map +1 -1
- package/lib/iconsets/mdi-svg.js +9 -1
- package/lib/iconsets/mdi-svg.js.map +1 -1
- package/lib/iconsets/mdi.js +9 -1
- package/lib/iconsets/mdi.js.map +1 -1
- package/lib/labs/VPie/VPie.css +105 -0
- package/lib/labs/VPie/VPie.d.ts +891 -0
- package/lib/labs/VPie/VPie.js +291 -0
- package/lib/labs/VPie/VPie.js.map +1 -0
- package/lib/labs/VPie/VPie.sass +109 -0
- package/lib/labs/VPie/VPieSegment.d.ts +310 -0
- package/lib/labs/VPie/VPieSegment.js +103 -0
- package/lib/labs/VPie/VPieSegment.js.map +1 -0
- package/lib/labs/VPie/VPieTooltip.d.ts +279 -0
- package/lib/labs/VPie/VPieTooltip.js +84 -0
- package/lib/labs/VPie/VPieTooltip.js.map +1 -0
- package/lib/labs/VPie/_variables.scss +11 -0
- package/lib/labs/VPie/index.d.ts +3 -0
- package/lib/labs/VPie/index.js +4 -0
- package/lib/labs/VPie/index.js.map +1 -0
- package/lib/labs/VPie/types.d.ts +16 -0
- package/lib/labs/VPie/types.js +2 -0
- package/lib/labs/VPie/types.js.map +1 -0
- package/lib/labs/VPie/utils.d.ts +23 -0
- package/lib/labs/VPie/utils.js +49 -0
- package/lib/labs/VPie/utils.js.map +1 -0
- package/lib/labs/VVideo/VVideo.css +322 -0
- package/lib/labs/VVideo/VVideo.d.ts +6932 -0
- package/lib/labs/VVideo/VVideo.js +424 -0
- package/lib/labs/VVideo/VVideo.js.map +1 -0
- package/lib/labs/VVideo/VVideo.sass +304 -0
- package/lib/labs/VVideo/VVideoControls.d.ts +3524 -0
- package/lib/labs/VVideo/VVideoControls.js +236 -0
- package/lib/labs/VVideo/VVideoControls.js.map +1 -0
- package/lib/labs/VVideo/VVideoVolume.d.ts +3088 -0
- package/lib/labs/VVideo/VVideoVolume.js +94 -0
- package/lib/labs/VVideo/VVideoVolume.js.map +1 -0
- package/lib/labs/VVideo/_variables.scss +58 -0
- package/lib/labs/VVideo/index.d.ts +3 -0
- package/lib/labs/VVideo/index.js +4 -0
- package/lib/labs/VVideo/index.js.map +1 -0
- package/lib/labs/components.d.ts +2 -0
- package/lib/labs/components.js +2 -0
- package/lib/labs/components.js.map +1 -1
- package/lib/locale/af.d.ts +11 -0
- package/lib/locale/af.js +11 -0
- package/lib/locale/af.js.map +1 -1
- package/lib/locale/ar.d.ts +11 -0
- package/lib/locale/ar.js +11 -0
- package/lib/locale/ar.js.map +1 -1
- package/lib/locale/az.d.ts +11 -0
- package/lib/locale/az.js +11 -0
- package/lib/locale/az.js.map +1 -1
- package/lib/locale/bg.d.ts +11 -0
- package/lib/locale/bg.js +11 -0
- package/lib/locale/bg.js.map +1 -1
- package/lib/locale/ca.d.ts +11 -0
- package/lib/locale/ca.js +11 -0
- package/lib/locale/ca.js.map +1 -1
- package/lib/locale/ckb.d.ts +11 -0
- package/lib/locale/ckb.js +11 -0
- package/lib/locale/ckb.js.map +1 -1
- package/lib/locale/cs.d.ts +11 -0
- package/lib/locale/cs.js +11 -0
- package/lib/locale/cs.js.map +1 -1
- package/lib/locale/da.d.ts +11 -0
- package/lib/locale/da.js +11 -0
- package/lib/locale/da.js.map +1 -1
- package/lib/locale/de.d.ts +11 -0
- package/lib/locale/de.js +11 -0
- package/lib/locale/de.js.map +1 -1
- package/lib/locale/el.d.ts +11 -0
- package/lib/locale/el.js +11 -0
- package/lib/locale/el.js.map +1 -1
- package/lib/locale/en.d.ts +11 -0
- package/lib/locale/en.js +11 -0
- package/lib/locale/en.js.map +1 -1
- package/lib/locale/es.d.ts +11 -0
- package/lib/locale/es.js +11 -0
- package/lib/locale/es.js.map +1 -1
- package/lib/locale/et.d.ts +11 -0
- package/lib/locale/et.js +11 -0
- package/lib/locale/et.js.map +1 -1
- package/lib/locale/fa.d.ts +11 -0
- package/lib/locale/fa.js +11 -0
- package/lib/locale/fa.js.map +1 -1
- package/lib/locale/fi.d.ts +11 -0
- package/lib/locale/fi.js +11 -0
- package/lib/locale/fi.js.map +1 -1
- package/lib/locale/fr.d.ts +11 -0
- package/lib/locale/fr.js +11 -0
- package/lib/locale/fr.js.map +1 -1
- package/lib/locale/he.d.ts +11 -0
- package/lib/locale/he.js +11 -0
- package/lib/locale/he.js.map +1 -1
- package/lib/locale/hr.d.ts +11 -0
- package/lib/locale/hr.js +11 -0
- package/lib/locale/hr.js.map +1 -1
- package/lib/locale/hu.d.ts +11 -0
- package/lib/locale/hu.js +11 -0
- package/lib/locale/hu.js.map +1 -1
- package/lib/locale/id.d.ts +11 -0
- package/lib/locale/id.js +11 -0
- package/lib/locale/id.js.map +1 -1
- package/lib/locale/it.d.ts +11 -0
- package/lib/locale/it.js +11 -0
- package/lib/locale/it.js.map +1 -1
- package/lib/locale/ja.d.ts +11 -0
- package/lib/locale/ja.js +11 -0
- package/lib/locale/ja.js.map +1 -1
- package/lib/locale/km.d.ts +11 -0
- package/lib/locale/km.js +11 -0
- package/lib/locale/km.js.map +1 -1
- package/lib/locale/ko.d.ts +11 -0
- package/lib/locale/ko.js +11 -0
- package/lib/locale/ko.js.map +1 -1
- package/lib/locale/lt.d.ts +11 -0
- package/lib/locale/lt.js +11 -0
- package/lib/locale/lt.js.map +1 -1
- package/lib/locale/lv.d.ts +11 -0
- package/lib/locale/lv.js +11 -0
- package/lib/locale/lv.js.map +1 -1
- package/lib/locale/nl.d.ts +11 -0
- package/lib/locale/nl.js +11 -0
- package/lib/locale/nl.js.map +1 -1
- package/lib/locale/no.d.ts +11 -0
- package/lib/locale/no.js +11 -0
- package/lib/locale/no.js.map +1 -1
- package/lib/locale/pl.d.ts +11 -0
- package/lib/locale/pl.js +11 -0
- package/lib/locale/pl.js.map +1 -1
- package/lib/locale/pt.d.ts +11 -0
- package/lib/locale/pt.js +11 -0
- package/lib/locale/pt.js.map +1 -1
- package/lib/locale/ro.d.ts +11 -0
- package/lib/locale/ro.js +11 -0
- package/lib/locale/ro.js.map +1 -1
- package/lib/locale/ru.d.ts +11 -0
- package/lib/locale/ru.js +11 -0
- package/lib/locale/ru.js.map +1 -1
- package/lib/locale/sk.d.ts +11 -0
- package/lib/locale/sk.js +11 -0
- package/lib/locale/sk.js.map +1 -1
- package/lib/locale/sl.d.ts +11 -0
- package/lib/locale/sl.js +11 -0
- package/lib/locale/sl.js.map +1 -1
- package/lib/locale/sr-Cyrl.d.ts +11 -0
- package/lib/locale/sr-Cyrl.js +11 -0
- package/lib/locale/sr-Cyrl.js.map +1 -1
- package/lib/locale/sr-Latn.d.ts +11 -0
- package/lib/locale/sr-Latn.js +11 -0
- package/lib/locale/sr-Latn.js.map +1 -1
- package/lib/locale/sv.d.ts +11 -0
- package/lib/locale/sv.js +11 -0
- package/lib/locale/sv.js.map +1 -1
- package/lib/locale/th.d.ts +11 -0
- package/lib/locale/th.js +11 -0
- package/lib/locale/th.js.map +1 -1
- package/lib/locale/tr.d.ts +11 -0
- package/lib/locale/tr.js +11 -0
- package/lib/locale/tr.js.map +1 -1
- package/lib/locale/uk.d.ts +11 -0
- package/lib/locale/uk.js +11 -0
- package/lib/locale/uk.js.map +1 -1
- package/lib/locale/vi.d.ts +11 -0
- package/lib/locale/vi.js +11 -0
- package/lib/locale/vi.js.map +1 -1
- package/lib/locale/zh-Hans.d.ts +11 -0
- package/lib/locale/zh-Hans.js +11 -0
- package/lib/locale/zh-Hans.js.map +1 -1
- package/lib/locale/zh-Hant.d.ts +11 -0
- package/lib/locale/zh-Hant.js +11 -0
- package/lib/locale/zh-Hant.js.map +1 -1
- package/lib/util/easing.d.ts +22 -0
- package/lib/util/easing.js +53 -0
- package/lib/util/easing.js.map +1 -1
- package/lib/util/index.d.ts +1 -0
- package/lib/util/index.js +1 -0
- package/lib/util/index.js.map +1 -1
- package/lib/util/svg-arc-corners.d.ts +4 -0
- package/lib/util/svg-arc-corners.js +73 -0
- package/lib/util/svg-arc-corners.js.map +1 -0
- package/lib/util/timeUtils.d.ts +1 -0
- package/lib/util/timeUtils.js +4 -0
- package/lib/util/timeUtils.js.map +1 -0
- package/package.json +1 -1
package/dist/vuetify-labs.esm.js
CHANGED
@@ -1,10 +1,10 @@
|
|
1
1
|
/*!
|
2
|
-
* Vuetify v3.9.2-master.2025-07-
|
2
|
+
* Vuetify v3.9.2-master.2025-07-25
|
3
3
|
* Forged by John Leider
|
4
4
|
* Released under the MIT License.
|
5
5
|
*/
|
6
6
|
|
7
|
-
import { shallowRef, reactive, watchEffect, toRef, capitalize, unref, Fragment, camelize, isVNode, Comment, warn, getCurrentInstance as getCurrentInstance$1, ref, computed, provide, inject as inject$1, defineComponent as defineComponent$1, h,
|
7
|
+
import { shallowRef, reactive, watchEffect, toRef, capitalize, unref, Fragment, camelize, isVNode, Comment, warn, getCurrentInstance as getCurrentInstance$1, ref, computed, provide, inject as inject$1, defineComponent as defineComponent$1, h, toValue, watch, onBeforeUnmount, readonly, onMounted, useId, onDeactivated, onActivated, onScopeDispose, effectScope, toRaw, getCurrentScope, createElementVNode, normalizeStyle, normalizeClass, createVNode, TransitionGroup, Transition, mergeProps, toRefs, isRef, onBeforeMount, nextTick, withDirectives, vShow, onUpdated, Text, resolveDynamicComponent, toDisplayString, markRaw, Teleport, cloneVNode, createTextVNode, normalizeProps, guardReactiveProps, onUnmounted, onBeforeUpdate, withModifiers, vModelText, resolveComponent, render } from 'vue';
|
8
8
|
|
9
9
|
// Types
|
10
10
|
// eslint-disable-line vue/prefer-import-from-vue
|
@@ -1562,10 +1562,64 @@ function attachedRoot(node) {
|
|
1562
1562
|
return root;
|
1563
1563
|
}
|
1564
1564
|
|
1565
|
+
// Utilities
|
1566
|
+
|
1567
|
+
// Types
|
1568
|
+
|
1565
1569
|
const standardEasing = 'cubic-bezier(0.4, 0, 0.2, 1)';
|
1566
1570
|
const deceleratedEasing = 'cubic-bezier(0.0, 0, 0.2, 1)'; // Entering
|
1567
1571
|
const acceleratedEasing = 'cubic-bezier(0.4, 0, 1, 1)'; // Leaving
|
1568
1572
|
|
1573
|
+
const easingPatterns = {
|
1574
|
+
linear: t => t,
|
1575
|
+
easeInQuad: t => t ** 2,
|
1576
|
+
easeOutQuad: t => t * (2 - t),
|
1577
|
+
easeInOutQuad: t => t < 0.5 ? 2 * t ** 2 : -1 + (4 - 2 * t) * t,
|
1578
|
+
easeInCubic: t => t ** 3,
|
1579
|
+
easeOutCubic: t => --t ** 3 + 1,
|
1580
|
+
easeInOutCubic: t => t < 0.5 ? 4 * t ** 3 : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1,
|
1581
|
+
easeInQuart: t => t ** 4,
|
1582
|
+
easeOutQuart: t => 1 - --t ** 4,
|
1583
|
+
easeInOutQuart: t => t < 0.5 ? 8 * t ** 4 : 1 - 8 * --t ** 4,
|
1584
|
+
easeInQuint: t => t ** 5,
|
1585
|
+
easeOutQuint: t => 1 + --t ** 5,
|
1586
|
+
easeInOutQuint: t => t < 0.5 ? 16 * t ** 5 : 1 + 16 * --t ** 5
|
1587
|
+
};
|
1588
|
+
function useTransition(source, options) {
|
1589
|
+
const defaultTransition = {
|
1590
|
+
duration: 300,
|
1591
|
+
transition: easingPatterns.easeInOutCubic
|
1592
|
+
};
|
1593
|
+
let raf = -1;
|
1594
|
+
const outputRef = shallowRef(toValue(source));
|
1595
|
+
watch(() => toValue(source), async to => {
|
1596
|
+
cancelAnimationFrame(raf);
|
1597
|
+
const easing = {
|
1598
|
+
...defaultTransition,
|
1599
|
+
...toValue(options)
|
1600
|
+
};
|
1601
|
+
await executeTransition(outputRef, outputRef.value, to, easing);
|
1602
|
+
});
|
1603
|
+
function executeTransition(out, from, to, options) {
|
1604
|
+
const startTime = performance.now();
|
1605
|
+
const ease = options.transition ?? easingPatterns.easeInOutCubic;
|
1606
|
+
return new Promise(resolve => {
|
1607
|
+
raf = requestAnimationFrame(function step(currentTime) {
|
1608
|
+
const timeElapsed = currentTime - startTime;
|
1609
|
+
const progress = timeElapsed / options.duration;
|
1610
|
+
out.value = from + (to - from) * ease(clamp(progress, 0, 1));
|
1611
|
+
if (progress < 1) {
|
1612
|
+
raf = requestAnimationFrame(step);
|
1613
|
+
} else {
|
1614
|
+
out.value = to;
|
1615
|
+
resolve();
|
1616
|
+
}
|
1617
|
+
});
|
1618
|
+
});
|
1619
|
+
}
|
1620
|
+
return computed(() => outputRef.value);
|
1621
|
+
}
|
1622
|
+
|
1569
1623
|
// Utilities
|
1570
1624
|
function getPrefixedEventHandlers(attrs, suffix, getData) {
|
1571
1625
|
return Object.keys(attrs).filter(key => isOn(key) && key.endsWith(suffix)).reduce((acc, key) => {
|
@@ -1656,6 +1710,10 @@ function useRender(render) {
|
|
1656
1710
|
vm.render = render;
|
1657
1711
|
}
|
1658
1712
|
|
1713
|
+
function formatTime(seconds) {
|
1714
|
+
return [Math.floor(seconds % 60), Math.floor(seconds / 60 % 60), Math.floor(seconds / 60 / 60 % 60)].filter((x, i) => i < 2 || x > 0).reverse().map(String).map((x, i) => i > 0 ? x.padStart(2, '0') : x).join(':');
|
1715
|
+
}
|
1716
|
+
|
1659
1717
|
// Utilities
|
1660
1718
|
|
1661
1719
|
// Types
|
@@ -2176,6 +2234,17 @@ var en = {
|
|
2176
2234
|
option: 'Option',
|
2177
2235
|
plus: 'plus',
|
2178
2236
|
shortcut: 'Keyboard shortcut: {0}'
|
2237
|
+
},
|
2238
|
+
video: {
|
2239
|
+
play: 'Play',
|
2240
|
+
pause: 'Pause',
|
2241
|
+
seek: 'Seek',
|
2242
|
+
volume: 'Volume',
|
2243
|
+
showVolume: 'Show volume control',
|
2244
|
+
mute: 'Mute',
|
2245
|
+
unmute: 'Unmute',
|
2246
|
+
enterFullscreen: 'Full screen',
|
2247
|
+
exitFullscreen: 'Exit full screen'
|
2179
2248
|
}
|
2180
2249
|
};
|
2181
2250
|
|
@@ -4258,7 +4327,7 @@ function useDensity(props) {
|
|
4258
4327
|
|
4259
4328
|
// Types
|
4260
4329
|
|
4261
|
-
const allowedVariants$
|
4330
|
+
const allowedVariants$4 = ['elevated', 'flat', 'tonal', 'outlined', 'text', 'plain'];
|
4262
4331
|
function genOverlays(isClickable, name) {
|
4263
4332
|
return createElementVNode(Fragment, null, [isClickable && createElementVNode("span", {
|
4264
4333
|
"key": "overlay",
|
@@ -4273,7 +4342,7 @@ const makeVariantProps = propsFactory({
|
|
4273
4342
|
variant: {
|
4274
4343
|
type: String,
|
4275
4344
|
default: 'elevated',
|
4276
|
-
validator: v => allowedVariants$
|
4345
|
+
validator: v => allowedVariants$4.includes(v)
|
4277
4346
|
}
|
4278
4347
|
}, 'variant');
|
4279
4348
|
function useVariant(props) {
|
@@ -4697,7 +4766,15 @@ const aliases = {
|
|
4697
4766
|
arrowdown: 'mdi-arrow-down',
|
4698
4767
|
arrowleft: 'mdi-arrow-left',
|
4699
4768
|
arrowright: 'mdi-arrow-right',
|
4700
|
-
backspace: 'mdi-backspace'
|
4769
|
+
backspace: 'mdi-backspace',
|
4770
|
+
play: 'mdi-play',
|
4771
|
+
pause: 'mdi-pause',
|
4772
|
+
fullscreen: 'mdi-fullscreen',
|
4773
|
+
fullscreenExit: 'mdi-fullscreen-exit',
|
4774
|
+
volumeHigh: 'mdi-volume-high',
|
4775
|
+
volumeMedium: 'mdi-volume-medium',
|
4776
|
+
volumeLow: 'mdi-volume-low',
|
4777
|
+
volumeOff: 'mdi-volume-variant-off'
|
4701
4778
|
};
|
4702
4779
|
const mdi = {
|
4703
4780
|
// Not using mergeProps here, functional components merge props by default (?)
|
@@ -7666,21 +7743,7 @@ function genDefaults() {
|
|
7666
7743
|
layout: false,
|
7667
7744
|
offset: 0,
|
7668
7745
|
easing: 'easeInOutCubic',
|
7669
|
-
patterns:
|
7670
|
-
linear: t => t,
|
7671
|
-
easeInQuad: t => t ** 2,
|
7672
|
-
easeOutQuad: t => t * (2 - t),
|
7673
|
-
easeInOutQuad: t => t < 0.5 ? 2 * t ** 2 : -1 + (4 - 2 * t) * t,
|
7674
|
-
easeInCubic: t => t ** 3,
|
7675
|
-
easeOutCubic: t => --t ** 3 + 1,
|
7676
|
-
easeInOutCubic: t => t < 0.5 ? 4 * t ** 3 : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1,
|
7677
|
-
easeInQuart: t => t ** 4,
|
7678
|
-
easeOutQuart: t => 1 - --t ** 4,
|
7679
|
-
easeInOutQuart: t => t < 0.5 ? 8 * t ** 4 : 1 - 8 * --t ** 4,
|
7680
|
-
easeInQuint: t => t ** 5,
|
7681
|
-
easeOutQuint: t => 1 + --t ** 5,
|
7682
|
-
easeInOutQuint: t => t < 0.5 ? 16 * t ** 5 : 1 + 16 * --t ** 5
|
7683
|
-
}
|
7746
|
+
patterns: easingPatterns
|
7684
7747
|
};
|
7685
7748
|
}
|
7686
7749
|
function getContainer(el) {
|
@@ -10517,11 +10580,23 @@ function connectedLocationStrategy(data, props, contentStyles) {
|
|
10517
10580
|
const result = updateLocation();
|
10518
10581
|
if (result) flipped.push(result.flipped);
|
10519
10582
|
});
|
10520
|
-
|
10521
|
-
|
10522
|
-
|
10583
|
+
let targetBox = new Box({
|
10584
|
+
x: 0,
|
10585
|
+
y: 0,
|
10586
|
+
width: 0,
|
10587
|
+
height: 0
|
10588
|
+
});
|
10589
|
+
watch(data.target, (newTarget, oldTarget) => {
|
10523
10590
|
if (oldTarget && !Array.isArray(oldTarget)) observer.unobserve(oldTarget);
|
10524
|
-
if (
|
10591
|
+
if (!Array.isArray(newTarget)) {
|
10592
|
+
if (newTarget) observer.observe(newTarget);
|
10593
|
+
} else if (!deepEqual(newTarget, oldTarget)) {
|
10594
|
+
updateLocation();
|
10595
|
+
}
|
10596
|
+
}, {
|
10597
|
+
immediate: true
|
10598
|
+
});
|
10599
|
+
watch(data.contentEl, (newContentEl, oldContentEl) => {
|
10525
10600
|
if (oldContentEl) observer.unobserve(oldContentEl);
|
10526
10601
|
if (newContentEl) observer.observe(newContentEl);
|
10527
10602
|
}, {
|
@@ -10530,12 +10605,6 @@ function connectedLocationStrategy(data, props, contentStyles) {
|
|
10530
10605
|
onScopeDispose(() => {
|
10531
10606
|
observer.disconnect();
|
10532
10607
|
});
|
10533
|
-
let targetBox = new Box({
|
10534
|
-
x: 0,
|
10535
|
-
y: 0,
|
10536
|
-
width: 0,
|
10537
|
-
height: 0
|
10538
|
-
});
|
10539
10608
|
|
10540
10609
|
// eslint-disable-next-line max-statements
|
10541
10610
|
function updateLocation() {
|
@@ -10827,11 +10896,12 @@ function closeScrollStrategy(data) {
|
|
10827
10896
|
function onScroll(e) {
|
10828
10897
|
data.isActive.value = false;
|
10829
10898
|
}
|
10830
|
-
bindScroll(data.
|
10899
|
+
bindScroll(data.target.value ?? data.contentEl.value, onScroll);
|
10831
10900
|
}
|
10832
10901
|
function blockScrollStrategy(data, props) {
|
10833
10902
|
const offsetParent = data.root.value?.offsetParent;
|
10834
|
-
const
|
10903
|
+
const target = Array.isArray(data.target.value) ? document.elementFromPoint(...data.target.value) : data.target.value;
|
10904
|
+
const scrollElements = [...new Set([...getScrollParents(target, props.contained ? offsetParent : undefined), ...getScrollParents(data.contentEl.value, props.contained ? offsetParent : undefined)])].filter(el => !el.classList.contains('v-overlay-scroll-blocked'));
|
10835
10905
|
const scrollbarWidth = window.innerWidth - document.documentElement.offsetWidth;
|
10836
10906
|
const scrollableParent = (el => hasScrollbar(el) && el)(offsetParent || document.documentElement);
|
10837
10907
|
if (scrollableParent) {
|
@@ -10878,7 +10948,7 @@ function repositionScrollStrategy(data, props, scope) {
|
|
10878
10948
|
}
|
10879
10949
|
ric = (typeof requestIdleCallback === 'undefined' ? cb => cb() : requestIdleCallback)(() => {
|
10880
10950
|
scope.run(() => {
|
10881
|
-
bindScroll(data.
|
10951
|
+
bindScroll(data.target.value ?? data.contentEl.value, e => {
|
10882
10952
|
if (slow) {
|
10883
10953
|
// If the position calculation is slow,
|
10884
10954
|
// defer updates until scrolling is finished.
|
@@ -10903,7 +10973,8 @@ function repositionScrollStrategy(data, props, scope) {
|
|
10903
10973
|
}
|
10904
10974
|
|
10905
10975
|
/** @private */
|
10906
|
-
function bindScroll(
|
10976
|
+
function bindScroll(target, onScroll) {
|
10977
|
+
const el = Array.isArray(target) ? document.elementFromPoint(...target) : target;
|
10907
10978
|
const scrollElements = [document, ...getScrollParents(el)];
|
10908
10979
|
scrollElements.forEach(el => {
|
10909
10980
|
el.addEventListener('scroll', onScroll, {
|
@@ -11585,6 +11656,7 @@ const VOverlay = genericComponent()({
|
|
11585
11656
|
root,
|
11586
11657
|
contentEl,
|
11587
11658
|
targetEl,
|
11659
|
+
target,
|
11588
11660
|
isActive,
|
11589
11661
|
updateLocation
|
11590
11662
|
});
|
@@ -11980,7 +12052,7 @@ const VFieldLabel = genericComponent()({
|
|
11980
12052
|
|
11981
12053
|
// Types
|
11982
12054
|
|
11983
|
-
const allowedVariants$
|
12055
|
+
const allowedVariants$3 = ['underlined', 'outlined', 'filled', 'solo', 'solo-inverted', 'solo-filled', 'plain'];
|
11984
12056
|
const makeVFieldProps = propsFactory({
|
11985
12057
|
appendInnerIcon: IconValue,
|
11986
12058
|
bgColor: String,
|
@@ -12014,7 +12086,7 @@ const makeVFieldProps = propsFactory({
|
|
12014
12086
|
variant: {
|
12015
12087
|
type: String,
|
12016
12088
|
default: 'filled',
|
12017
|
-
validator: v => allowedVariants$
|
12089
|
+
validator: v => allowedVariants$3.includes(v)
|
12018
12090
|
},
|
12019
12091
|
'onClick:clear': EventProp(),
|
12020
12092
|
'onClick:appendInner': EventProp(),
|
@@ -16176,6 +16248,7 @@ const makeSliderProps = propsFactory({
|
|
16176
16248
|
validator: v => ['vertical', 'horizontal'].includes(v)
|
16177
16249
|
},
|
16178
16250
|
reverse: Boolean,
|
16251
|
+
noKeyboard: Boolean,
|
16179
16252
|
...makeRoundedProps(),
|
16180
16253
|
...makeElevationProps({
|
16181
16254
|
elevation: 2
|
@@ -16379,6 +16452,7 @@ const useSlider = _ref => {
|
|
16379
16452
|
min,
|
16380
16453
|
max,
|
16381
16454
|
mousePressed,
|
16455
|
+
noKeyboard: toRef(() => props.noKeyboard),
|
16382
16456
|
numTicks,
|
16383
16457
|
onSliderMousedown,
|
16384
16458
|
onSliderTouchstart,
|
@@ -16431,6 +16505,7 @@ const makeVSliderThumbProps = propsFactory({
|
|
16431
16505
|
default: true
|
16432
16506
|
},
|
16433
16507
|
name: String,
|
16508
|
+
noKeyboard: Boolean,
|
16434
16509
|
...makeComponentProps()
|
16435
16510
|
}, 'VSliderThumb');
|
16436
16511
|
const VSliderThumb = genericComponent()({
|
@@ -16493,6 +16568,7 @@ const VSliderThumb = genericComponent()({
|
|
16493
16568
|
if (step.value) return [1, 2, 3];else return [1, 5, 10];
|
16494
16569
|
});
|
16495
16570
|
function parseKeydown(e, value) {
|
16571
|
+
if (props.noKeyboard) return;
|
16496
16572
|
if (!relevantKeys.includes(e.key)) return;
|
16497
16573
|
e.preventDefault();
|
16498
16574
|
const _step = step.value || 0.1;
|
@@ -16728,7 +16804,8 @@ const VSlider = genericComponent()({
|
|
16728
16804
|
trackContainerRef,
|
16729
16805
|
position,
|
16730
16806
|
hasLabels,
|
16731
|
-
readonly
|
16807
|
+
readonly,
|
16808
|
+
noKeyboard
|
16732
16809
|
} = useSlider({
|
16733
16810
|
props,
|
16734
16811
|
steps,
|
@@ -16804,6 +16881,7 @@ const VSlider = genericComponent()({
|
|
16804
16881
|
"ref": thumbContainerRef,
|
16805
16882
|
"aria-describedby": messagesId.value,
|
16806
16883
|
"focused": isFocused.value,
|
16884
|
+
"noKeyboard": noKeyboard.value,
|
16807
16885
|
"min": min.value,
|
16808
16886
|
"max": max.value,
|
16809
16887
|
"modelValue": model.value,
|
@@ -23880,7 +23958,7 @@ const VExpansionPanel = genericComponent()({
|
|
23880
23958
|
|
23881
23959
|
// Types
|
23882
23960
|
|
23883
|
-
const allowedVariants = ['default', 'accordion', 'inset', 'popout'];
|
23961
|
+
const allowedVariants$2 = ['default', 'accordion', 'inset', 'popout'];
|
23884
23962
|
const makeVExpansionPanelsProps = propsFactory({
|
23885
23963
|
flat: Boolean,
|
23886
23964
|
...makeGroupProps(),
|
@@ -23891,7 +23969,7 @@ const makeVExpansionPanelsProps = propsFactory({
|
|
23891
23969
|
variant: {
|
23892
23970
|
type: String,
|
23893
23971
|
default: 'default',
|
23894
|
-
validator: v => allowedVariants.includes(v)
|
23972
|
+
validator: v => allowedVariants$2.includes(v)
|
23895
23973
|
}
|
23896
23974
|
}, 'VExpansionPanels');
|
23897
23975
|
const VExpansionPanels = genericComponent()({
|
@@ -32423,6 +32501,614 @@ const VMaskInput = genericComponent()({
|
|
32423
32501
|
}
|
32424
32502
|
});
|
32425
32503
|
|
32504
|
+
// Utilities
|
32505
|
+
|
32506
|
+
// Types
|
32507
|
+
|
32508
|
+
// Types
|
32509
|
+
|
32510
|
+
// Composables
|
32511
|
+
const makeRevealProps = propsFactory({
|
32512
|
+
reveal: {
|
32513
|
+
type: [Boolean, Object],
|
32514
|
+
default: false
|
32515
|
+
}
|
32516
|
+
}, 'reveal');
|
32517
|
+
function useReveal(props) {
|
32518
|
+
const defaultDuration = 900;
|
32519
|
+
const duration = toRef(() => typeof props.reveal === 'object' ? Math.max(0, Number(props.reveal.duration ?? defaultDuration)) : defaultDuration);
|
32520
|
+
const state = shallowRef(props.reveal ? 'initial' : 'disabled');
|
32521
|
+
onMounted(async () => {
|
32522
|
+
if (props.reveal) {
|
32523
|
+
state.value = 'initial';
|
32524
|
+
await new Promise(resolve => requestAnimationFrame(resolve));
|
32525
|
+
state.value = 'pending';
|
32526
|
+
await new Promise(resolve => setTimeout(resolve, duration.value));
|
32527
|
+
state.value = 'done';
|
32528
|
+
}
|
32529
|
+
});
|
32530
|
+
return {
|
32531
|
+
duration,
|
32532
|
+
state
|
32533
|
+
};
|
32534
|
+
}
|
32535
|
+
|
32536
|
+
/*
|
32537
|
+
* Credits: Alexander Milevski https://github.com/w8r/svg-arc-corners
|
32538
|
+
*/
|
32539
|
+
|
32540
|
+
function pointOnArc(center, radius, angle) {
|
32541
|
+
const radians = (angle - 90) * Math.PI / 180.0;
|
32542
|
+
return [center[0] + radius * Math.cos(radians), center[1] + radius * Math.sin(radians)];
|
32543
|
+
}
|
32544
|
+
function drawCircle(_ref, r, width) {
|
32545
|
+
let [x, y] = _ref;
|
32546
|
+
const innerRadius = r - width;
|
32547
|
+
return ['M', x - r, y, 'A', r, r, 0, 1, 0, x + r, y, 'A', r, r, 0, 1, 0, x - r, y, 'M', x - innerRadius, y, 'A', innerRadius, innerRadius, 0, 1, 0, x + innerRadius, y, 'A', innerRadius, innerRadius, 0, 1, 0, x - innerRadius, y, 'Z'];
|
32548
|
+
}
|
32549
|
+
function simpleArc(center, r, startAngle, endAngle) {
|
32550
|
+
const start = pointOnArc(center, r, startAngle);
|
32551
|
+
const end = pointOnArc(center, r, endAngle);
|
32552
|
+
const sweep = endAngle - startAngle > 180 ? 1 : 0;
|
32553
|
+
return [`M${start[0]} ${start[1]}`, `A${r} ${r} 0 ${sweep} 1 ${end[0]} ${end[1]}`, `L${center[0]} ${center[1]}Z`].join(' ');
|
32554
|
+
}
|
32555
|
+
function roundedArc(center, radius, startAngle, endAngle, width, rounding) {
|
32556
|
+
width = Math.min(radius, width);
|
32557
|
+
if (Math.abs(endAngle - startAngle) === 360) {
|
32558
|
+
return drawCircle(center, radius, width).join(' ');
|
32559
|
+
}
|
32560
|
+
if (rounding === 0 && radius === width) {
|
32561
|
+
return simpleArc(center, radius, startAngle, endAngle);
|
32562
|
+
}
|
32563
|
+
const innerR = radius - width;
|
32564
|
+
const circumference = Math.abs(endAngle - startAngle);
|
32565
|
+
rounding = Math.min(width / 2, rounding);
|
32566
|
+
if (360 * (rounding / (Math.PI * (radius - width))) > Math.abs(startAngle - endAngle)) {
|
32567
|
+
rounding = circumference / 360 * innerR * Math.PI;
|
32568
|
+
}
|
32569
|
+
|
32570
|
+
// inner and outer radiuses
|
32571
|
+
const innerR2 = innerR + rounding;
|
32572
|
+
const outerRadius = radius - rounding;
|
32573
|
+
|
32574
|
+
// butts corner points
|
32575
|
+
const oStart = pointOnArc(center, outerRadius, startAngle);
|
32576
|
+
const oEnd = pointOnArc(center, outerRadius, endAngle);
|
32577
|
+
const iStart = pointOnArc(center, innerR2, startAngle);
|
32578
|
+
const iEnd = pointOnArc(center, innerR2, endAngle);
|
32579
|
+
const iSection = innerR ? 360 * (rounding / (2 * Math.PI * innerR)) : 0;
|
32580
|
+
const oSection = 360 * (rounding / (2 * Math.PI * radius));
|
32581
|
+
|
32582
|
+
// arcs endpoints
|
32583
|
+
const iArcStart = pointOnArc(center, innerR, startAngle + iSection);
|
32584
|
+
const iArcEnd = pointOnArc(center, innerR, endAngle - iSection);
|
32585
|
+
const oArcStart = pointOnArc(center, radius, startAngle + oSection);
|
32586
|
+
const oArcEnd = pointOnArc(center, radius, endAngle - oSection);
|
32587
|
+
const arcSweep1 = circumference > 180 + 2 * oSection ? 1 : 0;
|
32588
|
+
const arcSweep2 = circumference > 180 + 2 * iSection ? 1 : 0;
|
32589
|
+
return [
|
32590
|
+
// begin path
|
32591
|
+
'M', oStart[0], oStart[1],
|
32592
|
+
// outer start corner
|
32593
|
+
'A', rounding, rounding, 0, 0, 1, oArcStart[0], oArcStart[1],
|
32594
|
+
// outer main arc
|
32595
|
+
'A', radius, radius, 0, arcSweep1, 1, oArcEnd[0], oArcEnd[1],
|
32596
|
+
// outer end corner
|
32597
|
+
'A', rounding, rounding, 0, 0, 1, oEnd[0], oEnd[1],
|
32598
|
+
// end butt
|
32599
|
+
'L', iEnd[0], iEnd[1],
|
32600
|
+
// inner end corner
|
32601
|
+
'A', rounding, rounding, 0, 0, 1, iArcEnd[0], iArcEnd[1],
|
32602
|
+
// inner arc
|
32603
|
+
'A', innerR, innerR, 0, arcSweep2, 0, iArcStart[0], iArcStart[1],
|
32604
|
+
// inner start corner
|
32605
|
+
'A', rounding, rounding, 0, 0, 1, iStart[0], iStart[1], 'Z' // end path
|
32606
|
+
].join(' ');
|
32607
|
+
}
|
32608
|
+
|
32609
|
+
// Utilities
|
32610
|
+
|
32611
|
+
// Types
|
32612
|
+
|
32613
|
+
function formatTextTemplate(template, item) {
|
32614
|
+
return item ? template.replaceAll('[title]', item.title).replaceAll('[value]', String(item.value)) : undefined;
|
32615
|
+
}
|
32616
|
+
function usePieArc(props, isHovering) {
|
32617
|
+
const hoverZoomRatio = toRef(() => clamp(Number(props.hoverScale ?? 0), 0, 0.25));
|
32618
|
+
const normalizedValue = toRef(() => clamp(props.value - 100 * Number(props.gap ?? 0) / 360, 0.01, 99.99));
|
32619
|
+
const normalizedInnerCut = toRef(() => {
|
32620
|
+
const min = Number(props.rounded ?? 0) > 0 ? 0.2 : 0;
|
32621
|
+
return clamp(Number(props.innerCut ?? 0) / 100, min, 1);
|
32622
|
+
});
|
32623
|
+
const radians = computed(() => (360 * (-normalizedValue.value / 100) + 90) * (Math.PI / 180));
|
32624
|
+
const arcWidth = computed(() => 50 * (1 - normalizedInnerCut.value) * (isHovering.value ? 1 : 1 - hoverZoomRatio.value));
|
32625
|
+
const outerX = toRef(() => 50 + 50 * Math.cos(radians.value));
|
32626
|
+
const outerY = toRef(() => 50 - 50 * Math.sin(radians.value));
|
32627
|
+
return {
|
32628
|
+
hoverZoomRatio,
|
32629
|
+
normalizedValue,
|
32630
|
+
normalizedInnerCut,
|
32631
|
+
outerX,
|
32632
|
+
outerY,
|
32633
|
+
arcWidth
|
32634
|
+
};
|
32635
|
+
}
|
32636
|
+
function useOuterSlicePath(_ref) {
|
32637
|
+
let {
|
32638
|
+
angle,
|
32639
|
+
radius,
|
32640
|
+
size,
|
32641
|
+
width,
|
32642
|
+
rounded
|
32643
|
+
} = _ref;
|
32644
|
+
return computed(() => roundedArc([50, 50], toValue(radius), toValue(angle), toValue(angle) + 360 * toValue(size) / 100,
|
32645
|
+
// angle end,
|
32646
|
+
toValue(width), toValue(rounded)));
|
32647
|
+
}
|
32648
|
+
function useInnerSlicePath(_ref2) {
|
32649
|
+
let {
|
32650
|
+
angle,
|
32651
|
+
radius,
|
32652
|
+
size
|
32653
|
+
} = _ref2;
|
32654
|
+
return computed(() => simpleArc([50, 50], toValue(radius), toValue(angle), toValue(angle) + 360 * toValue(size) / 100 // angle end,
|
32655
|
+
));
|
32656
|
+
}
|
32657
|
+
|
32658
|
+
// Types
|
32659
|
+
|
32660
|
+
const makeVPieSegmentProps = propsFactory({
|
32661
|
+
rotate: [Number, String],
|
32662
|
+
value: {
|
32663
|
+
type: Number,
|
32664
|
+
default: 0
|
32665
|
+
},
|
32666
|
+
color: String,
|
32667
|
+
innerCut: [Number, String],
|
32668
|
+
hoverScale: {
|
32669
|
+
type: [Number, String],
|
32670
|
+
default: 0.05
|
32671
|
+
},
|
32672
|
+
gap: [Number, String],
|
32673
|
+
rounded: [Number, String],
|
32674
|
+
animation: {
|
32675
|
+
type: [Boolean, Object],
|
32676
|
+
default: false
|
32677
|
+
},
|
32678
|
+
pattern: String,
|
32679
|
+
hideSlice: Boolean,
|
32680
|
+
...makeRevealProps()
|
32681
|
+
}, 'VPieSegment');
|
32682
|
+
const VPieSegment = genericComponent()({
|
32683
|
+
name: 'VPieSegment',
|
32684
|
+
props: makeVPieSegmentProps(),
|
32685
|
+
setup(props) {
|
32686
|
+
const isHovering = shallowRef(false);
|
32687
|
+
const {
|
32688
|
+
state: revealState,
|
32689
|
+
duration: revealDuration
|
32690
|
+
} = useReveal(props);
|
32691
|
+
const transitionConfig = computed(() => {
|
32692
|
+
const defaultEasing = 'easeInOutCubic';
|
32693
|
+
const defaultDuration = 400;
|
32694
|
+
const easingName = typeof props.animation === 'object' ? props.animation.easing ?? defaultEasing : defaultEasing;
|
32695
|
+
return {
|
32696
|
+
duration: ['initial', 'pending'].includes(revealState.value) ? revealDuration.value : typeof props.animation === 'object' ? props.animation.duration : props.animation ? defaultDuration : 0,
|
32697
|
+
transition: easingPatterns[easingName]
|
32698
|
+
};
|
32699
|
+
});
|
32700
|
+
const {
|
32701
|
+
hoverZoomRatio,
|
32702
|
+
normalizedValue,
|
32703
|
+
normalizedInnerCut,
|
32704
|
+
outerX,
|
32705
|
+
outerY,
|
32706
|
+
arcWidth
|
32707
|
+
} = usePieArc(props, isHovering);
|
32708
|
+
const arcSize = toRef(() => revealState.value === 'initial' ? 0 : normalizedValue.value);
|
32709
|
+
const currentArcSize = useTransition(arcSize, transitionConfig);
|
32710
|
+
const angle = toRef(() => revealState.value === 'initial' ? 0 : Number(props.rotate ?? 0) + Number(props.gap ?? 0) / 2);
|
32711
|
+
const currentAngle = useTransition(angle, transitionConfig);
|
32712
|
+
const arcRadius = toRef(() => 50 * (isHovering.value ? 1 : 1 - hoverZoomRatio.value));
|
32713
|
+
const currentArcRadius = useTransition(arcRadius, transitionConfig);
|
32714
|
+
const currentArcWidth = useTransition(arcWidth, transitionConfig);
|
32715
|
+
const outerSlicePath = useOuterSlicePath({
|
32716
|
+
angle: currentAngle,
|
32717
|
+
radius: currentArcRadius,
|
32718
|
+
size: currentArcSize,
|
32719
|
+
width: currentArcWidth,
|
32720
|
+
rounded: () => Number(props.rounded ?? 0)
|
32721
|
+
});
|
32722
|
+
const innerSlicePath = useInnerSlicePath({
|
32723
|
+
angle: currentAngle,
|
32724
|
+
radius: () => currentArcRadius.value - currentArcWidth.value,
|
32725
|
+
size: currentArcSize
|
32726
|
+
});
|
32727
|
+
const overlayPath = toRef(() => `M 50 0 A 50 50 0 ${normalizedValue.value > 50 ? 1 : 0} 1 ${outerX.value} ${outerY.value} L 50 50`);
|
32728
|
+
return () => createElementVNode("g", {
|
32729
|
+
"class": "v-pie-segment",
|
32730
|
+
"style": {
|
32731
|
+
color: props.color
|
32732
|
+
}
|
32733
|
+
}, [createElementVNode("path", {
|
32734
|
+
"key": "outer-slice",
|
32735
|
+
"fill": "currentColor",
|
32736
|
+
"shape-rendering": "geometricPrecision",
|
32737
|
+
"d": outerSlicePath.value
|
32738
|
+
}, null), props.pattern && createElementVNode("path", {
|
32739
|
+
"key": "pattern-overlay",
|
32740
|
+
"shape-rendering": "geometricPrecision",
|
32741
|
+
"fill": props.pattern,
|
32742
|
+
"d": outerSlicePath.value
|
32743
|
+
}, null), !props.hideSlice && normalizedInnerCut.value > 0 && createElementVNode("path", {
|
32744
|
+
"key": "inner-slice",
|
32745
|
+
"fill": "oklch(from currentColor l c h / calc(alpha / 2))",
|
32746
|
+
"d": innerSlicePath.value
|
32747
|
+
}, null), ['disabled', 'done'].includes(revealState.value) && createElementVNode("path", {
|
32748
|
+
"transform": `rotate(${currentAngle.value} 50 50)`,
|
32749
|
+
"class": "v-pie-segment__overlay",
|
32750
|
+
"d": overlayPath.value,
|
32751
|
+
"onMouseenter": () => isHovering.value = true,
|
32752
|
+
"onMouseleave": () => isHovering.value = false
|
32753
|
+
}, null)]);
|
32754
|
+
}
|
32755
|
+
});
|
32756
|
+
|
32757
|
+
// Types
|
32758
|
+
|
32759
|
+
const makeVPieTooltipProps = propsFactory({
|
32760
|
+
modelValue: Boolean,
|
32761
|
+
item: {
|
32762
|
+
type: Object,
|
32763
|
+
default: null
|
32764
|
+
},
|
32765
|
+
titleFormat: {
|
32766
|
+
type: [String, Function],
|
32767
|
+
default: '[title]'
|
32768
|
+
},
|
32769
|
+
subtitleFormat: {
|
32770
|
+
type: [String, Function],
|
32771
|
+
default: '[value]'
|
32772
|
+
},
|
32773
|
+
...makeTransitionProps(),
|
32774
|
+
...pick(makeVTooltipProps(), ['offset'])
|
32775
|
+
}, 'VPieTooltip');
|
32776
|
+
const VPieTooltip = genericComponent()({
|
32777
|
+
name: 'VPieTooltip',
|
32778
|
+
props: makeVPieTooltipProps(),
|
32779
|
+
setup(props, _ref) {
|
32780
|
+
let {
|
32781
|
+
slots
|
32782
|
+
} = _ref;
|
32783
|
+
const target = shallowRef([0, 0]);
|
32784
|
+
const vm = getCurrentInstance('VPieTooltip');
|
32785
|
+
let frame = -1;
|
32786
|
+
function onMouseMove(_ref2) {
|
32787
|
+
let {
|
32788
|
+
clientX,
|
32789
|
+
clientY
|
32790
|
+
} = _ref2;
|
32791
|
+
cancelAnimationFrame(frame);
|
32792
|
+
frame = requestAnimationFrame(() => {
|
32793
|
+
target.value = [clientX, clientY];
|
32794
|
+
});
|
32795
|
+
}
|
32796
|
+
onMounted(() => {
|
32797
|
+
vm.proxy.$el.parentNode.addEventListener('mousemove', onMouseMove);
|
32798
|
+
});
|
32799
|
+
onBeforeUnmount(() => {
|
32800
|
+
vm.proxy.$el.parentNode.removeEventListener('mousemove', onMouseMove);
|
32801
|
+
});
|
32802
|
+
const tooltipTitleFormatFunction = toRef(() => segment => {
|
32803
|
+
return typeof props.titleFormat === 'function' ? props.titleFormat(segment) : formatTextTemplate(props.titleFormat, segment);
|
32804
|
+
});
|
32805
|
+
const tooltipSubtitleFormatFunction = toRef(() => segment => {
|
32806
|
+
return typeof props.subtitleFormat === 'function' ? props.subtitleFormat(segment) : formatTextTemplate(props.subtitleFormat, segment);
|
32807
|
+
});
|
32808
|
+
return () => createVNode(VTooltip, {
|
32809
|
+
"offset": props.offset,
|
32810
|
+
"modelValue": props.modelValue,
|
32811
|
+
"target": target.value,
|
32812
|
+
"contentClass": "v-pie__tooltip-content"
|
32813
|
+
}, {
|
32814
|
+
default: () => [!!props.item && (slots.default?.({
|
32815
|
+
item: props.item
|
32816
|
+
}) ?? createVNode(MaybeTransition, {
|
32817
|
+
"transition": props.transition,
|
32818
|
+
"mode": "out-in"
|
32819
|
+
}, {
|
32820
|
+
default: () => [createVNode(VListItem, {
|
32821
|
+
"key": props.item.key,
|
32822
|
+
"density": "compact",
|
32823
|
+
"title": tooltipTitleFormatFunction.value(props.item),
|
32824
|
+
"subtitle": tooltipSubtitleFormatFunction.value(props.item)
|
32825
|
+
}, {
|
32826
|
+
prepend: slots.prepend ? () => slots.prepend({
|
32827
|
+
item: props.item
|
32828
|
+
}) : undefined
|
32829
|
+
})]
|
32830
|
+
}))]
|
32831
|
+
});
|
32832
|
+
}
|
32833
|
+
});
|
32834
|
+
|
32835
|
+
// Types
|
32836
|
+
|
32837
|
+
const makeVPieProps = propsFactory({
|
32838
|
+
title: String,
|
32839
|
+
bgColor: String,
|
32840
|
+
items: {
|
32841
|
+
type: Array,
|
32842
|
+
default: () => []
|
32843
|
+
},
|
32844
|
+
palette: {
|
32845
|
+
type: Array,
|
32846
|
+
default: () => []
|
32847
|
+
},
|
32848
|
+
itemKey: {
|
32849
|
+
type: String,
|
32850
|
+
default: 'key'
|
32851
|
+
},
|
32852
|
+
itemValue: {
|
32853
|
+
type: String,
|
32854
|
+
default: 'value'
|
32855
|
+
},
|
32856
|
+
itemTitle: {
|
32857
|
+
type: String,
|
32858
|
+
default: 'title'
|
32859
|
+
},
|
32860
|
+
size: {
|
32861
|
+
type: [Number, String],
|
32862
|
+
default: 250
|
32863
|
+
},
|
32864
|
+
rotate: [Number, String],
|
32865
|
+
gaugeCut: [Number, String],
|
32866
|
+
legend: {
|
32867
|
+
type: [Boolean, Object],
|
32868
|
+
default: false
|
32869
|
+
},
|
32870
|
+
tooltip: {
|
32871
|
+
type: [Boolean, Object],
|
32872
|
+
default: false
|
32873
|
+
},
|
32874
|
+
...makeDensityProps(),
|
32875
|
+
...pick(makeVPieSegmentProps(), ['animation', 'gap', 'rounded', 'innerCut', 'hoverScale', 'hideSlice', 'reveal'])
|
32876
|
+
}, 'VPie');
|
32877
|
+
const VPie = genericComponent()({
|
32878
|
+
name: 'VPie',
|
32879
|
+
props: makeVPieProps(),
|
32880
|
+
setup(props, _ref) {
|
32881
|
+
let {
|
32882
|
+
slots
|
32883
|
+
} = _ref;
|
32884
|
+
const legendConfig = computed(() => ({
|
32885
|
+
visible: !!props.legend,
|
32886
|
+
position: 'bottom',
|
32887
|
+
textFormat: '[title]',
|
32888
|
+
...(typeof props.legend === 'object' ? props.legend : {})
|
32889
|
+
}));
|
32890
|
+
const {
|
32891
|
+
colorClasses,
|
32892
|
+
colorStyles
|
32893
|
+
} = useColor(() => ({
|
32894
|
+
background: props.bgColor
|
32895
|
+
}));
|
32896
|
+
const textColorStyles = toRef(() => pick(colorStyles.value, ['color', 'caretColor']));
|
32897
|
+
const legendAvatarSize = toRef(() => ({
|
32898
|
+
default: 20,
|
32899
|
+
comfortable: 18,
|
32900
|
+
compact: 16
|
32901
|
+
})[props.density ?? 'default']);
|
32902
|
+
const legendDirection = toRef(() => ['left', 'right'].includes(legendConfig.value.position) ? 'vertical' : 'horizontal');
|
32903
|
+
const legendMode = toRef(() => !legendConfig.value.visible ? 'hidden' : legendConfig.value.position);
|
32904
|
+
const legendTextFormatFunction = toRef(() => item => {
|
32905
|
+
return typeof legendConfig.value.textFormat === 'function' ? legendConfig.value.textFormat(item) : formatTextTemplate(legendConfig.value.textFormat, item);
|
32906
|
+
});
|
32907
|
+
const arcs = computed(() => {
|
32908
|
+
// hidden items get (value: 0) to trigger disappearing animation
|
32909
|
+
return props.items.filter(Boolean).map((item, index) => {
|
32910
|
+
return {
|
32911
|
+
key: item[props.itemKey],
|
32912
|
+
color: item.color ?? colorFromPalette(index),
|
32913
|
+
value: item[props.itemValue],
|
32914
|
+
title: String(item[props.itemTitle]),
|
32915
|
+
pattern: item.pattern ?? patternFromPalette(index),
|
32916
|
+
raw: item
|
32917
|
+
};
|
32918
|
+
});
|
32919
|
+
});
|
32920
|
+
const visibleItemsKeys = shallowRef([]);
|
32921
|
+
watch(() => arcs.value.length, () => {
|
32922
|
+
// reset when number of items changes
|
32923
|
+
visibleItemsKeys.value = arcs.value.map(a => a.key);
|
32924
|
+
}, {
|
32925
|
+
immediate: true
|
32926
|
+
});
|
32927
|
+
const visibleItems = computed(() => {
|
32928
|
+
// hidden items get (value: 0) to trigger disappearing animation
|
32929
|
+
return arcs.value.map(item => {
|
32930
|
+
return isActive(item) ? item : {
|
32931
|
+
...item,
|
32932
|
+
value: 0
|
32933
|
+
};
|
32934
|
+
});
|
32935
|
+
});
|
32936
|
+
const total = computed(() => visibleItems.value.reduce((sum, item) => sum + item.value, 0));
|
32937
|
+
const gaugeCut = toRef(() => Number(props.gaugeCut ?? 0));
|
32938
|
+
const gaugeOffset = computed(() => (1 - Math.cos(Math.PI * Math.min(90, gaugeCut.value / 2) / 180)) / 2);
|
32939
|
+
const rotateDeg = computed(() => `${gaugeCut.value ? 180 + gaugeCut.value / 2 : props.rotate ?? 0}deg`);
|
32940
|
+
function arcOffset(index) {
|
32941
|
+
return visibleItems.value.slice(0, index).reduce((acc, s) => acc + (total.value > 0 ? s.value / total.value : 0) * (360 - gaugeCut.value), 0);
|
32942
|
+
}
|
32943
|
+
function arcSize(v) {
|
32944
|
+
return v / total.value * (100 - gaugeCut.value / 3.6);
|
32945
|
+
}
|
32946
|
+
function colorFromPalette(index) {
|
32947
|
+
if (props.palette.length === 0) return undefined;
|
32948
|
+
const paletteItem = props.palette[index % props.palette.length];
|
32949
|
+
return typeof paletteItem === 'object' ? paletteItem.color : paletteItem;
|
32950
|
+
}
|
32951
|
+
function patternFromPalette(index) {
|
32952
|
+
if (props.palette.length === 0) return undefined;
|
32953
|
+
const paletteItem = props.palette[index % props.palette.length];
|
32954
|
+
return typeof paletteItem === 'object' ? paletteItem.pattern : undefined;
|
32955
|
+
}
|
32956
|
+
function isActive(item) {
|
32957
|
+
return visibleItemsKeys.value.includes(item.key);
|
32958
|
+
}
|
32959
|
+
function toggle(item) {
|
32960
|
+
if (isActive(item)) {
|
32961
|
+
visibleItemsKeys.value = visibleItemsKeys.value.filter(x => x !== item.key);
|
32962
|
+
} else {
|
32963
|
+
visibleItemsKeys.value = [...visibleItemsKeys.value, item.key];
|
32964
|
+
}
|
32965
|
+
}
|
32966
|
+
const tooltipItem = shallowRef(null);
|
32967
|
+
const tooltipVisible = shallowRef(false);
|
32968
|
+
let mouseLeaveTimeout = null;
|
32969
|
+
function onMouseenter(item) {
|
32970
|
+
if (!props.tooltip) return;
|
32971
|
+
clearTimeout(mouseLeaveTimeout);
|
32972
|
+
tooltipVisible.value = true;
|
32973
|
+
tooltipItem.value = item;
|
32974
|
+
}
|
32975
|
+
function onMouseleave() {
|
32976
|
+
if (!props.tooltip) return;
|
32977
|
+
clearTimeout(mouseLeaveTimeout);
|
32978
|
+
mouseLeaveTimeout = setTimeout(() => {
|
32979
|
+
tooltipVisible.value = false;
|
32980
|
+
|
32981
|
+
// intentionally reusing timeout here
|
32982
|
+
mouseLeaveTimeout = setTimeout(() => {
|
32983
|
+
tooltipItem.value = null;
|
32984
|
+
}, 500);
|
32985
|
+
}, 100);
|
32986
|
+
}
|
32987
|
+
return () => {
|
32988
|
+
const segmentProps = pick(props, ['animation', 'gap', 'rounded', 'hideSlice', 'reveal', 'innerCut', 'hoverScale']);
|
32989
|
+
const defaultTooltipTransition = {
|
32990
|
+
name: 'fade-transition',
|
32991
|
+
duration: 150
|
32992
|
+
};
|
32993
|
+
const tooltipProps = {
|
32994
|
+
item: tooltipItem.value,
|
32995
|
+
modelValue: tooltipVisible.value,
|
32996
|
+
titleFormat: typeof props.tooltip === 'object' ? props.tooltip.titleFormat : '[title]',
|
32997
|
+
subtitleFormat: typeof props.tooltip === 'object' ? props.tooltip.subtitleFormat : '[value]',
|
32998
|
+
transition: typeof props.tooltip === 'object' ? props.tooltip.transition : defaultTooltipTransition,
|
32999
|
+
offset: typeof props.tooltip === 'object' ? props.tooltip.offset : 16
|
33000
|
+
};
|
33001
|
+
const legendDefaults = {
|
33002
|
+
VChipGroup: {
|
33003
|
+
direction: legendDirection.value
|
33004
|
+
},
|
33005
|
+
VChip: {
|
33006
|
+
density: props.density
|
33007
|
+
},
|
33008
|
+
VAvatar: {
|
33009
|
+
size: legendAvatarSize.value
|
33010
|
+
}
|
33011
|
+
};
|
33012
|
+
const tooltipDefaults = {
|
33013
|
+
VAvatar: {
|
33014
|
+
size: 28
|
33015
|
+
}
|
33016
|
+
};
|
33017
|
+
const avatarSlot = _ref2 => {
|
33018
|
+
let {
|
33019
|
+
item
|
33020
|
+
} = _ref2;
|
33021
|
+
return createVNode(VAvatar, {
|
33022
|
+
"color": item.color,
|
33023
|
+
"start": true
|
33024
|
+
}, {
|
33025
|
+
default: () => [item.pattern && createElementVNode("svg", {
|
33026
|
+
"height": "40",
|
33027
|
+
"width": "40"
|
33028
|
+
}, [createElementVNode("rect", {
|
33029
|
+
"width": "40",
|
33030
|
+
"height": "40",
|
33031
|
+
"fill": item.pattern
|
33032
|
+
}, null)])]
|
33033
|
+
});
|
33034
|
+
};
|
33035
|
+
return createElementVNode("div", {
|
33036
|
+
"class": normalizeClass(['v-pie', `v-pie--legend-${legendMode.value}`]),
|
33037
|
+
"style": {
|
33038
|
+
'--v-pie-size': convertToUnit(props.size)
|
33039
|
+
}
|
33040
|
+
}, [slots.title?.() ?? (props.title && createElementVNode("div", {
|
33041
|
+
"class": "v-pie__title"
|
33042
|
+
}, [props.title])), createElementVNode("div", {
|
33043
|
+
"class": normalizeClass(['v-pie__content', colorClasses.value]),
|
33044
|
+
"style": normalizeStyle([{
|
33045
|
+
transform: `rotate(${rotateDeg.value})`,
|
33046
|
+
marginBottom: `calc(-1 * ${convertToUnit(props.size)} * ${gaugeOffset.value})`
|
33047
|
+
}, textColorStyles.value])
|
33048
|
+
}, [createElementVNode("div", {
|
33049
|
+
"class": normalizeClass(['v-pie__content-underlay', colorClasses.value]),
|
33050
|
+
"style": normalizeStyle(colorStyles.value)
|
33051
|
+
}, null), createElementVNode("svg", {
|
33052
|
+
"xmlns": "http://www.w3.org/2000/svg",
|
33053
|
+
"viewBox": "0 0 100 100"
|
33054
|
+
}, [arcs.value.map((item, index) => createVNode(VPieSegment, mergeProps(segmentProps, {
|
33055
|
+
"key": item.key,
|
33056
|
+
"color": item.color,
|
33057
|
+
"value": isActive(item) ? arcSize(item.value) : 0,
|
33058
|
+
"rotate": arcOffset(index),
|
33059
|
+
"pattern": item.pattern,
|
33060
|
+
"onMouseenter": () => onMouseenter(item),
|
33061
|
+
"onMouseleave": () => onMouseleave()
|
33062
|
+
}), null))]), createElementVNode("div", {
|
33063
|
+
"class": "v-pie__center-content",
|
33064
|
+
"style": {
|
33065
|
+
transform: `translate(-50%, -50%)
|
33066
|
+
rotate(-${rotateDeg.value})
|
33067
|
+
translateY(calc(-100% * ${gaugeOffset.value}))`
|
33068
|
+
}
|
33069
|
+
}, [createElementVNode("div", null, [slots.center?.({
|
33070
|
+
total: total.value
|
33071
|
+
})])])]), legendConfig.value.visible && createVNode(VDefaultsProvider, {
|
33072
|
+
"key": "legend",
|
33073
|
+
"defaults": legendDefaults
|
33074
|
+
}, {
|
33075
|
+
default: () => [createElementVNode("div", {
|
33076
|
+
"class": "v-pie__legend"
|
33077
|
+
}, [slots.legend?.({
|
33078
|
+
isActive,
|
33079
|
+
toggle,
|
33080
|
+
items: arcs.value
|
33081
|
+
}) ?? createVNode(VChipGroup, {
|
33082
|
+
"column": true,
|
33083
|
+
"multiple": true,
|
33084
|
+
"modelValue": visibleItemsKeys.value,
|
33085
|
+
"onUpdate:modelValue": $event => visibleItemsKeys.value = $event
|
33086
|
+
}, {
|
33087
|
+
default: () => [arcs.value.map(item => createVNode(VChip, {
|
33088
|
+
"value": item.key
|
33089
|
+
}, {
|
33090
|
+
prepend: () => avatarSlot({
|
33091
|
+
item
|
33092
|
+
}),
|
33093
|
+
default: () => createElementVNode("div", {
|
33094
|
+
"class": "v-pie__legend__text"
|
33095
|
+
}, [slots['legend-text']?.({
|
33096
|
+
item
|
33097
|
+
}) ?? legendTextFormatFunction.value(item)])
|
33098
|
+
}))]
|
33099
|
+
})])]
|
33100
|
+
}), !!props.tooltip && createVNode(VDefaultsProvider, {
|
33101
|
+
"defaults": tooltipDefaults
|
33102
|
+
}, {
|
33103
|
+
default: () => [createVNode(VPieTooltip, tooltipProps, {
|
33104
|
+
default: slots.tooltip,
|
33105
|
+
prepend: avatarSlot
|
33106
|
+
})]
|
33107
|
+
})]);
|
33108
|
+
};
|
33109
|
+
}
|
33110
|
+
});
|
33111
|
+
|
32426
33112
|
// Types
|
32427
33113
|
|
32428
33114
|
const makeVStepperVerticalActionsProps = propsFactory({
|
@@ -33182,6 +33868,799 @@ const VHotkey = genericComponent()({
|
|
33182
33868
|
}
|
33183
33869
|
});
|
33184
33870
|
|
33871
|
+
// Utilities
|
33872
|
+
|
33873
|
+
// Types
|
33874
|
+
|
33875
|
+
function useDirectiveComponent(component, props) {
|
33876
|
+
const concreteComponent = typeof component === 'string' ? resolveComponent(component) : component;
|
33877
|
+
const hook = mountComponent(concreteComponent, props);
|
33878
|
+
return {
|
33879
|
+
mounted: hook,
|
33880
|
+
updated: hook,
|
33881
|
+
unmounted(el) {
|
33882
|
+
render(null, el);
|
33883
|
+
}
|
33884
|
+
};
|
33885
|
+
}
|
33886
|
+
function mountComponent(component, props) {
|
33887
|
+
return function (el, binding, vnode) {
|
33888
|
+
const _props = typeof props === 'function' ? props(binding) : props;
|
33889
|
+
const text = binding.value?.text ?? binding.value ?? _props?.text;
|
33890
|
+
const value = isObject(binding.value) ? binding.value : {};
|
33891
|
+
|
33892
|
+
// Get the children from the props or directive value, or the element's children
|
33893
|
+
const children = () => text ?? el.textContent;
|
33894
|
+
|
33895
|
+
// If vnode.ctx is the same as the instance, then we're bound to a plain element
|
33896
|
+
// and need to find the nearest parent component instance to inherit provides from
|
33897
|
+
const provides = (vnode.ctx === binding.instance.$ ? findComponentParent(vnode, binding.instance.$)?.provides : vnode.ctx?.provides) ?? binding.instance.$.provides;
|
33898
|
+
const node = h(component, mergeProps(_props, value), children);
|
33899
|
+
node.appContext = Object.assign(Object.create(null), binding.instance.$.appContext, {
|
33900
|
+
provides
|
33901
|
+
});
|
33902
|
+
render(node, el);
|
33903
|
+
};
|
33904
|
+
}
|
33905
|
+
function findComponentParent(vnode, root) {
|
33906
|
+
// Walk the tree from root until we find the child vnode
|
33907
|
+
const stack = new Set();
|
33908
|
+
const walk = children => {
|
33909
|
+
for (const child of children) {
|
33910
|
+
if (!child) continue;
|
33911
|
+
if (child === vnode || child.el && vnode.el && child.el === vnode.el) {
|
33912
|
+
return true;
|
33913
|
+
}
|
33914
|
+
stack.add(child);
|
33915
|
+
let result;
|
33916
|
+
if (child.suspense) {
|
33917
|
+
result = walk([child.ssContent]);
|
33918
|
+
} else if (Array.isArray(child.children)) {
|
33919
|
+
result = walk(child.children);
|
33920
|
+
} else if (child.component?.vnode) {
|
33921
|
+
result = walk([child.component?.subTree]);
|
33922
|
+
}
|
33923
|
+
if (result) {
|
33924
|
+
return result;
|
33925
|
+
}
|
33926
|
+
stack.delete(child);
|
33927
|
+
}
|
33928
|
+
return false;
|
33929
|
+
};
|
33930
|
+
if (!walk([root.subTree])) {
|
33931
|
+
consoleError('Could not find original vnode, component will not inherit provides');
|
33932
|
+
return root;
|
33933
|
+
}
|
33934
|
+
|
33935
|
+
// Return the first component parent
|
33936
|
+
const result = Array.from(stack).reverse();
|
33937
|
+
for (const child of result) {
|
33938
|
+
if (child.component) {
|
33939
|
+
return child.component;
|
33940
|
+
}
|
33941
|
+
}
|
33942
|
+
return root;
|
33943
|
+
}
|
33944
|
+
|
33945
|
+
// Components
|
33946
|
+
|
33947
|
+
// Types
|
33948
|
+
|
33949
|
+
const Tooltip = useDirectiveComponent(VTooltip, binding => {
|
33950
|
+
return {
|
33951
|
+
activator: 'parent',
|
33952
|
+
location: binding.arg?.replace('-', ' '),
|
33953
|
+
text: typeof binding.value === 'boolean' ? undefined : binding.value
|
33954
|
+
};
|
33955
|
+
});
|
33956
|
+
|
33957
|
+
// Types
|
33958
|
+
|
33959
|
+
const makeVVideoVolumeProps = propsFactory({
|
33960
|
+
inline: Boolean,
|
33961
|
+
label: String,
|
33962
|
+
direction: {
|
33963
|
+
type: String,
|
33964
|
+
default: 'vertical'
|
33965
|
+
},
|
33966
|
+
modelValue: {
|
33967
|
+
type: Number,
|
33968
|
+
default: 0
|
33969
|
+
},
|
33970
|
+
menuProps: Object,
|
33971
|
+
sliderProps: Object,
|
33972
|
+
onClick: EventProp(),
|
33973
|
+
...makeComponentProps()
|
33974
|
+
}, 'VVideoVolume');
|
33975
|
+
const VVideoVolume = genericComponent()({
|
33976
|
+
name: 'VVideoVolume',
|
33977
|
+
directives: {
|
33978
|
+
vTooltip: Tooltip
|
33979
|
+
},
|
33980
|
+
props: makeVVideoVolumeProps(),
|
33981
|
+
emits: {
|
33982
|
+
'update:modelValue': val => true
|
33983
|
+
},
|
33984
|
+
setup(props, _ref) {
|
33985
|
+
let {
|
33986
|
+
attrs
|
33987
|
+
} = _ref;
|
33988
|
+
const {
|
33989
|
+
t
|
33990
|
+
} = useLocale();
|
33991
|
+
const volume = useProxiedModel(props, 'modelValue');
|
33992
|
+
const volumeIcon = toRef(() => volume.value > 70 ? '$volumeHigh' : volume.value > 40 ? '$volumeMedium' : volume.value > 10 ? '$volumeLow' : '$volumeOff');
|
33993
|
+
const containerRef = ref();
|
33994
|
+
useRender(() => {
|
33995
|
+
const sliderDefaults = {
|
33996
|
+
hideDetails: true,
|
33997
|
+
step: 5,
|
33998
|
+
thumbSize: 16
|
33999
|
+
};
|
34000
|
+
return createElementVNode("div", {
|
34001
|
+
"class": normalizeClass(['v-video-volume', {
|
34002
|
+
'v-video-volume--inline': props.inline
|
34003
|
+
}, props.class]),
|
34004
|
+
"style": normalizeStyle(props.style),
|
34005
|
+
"ref": containerRef
|
34006
|
+
}, [withDirectives(createVNode(VIconBtn, mergeProps({
|
34007
|
+
"icon": volumeIcon.value,
|
34008
|
+
"aria-label": props.label,
|
34009
|
+
"onClick": props.onClick
|
34010
|
+
}, attrs), {
|
34011
|
+
default: () => [createVNode(VIcon, null, null), !props.inline && createVNode(VMenu, {
|
34012
|
+
"offset": "8",
|
34013
|
+
"activator": "parent",
|
34014
|
+
"attach": containerRef.value,
|
34015
|
+
"location": props.menuProps?.location ?? 'top center',
|
34016
|
+
"closeOnContentClick": false
|
34017
|
+
}, {
|
34018
|
+
default: () => [createElementVNode("div", {
|
34019
|
+
"class": normalizeClass(['v-video-volume__menu', `v-video-volume__menu--${props.direction}`])
|
34020
|
+
}, [createVNode(VSlider, mergeProps({
|
34021
|
+
"direction": props.direction,
|
34022
|
+
"aria-label": t('$vuetify.video.volume'),
|
34023
|
+
"modelValue": volume.value,
|
34024
|
+
"onUpdate:modelValue": v => volume.value = v
|
34025
|
+
}, sliderDefaults, props.sliderProps), null)])]
|
34026
|
+
})]
|
34027
|
+
}), [[Tooltip, props.label, 'top']]), props.inline && createVNode(VSlider, mergeProps({
|
34028
|
+
"class": "v-video-volume-inline__slider",
|
34029
|
+
"minWidth": "50",
|
34030
|
+
"aria-label": t('$vuetify.video.volume'),
|
34031
|
+
"modelValue": volume.value,
|
34032
|
+
"onUpdate:modelValue": v => volume.value = v,
|
34033
|
+
"onKeydown": e => {
|
34034
|
+
e.stopPropagation();
|
34035
|
+
}
|
34036
|
+
}, sliderDefaults, props.sliderProps), null)]);
|
34037
|
+
});
|
34038
|
+
}
|
34039
|
+
});
|
34040
|
+
|
34041
|
+
// Types
|
34042
|
+
|
34043
|
+
const allowedVariants$1 = ['hidden', 'default', 'tube', 'mini'];
|
34044
|
+
const makeVVideoControlsProps = propsFactory({
|
34045
|
+
color: String,
|
34046
|
+
backgroundColor: String,
|
34047
|
+
trackColor: String,
|
34048
|
+
playing: Boolean,
|
34049
|
+
hidePlay: Boolean,
|
34050
|
+
hideVolume: Boolean,
|
34051
|
+
hideFullscreen: Boolean,
|
34052
|
+
fullscreen: Boolean,
|
34053
|
+
floating: Boolean,
|
34054
|
+
splitTime: Boolean,
|
34055
|
+
pills: Boolean,
|
34056
|
+
detached: Boolean,
|
34057
|
+
progress: {
|
34058
|
+
type: Number,
|
34059
|
+
default: 0
|
34060
|
+
},
|
34061
|
+
duration: {
|
34062
|
+
type: Number,
|
34063
|
+
default: 0
|
34064
|
+
},
|
34065
|
+
volume: [Number, String],
|
34066
|
+
variant: {
|
34067
|
+
type: String,
|
34068
|
+
default: 'default',
|
34069
|
+
validator: v => allowedVariants$1.includes(v)
|
34070
|
+
},
|
34071
|
+
volumeProps: Object,
|
34072
|
+
...makeDensityProps(),
|
34073
|
+
...makeElevationProps(),
|
34074
|
+
...makeThemeProps()
|
34075
|
+
}, 'VVideoControls');
|
34076
|
+
const VVideoControls = genericComponent()({
|
34077
|
+
name: 'VVideoControls',
|
34078
|
+
directives: {
|
34079
|
+
vTooltip: Tooltip
|
34080
|
+
},
|
34081
|
+
props: makeVVideoControlsProps(),
|
34082
|
+
emits: {
|
34083
|
+
'update:playing': val => true,
|
34084
|
+
'update:progress': val => true,
|
34085
|
+
'update:volume': val => true,
|
34086
|
+
skip: val => true,
|
34087
|
+
'click:fullscreen': () => true
|
34088
|
+
},
|
34089
|
+
setup(props, _ref) {
|
34090
|
+
let {
|
34091
|
+
emit,
|
34092
|
+
slots
|
34093
|
+
} = _ref;
|
34094
|
+
const {
|
34095
|
+
t
|
34096
|
+
} = useLocale();
|
34097
|
+
const {
|
34098
|
+
themeClasses
|
34099
|
+
} = provideTheme(props);
|
34100
|
+
const {
|
34101
|
+
densityClasses
|
34102
|
+
} = useDensity(props);
|
34103
|
+
const {
|
34104
|
+
elevationClasses
|
34105
|
+
} = useElevation(props);
|
34106
|
+
const {
|
34107
|
+
backgroundColorClasses,
|
34108
|
+
backgroundColorStyles
|
34109
|
+
} = useBackgroundColor(() => {
|
34110
|
+
const fallbackBackground = props.detached ? 'surface' : undefined;
|
34111
|
+
return props.backgroundColor ?? fallbackBackground;
|
34112
|
+
});
|
34113
|
+
const playing = useProxiedModel(props, 'playing');
|
34114
|
+
const progress = useProxiedModel(props, 'progress');
|
34115
|
+
const volume = useProxiedModel(props, 'volume', 0, v => Number(v ?? 0));
|
34116
|
+
const lastVolume = shallowRef();
|
34117
|
+
const currentTime = computed(() => {
|
34118
|
+
const secondsElapsed = Math.round(props.progress / 100 * props.duration);
|
34119
|
+
return {
|
34120
|
+
elapsed: formatTime(secondsElapsed),
|
34121
|
+
remaining: formatTime(props.duration - secondsElapsed),
|
34122
|
+
total: formatTime(props.duration)
|
34123
|
+
};
|
34124
|
+
});
|
34125
|
+
const labels = computed(() => {
|
34126
|
+
const playIconLocaleKey = playing.value ? 'pause' : 'play';
|
34127
|
+
const volumeIconLocaleKey = props.volumeProps?.inline ? volume.value ? 'mute' : 'unmute' : 'showVolume';
|
34128
|
+
const fullscreenIconLocaleKey = props.fullscreen ? 'exitFullscreen' : 'enterFullscreen';
|
34129
|
+
return {
|
34130
|
+
seek: t('$vuetify.video.seek'),
|
34131
|
+
volume: t('$vuetify.video.volume'),
|
34132
|
+
playAction: t(`$vuetify.video.${playIconLocaleKey}`),
|
34133
|
+
volumeAction: t(`$vuetify.video.${volumeIconLocaleKey}`),
|
34134
|
+
fullscreenAction: t(`$vuetify.video.${fullscreenIconLocaleKey}`)
|
34135
|
+
};
|
34136
|
+
});
|
34137
|
+
function play() {
|
34138
|
+
playing.value = true;
|
34139
|
+
}
|
34140
|
+
function pause() {
|
34141
|
+
playing.value = false;
|
34142
|
+
}
|
34143
|
+
function skipTo(v) {
|
34144
|
+
progress.value = v;
|
34145
|
+
}
|
34146
|
+
function toggleMuted() {
|
34147
|
+
if (volume.value) {
|
34148
|
+
lastVolume.value = volume.value;
|
34149
|
+
volume.value = 0;
|
34150
|
+
} else {
|
34151
|
+
volume.value = lastVolume.value ?? 100;
|
34152
|
+
}
|
34153
|
+
}
|
34154
|
+
function toggleFullscreen() {
|
34155
|
+
emit('click:fullscreen');
|
34156
|
+
}
|
34157
|
+
useRender(() => {
|
34158
|
+
const sizes = props.pills ? [42, 36, 30] : [32, 28, 24];
|
34159
|
+
const innerDefaults = {
|
34160
|
+
VIconBtn: {
|
34161
|
+
size: props.density === 'compact' ? sizes[2] : props.density === 'comfortable' ? sizes[1] : sizes[0],
|
34162
|
+
iconSize: props.density === 'compact' ? 20 : props.density === 'comfortable' ? 24 : 26,
|
34163
|
+
variant: 'text',
|
34164
|
+
color: props.color
|
34165
|
+
},
|
34166
|
+
VSlider: {
|
34167
|
+
thumbSize: props.variant === 'tube' ? 10 : 16,
|
34168
|
+
hideDetails: true
|
34169
|
+
}
|
34170
|
+
};
|
34171
|
+
const regularBtnSize = innerDefaults.VIconBtn.size;
|
34172
|
+
const playBtnSize = props.pills ? regularBtnSize + 8 : regularBtnSize;
|
34173
|
+
const pillClasses = ['v-video-control__pill', props.pills ? elevationClasses.value : []];
|
34174
|
+
const slotProps = {
|
34175
|
+
play,
|
34176
|
+
pause,
|
34177
|
+
playing: playing.value,
|
34178
|
+
progress: progress.value,
|
34179
|
+
currentTime: currentTime.value,
|
34180
|
+
skipTo,
|
34181
|
+
volume,
|
34182
|
+
toggleMuted,
|
34183
|
+
fullscreen: props.fullscreen,
|
34184
|
+
toggleFullscreen,
|
34185
|
+
labels: labels.value
|
34186
|
+
};
|
34187
|
+
return createElementVNode("div", {
|
34188
|
+
"class": normalizeClass(['v-video-controls', `v-video-controls--variant-${props.variant}`, {
|
34189
|
+
'v-video-controls--pills': props.pills
|
34190
|
+
}, {
|
34191
|
+
'v-video-controls--detached': props.detached
|
34192
|
+
}, {
|
34193
|
+
'v-video-controls--floating': props.floating
|
34194
|
+
}, {
|
34195
|
+
'v-video-controls--split-time': props.splitTime
|
34196
|
+
}, backgroundColorClasses.value, props.detached && !props.pills ? elevationClasses.value : [], densityClasses.value, themeClasses.value]),
|
34197
|
+
"style": normalizeStyle([backgroundColorStyles.value, {
|
34198
|
+
'--v-video-controls-pill-height': `${regularBtnSize}px`
|
34199
|
+
}])
|
34200
|
+
}, [createVNode(VDefaultsProvider, {
|
34201
|
+
"defaults": innerDefaults
|
34202
|
+
}, {
|
34203
|
+
default: () => [slots.default?.(slotProps) ?? createElementVNode(Fragment, null, [props.variant !== 'mini' && createElementVNode(Fragment, null, [!props.hidePlay && createElementVNode("div", {
|
34204
|
+
"class": normalizeClass([pillClasses, 'v-video__action-play'])
|
34205
|
+
}, [withDirectives(createVNode(VIconBtn, {
|
34206
|
+
"icon": playing.value ? '$pause' : '$play',
|
34207
|
+
"size": playBtnSize,
|
34208
|
+
"aria-label": labels.value.playAction,
|
34209
|
+
"onClick": () => playing.value = !playing.value
|
34210
|
+
}, null), [[Tooltip, labels.value.playAction, 'top']])]), slots.prepend && createElementVNode("div", {
|
34211
|
+
"class": normalizeClass(pillClasses)
|
34212
|
+
}, [slots.prepend(slotProps)]), props.splitTime ? createElementVNode("span", {
|
34213
|
+
"class": normalizeClass([pillClasses, 'v-video__time'])
|
34214
|
+
}, [currentTime.value.elapsed]) : props.variant !== 'default' ? createElementVNode("span", {
|
34215
|
+
"class": normalizeClass([pillClasses, 'v-video__time'])
|
34216
|
+
}, [currentTime.value.elapsed, createTextVNode(" / "), currentTime.value.total]) : '', createVNode(VSlider, {
|
34217
|
+
"modelValue": props.progress,
|
34218
|
+
"noKeyboard": true,
|
34219
|
+
"color": props.trackColor ?? props.color,
|
34220
|
+
"trackColor": props.variant === 'tube' ? 'white' : undefined,
|
34221
|
+
"class": "v-video__track",
|
34222
|
+
"thumbLabel": "always",
|
34223
|
+
"aria-label": labels.value.seek,
|
34224
|
+
"onUpdate:modelValue": skipTo
|
34225
|
+
}, {
|
34226
|
+
'thumb-label': () => currentTime.value.elapsed
|
34227
|
+
}), props.variant === 'tube' && createVNode(VSpacer, null, null), props.splitTime ? createElementVNode("span", {
|
34228
|
+
"class": normalizeClass([pillClasses, 'v-video__time'])
|
34229
|
+
}, [currentTime.value.remaining]) : '']), props.variant === 'mini' && createElementVNode(Fragment, null, [createVNode(VSpacer, null, null), slots.prepend && createElementVNode("div", {
|
34230
|
+
"class": normalizeClass(pillClasses)
|
34231
|
+
}, [slots.prepend(slotProps)]), !props.hidePlay && createElementVNode("div", {
|
34232
|
+
"class": normalizeClass([pillClasses, 'v-video__action-play'])
|
34233
|
+
}, [withDirectives(createVNode(VIconBtn, {
|
34234
|
+
"icon": playing.value ? '$pause' : '$play',
|
34235
|
+
"size": playBtnSize,
|
34236
|
+
"aria-label": labels.value.playAction,
|
34237
|
+
"onClick": () => playing.value = !playing.value
|
34238
|
+
}, null), [[Tooltip, labels.value.playAction, 'top']])])]), (!props.hideVolume || !props.hideFullscreen || slots.append) && createElementVNode("div", {
|
34239
|
+
"class": normalizeClass(pillClasses)
|
34240
|
+
}, [!props.hideVolume && createVNode(VVideoVolume, mergeProps({
|
34241
|
+
"key": "volume-control",
|
34242
|
+
"sliderProps": {
|
34243
|
+
color: props.color
|
34244
|
+
},
|
34245
|
+
"modelValue": volume.value,
|
34246
|
+
"label": labels.value.volumeAction,
|
34247
|
+
"onUpdate:modelValue": v => volume.value = v,
|
34248
|
+
"onClick": () => props.volumeProps?.inline && toggleMuted()
|
34249
|
+
}, props.volumeProps), null), slots.append?.(slotProps), !props.hideFullscreen && withDirectives(createVNode(VIconBtn, {
|
34250
|
+
"icon": props.fullscreen ? '$fullscreenExit' : '$fullscreen',
|
34251
|
+
"aria-label": labels.value.fullscreenAction,
|
34252
|
+
"onClick": toggleFullscreen
|
34253
|
+
}, null), [[Tooltip, labels.value.fullscreenAction, 'top']])]), props.variant === 'mini' && createVNode(VSpacer, null, null)])]
|
34254
|
+
})]);
|
34255
|
+
});
|
34256
|
+
return {
|
34257
|
+
toggleMuted
|
34258
|
+
};
|
34259
|
+
}
|
34260
|
+
});
|
34261
|
+
|
34262
|
+
// Types
|
34263
|
+
|
34264
|
+
const allowedVariants = ['background', 'player'];
|
34265
|
+
const makeVVideoProps = propsFactory({
|
34266
|
+
autoplay: Boolean,
|
34267
|
+
muted: Boolean,
|
34268
|
+
eager: Boolean,
|
34269
|
+
src: String,
|
34270
|
+
type: String,
|
34271
|
+
// e.g. video/mp4
|
34272
|
+
image: String,
|
34273
|
+
hideOverlay: Boolean,
|
34274
|
+
noFullscreen: Boolean,
|
34275
|
+
startAt: [Number, String],
|
34276
|
+
variant: {
|
34277
|
+
type: String,
|
34278
|
+
default: 'player',
|
34279
|
+
validator: v => allowedVariants.includes(v)
|
34280
|
+
},
|
34281
|
+
controlsTransition: {
|
34282
|
+
type: [Boolean, String, Object],
|
34283
|
+
component: VFadeTransition
|
34284
|
+
},
|
34285
|
+
controlsVariant: {
|
34286
|
+
type: String,
|
34287
|
+
default: 'default'
|
34288
|
+
},
|
34289
|
+
controlsProps: {
|
34290
|
+
type: Object
|
34291
|
+
},
|
34292
|
+
rounded: [Boolean, Number, String, Array],
|
34293
|
+
...makeComponentProps(),
|
34294
|
+
...makeDensityProps(),
|
34295
|
+
...makeDimensionProps(),
|
34296
|
+
...makeThemeProps(),
|
34297
|
+
...omit(makeVVideoControlsProps(), ['fullscreen', 'variant'])
|
34298
|
+
}, 'VVideo');
|
34299
|
+
const VVideo = genericComponent()({
|
34300
|
+
name: 'VVideo',
|
34301
|
+
inheritAttrs: false,
|
34302
|
+
props: makeVVideoProps(),
|
34303
|
+
emits: {
|
34304
|
+
loaded: element => true,
|
34305
|
+
'update:playing': val => true,
|
34306
|
+
'update:progress': val => true,
|
34307
|
+
'update:volume': val => true
|
34308
|
+
},
|
34309
|
+
setup(props, _ref) {
|
34310
|
+
let {
|
34311
|
+
attrs,
|
34312
|
+
emit,
|
34313
|
+
slots
|
34314
|
+
} = _ref;
|
34315
|
+
const {
|
34316
|
+
themeClasses
|
34317
|
+
} = provideTheme(props);
|
34318
|
+
const {
|
34319
|
+
densityClasses
|
34320
|
+
} = useDensity(props);
|
34321
|
+
const {
|
34322
|
+
dimensionStyles
|
34323
|
+
} = useDimension(props);
|
34324
|
+
const {
|
34325
|
+
elevationClasses
|
34326
|
+
} = useElevation(props);
|
34327
|
+
const {
|
34328
|
+
ssr
|
34329
|
+
} = useDisplay();
|
34330
|
+
const roundedForContainer = toRef(() => Array.isArray(props.rounded) ? props.rounded[0] : props.rounded);
|
34331
|
+
const roundedForControls = toRef(() => Array.isArray(props.rounded) ? props.rounded.at(-1) : props.rounded ?? false);
|
34332
|
+
const {
|
34333
|
+
roundedClasses: roundedContainerClasses
|
34334
|
+
} = useRounded(roundedForContainer);
|
34335
|
+
const {
|
34336
|
+
roundedClasses: roundedControlsClasses
|
34337
|
+
} = useRounded(roundedForControls);
|
34338
|
+
const containerRef = ref();
|
34339
|
+
const videoRef = ref();
|
34340
|
+
const controlsRef = ref();
|
34341
|
+
const playing = useProxiedModel(props, 'playing');
|
34342
|
+
const progress = useProxiedModel(props, 'progress');
|
34343
|
+
const volume = useProxiedModel(props, 'volume', 0, v => Number(v ?? 0));
|
34344
|
+
const fullscreen = shallowRef(false);
|
34345
|
+
const waiting = shallowRef(false);
|
34346
|
+
const triggered = shallowRef(false);
|
34347
|
+
const startAfterLoad = shallowRef(false);
|
34348
|
+
const state = shallowRef(props.autoplay ? 'loading' : 'idle');
|
34349
|
+
const duration = shallowRef(0);
|
34350
|
+
const fullscreenEnabled = toRef(() => !props.noFullscreen && !String(attrs.controlsList ?? '').includes('nofullscreen'));
|
34351
|
+
function onTimeupdate() {
|
34352
|
+
const {
|
34353
|
+
currentTime,
|
34354
|
+
duration
|
34355
|
+
} = videoRef.value;
|
34356
|
+
progress.value = duration === 0 ? 0 : 100 * currentTime / duration;
|
34357
|
+
}
|
34358
|
+
async function onTriggered() {
|
34359
|
+
await nextTick();
|
34360
|
+
if (!videoRef.value) return;
|
34361
|
+
videoRef.value.addEventListener('timeupdate', onTimeupdate);
|
34362
|
+
videoRef.value.volume = volume.value / 100;
|
34363
|
+
if (state.value !== 'loaded') {
|
34364
|
+
state.value = 'loading';
|
34365
|
+
}
|
34366
|
+
}
|
34367
|
+
function onVideoLoaded() {
|
34368
|
+
state.value = 'loaded';
|
34369
|
+
duration.value = videoRef.value.duration;
|
34370
|
+
const startTime = Number(props.startAt ?? 0);
|
34371
|
+
if (startTime && startTime <= duration.value) {
|
34372
|
+
videoRef.value.currentTime = startTime;
|
34373
|
+
progress.value = duration.value === 0 ? 0 : 100 * startTime / duration.value;
|
34374
|
+
}
|
34375
|
+
if (startAfterLoad.value) {
|
34376
|
+
setTimeout(() => playing.value = true, 100);
|
34377
|
+
}
|
34378
|
+
emit('loaded', videoRef.value);
|
34379
|
+
}
|
34380
|
+
function onClick() {
|
34381
|
+
if (state.value !== 'loaded') {
|
34382
|
+
triggered.value = true;
|
34383
|
+
startAfterLoad.value = !startAfterLoad.value;
|
34384
|
+
}
|
34385
|
+
}
|
34386
|
+
function onKeydown(e) {
|
34387
|
+
if (!videoRef.value || e.ctrlKey) return;
|
34388
|
+
if (e.key.startsWith('Arrow')) {
|
34389
|
+
e.preventDefault();
|
34390
|
+
}
|
34391
|
+
switch (true) {
|
34392
|
+
case e.key === ' ':
|
34393
|
+
{
|
34394
|
+
if (!['A', 'BUTTON'].includes(e.target?.tagName)) {
|
34395
|
+
e.preventDefault();
|
34396
|
+
playing.value = !playing.value;
|
34397
|
+
}
|
34398
|
+
break;
|
34399
|
+
}
|
34400
|
+
case e.key === 'ArrowRight':
|
34401
|
+
{
|
34402
|
+
const step = 10 * (e.shiftKey ? 6 : 1);
|
34403
|
+
videoRef.value.currentTime = Math.min(videoRef.value.currentTime + step, duration.value);
|
34404
|
+
// TODO: show skip indicator
|
34405
|
+
break;
|
34406
|
+
}
|
34407
|
+
case e.key === 'ArrowLeft':
|
34408
|
+
{
|
34409
|
+
const step = 10 * (e.shiftKey ? 6 : 1);
|
34410
|
+
videoRef.value.currentTime = Math.max(videoRef.value.currentTime - step, 0);
|
34411
|
+
// TODO: show skip indicator
|
34412
|
+
break;
|
34413
|
+
}
|
34414
|
+
case createRange(10).map(String).includes(e.key):
|
34415
|
+
{
|
34416
|
+
skipTo(Number(e.key) * 10);
|
34417
|
+
break;
|
34418
|
+
}
|
34419
|
+
case e.key === 'ArrowUp':
|
34420
|
+
{
|
34421
|
+
volume.value = Math.min(volume.value + 10, 100);
|
34422
|
+
// TODO: show volume change indicator
|
34423
|
+
break;
|
34424
|
+
}
|
34425
|
+
case e.key === 'ArrowDown':
|
34426
|
+
{
|
34427
|
+
volume.value = Math.max(volume.value - 10, 0);
|
34428
|
+
// TODO: show volume change indicator
|
34429
|
+
break;
|
34430
|
+
}
|
34431
|
+
case e.key === 'm':
|
34432
|
+
{
|
34433
|
+
controlsRef.value?.toggleMuted();
|
34434
|
+
break;
|
34435
|
+
}
|
34436
|
+
case e.key === 'f':
|
34437
|
+
{
|
34438
|
+
toggleFullscreen();
|
34439
|
+
break;
|
34440
|
+
}
|
34441
|
+
}
|
34442
|
+
}
|
34443
|
+
function skipTo(v) {
|
34444
|
+
if (!videoRef.value) return;
|
34445
|
+
progress.value = v;
|
34446
|
+
videoRef.value.currentTime = duration.value * v / 100;
|
34447
|
+
}
|
34448
|
+
watch(() => props.src, v => {
|
34449
|
+
progress.value = 0;
|
34450
|
+
});
|
34451
|
+
watch(playing, v => {
|
34452
|
+
if (!videoRef.value) return;
|
34453
|
+
if (v) {
|
34454
|
+
videoRef.value.play();
|
34455
|
+
} else {
|
34456
|
+
videoRef.value.pause();
|
34457
|
+
}
|
34458
|
+
});
|
34459
|
+
watch(volume, v => {
|
34460
|
+
if (!videoRef.value) return;
|
34461
|
+
videoRef.value.volume = v / 100;
|
34462
|
+
});
|
34463
|
+
watch(triggered, () => onTriggered(), {
|
34464
|
+
once: true
|
34465
|
+
});
|
34466
|
+
watch(() => props.eager, v => v && (triggered.value = true), {
|
34467
|
+
immediate: true
|
34468
|
+
});
|
34469
|
+
onMounted(() => {
|
34470
|
+
if (props.autoplay && !ssr) {
|
34471
|
+
triggered.value = true;
|
34472
|
+
startAfterLoad.value = true;
|
34473
|
+
}
|
34474
|
+
});
|
34475
|
+
onBeforeUnmount(() => {
|
34476
|
+
videoRef.value?.removeEventListener('timeupdate', onTimeupdate);
|
34477
|
+
});
|
34478
|
+
function focusSlider() {
|
34479
|
+
const container = videoRef.value?.closest('.v-video');
|
34480
|
+
const innerSlider = container?.querySelector('[role="slider"]');
|
34481
|
+
innerSlider?.focus();
|
34482
|
+
}
|
34483
|
+
function fullscreenExitShortcut(e) {
|
34484
|
+
if (['ESC', 'f'].includes(e.key)) {
|
34485
|
+
toggleFullscreen();
|
34486
|
+
document.body.removeEventListener('keydown', fullscreenExitShortcut);
|
34487
|
+
}
|
34488
|
+
}
|
34489
|
+
async function toggleFullscreen() {
|
34490
|
+
if (!fullscreenEnabled.value || !document.fullscreenEnabled) {
|
34491
|
+
return;
|
34492
|
+
}
|
34493
|
+
if (document.fullscreenElement) {
|
34494
|
+
document.exitFullscreen();
|
34495
|
+
onFullscreenExit();
|
34496
|
+
} else {
|
34497
|
+
await containerRef.value?.requestFullscreen();
|
34498
|
+
document.body.addEventListener('keydown', fullscreenExitShortcut);
|
34499
|
+
document.addEventListener('fullscreenchange', onFullscreenExit);
|
34500
|
+
fullscreen.value = true;
|
34501
|
+
}
|
34502
|
+
}
|
34503
|
+
function onFullscreenExit() {
|
34504
|
+
// event fires with a delay after requestFullscreen(), ignore first run
|
34505
|
+
if (document.fullscreenElement) return;
|
34506
|
+
focusSlider();
|
34507
|
+
fullscreen.value = false;
|
34508
|
+
document.body.removeEventListener('keydown', fullscreenExitShortcut);
|
34509
|
+
document.removeEventListener('fullscreenchange', onFullscreenExit);
|
34510
|
+
}
|
34511
|
+
function onVideoClick(e) {
|
34512
|
+
e.preventDefault();
|
34513
|
+
if (state.value === 'loaded') {
|
34514
|
+
playing.value = !playing.value;
|
34515
|
+
focusSlider();
|
34516
|
+
}
|
34517
|
+
}
|
34518
|
+
function onDoubleClick(e) {
|
34519
|
+
e.preventDefault();
|
34520
|
+
toggleFullscreen();
|
34521
|
+
}
|
34522
|
+
let lastTap = 0;
|
34523
|
+
function onTouchend(e) {
|
34524
|
+
const now = performance.now();
|
34525
|
+
if (now - lastTap < 500) {
|
34526
|
+
e.preventDefault();
|
34527
|
+
toggleFullscreen();
|
34528
|
+
} else {
|
34529
|
+
lastTap = now;
|
34530
|
+
}
|
34531
|
+
}
|
34532
|
+
useRender(() => {
|
34533
|
+
const showControls = state.value === 'loaded' && props.variant === 'player' && props.controlsVariant !== 'hidden';
|
34534
|
+
const posterTransition = props.variant === 'background' ? 'poster-fade-out' : 'fade-transition';
|
34535
|
+
const overlayProps = {
|
34536
|
+
contained: true,
|
34537
|
+
persistent: true,
|
34538
|
+
contentClass: 'v-video__overlay-fill'
|
34539
|
+
};
|
34540
|
+
const controlsProps = {
|
34541
|
+
...VVideoControls.filterProps(omit(props, ['variant', 'rounded', 'hideVolume'])),
|
34542
|
+
rounded: Array.isArray(props.rounded) ? props.rounded.at(-1) : props.rounded,
|
34543
|
+
fullscreen: fullscreen.value,
|
34544
|
+
hideVolume: props.hideVolume || props.muted,
|
34545
|
+
hideFullscreen: props.hideFullscreen || !fullscreenEnabled.value,
|
34546
|
+
density: props.density,
|
34547
|
+
variant: props.controlsVariant,
|
34548
|
+
playing: playing.value,
|
34549
|
+
progress: progress.value,
|
34550
|
+
duration: duration.value,
|
34551
|
+
volume: volume.value,
|
34552
|
+
...props.controlsProps
|
34553
|
+
};
|
34554
|
+
const controlsEventHandlers = {
|
34555
|
+
onSkip: v => skipTo(v),
|
34556
|
+
'onClick:fullscreen': () => toggleFullscreen(),
|
34557
|
+
'onUpdate:playing': v => playing.value = v,
|
34558
|
+
'onUpdate:progress': v => skipTo(v),
|
34559
|
+
'onUpdate:volume': v => volume.value = v,
|
34560
|
+
onClick: e => e.stopPropagation()
|
34561
|
+
};
|
34562
|
+
const controlslist = [attrs.controlslist, props.noFullscreen ? 'nofullscreen' : ''].filter(Boolean).join(' ');
|
34563
|
+
const loadingIndicator = createVNode(VProgressCircular, {
|
34564
|
+
"indeterminate": true,
|
34565
|
+
"color": props.color,
|
34566
|
+
"width": "3",
|
34567
|
+
"size": Math.min(100, Number(props.height) / 2 || 50)
|
34568
|
+
}, null);
|
34569
|
+
const overlayPlayIcon = createVNode(VIconBtn, {
|
34570
|
+
"icon": "$play",
|
34571
|
+
"size": "80",
|
34572
|
+
"color": "#fff",
|
34573
|
+
"variant": "outlined",
|
34574
|
+
"iconSize": "50",
|
34575
|
+
"class": "v-video__center-icon"
|
34576
|
+
}, null);
|
34577
|
+
return createElementVNode("div", {
|
34578
|
+
"ref": containerRef,
|
34579
|
+
"class": normalizeClass(['v-video', `v-video--variant-${props.variant}`, `v-video--${state.value}`, {
|
34580
|
+
'v-video--playing': playing.value
|
34581
|
+
}, themeClasses.value, densityClasses.value, roundedContainerClasses.value, props.class]),
|
34582
|
+
"style": normalizeStyle([props.variant === 'background' ? [] : pick(dimensionStyles.value, ['width', 'min-width', 'max-width']), props.style]),
|
34583
|
+
"onKeydown": onKeydown,
|
34584
|
+
"onClick": onClick
|
34585
|
+
}, [createElementVNode("div", {
|
34586
|
+
"class": normalizeClass(['v-video__content', elevationClasses.value]),
|
34587
|
+
"style": normalizeStyle([props.variant === 'background' ? [] : dimensionStyles.value])
|
34588
|
+
}, [(props.eager || triggered.value) && createElementVNode("video", mergeProps({
|
34589
|
+
"key": "video-element",
|
34590
|
+
"class": ['v-video__video', roundedContainerClasses.value]
|
34591
|
+
}, omit(attrs, ['controlslist', 'class', 'style']), {
|
34592
|
+
"controlslist": controlslist,
|
34593
|
+
"autoplay": props.autoplay,
|
34594
|
+
"muted": props.muted,
|
34595
|
+
"playsinline": true,
|
34596
|
+
"ref": videoRef,
|
34597
|
+
"onLoadeddata": onVideoLoaded,
|
34598
|
+
"onPlay": () => playing.value = true,
|
34599
|
+
"onPause": () => playing.value = false,
|
34600
|
+
"onWaiting": () => waiting.value = true,
|
34601
|
+
"onPlaying": () => waiting.value = false,
|
34602
|
+
"onClick": onVideoClick,
|
34603
|
+
"onDblclick": onDoubleClick,
|
34604
|
+
"onTouchend": onTouchend
|
34605
|
+
}), [slots.sources?.() ?? createElementVNode("source", {
|
34606
|
+
"src": props.src,
|
34607
|
+
"type": props.type
|
34608
|
+
}, null)]), props.variant === 'player' && !props.hideOverlay && createVNode(VOverlay, mergeProps({
|
34609
|
+
"key": "pause-overlay",
|
34610
|
+
"modelValue": state.value === 'loaded',
|
34611
|
+
"opacity": "0"
|
34612
|
+
}, overlayProps), {
|
34613
|
+
default: () => [createVNode(VSpacer, null, null), createVNode(MaybeTransition, {
|
34614
|
+
"name": "fade-transition"
|
34615
|
+
}, {
|
34616
|
+
default: () => [!playing.value && overlayPlayIcon]
|
34617
|
+
}), createVNode(VSpacer, null, null)]
|
34618
|
+
}), props.variant === 'player' && !!slots.header ? createElementVNode("div", {
|
34619
|
+
"key": "header",
|
34620
|
+
"class": "v-video__header"
|
34621
|
+
}, [slots.header()]) : '', createVNode(VOverlay, mergeProps({
|
34622
|
+
"key": "poster-overlay",
|
34623
|
+
"modelValue": state.value !== 'loaded',
|
34624
|
+
"transition": posterTransition
|
34625
|
+
}, overlayProps), {
|
34626
|
+
default: () => [createVNode(VImg, {
|
34627
|
+
"cover": true,
|
34628
|
+
"src": props.image
|
34629
|
+
}, {
|
34630
|
+
default: () => [createElementVNode("div", {
|
34631
|
+
"class": normalizeClass(['v-video__overlay-fill', ...roundedContainerClasses.value])
|
34632
|
+
}, [overlayPlayIcon])]
|
34633
|
+
})]
|
34634
|
+
}), createVNode(VOverlay, mergeProps({
|
34635
|
+
"key": "loading-overlay",
|
34636
|
+
"modelValue": state.value === 'loading' || waiting.value,
|
34637
|
+
"opacity": ".1"
|
34638
|
+
}, overlayProps), {
|
34639
|
+
default: () => [loadingIndicator]
|
34640
|
+
})]), createVNode(MaybeTransition, {
|
34641
|
+
"key": "actions",
|
34642
|
+
"transition": props.controlsTransition
|
34643
|
+
}, {
|
34644
|
+
default: () => [showControls && createVNode(VVideoControls, mergeProps({
|
34645
|
+
"ref": controlsRef,
|
34646
|
+
"class": roundedControlsClasses.value
|
34647
|
+
}, controlsProps, controlsEventHandlers), {
|
34648
|
+
default: slots.controls,
|
34649
|
+
prepend: slots.prepend,
|
34650
|
+
append: slots.append
|
34651
|
+
})]
|
34652
|
+
})]);
|
34653
|
+
});
|
34654
|
+
return {
|
34655
|
+
video: videoRef,
|
34656
|
+
...forwardRefs({
|
34657
|
+
skipTo,
|
34658
|
+
toggleFullscreen
|
34659
|
+
}, controlsRef)
|
34660
|
+
};
|
34661
|
+
}
|
34662
|
+
});
|
34663
|
+
|
33185
34664
|
var components = /*#__PURE__*/Object.freeze({
|
33186
34665
|
__proto__: null,
|
33187
34666
|
VAlert: VAlert,
|
@@ -33308,6 +34787,9 @@ var components = /*#__PURE__*/Object.freeze({
|
|
33308
34787
|
VParallax: VParallax,
|
33309
34788
|
VPicker: VPicker,
|
33310
34789
|
VPickerTitle: VPickerTitle,
|
34790
|
+
VPie: VPie,
|
34791
|
+
VPieSegment: VPieSegment,
|
34792
|
+
VPieTooltip: VPieTooltip,
|
33311
34793
|
VProgressCircular: VProgressCircular,
|
33312
34794
|
VProgressLinear: VProgressLinear,
|
33313
34795
|
VPullToRefresh: VPullToRefresh,
|
@@ -33372,6 +34854,9 @@ var components = /*#__PURE__*/Object.freeze({
|
|
33372
34854
|
VTreeviewGroup: VTreeviewGroup,
|
33373
34855
|
VTreeviewItem: VTreeviewItem,
|
33374
34856
|
VValidation: VValidation,
|
34857
|
+
VVideo: VVideo,
|
34858
|
+
VVideoControls: VVideoControls,
|
34859
|
+
VVideoVolume: VVideoVolume,
|
33375
34860
|
VVirtualScroll: VVirtualScroll,
|
33376
34861
|
VWindow: VWindow,
|
33377
34862
|
VWindowItem: VWindowItem
|
@@ -33497,92 +34982,6 @@ const Scroll = {
|
|
33497
34982
|
updated
|
33498
34983
|
};
|
33499
34984
|
|
33500
|
-
// Utilities
|
33501
|
-
|
33502
|
-
// Types
|
33503
|
-
|
33504
|
-
function useDirectiveComponent(component, props) {
|
33505
|
-
const concreteComponent = typeof component === 'string' ? resolveComponent(component) : component;
|
33506
|
-
const hook = mountComponent(concreteComponent, props);
|
33507
|
-
return {
|
33508
|
-
mounted: hook,
|
33509
|
-
updated: hook,
|
33510
|
-
unmounted(el) {
|
33511
|
-
render(null, el);
|
33512
|
-
}
|
33513
|
-
};
|
33514
|
-
}
|
33515
|
-
function mountComponent(component, props) {
|
33516
|
-
return function (el, binding, vnode) {
|
33517
|
-
const _props = typeof props === 'function' ? props(binding) : props;
|
33518
|
-
const text = binding.value?.text ?? binding.value ?? _props?.text;
|
33519
|
-
const value = isObject(binding.value) ? binding.value : {};
|
33520
|
-
|
33521
|
-
// Get the children from the props or directive value, or the element's children
|
33522
|
-
const children = () => text ?? el.textContent;
|
33523
|
-
|
33524
|
-
// If vnode.ctx is the same as the instance, then we're bound to a plain element
|
33525
|
-
// and need to find the nearest parent component instance to inherit provides from
|
33526
|
-
const provides = (vnode.ctx === binding.instance.$ ? findComponentParent(vnode, binding.instance.$)?.provides : vnode.ctx?.provides) ?? binding.instance.$.provides;
|
33527
|
-
const node = h(component, mergeProps(_props, value), children);
|
33528
|
-
node.appContext = Object.assign(Object.create(null), binding.instance.$.appContext, {
|
33529
|
-
provides
|
33530
|
-
});
|
33531
|
-
render(node, el);
|
33532
|
-
};
|
33533
|
-
}
|
33534
|
-
function findComponentParent(vnode, root) {
|
33535
|
-
// Walk the tree from root until we find the child vnode
|
33536
|
-
const stack = new Set();
|
33537
|
-
const walk = children => {
|
33538
|
-
for (const child of children) {
|
33539
|
-
if (!child) continue;
|
33540
|
-
if (child === vnode || child.el && vnode.el && child.el === vnode.el) {
|
33541
|
-
return true;
|
33542
|
-
}
|
33543
|
-
stack.add(child);
|
33544
|
-
let result;
|
33545
|
-
if (child.suspense) {
|
33546
|
-
result = walk([child.ssContent]);
|
33547
|
-
} else if (Array.isArray(child.children)) {
|
33548
|
-
result = walk(child.children);
|
33549
|
-
} else if (child.component?.vnode) {
|
33550
|
-
result = walk([child.component?.subTree]);
|
33551
|
-
}
|
33552
|
-
if (result) {
|
33553
|
-
return result;
|
33554
|
-
}
|
33555
|
-
stack.delete(child);
|
33556
|
-
}
|
33557
|
-
return false;
|
33558
|
-
};
|
33559
|
-
if (!walk([root.subTree])) {
|
33560
|
-
consoleError('Could not find original vnode, component will not inherit provides');
|
33561
|
-
return root;
|
33562
|
-
}
|
33563
|
-
|
33564
|
-
// Return the first component parent
|
33565
|
-
const result = Array.from(stack).reverse();
|
33566
|
-
for (const child of result) {
|
33567
|
-
if (child.component) {
|
33568
|
-
return child.component;
|
33569
|
-
}
|
33570
|
-
}
|
33571
|
-
return root;
|
33572
|
-
}
|
33573
|
-
|
33574
|
-
// Components
|
33575
|
-
|
33576
|
-
// Types
|
33577
|
-
|
33578
|
-
const Tooltip = useDirectiveComponent(VTooltip, binding => {
|
33579
|
-
return {
|
33580
|
-
activator: 'parent',
|
33581
|
-
location: binding.arg?.replace('-', ' '),
|
33582
|
-
text: typeof binding.value === 'boolean' ? undefined : binding.value
|
33583
|
-
};
|
33584
|
-
});
|
33585
|
-
|
33586
34985
|
var directives = /*#__PURE__*/Object.freeze({
|
33587
34986
|
__proto__: null,
|
33588
34987
|
ClickOutside: ClickOutside,
|
@@ -33694,7 +35093,7 @@ function createVuetify$1() {
|
|
33694
35093
|
};
|
33695
35094
|
});
|
33696
35095
|
}
|
33697
|
-
const version$1 = "3.9.2-master.2025-07-
|
35096
|
+
const version$1 = "3.9.2-master.2025-07-25";
|
33698
35097
|
createVuetify$1.version = version$1;
|
33699
35098
|
|
33700
35099
|
// Vue's inject() can only be used in setup
|
@@ -33992,7 +35391,7 @@ var index = /*#__PURE__*/Object.freeze({
|
|
33992
35391
|
|
33993
35392
|
/* eslint-disable local-rules/sort-imports */
|
33994
35393
|
|
33995
|
-
const version = "3.9.2-master.2025-07-
|
35394
|
+
const version = "3.9.2-master.2025-07-25";
|
33996
35395
|
|
33997
35396
|
/* eslint-disable local-rules/sort-imports */
|
33998
35397
|
|