@vuetify/nightly 3.9.2-master.2025-07-23 → 3.9.2-master.2025-07-24
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 +11 -3
- package/dist/_component-variables-labs.sass +2 -1
- package/dist/json/attributes.json +2563 -2299
- package/dist/json/importMap-labs.json +24 -12
- package/dist/json/importMap.json +174 -174
- package/dist/json/tags.json +81 -0
- package/dist/json/web-types.json +5100 -3978
- package/dist/vuetify-labs.cjs +751 -15
- package/dist/vuetify-labs.css +5171 -4837
- package/dist/vuetify-labs.d.ts +6526 -845
- package/dist/vuetify-labs.esm.js +752 -16
- package/dist/vuetify-labs.esm.js.map +1 -1
- package/dist/vuetify-labs.js +751 -15
- package/dist/vuetify-labs.min.css +2 -2
- package/dist/vuetify.cjs +37 -9
- package/dist/vuetify.cjs.map +1 -1
- package/dist/vuetify.css +3169 -3169
- package/dist/vuetify.d.ts +88 -68
- package/dist/vuetify.esm.js +37 -9
- package/dist/vuetify.esm.js.map +1 -1
- package/dist/vuetify.js +37 -9
- package/dist/vuetify.js.map +1 -1
- package/dist/vuetify.min.css +2 -2
- package/dist/vuetify.min.js +264 -263
- 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/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 +1 -1
- package/lib/components/index.js.map +1 -1
- package/lib/entry-bundler.js +1 -1
- package/lib/framework.d.ts +60 -56
- 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/VVideo/VVideo.css +319 -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 +301 -0
- package/lib/labs/VVideo/VVideoControls.d.ts +3524 -0
- package/lib/labs/VVideo/VVideoControls.js +232 -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 +90 -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 +1 -0
- package/lib/labs/components.js +1 -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/index.d.ts +1 -0
- package/lib/util/index.js +1 -0
- package/lib/util/index.js.map +1 -1
- 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-24
|
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, onBeforeUnmount, watch, readonly, onMounted, useId, onDeactivated, onActivated, onScopeDispose, effectScope, toRaw, getCurrentScope, createElementVNode, normalizeStyle, normalizeClass, createVNode, TransitionGroup, Transition, mergeProps, toRefs, toValue, isRef, onBeforeMount, nextTick, withDirectives, vShow, onUpdated, Text, resolveDynamicComponent, toDisplayString, markRaw, Teleport, cloneVNode, createTextVNode, normalizeProps, guardReactiveProps, onUnmounted, onBeforeUpdate, withModifiers, vModelText, resolveComponent, render } from 'vue';
|
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, onBeforeUnmount, watch, readonly, onMounted, useId, onDeactivated, onActivated, onScopeDispose, effectScope, toRaw, getCurrentScope, createElementVNode, normalizeStyle, normalizeClass, createVNode, TransitionGroup, Transition, mergeProps, toRefs, toValue, isRef, onBeforeMount, nextTick, withDirectives, vShow, onUpdated, Text, resolveDynamicComponent, toDisplayString, markRaw, Teleport, cloneVNode, createTextVNode, normalizeProps, guardReactiveProps, onUnmounted, onBeforeUpdate, withModifiers, vModelText, resolveDirective, resolveComponent, render } from 'vue';
|
8
8
|
|
9
9
|
// Types
|
10
10
|
// eslint-disable-line vue/prefer-import-from-vue
|
@@ -1656,6 +1656,10 @@ function useRender(render) {
|
|
1656
1656
|
vm.render = render;
|
1657
1657
|
}
|
1658
1658
|
|
1659
|
+
function formatTime(seconds) {
|
1660
|
+
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(':');
|
1661
|
+
}
|
1662
|
+
|
1659
1663
|
// Utilities
|
1660
1664
|
|
1661
1665
|
// Types
|
@@ -2176,6 +2180,17 @@ var en = {
|
|
2176
2180
|
option: 'Option',
|
2177
2181
|
plus: 'plus',
|
2178
2182
|
shortcut: 'Keyboard shortcut: {0}'
|
2183
|
+
},
|
2184
|
+
video: {
|
2185
|
+
play: 'Play',
|
2186
|
+
pause: 'Pause',
|
2187
|
+
seek: 'Seek',
|
2188
|
+
volume: 'Volume',
|
2189
|
+
showVolume: 'Show volume control',
|
2190
|
+
mute: 'Mute',
|
2191
|
+
unmute: 'Unmute',
|
2192
|
+
enterFullscreen: 'Full screen',
|
2193
|
+
exitFullscreen: 'Exit full screen'
|
2179
2194
|
}
|
2180
2195
|
};
|
2181
2196
|
|
@@ -4258,7 +4273,7 @@ function useDensity(props) {
|
|
4258
4273
|
|
4259
4274
|
// Types
|
4260
4275
|
|
4261
|
-
const allowedVariants$
|
4276
|
+
const allowedVariants$4 = ['elevated', 'flat', 'tonal', 'outlined', 'text', 'plain'];
|
4262
4277
|
function genOverlays(isClickable, name) {
|
4263
4278
|
return createElementVNode(Fragment, null, [isClickable && createElementVNode("span", {
|
4264
4279
|
"key": "overlay",
|
@@ -4273,7 +4288,7 @@ const makeVariantProps = propsFactory({
|
|
4273
4288
|
variant: {
|
4274
4289
|
type: String,
|
4275
4290
|
default: 'elevated',
|
4276
|
-
validator: v => allowedVariants$
|
4291
|
+
validator: v => allowedVariants$4.includes(v)
|
4277
4292
|
}
|
4278
4293
|
}, 'variant');
|
4279
4294
|
function useVariant(props) {
|
@@ -4697,7 +4712,15 @@ const aliases = {
|
|
4697
4712
|
arrowdown: 'mdi-arrow-down',
|
4698
4713
|
arrowleft: 'mdi-arrow-left',
|
4699
4714
|
arrowright: 'mdi-arrow-right',
|
4700
|
-
backspace: 'mdi-backspace'
|
4715
|
+
backspace: 'mdi-backspace',
|
4716
|
+
play: 'mdi-play',
|
4717
|
+
pause: 'mdi-pause',
|
4718
|
+
fullscreen: 'mdi-fullscreen',
|
4719
|
+
fullscreenExit: 'mdi-fullscreen-exit',
|
4720
|
+
volumeHigh: 'mdi-volume-high',
|
4721
|
+
volumeMedium: 'mdi-volume-medium',
|
4722
|
+
volumeLow: 'mdi-volume-low',
|
4723
|
+
volumeOff: 'mdi-volume-variant-off'
|
4701
4724
|
};
|
4702
4725
|
const mdi = {
|
4703
4726
|
// Not using mergeProps here, functional components merge props by default (?)
|
@@ -10827,11 +10850,12 @@ function closeScrollStrategy(data) {
|
|
10827
10850
|
function onScroll(e) {
|
10828
10851
|
data.isActive.value = false;
|
10829
10852
|
}
|
10830
|
-
bindScroll(data.
|
10853
|
+
bindScroll(data.target.value ?? data.contentEl.value, onScroll);
|
10831
10854
|
}
|
10832
10855
|
function blockScrollStrategy(data, props) {
|
10833
10856
|
const offsetParent = data.root.value?.offsetParent;
|
10834
|
-
const
|
10857
|
+
const target = Array.isArray(data.target.value) ? document.elementFromPoint(...data.target.value) : data.target.value;
|
10858
|
+
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
10859
|
const scrollbarWidth = window.innerWidth - document.documentElement.offsetWidth;
|
10836
10860
|
const scrollableParent = (el => hasScrollbar(el) && el)(offsetParent || document.documentElement);
|
10837
10861
|
if (scrollableParent) {
|
@@ -10878,7 +10902,7 @@ function repositionScrollStrategy(data, props, scope) {
|
|
10878
10902
|
}
|
10879
10903
|
ric = (typeof requestIdleCallback === 'undefined' ? cb => cb() : requestIdleCallback)(() => {
|
10880
10904
|
scope.run(() => {
|
10881
|
-
bindScroll(data.
|
10905
|
+
bindScroll(data.target.value ?? data.contentEl.value, e => {
|
10882
10906
|
if (slow) {
|
10883
10907
|
// If the position calculation is slow,
|
10884
10908
|
// defer updates until scrolling is finished.
|
@@ -10903,7 +10927,8 @@ function repositionScrollStrategy(data, props, scope) {
|
|
10903
10927
|
}
|
10904
10928
|
|
10905
10929
|
/** @private */
|
10906
|
-
function bindScroll(
|
10930
|
+
function bindScroll(target, onScroll) {
|
10931
|
+
const el = Array.isArray(target) ? document.elementFromPoint(...target) : target;
|
10907
10932
|
const scrollElements = [document, ...getScrollParents(el)];
|
10908
10933
|
scrollElements.forEach(el => {
|
10909
10934
|
el.addEventListener('scroll', onScroll, {
|
@@ -11585,6 +11610,7 @@ const VOverlay = genericComponent()({
|
|
11585
11610
|
root,
|
11586
11611
|
contentEl,
|
11587
11612
|
targetEl,
|
11613
|
+
target,
|
11588
11614
|
isActive,
|
11589
11615
|
updateLocation
|
11590
11616
|
});
|
@@ -11980,7 +12006,7 @@ const VFieldLabel = genericComponent()({
|
|
11980
12006
|
|
11981
12007
|
// Types
|
11982
12008
|
|
11983
|
-
const allowedVariants$
|
12009
|
+
const allowedVariants$3 = ['underlined', 'outlined', 'filled', 'solo', 'solo-inverted', 'solo-filled', 'plain'];
|
11984
12010
|
const makeVFieldProps = propsFactory({
|
11985
12011
|
appendInnerIcon: IconValue,
|
11986
12012
|
bgColor: String,
|
@@ -12014,7 +12040,7 @@ const makeVFieldProps = propsFactory({
|
|
12014
12040
|
variant: {
|
12015
12041
|
type: String,
|
12016
12042
|
default: 'filled',
|
12017
|
-
validator: v => allowedVariants$
|
12043
|
+
validator: v => allowedVariants$3.includes(v)
|
12018
12044
|
},
|
12019
12045
|
'onClick:clear': EventProp(),
|
12020
12046
|
'onClick:appendInner': EventProp(),
|
@@ -16176,6 +16202,7 @@ const makeSliderProps = propsFactory({
|
|
16176
16202
|
validator: v => ['vertical', 'horizontal'].includes(v)
|
16177
16203
|
},
|
16178
16204
|
reverse: Boolean,
|
16205
|
+
noKeyboard: Boolean,
|
16179
16206
|
...makeRoundedProps(),
|
16180
16207
|
...makeElevationProps({
|
16181
16208
|
elevation: 2
|
@@ -16379,6 +16406,7 @@ const useSlider = _ref => {
|
|
16379
16406
|
min,
|
16380
16407
|
max,
|
16381
16408
|
mousePressed,
|
16409
|
+
noKeyboard: toRef(() => props.noKeyboard),
|
16382
16410
|
numTicks,
|
16383
16411
|
onSliderMousedown,
|
16384
16412
|
onSliderTouchstart,
|
@@ -16431,6 +16459,7 @@ const makeVSliderThumbProps = propsFactory({
|
|
16431
16459
|
default: true
|
16432
16460
|
},
|
16433
16461
|
name: String,
|
16462
|
+
noKeyboard: Boolean,
|
16434
16463
|
...makeComponentProps()
|
16435
16464
|
}, 'VSliderThumb');
|
16436
16465
|
const VSliderThumb = genericComponent()({
|
@@ -16493,6 +16522,7 @@ const VSliderThumb = genericComponent()({
|
|
16493
16522
|
if (step.value) return [1, 2, 3];else return [1, 5, 10];
|
16494
16523
|
});
|
16495
16524
|
function parseKeydown(e, value) {
|
16525
|
+
if (props.noKeyboard) return;
|
16496
16526
|
if (!relevantKeys.includes(e.key)) return;
|
16497
16527
|
e.preventDefault();
|
16498
16528
|
const _step = step.value || 0.1;
|
@@ -16728,7 +16758,8 @@ const VSlider = genericComponent()({
|
|
16728
16758
|
trackContainerRef,
|
16729
16759
|
position,
|
16730
16760
|
hasLabels,
|
16731
|
-
readonly
|
16761
|
+
readonly,
|
16762
|
+
noKeyboard
|
16732
16763
|
} = useSlider({
|
16733
16764
|
props,
|
16734
16765
|
steps,
|
@@ -16804,6 +16835,7 @@ const VSlider = genericComponent()({
|
|
16804
16835
|
"ref": thumbContainerRef,
|
16805
16836
|
"aria-describedby": messagesId.value,
|
16806
16837
|
"focused": isFocused.value,
|
16838
|
+
"noKeyboard": noKeyboard.value,
|
16807
16839
|
"min": min.value,
|
16808
16840
|
"max": max.value,
|
16809
16841
|
"modelValue": model.value,
|
@@ -23880,7 +23912,7 @@ const VExpansionPanel = genericComponent()({
|
|
23880
23912
|
|
23881
23913
|
// Types
|
23882
23914
|
|
23883
|
-
const allowedVariants = ['default', 'accordion', 'inset', 'popout'];
|
23915
|
+
const allowedVariants$2 = ['default', 'accordion', 'inset', 'popout'];
|
23884
23916
|
const makeVExpansionPanelsProps = propsFactory({
|
23885
23917
|
flat: Boolean,
|
23886
23918
|
...makeGroupProps(),
|
@@ -23891,7 +23923,7 @@ const makeVExpansionPanelsProps = propsFactory({
|
|
23891
23923
|
variant: {
|
23892
23924
|
type: String,
|
23893
23925
|
default: 'default',
|
23894
|
-
validator: v => allowedVariants.includes(v)
|
23926
|
+
validator: v => allowedVariants$2.includes(v)
|
23895
23927
|
}
|
23896
23928
|
}, 'VExpansionPanels');
|
23897
23929
|
const VExpansionPanels = genericComponent()({
|
@@ -33182,6 +33214,707 @@ const VHotkey = genericComponent()({
|
|
33182
33214
|
}
|
33183
33215
|
});
|
33184
33216
|
|
33217
|
+
// Types
|
33218
|
+
|
33219
|
+
const makeVVideoVolumeProps = propsFactory({
|
33220
|
+
inline: Boolean,
|
33221
|
+
label: String,
|
33222
|
+
direction: {
|
33223
|
+
type: String,
|
33224
|
+
default: 'vertical'
|
33225
|
+
},
|
33226
|
+
modelValue: {
|
33227
|
+
type: Number,
|
33228
|
+
default: 0
|
33229
|
+
},
|
33230
|
+
menuProps: Object,
|
33231
|
+
sliderProps: Object,
|
33232
|
+
onClick: EventProp(),
|
33233
|
+
...makeComponentProps()
|
33234
|
+
}, 'VVideoVolume');
|
33235
|
+
const VVideoVolume = genericComponent()({
|
33236
|
+
name: 'VVideoVolume',
|
33237
|
+
props: makeVVideoVolumeProps(),
|
33238
|
+
emits: {
|
33239
|
+
'update:modelValue': val => true
|
33240
|
+
},
|
33241
|
+
setup(props, _ref) {
|
33242
|
+
let {
|
33243
|
+
attrs
|
33244
|
+
} = _ref;
|
33245
|
+
const {
|
33246
|
+
t
|
33247
|
+
} = useLocale();
|
33248
|
+
const volume = useProxiedModel(props, 'modelValue');
|
33249
|
+
const volumeIcon = toRef(() => volume.value > 70 ? '$volumeHigh' : volume.value > 40 ? '$volumeMedium' : volume.value > 10 ? '$volumeLow' : '$volumeOff');
|
33250
|
+
const containerRef = ref();
|
33251
|
+
useRender(() => {
|
33252
|
+
const sliderDefaults = {
|
33253
|
+
hideDetails: true,
|
33254
|
+
step: 5,
|
33255
|
+
thumbSize: 16
|
33256
|
+
};
|
33257
|
+
return createElementVNode("div", {
|
33258
|
+
"class": normalizeClass(['v-video-volume', {
|
33259
|
+
'v-video-volume--inline': props.inline
|
33260
|
+
}, props.class]),
|
33261
|
+
"style": normalizeStyle(props.style),
|
33262
|
+
"ref": containerRef
|
33263
|
+
}, [withDirectives(createVNode(VIconBtn, mergeProps({
|
33264
|
+
"icon": volumeIcon.value,
|
33265
|
+
"aria-label": props.label,
|
33266
|
+
"onClick": props.onClick
|
33267
|
+
}, attrs), {
|
33268
|
+
default: () => [createVNode(VIcon, null, null), !props.inline && createVNode(VMenu, {
|
33269
|
+
"offset": "8",
|
33270
|
+
"activator": "parent",
|
33271
|
+
"attach": containerRef.value,
|
33272
|
+
"location": props.menuProps?.location ?? 'top center',
|
33273
|
+
"closeOnContentClick": false
|
33274
|
+
}, {
|
33275
|
+
default: () => [createElementVNode("div", {
|
33276
|
+
"class": normalizeClass(['v-video-volume__menu', `v-video-volume__menu--${props.direction}`])
|
33277
|
+
}, [createVNode(VSlider, mergeProps({
|
33278
|
+
"direction": props.direction,
|
33279
|
+
"aria-label": t('$vuetify.video.volume'),
|
33280
|
+
"modelValue": volume.value,
|
33281
|
+
"onUpdate:modelValue": v => volume.value = v
|
33282
|
+
}, sliderDefaults, props.sliderProps), null)])]
|
33283
|
+
})]
|
33284
|
+
}), [[resolveDirective("tooltip"), props.label, 'top']]), props.inline && createVNode(VSlider, mergeProps({
|
33285
|
+
"class": "v-video-volume-inline__slider",
|
33286
|
+
"minWidth": "50",
|
33287
|
+
"aria-label": t('$vuetify.video.volume'),
|
33288
|
+
"modelValue": volume.value,
|
33289
|
+
"onUpdate:modelValue": v => volume.value = v,
|
33290
|
+
"onKeydown": e => {
|
33291
|
+
e.stopPropagation();
|
33292
|
+
}
|
33293
|
+
}, sliderDefaults, props.sliderProps), null)]);
|
33294
|
+
});
|
33295
|
+
}
|
33296
|
+
});
|
33297
|
+
|
33298
|
+
// Types
|
33299
|
+
|
33300
|
+
const allowedVariants$1 = ['hidden', 'default', 'tube', 'mini'];
|
33301
|
+
const makeVVideoControlsProps = propsFactory({
|
33302
|
+
color: String,
|
33303
|
+
backgroundColor: String,
|
33304
|
+
trackColor: String,
|
33305
|
+
playing: Boolean,
|
33306
|
+
hidePlay: Boolean,
|
33307
|
+
hideVolume: Boolean,
|
33308
|
+
hideFullscreen: Boolean,
|
33309
|
+
fullscreen: Boolean,
|
33310
|
+
floating: Boolean,
|
33311
|
+
splitTime: Boolean,
|
33312
|
+
pills: Boolean,
|
33313
|
+
detached: Boolean,
|
33314
|
+
progress: {
|
33315
|
+
type: Number,
|
33316
|
+
default: 0
|
33317
|
+
},
|
33318
|
+
duration: {
|
33319
|
+
type: Number,
|
33320
|
+
default: 0
|
33321
|
+
},
|
33322
|
+
volume: [Number, String],
|
33323
|
+
variant: {
|
33324
|
+
type: String,
|
33325
|
+
default: 'default',
|
33326
|
+
validator: v => allowedVariants$1.includes(v)
|
33327
|
+
},
|
33328
|
+
volumeProps: Object,
|
33329
|
+
...makeDensityProps(),
|
33330
|
+
...makeElevationProps(),
|
33331
|
+
...makeThemeProps()
|
33332
|
+
}, 'VVideoControls');
|
33333
|
+
const VVideoControls = genericComponent()({
|
33334
|
+
name: 'VVideoControls',
|
33335
|
+
props: makeVVideoControlsProps(),
|
33336
|
+
emits: {
|
33337
|
+
'update:playing': val => true,
|
33338
|
+
'update:progress': val => true,
|
33339
|
+
'update:volume': val => true,
|
33340
|
+
skip: val => true,
|
33341
|
+
'click:fullscreen': () => true
|
33342
|
+
},
|
33343
|
+
setup(props, _ref) {
|
33344
|
+
let {
|
33345
|
+
emit,
|
33346
|
+
slots
|
33347
|
+
} = _ref;
|
33348
|
+
const {
|
33349
|
+
t
|
33350
|
+
} = useLocale();
|
33351
|
+
const {
|
33352
|
+
themeClasses
|
33353
|
+
} = provideTheme(props);
|
33354
|
+
const {
|
33355
|
+
densityClasses
|
33356
|
+
} = useDensity(props);
|
33357
|
+
const {
|
33358
|
+
elevationClasses
|
33359
|
+
} = useElevation(props);
|
33360
|
+
const {
|
33361
|
+
backgroundColorClasses,
|
33362
|
+
backgroundColorStyles
|
33363
|
+
} = useBackgroundColor(() => {
|
33364
|
+
const fallbackBackground = props.detached ? 'surface' : undefined;
|
33365
|
+
return props.backgroundColor ?? fallbackBackground;
|
33366
|
+
});
|
33367
|
+
const playing = useProxiedModel(props, 'playing');
|
33368
|
+
const progress = useProxiedModel(props, 'progress');
|
33369
|
+
const volume = useProxiedModel(props, 'volume', 0, v => Number(v ?? 0));
|
33370
|
+
const lastVolume = shallowRef();
|
33371
|
+
const currentTime = computed(() => {
|
33372
|
+
const secondsElapsed = Math.round(props.progress / 100 * props.duration);
|
33373
|
+
return {
|
33374
|
+
elapsed: formatTime(secondsElapsed),
|
33375
|
+
remaining: formatTime(props.duration - secondsElapsed),
|
33376
|
+
total: formatTime(props.duration)
|
33377
|
+
};
|
33378
|
+
});
|
33379
|
+
const labels = computed(() => {
|
33380
|
+
const playIconLocaleKey = playing.value ? 'pause' : 'play';
|
33381
|
+
const volumeIconLocaleKey = props.volumeProps?.inline ? volume.value ? 'mute' : 'unmute' : 'showVolume';
|
33382
|
+
const fullscreenIconLocaleKey = props.fullscreen ? 'exitFullscreen' : 'enterFullscreen';
|
33383
|
+
return {
|
33384
|
+
seek: t('$vuetify.video.seek'),
|
33385
|
+
volume: t('$vuetify.video.volume'),
|
33386
|
+
playAction: t(`$vuetify.video.${playIconLocaleKey}`),
|
33387
|
+
volumeAction: t(`$vuetify.video.${volumeIconLocaleKey}`),
|
33388
|
+
fullscreenAction: t(`$vuetify.video.${fullscreenIconLocaleKey}`)
|
33389
|
+
};
|
33390
|
+
});
|
33391
|
+
function play() {
|
33392
|
+
playing.value = true;
|
33393
|
+
}
|
33394
|
+
function pause() {
|
33395
|
+
playing.value = false;
|
33396
|
+
}
|
33397
|
+
function skipTo(v) {
|
33398
|
+
progress.value = v;
|
33399
|
+
}
|
33400
|
+
function toggleMuted() {
|
33401
|
+
if (volume.value) {
|
33402
|
+
lastVolume.value = volume.value;
|
33403
|
+
volume.value = 0;
|
33404
|
+
} else {
|
33405
|
+
volume.value = lastVolume.value ?? 100;
|
33406
|
+
}
|
33407
|
+
}
|
33408
|
+
function toggleFullscreen() {
|
33409
|
+
emit('click:fullscreen');
|
33410
|
+
}
|
33411
|
+
useRender(() => {
|
33412
|
+
const sizes = props.pills ? [42, 36, 30] : [32, 28, 24];
|
33413
|
+
const innerDefaults = {
|
33414
|
+
VIconBtn: {
|
33415
|
+
size: props.density === 'compact' ? sizes[2] : props.density === 'comfortable' ? sizes[1] : sizes[0],
|
33416
|
+
iconSize: props.density === 'compact' ? 20 : props.density === 'comfortable' ? 24 : 26,
|
33417
|
+
variant: 'text',
|
33418
|
+
color: props.color
|
33419
|
+
},
|
33420
|
+
VSlider: {
|
33421
|
+
thumbSize: props.variant === 'tube' ? 10 : 16,
|
33422
|
+
hideDetails: true
|
33423
|
+
}
|
33424
|
+
};
|
33425
|
+
const regularBtnSize = innerDefaults.VIconBtn.size;
|
33426
|
+
const playBtnSize = props.pills ? regularBtnSize + 8 : regularBtnSize;
|
33427
|
+
const pillClasses = ['v-video-control__pill', props.pills ? elevationClasses.value : []];
|
33428
|
+
const slotProps = {
|
33429
|
+
play,
|
33430
|
+
pause,
|
33431
|
+
playing: playing.value,
|
33432
|
+
progress: progress.value,
|
33433
|
+
currentTime: currentTime.value,
|
33434
|
+
skipTo,
|
33435
|
+
volume,
|
33436
|
+
toggleMuted,
|
33437
|
+
fullscreen: props.fullscreen,
|
33438
|
+
toggleFullscreen,
|
33439
|
+
labels: labels.value
|
33440
|
+
};
|
33441
|
+
return createElementVNode("div", {
|
33442
|
+
"class": normalizeClass(['v-video-controls', `v-video-controls--variant-${props.variant}`, {
|
33443
|
+
'v-video-controls--pills': props.pills
|
33444
|
+
}, {
|
33445
|
+
'v-video-controls--detached': props.detached
|
33446
|
+
}, {
|
33447
|
+
'v-video-controls--floating': props.floating
|
33448
|
+
}, {
|
33449
|
+
'v-video-controls--split-time': props.splitTime
|
33450
|
+
}, backgroundColorClasses.value, props.detached && !props.pills ? elevationClasses.value : [], densityClasses.value, themeClasses.value]),
|
33451
|
+
"style": normalizeStyle([backgroundColorStyles.value, {
|
33452
|
+
'--v-video-controls-pill-height': `${regularBtnSize}px`
|
33453
|
+
}])
|
33454
|
+
}, [createVNode(VDefaultsProvider, {
|
33455
|
+
"defaults": innerDefaults
|
33456
|
+
}, {
|
33457
|
+
default: () => [slots.default?.(slotProps) ?? createElementVNode(Fragment, null, [props.variant !== 'mini' && createElementVNode(Fragment, null, [!props.hidePlay && createElementVNode("div", {
|
33458
|
+
"class": normalizeClass([pillClasses, 'v-video__action-play'])
|
33459
|
+
}, [withDirectives(createVNode(VIconBtn, {
|
33460
|
+
"icon": playing.value ? '$pause' : '$play',
|
33461
|
+
"size": playBtnSize,
|
33462
|
+
"aria-label": labels.value.playAction,
|
33463
|
+
"onClick": () => playing.value = !playing.value
|
33464
|
+
}, null), [[resolveDirective("tooltip"), labels.value.playAction, 'top']])]), slots.prepend && createElementVNode("div", {
|
33465
|
+
"class": normalizeClass(pillClasses)
|
33466
|
+
}, [slots.prepend(slotProps)]), props.splitTime ? createElementVNode("span", {
|
33467
|
+
"class": normalizeClass([pillClasses, 'v-video__time'])
|
33468
|
+
}, [currentTime.value.elapsed]) : props.variant !== 'default' ? createElementVNode("span", {
|
33469
|
+
"class": normalizeClass([pillClasses, 'v-video__time'])
|
33470
|
+
}, [currentTime.value.elapsed, createTextVNode(" / "), currentTime.value.total]) : '', createVNode(VSlider, {
|
33471
|
+
"modelValue": props.progress,
|
33472
|
+
"noKeyboard": true,
|
33473
|
+
"color": props.trackColor ?? props.color,
|
33474
|
+
"trackColor": props.variant === 'tube' ? 'white' : undefined,
|
33475
|
+
"class": "v-video__track",
|
33476
|
+
"thumbLabel": "always",
|
33477
|
+
"aria-label": labels.value.seek,
|
33478
|
+
"onUpdate:modelValue": skipTo
|
33479
|
+
}, {
|
33480
|
+
'thumb-label': () => currentTime.value.elapsed
|
33481
|
+
}), props.variant === 'tube' && createVNode(VSpacer, null, null), props.splitTime ? createElementVNode("span", {
|
33482
|
+
"class": normalizeClass([pillClasses, 'v-video__time'])
|
33483
|
+
}, [currentTime.value.remaining]) : '']), props.variant === 'mini' && createElementVNode(Fragment, null, [createVNode(VSpacer, null, null), slots.prepend && createElementVNode("div", {
|
33484
|
+
"class": normalizeClass(pillClasses)
|
33485
|
+
}, [slots.prepend(slotProps)]), !props.hidePlay && createElementVNode("div", {
|
33486
|
+
"class": normalizeClass([pillClasses, 'v-video__action-play'])
|
33487
|
+
}, [withDirectives(createVNode(VIconBtn, {
|
33488
|
+
"icon": playing.value ? '$pause' : '$play',
|
33489
|
+
"size": playBtnSize,
|
33490
|
+
"aria-label": labels.value.playAction,
|
33491
|
+
"onClick": () => playing.value = !playing.value
|
33492
|
+
}, null), [[resolveDirective("tooltip"), labels.value.playAction, 'top']])])]), (!props.hideVolume || !props.hideFullscreen || slots.append) && createElementVNode("div", {
|
33493
|
+
"class": normalizeClass(pillClasses)
|
33494
|
+
}, [!props.hideVolume && createVNode(VVideoVolume, mergeProps({
|
33495
|
+
"key": "volume-control",
|
33496
|
+
"sliderProps": {
|
33497
|
+
color: props.color
|
33498
|
+
},
|
33499
|
+
"modelValue": volume.value,
|
33500
|
+
"label": labels.value.volumeAction,
|
33501
|
+
"onUpdate:modelValue": v => volume.value = v,
|
33502
|
+
"onClick": () => props.volumeProps?.inline && toggleMuted()
|
33503
|
+
}, props.volumeProps), null), slots.append?.(slotProps), !props.hideFullscreen && withDirectives(createVNode(VIconBtn, {
|
33504
|
+
"icon": props.fullscreen ? '$fullscreenExit' : '$fullscreen',
|
33505
|
+
"aria-label": labels.value.fullscreenAction,
|
33506
|
+
"onClick": toggleFullscreen
|
33507
|
+
}, null), [[resolveDirective("tooltip"), labels.value.fullscreenAction, 'top']])]), props.variant === 'mini' && createVNode(VSpacer, null, null)])]
|
33508
|
+
})]);
|
33509
|
+
});
|
33510
|
+
return {
|
33511
|
+
toggleMuted
|
33512
|
+
};
|
33513
|
+
}
|
33514
|
+
});
|
33515
|
+
|
33516
|
+
// Types
|
33517
|
+
|
33518
|
+
const allowedVariants = ['background', 'player'];
|
33519
|
+
const makeVVideoProps = propsFactory({
|
33520
|
+
autoplay: Boolean,
|
33521
|
+
muted: Boolean,
|
33522
|
+
eager: Boolean,
|
33523
|
+
src: String,
|
33524
|
+
type: String,
|
33525
|
+
// e.g. video/mp4
|
33526
|
+
image: String,
|
33527
|
+
hideOverlay: Boolean,
|
33528
|
+
noFullscreen: Boolean,
|
33529
|
+
startAt: [Number, String],
|
33530
|
+
variant: {
|
33531
|
+
type: String,
|
33532
|
+
default: 'player',
|
33533
|
+
validator: v => allowedVariants.includes(v)
|
33534
|
+
},
|
33535
|
+
controlsTransition: {
|
33536
|
+
type: [Boolean, String, Object],
|
33537
|
+
component: VFadeTransition
|
33538
|
+
},
|
33539
|
+
controlsVariant: {
|
33540
|
+
type: String,
|
33541
|
+
default: 'default'
|
33542
|
+
},
|
33543
|
+
controlsProps: {
|
33544
|
+
type: Object
|
33545
|
+
},
|
33546
|
+
rounded: [Boolean, Number, String, Array],
|
33547
|
+
...makeComponentProps(),
|
33548
|
+
...makeDensityProps(),
|
33549
|
+
...makeDimensionProps(),
|
33550
|
+
...makeThemeProps(),
|
33551
|
+
...omit(makeVVideoControlsProps(), ['fullscreen', 'variant'])
|
33552
|
+
}, 'VVideo');
|
33553
|
+
const VVideo = genericComponent()({
|
33554
|
+
name: 'VVideo',
|
33555
|
+
inheritAttrs: false,
|
33556
|
+
props: makeVVideoProps(),
|
33557
|
+
emits: {
|
33558
|
+
loaded: element => true,
|
33559
|
+
'update:playing': val => true,
|
33560
|
+
'update:progress': val => true,
|
33561
|
+
'update:volume': val => true
|
33562
|
+
},
|
33563
|
+
setup(props, _ref) {
|
33564
|
+
let {
|
33565
|
+
attrs,
|
33566
|
+
emit,
|
33567
|
+
slots
|
33568
|
+
} = _ref;
|
33569
|
+
const {
|
33570
|
+
themeClasses
|
33571
|
+
} = provideTheme(props);
|
33572
|
+
const {
|
33573
|
+
densityClasses
|
33574
|
+
} = useDensity(props);
|
33575
|
+
const {
|
33576
|
+
dimensionStyles
|
33577
|
+
} = useDimension(props);
|
33578
|
+
const {
|
33579
|
+
elevationClasses
|
33580
|
+
} = useElevation(props);
|
33581
|
+
const {
|
33582
|
+
ssr
|
33583
|
+
} = useDisplay();
|
33584
|
+
const roundedForContainer = toRef(() => Array.isArray(props.rounded) ? props.rounded[0] : props.rounded);
|
33585
|
+
const roundedForControls = toRef(() => Array.isArray(props.rounded) ? props.rounded.at(-1) : props.rounded ?? false);
|
33586
|
+
const {
|
33587
|
+
roundedClasses: roundedContainerClasses
|
33588
|
+
} = useRounded(roundedForContainer);
|
33589
|
+
const {
|
33590
|
+
roundedClasses: roundedControlsClasses
|
33591
|
+
} = useRounded(roundedForControls);
|
33592
|
+
const containerRef = ref();
|
33593
|
+
const videoRef = ref();
|
33594
|
+
const controlsRef = ref();
|
33595
|
+
const playing = useProxiedModel(props, 'playing');
|
33596
|
+
const progress = useProxiedModel(props, 'progress');
|
33597
|
+
const volume = useProxiedModel(props, 'volume', 0, v => Number(v ?? 0));
|
33598
|
+
const fullscreen = shallowRef(false);
|
33599
|
+
const waiting = shallowRef(false);
|
33600
|
+
const triggered = shallowRef(false);
|
33601
|
+
const startAfterLoad = shallowRef(false);
|
33602
|
+
const state = shallowRef(props.autoplay ? 'loading' : 'idle');
|
33603
|
+
const duration = shallowRef(0);
|
33604
|
+
const fullscreenEnabled = toRef(() => !props.noFullscreen && !String(attrs.controlsList ?? '').includes('nofullscreen'));
|
33605
|
+
function onTimeupdate() {
|
33606
|
+
const {
|
33607
|
+
currentTime,
|
33608
|
+
duration
|
33609
|
+
} = videoRef.value;
|
33610
|
+
progress.value = duration === 0 ? 0 : 100 * currentTime / duration;
|
33611
|
+
}
|
33612
|
+
async function onTriggered() {
|
33613
|
+
await nextTick();
|
33614
|
+
if (!videoRef.value) return;
|
33615
|
+
videoRef.value.addEventListener('timeupdate', onTimeupdate);
|
33616
|
+
videoRef.value.volume = volume.value / 100;
|
33617
|
+
if (state.value !== 'loaded') {
|
33618
|
+
state.value = 'loading';
|
33619
|
+
}
|
33620
|
+
}
|
33621
|
+
function onVideoLoaded() {
|
33622
|
+
state.value = 'loaded';
|
33623
|
+
duration.value = videoRef.value.duration;
|
33624
|
+
const startTime = Number(props.startAt ?? 0);
|
33625
|
+
if (startTime && startTime <= duration.value) {
|
33626
|
+
videoRef.value.currentTime = startTime;
|
33627
|
+
progress.value = duration.value === 0 ? 0 : 100 * startTime / duration.value;
|
33628
|
+
}
|
33629
|
+
if (startAfterLoad.value) {
|
33630
|
+
setTimeout(() => playing.value = true, 100);
|
33631
|
+
}
|
33632
|
+
emit('loaded', videoRef.value);
|
33633
|
+
}
|
33634
|
+
function onClick() {
|
33635
|
+
if (state.value !== 'loaded') {
|
33636
|
+
triggered.value = true;
|
33637
|
+
startAfterLoad.value = !startAfterLoad.value;
|
33638
|
+
}
|
33639
|
+
}
|
33640
|
+
function onKeydown(e) {
|
33641
|
+
if (!videoRef.value || e.ctrlKey) return;
|
33642
|
+
if (e.key.startsWith('Arrow')) {
|
33643
|
+
e.preventDefault();
|
33644
|
+
}
|
33645
|
+
switch (true) {
|
33646
|
+
case e.key === ' ':
|
33647
|
+
{
|
33648
|
+
if (!['A', 'BUTTON'].includes(e.target?.tagName)) {
|
33649
|
+
e.preventDefault();
|
33650
|
+
playing.value = !playing.value;
|
33651
|
+
}
|
33652
|
+
break;
|
33653
|
+
}
|
33654
|
+
case e.key === 'ArrowRight':
|
33655
|
+
{
|
33656
|
+
const step = 10 * (e.shiftKey ? 6 : 1);
|
33657
|
+
videoRef.value.currentTime = Math.min(videoRef.value.currentTime + step, duration.value);
|
33658
|
+
// TODO: show skip indicator
|
33659
|
+
break;
|
33660
|
+
}
|
33661
|
+
case e.key === 'ArrowLeft':
|
33662
|
+
{
|
33663
|
+
const step = 10 * (e.shiftKey ? 6 : 1);
|
33664
|
+
videoRef.value.currentTime = Math.max(videoRef.value.currentTime - step, 0);
|
33665
|
+
// TODO: show skip indicator
|
33666
|
+
break;
|
33667
|
+
}
|
33668
|
+
case createRange(10).map(String).includes(e.key):
|
33669
|
+
{
|
33670
|
+
skipTo(Number(e.key) * 10);
|
33671
|
+
break;
|
33672
|
+
}
|
33673
|
+
case e.key === 'ArrowUp':
|
33674
|
+
{
|
33675
|
+
volume.value = Math.min(volume.value + 10, 100);
|
33676
|
+
// TODO: show volume change indicator
|
33677
|
+
break;
|
33678
|
+
}
|
33679
|
+
case e.key === 'ArrowDown':
|
33680
|
+
{
|
33681
|
+
volume.value = Math.max(volume.value - 10, 0);
|
33682
|
+
// TODO: show volume change indicator
|
33683
|
+
break;
|
33684
|
+
}
|
33685
|
+
case e.key === 'm':
|
33686
|
+
{
|
33687
|
+
controlsRef.value?.toggleMuted();
|
33688
|
+
break;
|
33689
|
+
}
|
33690
|
+
case e.key === 'f':
|
33691
|
+
{
|
33692
|
+
toggleFullscreen();
|
33693
|
+
break;
|
33694
|
+
}
|
33695
|
+
}
|
33696
|
+
}
|
33697
|
+
function skipTo(v) {
|
33698
|
+
if (!videoRef.value) return;
|
33699
|
+
progress.value = v;
|
33700
|
+
videoRef.value.currentTime = duration.value * v / 100;
|
33701
|
+
}
|
33702
|
+
watch(() => props.src, v => {
|
33703
|
+
progress.value = 0;
|
33704
|
+
});
|
33705
|
+
watch(playing, v => {
|
33706
|
+
if (!videoRef.value) return;
|
33707
|
+
if (v) {
|
33708
|
+
videoRef.value.play();
|
33709
|
+
} else {
|
33710
|
+
videoRef.value.pause();
|
33711
|
+
}
|
33712
|
+
});
|
33713
|
+
watch(volume, v => {
|
33714
|
+
if (!videoRef.value) return;
|
33715
|
+
videoRef.value.volume = v / 100;
|
33716
|
+
});
|
33717
|
+
watch(triggered, () => onTriggered(), {
|
33718
|
+
once: true
|
33719
|
+
});
|
33720
|
+
watch(() => props.eager, v => v && (triggered.value = true), {
|
33721
|
+
immediate: true
|
33722
|
+
});
|
33723
|
+
onMounted(() => {
|
33724
|
+
if (props.autoplay && !ssr) {
|
33725
|
+
triggered.value = true;
|
33726
|
+
startAfterLoad.value = true;
|
33727
|
+
}
|
33728
|
+
});
|
33729
|
+
onBeforeUnmount(() => {
|
33730
|
+
videoRef.value?.removeEventListener('timeupdate', onTimeupdate);
|
33731
|
+
});
|
33732
|
+
function focusSlider() {
|
33733
|
+
const container = videoRef.value?.closest('.v-video');
|
33734
|
+
const innerSlider = container?.querySelector('[role="slider"]');
|
33735
|
+
innerSlider?.focus();
|
33736
|
+
}
|
33737
|
+
function fullscreenExitShortcut(e) {
|
33738
|
+
if (['ESC', 'f'].includes(e.key)) {
|
33739
|
+
toggleFullscreen();
|
33740
|
+
document.body.removeEventListener('keydown', fullscreenExitShortcut);
|
33741
|
+
}
|
33742
|
+
}
|
33743
|
+
async function toggleFullscreen() {
|
33744
|
+
if (!fullscreenEnabled.value || !document.fullscreenEnabled) {
|
33745
|
+
return;
|
33746
|
+
}
|
33747
|
+
if (document.fullscreenElement) {
|
33748
|
+
document.exitFullscreen();
|
33749
|
+
onFullscreenExit();
|
33750
|
+
} else {
|
33751
|
+
await containerRef.value?.requestFullscreen();
|
33752
|
+
document.body.addEventListener('keydown', fullscreenExitShortcut);
|
33753
|
+
document.addEventListener('fullscreenchange', onFullscreenExit);
|
33754
|
+
fullscreen.value = true;
|
33755
|
+
}
|
33756
|
+
}
|
33757
|
+
function onFullscreenExit() {
|
33758
|
+
// event fires with a delay after requestFullscreen(), ignore first run
|
33759
|
+
if (document.fullscreenElement) return;
|
33760
|
+
focusSlider();
|
33761
|
+
fullscreen.value = false;
|
33762
|
+
document.body.removeEventListener('keydown', fullscreenExitShortcut);
|
33763
|
+
document.removeEventListener('fullscreenchange', onFullscreenExit);
|
33764
|
+
}
|
33765
|
+
function onVideoClick(e) {
|
33766
|
+
e.preventDefault();
|
33767
|
+
if (state.value === 'loaded') {
|
33768
|
+
playing.value = !playing.value;
|
33769
|
+
focusSlider();
|
33770
|
+
}
|
33771
|
+
}
|
33772
|
+
function onDoubleClick(e) {
|
33773
|
+
e.preventDefault();
|
33774
|
+
toggleFullscreen();
|
33775
|
+
}
|
33776
|
+
let lastTap = 0;
|
33777
|
+
function onTouchend(e) {
|
33778
|
+
const now = performance.now();
|
33779
|
+
if (now - lastTap < 500) {
|
33780
|
+
e.preventDefault();
|
33781
|
+
toggleFullscreen();
|
33782
|
+
} else {
|
33783
|
+
lastTap = now;
|
33784
|
+
}
|
33785
|
+
}
|
33786
|
+
useRender(() => {
|
33787
|
+
const showControls = state.value === 'loaded' && props.variant === 'player' && props.controlsVariant !== 'hidden';
|
33788
|
+
const posterTransition = props.variant === 'background' ? 'poster-fade-out' : 'fade-transition';
|
33789
|
+
const overlayProps = {
|
33790
|
+
contained: true,
|
33791
|
+
persistent: true,
|
33792
|
+
contentClass: 'v-video__overlay-fill'
|
33793
|
+
};
|
33794
|
+
const controlsProps = {
|
33795
|
+
...VVideoControls.filterProps(omit(props, ['variant', 'rounded', 'hideVolume'])),
|
33796
|
+
rounded: Array.isArray(props.rounded) ? props.rounded.at(-1) : props.rounded,
|
33797
|
+
fullscreen: fullscreen.value,
|
33798
|
+
hideVolume: props.hideVolume || props.muted,
|
33799
|
+
hideFullscreen: props.hideFullscreen || !fullscreenEnabled.value,
|
33800
|
+
density: props.density,
|
33801
|
+
variant: props.controlsVariant,
|
33802
|
+
playing: playing.value,
|
33803
|
+
progress: progress.value,
|
33804
|
+
duration: duration.value,
|
33805
|
+
volume: volume.value,
|
33806
|
+
...props.controlsProps
|
33807
|
+
};
|
33808
|
+
const controlsEventHandlers = {
|
33809
|
+
onSkip: v => skipTo(v),
|
33810
|
+
'onClick:fullscreen': () => toggleFullscreen(),
|
33811
|
+
'onUpdate:playing': v => playing.value = v,
|
33812
|
+
'onUpdate:progress': v => skipTo(v),
|
33813
|
+
'onUpdate:volume': v => volume.value = v,
|
33814
|
+
onClick: e => e.stopPropagation()
|
33815
|
+
};
|
33816
|
+
const controlslist = [attrs.controlslist, props.noFullscreen ? 'nofullscreen' : ''].filter(Boolean).join(' ');
|
33817
|
+
const loadingIndicator = createVNode(VProgressCircular, {
|
33818
|
+
"indeterminate": true,
|
33819
|
+
"color": props.color,
|
33820
|
+
"width": "3",
|
33821
|
+
"size": Math.min(100, Number(props.height) / 2 || 50)
|
33822
|
+
}, null);
|
33823
|
+
const overlayPlayIcon = createVNode(VIconBtn, {
|
33824
|
+
"icon": "$play",
|
33825
|
+
"size": "80",
|
33826
|
+
"color": "#fff",
|
33827
|
+
"variant": "outlined",
|
33828
|
+
"iconSize": "50",
|
33829
|
+
"class": "v-video__center-icon"
|
33830
|
+
}, null);
|
33831
|
+
return createElementVNode("div", {
|
33832
|
+
"ref": containerRef,
|
33833
|
+
"class": normalizeClass(['v-video', `v-video--variant-${props.variant}`, `v-video--${state.value}`, {
|
33834
|
+
'v-video--playing': playing.value
|
33835
|
+
}, themeClasses.value, densityClasses.value, roundedContainerClasses.value, props.class]),
|
33836
|
+
"style": normalizeStyle([props.variant === 'background' ? [] : pick(dimensionStyles.value, ['width', 'min-width', 'max-width']), props.style]),
|
33837
|
+
"onKeydown": onKeydown,
|
33838
|
+
"onClick": onClick
|
33839
|
+
}, [createElementVNode("div", {
|
33840
|
+
"class": normalizeClass(['v-video__content', elevationClasses.value]),
|
33841
|
+
"style": normalizeStyle([props.variant === 'background' ? [] : dimensionStyles.value])
|
33842
|
+
}, [(props.eager || triggered.value) && createElementVNode("video", mergeProps({
|
33843
|
+
"key": "video-element",
|
33844
|
+
"class": ['v-video__video', roundedContainerClasses.value]
|
33845
|
+
}, omit(attrs, ['controlslist', 'class', 'style']), {
|
33846
|
+
"controlslist": controlslist,
|
33847
|
+
"autoplay": props.autoplay,
|
33848
|
+
"muted": props.muted,
|
33849
|
+
"playsinline": true,
|
33850
|
+
"ref": videoRef,
|
33851
|
+
"onLoadeddata": onVideoLoaded,
|
33852
|
+
"onPlay": () => playing.value = true,
|
33853
|
+
"onPause": () => playing.value = false,
|
33854
|
+
"onWaiting": () => waiting.value = true,
|
33855
|
+
"onPlaying": () => waiting.value = false,
|
33856
|
+
"onClick": onVideoClick,
|
33857
|
+
"onDblclick": onDoubleClick,
|
33858
|
+
"onTouchend": onTouchend
|
33859
|
+
}), [slots.sources?.() ?? createElementVNode("source", {
|
33860
|
+
"src": props.src,
|
33861
|
+
"type": props.type
|
33862
|
+
}, null)]), props.variant === 'player' && !props.hideOverlay && createVNode(VOverlay, mergeProps({
|
33863
|
+
"key": "pause-overlay",
|
33864
|
+
"modelValue": state.value === 'loaded',
|
33865
|
+
"opacity": "0"
|
33866
|
+
}, overlayProps), {
|
33867
|
+
default: () => [createVNode(VSpacer, null, null), createVNode(MaybeTransition, {
|
33868
|
+
"name": "fade-transition"
|
33869
|
+
}, {
|
33870
|
+
default: () => [!playing.value && overlayPlayIcon]
|
33871
|
+
}), createVNode(VSpacer, null, null)]
|
33872
|
+
}), props.variant === 'player' && !!slots.header ? createElementVNode("div", {
|
33873
|
+
"key": "header",
|
33874
|
+
"class": "v-video__header"
|
33875
|
+
}, [slots.header()]) : '', createVNode(VOverlay, mergeProps({
|
33876
|
+
"key": "poster-overlay",
|
33877
|
+
"modelValue": state.value !== 'loaded',
|
33878
|
+
"transition": posterTransition
|
33879
|
+
}, overlayProps), {
|
33880
|
+
default: () => [createVNode(VImg, {
|
33881
|
+
"cover": true,
|
33882
|
+
"src": props.image
|
33883
|
+
}, {
|
33884
|
+
default: () => [createElementVNode("div", {
|
33885
|
+
"class": normalizeClass(['v-video__overlay-fill', ...roundedContainerClasses.value])
|
33886
|
+
}, [overlayPlayIcon])]
|
33887
|
+
})]
|
33888
|
+
}), createVNode(VOverlay, mergeProps({
|
33889
|
+
"key": "loading-overlay",
|
33890
|
+
"modelValue": state.value === 'loading' || waiting.value,
|
33891
|
+
"opacity": ".1"
|
33892
|
+
}, overlayProps), {
|
33893
|
+
default: () => [loadingIndicator]
|
33894
|
+
})]), createVNode(MaybeTransition, {
|
33895
|
+
"key": "actions",
|
33896
|
+
"transition": props.controlsTransition
|
33897
|
+
}, {
|
33898
|
+
default: () => [showControls && createVNode(VVideoControls, mergeProps({
|
33899
|
+
"ref": controlsRef,
|
33900
|
+
"class": roundedControlsClasses.value
|
33901
|
+
}, controlsProps, controlsEventHandlers), {
|
33902
|
+
default: slots.controls,
|
33903
|
+
prepend: slots.prepend,
|
33904
|
+
append: slots.append
|
33905
|
+
})]
|
33906
|
+
})]);
|
33907
|
+
});
|
33908
|
+
return {
|
33909
|
+
video: videoRef,
|
33910
|
+
...forwardRefs({
|
33911
|
+
skipTo,
|
33912
|
+
toggleFullscreen
|
33913
|
+
}, controlsRef)
|
33914
|
+
};
|
33915
|
+
}
|
33916
|
+
});
|
33917
|
+
|
33185
33918
|
var components = /*#__PURE__*/Object.freeze({
|
33186
33919
|
__proto__: null,
|
33187
33920
|
VAlert: VAlert,
|
@@ -33372,6 +34105,9 @@ var components = /*#__PURE__*/Object.freeze({
|
|
33372
34105
|
VTreeviewGroup: VTreeviewGroup,
|
33373
34106
|
VTreeviewItem: VTreeviewItem,
|
33374
34107
|
VValidation: VValidation,
|
34108
|
+
VVideo: VVideo,
|
34109
|
+
VVideoControls: VVideoControls,
|
34110
|
+
VVideoVolume: VVideoVolume,
|
33375
34111
|
VVirtualScroll: VVirtualScroll,
|
33376
34112
|
VWindow: VWindow,
|
33377
34113
|
VWindowItem: VWindowItem
|
@@ -33694,7 +34430,7 @@ function createVuetify$1() {
|
|
33694
34430
|
};
|
33695
34431
|
});
|
33696
34432
|
}
|
33697
|
-
const version$1 = "3.9.2-master.2025-07-
|
34433
|
+
const version$1 = "3.9.2-master.2025-07-24";
|
33698
34434
|
createVuetify$1.version = version$1;
|
33699
34435
|
|
33700
34436
|
// Vue's inject() can only be used in setup
|
@@ -33992,7 +34728,7 @@ var index = /*#__PURE__*/Object.freeze({
|
|
33992
34728
|
|
33993
34729
|
/* eslint-disable local-rules/sort-imports */
|
33994
34730
|
|
33995
|
-
const version = "3.9.2-master.2025-07-
|
34731
|
+
const version = "3.9.2-master.2025-07-24";
|
33996
34732
|
|
33997
34733
|
/* eslint-disable local-rules/sort-imports */
|
33998
34734
|
|