vanilla-vue-ui 0.0.25 β 0.0.27
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/package.json
CHANGED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// Replace vue3 with vue if you are using Storybook for Vue 2
|
|
2
|
+
import type { Meta, StoryObj } from '@storybook/vue3';
|
|
3
|
+
import GameDialog from './GameDialog.vue';
|
|
4
|
+
|
|
5
|
+
type GameDialogProps = InstanceType<typeof GameDialog>['$props']
|
|
6
|
+
|
|
7
|
+
const meta: Meta<typeof GameDialog> = {
|
|
8
|
+
component: GameDialog,
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export default meta;
|
|
12
|
+
type Story = StoryObj<typeof GameDialog>;
|
|
13
|
+
|
|
14
|
+
/*
|
|
15
|
+
*π Render functions are a framework specific feature to allow you control on how the component renders.
|
|
16
|
+
* See https://storybook.js.org/docs/api/csf
|
|
17
|
+
* to learn how to use render functions.
|
|
18
|
+
*/
|
|
19
|
+
export const Primary: Story = {
|
|
20
|
+
render: (args: GameDialogProps) => ({
|
|
21
|
+
setup() {
|
|
22
|
+
return { args }
|
|
23
|
+
},
|
|
24
|
+
components: { GameDialog },
|
|
25
|
+
template: '<GameDialog v-bind="args" />',
|
|
26
|
+
}),
|
|
27
|
+
args: {
|
|
28
|
+
text: 'γγγ«γ‘γ―',
|
|
29
|
+
link: '/ja/blog/tag/εεΉ΄γγ£γ¬γ³γΈ/',
|
|
30
|
+
linkLabel: 'γγ‘γ',
|
|
31
|
+
speed: 200,
|
|
32
|
+
autoStart: true,
|
|
33
|
+
}
|
|
34
|
+
};
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
class="
|
|
4
|
+
relative max-w-sm text-white select-none
|
|
5
|
+
bg-black
|
|
6
|
+
transition-all duration-150 ease-out
|
|
7
|
+
origin-bottom
|
|
8
|
+
animate-[dialogPop_0.2s_ease-out]
|
|
9
|
+
"
|
|
10
|
+
@click="skip"
|
|
11
|
+
>
|
|
12
|
+
<span>{{ displayText }}</span>
|
|
13
|
+
|
|
14
|
+
<a
|
|
15
|
+
v-if="isFinished && link"
|
|
16
|
+
:href="link"
|
|
17
|
+
class="
|
|
18
|
+
ml-2 inline-block text-yellow-400
|
|
19
|
+
animate-[dialogBlink_1.2s_steps(2)_infinite]
|
|
20
|
+
hover:underline
|
|
21
|
+
"
|
|
22
|
+
>
|
|
23
|
+
βΆ {{ linkLabel }}
|
|
24
|
+
</a>
|
|
25
|
+
</div>
|
|
26
|
+
</template>
|
|
27
|
+
|
|
28
|
+
<script setup lang="ts">
|
|
29
|
+
import { ref, onMounted, watch } from 'vue'
|
|
30
|
+
|
|
31
|
+
const props = withDefaults(defineProps<{
|
|
32
|
+
text: string
|
|
33
|
+
speed?: number
|
|
34
|
+
link?: string
|
|
35
|
+
linkLabel?: string
|
|
36
|
+
autoStart?: boolean
|
|
37
|
+
}>(), {
|
|
38
|
+
speed: 60,
|
|
39
|
+
link: '',
|
|
40
|
+
linkLabel: 'γ€γ₯γ',
|
|
41
|
+
autoStart: true,
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
const displayText = ref('')
|
|
45
|
+
const isFinished = ref(false)
|
|
46
|
+
|
|
47
|
+
let index = 0
|
|
48
|
+
let timer: number | null = null
|
|
49
|
+
|
|
50
|
+
const start = () => {
|
|
51
|
+
clear()
|
|
52
|
+
displayText.value = ''
|
|
53
|
+
isFinished.value = false
|
|
54
|
+
index = 0
|
|
55
|
+
|
|
56
|
+
timer = window.setInterval(() => {
|
|
57
|
+
displayText.value += props.text[index]
|
|
58
|
+
index++
|
|
59
|
+
|
|
60
|
+
if (index >= props.text.length) finish()
|
|
61
|
+
}, props.speed)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const finish = () => {
|
|
65
|
+
clear()
|
|
66
|
+
isFinished.value = true
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const clear = () => {
|
|
70
|
+
if (timer !== null) {
|
|
71
|
+
clearInterval(timer)
|
|
72
|
+
timer = null
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const skip = () => {
|
|
77
|
+
if (!isFinished.value) {
|
|
78
|
+
displayText.value = props.text
|
|
79
|
+
finish()
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
onMounted(() => {
|
|
84
|
+
if (props.autoStart) start()
|
|
85
|
+
})
|
|
86
|
+
|
|
87
|
+
watch(() => props.text, () => {
|
|
88
|
+
if (props.autoStart) start()
|
|
89
|
+
})
|
|
90
|
+
|
|
91
|
+
defineExpose({ start, finish })
|
|
92
|
+
</script>
|
|
93
|
+
|
|
94
|
+
<style scoped>
|
|
95
|
+
@keyframes dialogPop {
|
|
96
|
+
from {
|
|
97
|
+
transform: scale(0.95);
|
|
98
|
+
opacity: 0;
|
|
99
|
+
}
|
|
100
|
+
to {
|
|
101
|
+
transform: scale(1);
|
|
102
|
+
opacity: 1;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
@keyframes dialogBlink {
|
|
107
|
+
50% { opacity: 0.3 }
|
|
108
|
+
}
|
|
109
|
+
</style>
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<span class="hidden"></span>
|
|
3
|
+
</template>
|
|
4
|
+
|
|
5
|
+
<script setup lang="ts">
|
|
6
|
+
import { onMounted } from 'vue'
|
|
7
|
+
|
|
8
|
+
const SCRIPT_SRC = 'https://platform.twitter.com/widgets.js'
|
|
9
|
+
|
|
10
|
+
onMounted(() => {
|
|
11
|
+
// γγ§γ«θͺγΏθΎΌγΎγγ¦γγγδΊιθͺγΏθΎΌγΏγγͺγ
|
|
12
|
+
const exists = document.querySelector<HTMLScriptElement>(
|
|
13
|
+
`script[src="${SCRIPT_SRC}"]`,
|
|
14
|
+
)
|
|
15
|
+
if (exists) return
|
|
16
|
+
|
|
17
|
+
const script = document.createElement('script')
|
|
18
|
+
script.src = SCRIPT_SRC
|
|
19
|
+
script.async = true
|
|
20
|
+
script.charset = 'utf-8'
|
|
21
|
+
|
|
22
|
+
document.head.appendChild(script)
|
|
23
|
+
})
|
|
24
|
+
</script>
|