@nuxt/scripts 0.3.3 → 0.3.5
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/dist/client/200.html +5 -5
- package/dist/client/404.html +5 -5
- package/dist/client/_nuxt/{B-3dzucQ.js → B-VcbH-p.js} +1 -1
- package/dist/client/_nuxt/{CmaBlQfy.js → Da7ySKCR.js} +1 -1
- package/dist/client/_nuxt/Duz6zLk8.js +31 -0
- package/dist/client/_nuxt/builds/latest.json +1 -1
- package/dist/client/_nuxt/builds/meta/ce1e7798-e27a-4397-9734-cd67ecbfb4ca.json +1 -0
- package/dist/client/_nuxt/{D-T6Aidr.js → enpXmyCL.js} +1 -1
- package/dist/client/index.html +5 -5
- package/dist/module.d.mts +2 -2
- package/dist/module.d.ts +2 -2
- package/dist/module.json +1 -1
- package/dist/module.mjs +67 -36
- package/dist/registry.d.mts +2 -2
- package/dist/registry.d.ts +2 -2
- package/dist/registry.mjs +16 -16
- package/dist/runtime/components/ScriptGoogleMaps.vue +264 -0
- package/dist/runtime/components/ScriptLemonSqueezyButton.vue +42 -0
- package/dist/runtime/components/ScriptLoadingIndicator.vue +15 -0
- package/dist/runtime/components/ScriptStripePricingTable.vue +47 -0
- package/dist/runtime/components/ScriptVimeoPlayer.vue +243 -0
- package/dist/runtime/components/ScriptYouTubePlayer.vue +160 -0
- package/dist/runtime/composables/useElementScriptTrigger.d.ts +3 -3
- package/dist/runtime/composables/useElementScriptTrigger.mjs +41 -5
- package/dist/runtime/composables/useScript.d.ts +1 -1
- package/dist/runtime/composables/useScript.mjs +7 -6
- package/dist/runtime/registry/cloudflare-web-analytics.mjs +2 -2
- package/dist/runtime/registry/fathom-analytics.d.ts +2 -2
- package/dist/runtime/registry/fathom-analytics.mjs +2 -2
- package/dist/runtime/registry/google-analytics.d.ts +4 -2
- package/dist/runtime/registry/google-analytics.mjs +13 -8
- package/dist/runtime/registry/google-maps.mjs +2 -2
- package/dist/runtime/registry/google-tag-manager.mjs +2 -2
- package/dist/runtime/registry/hotjar.mjs +4 -4
- package/dist/runtime/registry/intercom.mjs +3 -8
- package/dist/runtime/registry/lemon-squeezy.d.ts +1 -2
- package/dist/runtime/registry/lemon-squeezy.mjs +3 -6
- package/dist/runtime/registry/matomo-analytics.mjs +11 -10
- package/dist/runtime/registry/{facebook-pixel.d.ts → meta-pixel.d.ts} +7 -7
- package/dist/runtime/registry/{facebook-pixel.mjs → meta-pixel.mjs} +9 -7
- package/dist/runtime/registry/npm.mjs +2 -2
- package/dist/runtime/registry/plausible-analytics.mjs +2 -2
- package/dist/runtime/registry/segment.d.ts +22 -9
- package/dist/runtime/registry/segment.mjs +43 -21
- package/dist/runtime/registry/stripe.mjs +4 -4
- package/dist/runtime/registry/vimeo-player.d.ts +6 -6
- package/dist/runtime/registry/vimeo-player.mjs +30 -34
- package/dist/runtime/registry/x-pixel.mjs +17 -13
- package/dist/runtime/registry/youtube-player.d.ts +14 -0
- package/dist/runtime/registry/{youtube-iframe.mjs → youtube-player.mjs} +22 -20
- package/dist/runtime/types.d.ts +33 -16
- package/dist/runtime/types.mjs +2 -0
- package/dist/runtime/utils.d.ts +3 -2
- package/dist/runtime/utils.mjs +15 -13
- package/package.json +6 -6
- package/dist/client/_nuxt/CMNIl2hT.js +0 -31
- package/dist/client/_nuxt/builds/meta/8b865286-abcf-4201-a2af-ee13e4478155.json +0 -1
- package/dist/runtime/components/GoogleMaps.vue +0 -130
- package/dist/runtime/components/LemonSqueezyButton.vue +0 -28
- package/dist/runtime/components/StripePricingTableEmbed.vue +0 -33
- package/dist/runtime/components/VimeoEmbed.vue +0 -161
- package/dist/runtime/components/YouTubeEmbed.vue +0 -79
- package/dist/runtime/registry/youtube-iframe.d.ts +0 -15
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"id":"8b865286-abcf-4201-a2af-ee13e4478155","timestamp":1714631612463,"matcher":{"static":{},"wildcard":{},"dynamic":{}},"prerendered":[]}
|
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
<script lang="ts" setup>
|
|
2
|
-
import { type PropType, computed, ref, watch } from 'vue'
|
|
3
|
-
import { withQuery } from 'ufo'
|
|
4
|
-
import type google from 'google.maps'
|
|
5
|
-
import { defu } from 'defu'
|
|
6
|
-
import type { ElementScriptTrigger } from '../composables/useElementScriptTrigger'
|
|
7
|
-
import { useElementScriptTrigger, useRuntimeConfig, useScriptGoogleMaps } from '#imports'
|
|
8
|
-
|
|
9
|
-
const props = defineProps({
|
|
10
|
-
trigger: { type: String as PropType<ElementScriptTrigger>, required: false, default: 'mouseover' },
|
|
11
|
-
/**
|
|
12
|
-
* Defines the Google Maps API key. Must have access to the Static Maps API as well.
|
|
13
|
-
*
|
|
14
|
-
* @see https://developers.google.com/maps/documentation/javascript/get-api-key
|
|
15
|
-
*/
|
|
16
|
-
apiKey: { type: String, required: true },
|
|
17
|
-
/**
|
|
18
|
-
* Defines map marker location.
|
|
19
|
-
*
|
|
20
|
-
* @example City Hall, New York, NY
|
|
21
|
-
*/
|
|
22
|
-
query: { type: String, required: false, default: '' },
|
|
23
|
-
/**
|
|
24
|
-
* Defines center of the map view.
|
|
25
|
-
*
|
|
26
|
-
* @example 37.4218,-122.0840
|
|
27
|
-
*/
|
|
28
|
-
options: { type: Object as PropType<Omit<google.maps.MapOptions, 'center'>>, required: false, default: undefined },
|
|
29
|
-
/**
|
|
30
|
-
* Defines the width of the map.
|
|
31
|
-
*/
|
|
32
|
-
width: { type: Number, required: false, default: 500 },
|
|
33
|
-
/**
|
|
34
|
-
* Defines the height of the map
|
|
35
|
-
*/
|
|
36
|
-
height: { type: Number, required: false, default: 400 },
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
const apiKey = props.apiKey || useRuntimeConfig().public.scripts?.googleMaps?.apikey
|
|
40
|
-
|
|
41
|
-
if (!apiKey)
|
|
42
|
-
throw new Error('GoogleMaps requires an API key')
|
|
43
|
-
if (!props.query && !props.options?.center)
|
|
44
|
-
throw new Error('GoogleMaps requires either a query or center option')
|
|
45
|
-
|
|
46
|
-
const elMap = ref<HTMLElement>()
|
|
47
|
-
|
|
48
|
-
const { $script } = useScriptGoogleMaps({
|
|
49
|
-
apiKey: props.apiKey,
|
|
50
|
-
scriptOptions: {
|
|
51
|
-
trigger: useElementScriptTrigger({ trigger: props.trigger, el: elMap }),
|
|
52
|
-
},
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
const options = computed(() => {
|
|
56
|
-
return defu(props.options, {
|
|
57
|
-
zoom: 15,
|
|
58
|
-
mapId: 'map',
|
|
59
|
-
})
|
|
60
|
-
})
|
|
61
|
-
const ready = ref(false)
|
|
62
|
-
|
|
63
|
-
function queryMaps(maps: google.maps, marker: google.maps.MarkerLibrary, map: google.maps.Map) {
|
|
64
|
-
const request = {
|
|
65
|
-
query: props.query,
|
|
66
|
-
fields: ['name', 'geometry'],
|
|
67
|
-
}
|
|
68
|
-
const markers: google.maps.AdvancedMarkerElement[] = []
|
|
69
|
-
const service = new maps.places.PlacesService(map)
|
|
70
|
-
service.findPlaceFromQuery(request, (results, status) => {
|
|
71
|
-
if (status === maps.places.PlacesServiceStatus.OK && results) {
|
|
72
|
-
for (let i = 0; i < results.length; i++) {
|
|
73
|
-
const location = results[i].geometry?.location
|
|
74
|
-
location && markers.push(
|
|
75
|
-
new marker.AdvancedMarkerElement({
|
|
76
|
-
map,
|
|
77
|
-
position: location,
|
|
78
|
-
}),
|
|
79
|
-
)
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
if (results[0].geometry?.location)
|
|
83
|
-
markers[0] && map.setCenter(results[0].geometry.location)
|
|
84
|
-
ready.value = true
|
|
85
|
-
}
|
|
86
|
-
})
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// create the map
|
|
90
|
-
$script.then(async (instance) => {
|
|
91
|
-
const maps = await instance.maps
|
|
92
|
-
const marker = await maps.importLibrary('marker') as google.maps.MarkerLibrary
|
|
93
|
-
|
|
94
|
-
const mapDiv = document.createElement('div')
|
|
95
|
-
mapDiv.style.width = '100%'
|
|
96
|
-
mapDiv.style.height = '100%'
|
|
97
|
-
const _ = watch(ready, (v) => {
|
|
98
|
-
v && elMap.value?.appendChild(mapDiv)
|
|
99
|
-
_()
|
|
100
|
-
})
|
|
101
|
-
|
|
102
|
-
const map = new maps.Map(mapDiv, options.value)
|
|
103
|
-
watch(options, () => map.setOptions(options.value))
|
|
104
|
-
watch(() => props.query, () => {
|
|
105
|
-
queryMaps(maps, marker, map)
|
|
106
|
-
}, {
|
|
107
|
-
immediate: !!props.query,
|
|
108
|
-
})
|
|
109
|
-
if (!props.query)
|
|
110
|
-
ready.value = true
|
|
111
|
-
})
|
|
112
|
-
|
|
113
|
-
const poster = computed(() => {
|
|
114
|
-
return withQuery('https://maps.googleapis.com/maps/api/staticmap', {
|
|
115
|
-
center: props.query, // will be overriden by options if they were set
|
|
116
|
-
size: `${props.width}x${props.height}`,
|
|
117
|
-
key: apiKey,
|
|
118
|
-
scale: 2, // we assume a high DPI to avoid hydration issues
|
|
119
|
-
...options.value,
|
|
120
|
-
})
|
|
121
|
-
})
|
|
122
|
-
</script>
|
|
123
|
-
|
|
124
|
-
<template>
|
|
125
|
-
<div ref="elMap" :style="{ width: `${width}px`, height: `${height}px`, position: 'relative' }">
|
|
126
|
-
<slot>
|
|
127
|
-
<img v-if="!ready" :src="poster" title="" :width="width" :height="height">
|
|
128
|
-
</slot>
|
|
129
|
-
</div>
|
|
130
|
-
</template>
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
<script lang="ts" setup>
|
|
2
|
-
import { useScriptLemonSqueezy } from '#imports'
|
|
3
|
-
|
|
4
|
-
defineProps<{
|
|
5
|
-
href: string
|
|
6
|
-
}>()
|
|
7
|
-
|
|
8
|
-
const emits = defineEmits<{
|
|
9
|
-
event: [{ event: string, data?: Record<string, any> }]
|
|
10
|
-
}>()
|
|
11
|
-
|
|
12
|
-
const instance = useScriptLemonSqueezy()
|
|
13
|
-
instance.Setup({
|
|
14
|
-
eventHandler(event) {
|
|
15
|
-
emits('event', event)
|
|
16
|
-
},
|
|
17
|
-
})
|
|
18
|
-
|
|
19
|
-
defineExpose({
|
|
20
|
-
instance,
|
|
21
|
-
})
|
|
22
|
-
</script>
|
|
23
|
-
|
|
24
|
-
<template>
|
|
25
|
-
<a :href="href" class="lemonsqueezy-button">
|
|
26
|
-
<slot />
|
|
27
|
-
</a>
|
|
28
|
-
</template>
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
import { ref } from 'vue'
|
|
3
|
-
import type { ElementScriptTrigger } from '../composables/useElementScriptTrigger'
|
|
4
|
-
import { useElementScriptTrigger, useScript } from '#imports'
|
|
5
|
-
|
|
6
|
-
const props = defineProps<{
|
|
7
|
-
trigger?: ElementScriptTrigger
|
|
8
|
-
publishableKey: string
|
|
9
|
-
pricingTableId: string
|
|
10
|
-
clientReferenceId?: string
|
|
11
|
-
customerEmail?: string
|
|
12
|
-
customerSessionClientSecret?: string
|
|
13
|
-
}>()
|
|
14
|
-
|
|
15
|
-
const table = ref()
|
|
16
|
-
useScript(`https://js.stripe.com/v3/pricing-table.js`, {
|
|
17
|
-
trigger: useElementScriptTrigger({ trigger: props.trigger, el: table }),
|
|
18
|
-
})
|
|
19
|
-
</script>
|
|
20
|
-
|
|
21
|
-
<template>
|
|
22
|
-
<ClientOnly>
|
|
23
|
-
<stripe-pricing-table
|
|
24
|
-
ref="table"
|
|
25
|
-
v-bind="$attrs"
|
|
26
|
-
:publishable-key="publishableKey"
|
|
27
|
-
:pricing-table-id="pricingTableId"
|
|
28
|
-
:client-reference-id="clientReferenceId"
|
|
29
|
-
:customer-email="customerEmail"
|
|
30
|
-
:customer-session-client-secret="customerSessionClientSecret"
|
|
31
|
-
/>
|
|
32
|
-
</ClientOnly>
|
|
33
|
-
</template>
|
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
import { computed, onBeforeUnmount, ref, watch } from 'vue'
|
|
3
|
-
import type Player from 'vimeo__player'
|
|
4
|
-
import type { EventMap, VimeoVideoQuality } from 'vimeo__player'
|
|
5
|
-
import type { ElementScriptTrigger } from '../composables/useElementScriptTrigger'
|
|
6
|
-
import { useAsyncData, useElementScriptTrigger, useScriptVimeoPlayer } from '#imports'
|
|
7
|
-
|
|
8
|
-
const props = withDefaults(defineProps<{
|
|
9
|
-
// custom
|
|
10
|
-
trigger?: ElementScriptTrigger
|
|
11
|
-
// copied from @types/vimeo__player
|
|
12
|
-
id: number | undefined
|
|
13
|
-
url?: string | undefined
|
|
14
|
-
autopause?: boolean | undefined
|
|
15
|
-
autoplay?: boolean | undefined
|
|
16
|
-
background?: boolean | undefined
|
|
17
|
-
byline?: boolean | undefined
|
|
18
|
-
color?: string | undefined
|
|
19
|
-
controls?: boolean | undefined
|
|
20
|
-
dnt?: boolean | undefined
|
|
21
|
-
height?: number | undefined
|
|
22
|
-
// eslint-disable-next-line vue/prop-name-casing
|
|
23
|
-
interactive_params?: string | undefined
|
|
24
|
-
keyboard?: boolean | undefined
|
|
25
|
-
loop?: boolean | undefined
|
|
26
|
-
maxheight?: number | undefined
|
|
27
|
-
maxwidth?: number | undefined
|
|
28
|
-
muted?: boolean | undefined
|
|
29
|
-
pip?: boolean | undefined
|
|
30
|
-
playsinline?: boolean | undefined
|
|
31
|
-
portrait?: boolean | undefined
|
|
32
|
-
responsive?: boolean | undefined
|
|
33
|
-
speed?: boolean | undefined
|
|
34
|
-
quality?: VimeoVideoQuality | undefined
|
|
35
|
-
texttrack?: string | undefined
|
|
36
|
-
title?: boolean | undefined
|
|
37
|
-
transparent?: boolean | undefined
|
|
38
|
-
width?: number | undefined
|
|
39
|
-
}>(), {
|
|
40
|
-
trigger: 'mouseover',
|
|
41
|
-
width: 640,
|
|
42
|
-
height: 480,
|
|
43
|
-
loop: false,
|
|
44
|
-
controls: true,
|
|
45
|
-
})
|
|
46
|
-
|
|
47
|
-
const emits = defineEmits<{
|
|
48
|
-
play: [e: EventMap['play'], player: Player]
|
|
49
|
-
playing: [e: EventMap['playing'], player: Player]
|
|
50
|
-
pause: [e: EventMap['pause'], player: Player]
|
|
51
|
-
ended: [e: EventMap['ended'], player: Player]
|
|
52
|
-
timeupdate: [e: EventMap['timeupdate'], player: Player]
|
|
53
|
-
progress: [e: EventMap['progress'], player: Player]
|
|
54
|
-
seeking: [e: EventMap['seeking'], player: Player]
|
|
55
|
-
seeked: [e: EventMap['seeked'], player: Player]
|
|
56
|
-
texttrackchange: [e: EventMap['texttrackchange'], player: Player]
|
|
57
|
-
chapterchange: [e: EventMap['chapterchange'], player: Player]
|
|
58
|
-
cuechange: [e: EventMap['cuechange'], player: Player]
|
|
59
|
-
cuepoint: [e: EventMap['cuepoint'], player: Player]
|
|
60
|
-
volumechange: [e: EventMap['volumechange'], player: Player]
|
|
61
|
-
playbackratechange: [e: EventMap['playbackratechange'], player: Player]
|
|
62
|
-
bufferstart: [e: EventMap['bufferstart'], player: Player]
|
|
63
|
-
bufferend: [e: EventMap['bufferend'], player: Player]
|
|
64
|
-
error: [e: EventMap['error'], player: Player]
|
|
65
|
-
loaded: [e: EventMap['loaded'], player: Player]
|
|
66
|
-
durationchange: [e: EventMap['durationchange'], player: Player]
|
|
67
|
-
fullscreenchange: [e: EventMap['fullscreenchange'], player: Player]
|
|
68
|
-
qualitychange: [e: EventMap['qualitychange'], player: Player]
|
|
69
|
-
camerachange: [e: EventMap['camerachange'], player: Player]
|
|
70
|
-
resize: [e: EventMap['resize'], player: Player]
|
|
71
|
-
enterpictureinpicture: [e: EventMap['enterpictureinpicture'], player: Player]
|
|
72
|
-
leavepictureinpicture: [e: EventMap['leavepictureinpicture'], player: Player]
|
|
73
|
-
}>()
|
|
74
|
-
|
|
75
|
-
const events = [
|
|
76
|
-
'play',
|
|
77
|
-
'playing',
|
|
78
|
-
'pause',
|
|
79
|
-
'ended',
|
|
80
|
-
'timeupdate',
|
|
81
|
-
'progress',
|
|
82
|
-
'seeking',
|
|
83
|
-
'seeked',
|
|
84
|
-
'texttrackchange',
|
|
85
|
-
'chapterchange',
|
|
86
|
-
'cuechange',
|
|
87
|
-
'cuepoint',
|
|
88
|
-
'volumechange',
|
|
89
|
-
'playbackratechange',
|
|
90
|
-
'bufferstart',
|
|
91
|
-
'bufferend',
|
|
92
|
-
'error',
|
|
93
|
-
'loaded',
|
|
94
|
-
'durationchange',
|
|
95
|
-
'fullscreenchange',
|
|
96
|
-
'qualitychange',
|
|
97
|
-
'camerachange',
|
|
98
|
-
'resize',
|
|
99
|
-
]
|
|
100
|
-
|
|
101
|
-
const elVimeo = ref()
|
|
102
|
-
const root = ref()
|
|
103
|
-
|
|
104
|
-
const ready = ref(false)
|
|
105
|
-
const { $script } = useScriptVimeoPlayer({
|
|
106
|
-
scriptOptions: {
|
|
107
|
-
trigger: useElementScriptTrigger({ trigger: props.trigger, el: root.value }),
|
|
108
|
-
},
|
|
109
|
-
})
|
|
110
|
-
|
|
111
|
-
const { data: payload } = useAsyncData(
|
|
112
|
-
`vimeo-embed:${props.id}`,
|
|
113
|
-
// TODO ideally we cache this
|
|
114
|
-
() => $fetch(`https://vimeo.com/api/v2/video/${props.id}.json`).then(res => res[0]),
|
|
115
|
-
{
|
|
116
|
-
watch: [() => props.id],
|
|
117
|
-
},
|
|
118
|
-
)
|
|
119
|
-
|
|
120
|
-
const poster = computed(() => {
|
|
121
|
-
const { width, height } = props
|
|
122
|
-
// 2 dpi for retina, this is safest while SSR
|
|
123
|
-
return payload.value.thumbnail_large.replace(/-d_[\dx]+$/i, `-d_${Math.round(width * 2)}x${Math.round(height * 2)}`)
|
|
124
|
-
})
|
|
125
|
-
|
|
126
|
-
let player: Player
|
|
127
|
-
$script.then(({ Player }) => {
|
|
128
|
-
// filter props for false values
|
|
129
|
-
player = Player(elVimeo.value, {
|
|
130
|
-
...props,
|
|
131
|
-
url: encodeURI(`https://vimeo.com/${props.id}`),
|
|
132
|
-
})
|
|
133
|
-
|
|
134
|
-
events.forEach((event) => {
|
|
135
|
-
player.on(event, (e: any) => {
|
|
136
|
-
emits(event as keyof typeof emits, e, player)
|
|
137
|
-
if (event === 'loaded')
|
|
138
|
-
ready.value = true
|
|
139
|
-
})
|
|
140
|
-
})
|
|
141
|
-
})
|
|
142
|
-
|
|
143
|
-
onBeforeUnmount(() => player?.unload())
|
|
144
|
-
|
|
145
|
-
defineExpose({
|
|
146
|
-
player,
|
|
147
|
-
})
|
|
148
|
-
|
|
149
|
-
watch(() => props.id, (v) => {
|
|
150
|
-
v && player?.loadVideo(v)
|
|
151
|
-
})
|
|
152
|
-
</script>
|
|
153
|
-
|
|
154
|
-
<template>
|
|
155
|
-
<div ref="root" :style="{ width: `${width}px`, height: `${height}px`, position: 'relative' }">
|
|
156
|
-
<div v-show="ready" ref="elVimeo" style="width: 100%; height: 100%;" />
|
|
157
|
-
<slot v-bind="payload" :poster="poster">
|
|
158
|
-
<img v-if="!ready" :src="poster" v-bind="trigger ? { loading: 'lazy' } : {}" :width="width" :height="height" :style="{ aspectRatio: '4/3', cursor: $script.status.value !== 'awaitingLoad' ? 'wait' : '' }">
|
|
159
|
-
</slot>
|
|
160
|
-
</div>
|
|
161
|
-
</template>
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
import { computed, ref, watch } from 'vue'
|
|
3
|
-
import type YT from 'youtube'
|
|
4
|
-
import type { ElementScriptTrigger } from '../composables/useElementScriptTrigger'
|
|
5
|
-
import { useElementScriptTrigger, useScriptYouTubeIframe } from '#imports'
|
|
6
|
-
|
|
7
|
-
const props = withDefaults(defineProps<{
|
|
8
|
-
trigger?: ElementScriptTrigger
|
|
9
|
-
videoId: string
|
|
10
|
-
playerVars?: YT.PlayerVars
|
|
11
|
-
width?: number
|
|
12
|
-
height?: number
|
|
13
|
-
}>(), {
|
|
14
|
-
playerVars: { autoplay: 1, playsinline: 1 },
|
|
15
|
-
width: 640,
|
|
16
|
-
height: 480,
|
|
17
|
-
})
|
|
18
|
-
|
|
19
|
-
const emits = defineEmits<{
|
|
20
|
-
onReady: [e: YT.PlayerEvent]
|
|
21
|
-
onStateChange: [e: YT.PlayerEvent]
|
|
22
|
-
onPlaybackQualityChange: [e: YT.PlayerEvent]
|
|
23
|
-
onPlaybackRateChange: [e: YT.PlayerEvent]
|
|
24
|
-
onError: [e: YT.PlayerEvent]
|
|
25
|
-
onApiChange: [e: YT.PlayerEvent]
|
|
26
|
-
}>()
|
|
27
|
-
const events: (keyof YT.Events)[] = [
|
|
28
|
-
'onReady',
|
|
29
|
-
'onStateChange',
|
|
30
|
-
'onPlaybackQualityChange',
|
|
31
|
-
'onPlaybackRateChange',
|
|
32
|
-
'onError',
|
|
33
|
-
'onApiChange',
|
|
34
|
-
]
|
|
35
|
-
const elYoutube = ref()
|
|
36
|
-
|
|
37
|
-
const ready = ref(false)
|
|
38
|
-
const { $script } = useScriptYouTubeIframe({
|
|
39
|
-
scriptOptions: {
|
|
40
|
-
trigger: useElementScriptTrigger({ trigger: props.trigger, el: elYoutube.value }),
|
|
41
|
-
},
|
|
42
|
-
})
|
|
43
|
-
|
|
44
|
-
let player: YT.Player
|
|
45
|
-
$script.then(async (instance) => {
|
|
46
|
-
const YT = await instance.YT
|
|
47
|
-
await new Promise<void>((resolve) => {
|
|
48
|
-
if (typeof YT.Player === 'undefined')
|
|
49
|
-
YT.ready(resolve)
|
|
50
|
-
else
|
|
51
|
-
resolve()
|
|
52
|
-
})
|
|
53
|
-
player = new YT.Player(elYoutube.value, {
|
|
54
|
-
...props,
|
|
55
|
-
events: Object.fromEntries(events.map(event => [event, (e: any) => {
|
|
56
|
-
// @ts-expect-error untyped
|
|
57
|
-
emits(event, e)
|
|
58
|
-
}])),
|
|
59
|
-
})
|
|
60
|
-
})
|
|
61
|
-
|
|
62
|
-
defineExpose({
|
|
63
|
-
player,
|
|
64
|
-
})
|
|
65
|
-
|
|
66
|
-
watch(() => props.videoId, () => {
|
|
67
|
-
player?.loadVideoById(props.videoId)
|
|
68
|
-
})
|
|
69
|
-
|
|
70
|
-
const poster = computed(() => `https://i.ytimg.com/vi_webp/${props.videoId}/sddefault.webp`)
|
|
71
|
-
</script>
|
|
72
|
-
|
|
73
|
-
<template>
|
|
74
|
-
<div ref="elYoutube" :style="{ width: `${width}px`, height: `${height}px`, position: 'relative' }">
|
|
75
|
-
<slot :poster="poster">
|
|
76
|
-
<img v-if="!ready" :src="poster" title="" :width="width" :height="height">
|
|
77
|
-
</slot>
|
|
78
|
-
</div>
|
|
79
|
-
</template>
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/// <reference types="youtube" />
|
|
2
|
-
import type { RegistryScriptInput } from '#nuxt-scripts';
|
|
3
|
-
export interface YouTubeIframeApi {
|
|
4
|
-
YT: typeof YT;
|
|
5
|
-
}
|
|
6
|
-
declare global {
|
|
7
|
-
interface Window extends YouTubeIframeApi {
|
|
8
|
-
onYouTubeIframeAPIReady: () => void;
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
export declare const YouTubeIframeOptions: import("valibot").ObjectSchema<{}, undefined, {}>;
|
|
12
|
-
export type YouTubeIFrameInput = RegistryScriptInput<typeof YouTubeIframeOptions>;
|
|
13
|
-
export declare function useScriptYouTubeIframe<T extends YouTubeIframeApi>(_options: YouTubeIFrameInput): T & {
|
|
14
|
-
$script: Promise<T> & import("@unhead/vue").VueScriptInstance<T>;
|
|
15
|
-
};
|