@voidzero-dev/vitepress-theme 0.0.11 → 0.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/assets/terminal-background.jpg +0 -0
  2. package/components/Eyebrow.vue +11 -0
  3. package/components/Footer.vue +44 -0
  4. package/components/Header.vue +38 -0
  5. package/components/RiveAnimation.vue +144 -0
  6. package/components/Terminal.vue +165 -0
  7. package/components/terminal-animations/TerminalAnimation1.vue +53 -0
  8. package/components/terminal-animations/TerminalAnimation2.vue +58 -0
  9. package/components/terminal-animations/TerminalAnimation3.vue +45 -0
  10. package/components/terminal-animations/TerminalAnimation4.vue +49 -0
  11. package/components/terminal-animations/TerminalAnimation5.vue +50 -0
  12. package/components/terminal-animations/TerminalAnimation6.vue +54 -0
  13. package/index.ts +44 -0
  14. package/package.json +18 -21
  15. package/{dist/index.css → style.css} +7 -7
  16. package/dist/_virtual/_/plugin-vue/export-helper.js +0 -11
  17. package/dist/assets/cta-background-CgYtVhnO.jpg +0 -1
  18. package/dist/assets/cta-background.jpg +0 -1
  19. package/dist/index.d.ts +0 -2
  20. package/dist/index.js +0 -3
  21. package/dist/vitepress/assets/cta-background.js +0 -5
  22. package/dist/vitepress/components/Eyebrow.js +0 -18
  23. package/dist/vitepress/components/Footer.js +0 -72
  24. package/dist/vitepress/components/Header.js +0 -34
  25. package/dist/vitepress/components/RiveAnimation.js +0 -117
  26. package/dist/vitepress/components/Terminal.js +0 -161
  27. package/dist/vitepress/components/icons/VZIconBluesky.js +0 -21
  28. package/dist/vitepress/components/icons/VZIconGitHub.js +0 -21
  29. package/dist/vitepress/components/icons/VZIconLogo.js +0 -24
  30. package/dist/vitepress/components/icons/VZIconTwitter.js +0 -21
  31. package/dist/vitepress/components/terminal-animations/TerminalAnimation1.js +0 -37
  32. package/dist/vitepress/components/terminal-animations/TerminalAnimation2.js +0 -44
  33. package/dist/vitepress/components/terminal-animations/TerminalAnimation3.js +0 -37
  34. package/dist/vitepress/components/terminal-animations/TerminalAnimation4.js +0 -37
  35. package/dist/vitepress/components/terminal-animations/TerminalAnimation5.js +0 -37
  36. package/dist/vitepress/components/terminal-animations/TerminalAnimation6.js +0 -37
  37. package/dist/vitepress/index.d.ts +0 -34
  38. package/dist/vitepress/index.js +0 -21
  39. /package/{dist/assets → assets}/checkmark.svg +0 -0
  40. /package/{dist/assets → assets}/primary-button-background.jpg +0 -0
  41. /package/{dist/fonts → fonts}/APK-Protocol-Medium.woff2 +0 -0
  42. /package/{dist/fonts → fonts}/KHTeka-Medium.woff2 +0 -0
  43. /package/{dist/fonts → fonts}/KHTeka-Regular.woff2 +0 -0
  44. /package/{dist/fonts → fonts}/KHTekaMono-Medium.woff2 +0 -0
  45. /package/{dist/fonts → fonts}/KHTekaMono-Regular.woff2 +0 -0
Binary file
@@ -0,0 +1,11 @@
1
+ <script setup lang="ts">
2
+ defineProps<{
3
+ title: string
4
+ }>()
5
+ </script>
6
+
7
+ <template>
8
+ <section class="wrapper wrapper--ticks border-t p-5 pl-10">
9
+ <span class="text-nickel dark:text-white text-xs font-medium font-mono uppercase tracking-wide">{{ title }}</span>
10
+ </section>
11
+ </template>
@@ -0,0 +1,44 @@
1
+ <template>
2
+ <footer class="bg-primary" data-theme="dark">
3
+ <section class="wrapper">
4
+ <div class="bg-wine py-16 md:py-30 px-5 md:px-0 overflow-clip flex flex-col items-center justify-center gap-8 md:gap-12">
5
+ <h2 class="text-white w-full md:w-2xl text-center text-balance">Take your team's productivity to the next level with Vite+</h2>
6
+ <div class="flex items-center gap-5">
7
+ <a href="https://tally.so/r/nGWebL" target="_blank" rel="noopener noreferrer" class="button">Register your interest</a>
8
+ <a href="https://voidzero.dev/posts/announcing-vite-plus?utm_source=viteplusdev&utm_content=bottom_learn_more" target="_blank" rel="noopener noreferrer" class="button">
9
+ Learn more
10
+ </a>
11
+ </div>
12
+ </div>
13
+ <div class="px-5 md:px-24 pt-10 md:pt-16 pb-16 md:pb-30 flex flex-col md:flex-row gap-10 md:gap-0 md:justify-between">
14
+ <div>
15
+ <p class="text-grey text-xs font-mono uppercase tracking-wide mb-8">Company</p>
16
+ <ul class="flex flex-col gap-3">
17
+ <li><a href="https://voidzero.dev/" target="_blank" rel="noopener noreferrer" class="text-white text-base">VoidZero</a></li>
18
+ <li><a href="https://vite.dev/" target="_blank" rel="noopener noreferrer" class="text-white text-base">Vite</a></li>
19
+ <li><a href="https://rolldown.rs/" target="_blank" rel="noopener noreferrer" class="text-white text-base">Rolldown</a></li>
20
+ <li><a href="https://vitest.dev/" target="_blank" rel="noopener noreferrer" class="text-white text-base">Vitest</a></li>
21
+ <li><a href="https://oxc.rs/" target="_blank" rel="noopener noreferrer" class="text-white text-base">Oxc</a></li>
22
+ </ul>
23
+ </div>
24
+ <div>
25
+ <p class="text-grey text-xs font-mono uppercase tracking-wide mb-8">Social</p>
26
+ <ul class="flex flex-col gap-3">
27
+ <li><a href="https://github.com/voidzero-dev" target="_blank" rel="noopener noreferrer" class="text-white text-base">GitHub</a></li>
28
+ <li><a href="https://web-cdn.bsky.app/profile/voidzero.dev" target="_blank" rel="noopener noreferrer" class="text-white text-base">Bluesky</a></li>
29
+ <li><a href="https://x.com/voidzerodev" target="_blank" rel="noopener noreferrer" class="text-white text-base">X.com</a></li>
30
+ </ul>
31
+ </div>
32
+ </div>
33
+ </section>
34
+ <section class="wrapper wrapper--ticks border-t py-5 px-5 md:px-24">
35
+ <p class="text-sm">© {{ new Date().getFullYear() }} VoidZero Inc. <span class="hidden sm:inline ">All Rights Reserved.</span></p>
36
+ </section>
37
+ </footer>
38
+ </template>
39
+
40
+ <style scoped>
41
+
42
+ </style>
43
+ <script setup lang="ts">
44
+ </script>
@@ -0,0 +1,38 @@
1
+ <script setup lang="ts">
2
+ import {useData, useRoute} from 'vitepress'
3
+
4
+ const {site, theme} = useData()
5
+ const nav = theme.value.nav
6
+
7
+ const route = useRoute()
8
+ </script>
9
+
10
+ <template>
11
+ <header class="wrapper px-6 py-7 flex items-center justify-between">
12
+ <div class="flex items-center gap-10">
13
+ <a href="/" class="text-primary dark:text-white font-heading text-lg font-medium">
14
+ {{ site.title }}
15
+ </a>
16
+ <ul class="nav">
17
+ <li v-for="navItem in nav" :key="navItem.link">
18
+ <a
19
+ :class="{ active: route.path === navItem.link }"
20
+ :href="navItem.link"
21
+ >
22
+ {{ navItem.text }}
23
+ </a>
24
+ </li>
25
+ </ul>
26
+ </div>
27
+
28
+ <div class="flex items-center gap-6">
29
+ <slot name="right-side">
30
+ <!-- Right-aligned links / calls-to-action -->
31
+ </slot>
32
+ </div>
33
+ </header>
34
+ </template>
35
+
36
+ <style scoped>
37
+
38
+ </style>
@@ -0,0 +1,144 @@
1
+ <script setup lang="ts">
2
+ import * as rive from "@rive-app/canvas"
3
+ import { ref, onMounted, onUnmounted, computed } from "vue"
4
+
5
+ interface Props {
6
+ desktopSrc: string
7
+ mobileSrc?: string
8
+ breakpoint?: number
9
+ stateMachines?: string
10
+ canvasClass?: string
11
+ desktopWidth?: number
12
+ desktopHeight?: number
13
+ mobileWidth?: number
14
+ mobileHeight?: number
15
+ }
16
+
17
+ const props = withDefaults(defineProps<Props>(), {
18
+ breakpoint: 768, // md breakpoint
19
+ stateMachines: "State Machine 1",
20
+ canvasClass: "w-full"
21
+ })
22
+
23
+ const canvasRef = ref<HTMLCanvasElement | null>(null)
24
+ const containerRef = ref<HTMLElement | null>(null)
25
+ let riveInstance: rive.Rive | null = null
26
+ let hasStarted = ref(false)
27
+ let observer: IntersectionObserver | null = null
28
+
29
+ const isMobile = ref(false)
30
+
31
+ const checkMobile = () => {
32
+ isMobile.value = window.innerWidth < props.breakpoint
33
+ }
34
+
35
+ const getCurrentSrc = () => {
36
+ return isMobile.value && props.mobileSrc ? props.mobileSrc : props.desktopSrc
37
+ }
38
+
39
+ const currentWidth = computed(() => {
40
+ return isMobile.value && props.mobileWidth ? props.mobileWidth : props.desktopWidth
41
+ })
42
+
43
+ const currentHeight = computed(() => {
44
+ return isMobile.value && props.mobileHeight ? props.mobileHeight : props.desktopHeight
45
+ })
46
+
47
+ const loadAnimation = () => {
48
+ if (!canvasRef.value || riveInstance) return
49
+
50
+ const src = getCurrentSrc()
51
+
52
+ riveInstance = new rive.Rive({
53
+ src,
54
+ canvas: canvasRef.value,
55
+ autoplay: false,
56
+ stateMachines: props.stateMachines,
57
+ onLoad: () => {
58
+ riveInstance?.resizeDrawingSurfaceToCanvas()
59
+ }
60
+ })
61
+ }
62
+
63
+ const playAnimation = () => {
64
+ if (riveInstance) {
65
+ riveInstance.play()
66
+ }
67
+ }
68
+
69
+ const cleanupAnimation = () => {
70
+ if (riveInstance) {
71
+ riveInstance.cleanup()
72
+ riveInstance = null
73
+ }
74
+ }
75
+
76
+ const handleResize = () => {
77
+ const wasMobile = isMobile.value
78
+ checkMobile()
79
+
80
+ // If mobile state changed, reload with correct source
81
+ if (wasMobile !== isMobile.value) {
82
+ const wasPlaying = hasStarted.value
83
+ cleanupAnimation()
84
+ loadAnimation()
85
+ if (wasPlaying) {
86
+ playAnimation()
87
+ }
88
+ }
89
+ }
90
+
91
+ onMounted(() => {
92
+ checkMobile()
93
+
94
+ // Load animation immediately
95
+ loadAnimation()
96
+
97
+ // Set up intersection observer to play animation when in viewport
98
+ observer = new IntersectionObserver(
99
+ (entries) => {
100
+ entries.forEach((entry) => {
101
+ if (entry.isIntersecting && !hasStarted.value) {
102
+ hasStarted.value = true
103
+ playAnimation()
104
+ }
105
+ })
106
+ },
107
+ {
108
+ threshold: 0.1 // Start when 10% visible
109
+ }
110
+ )
111
+
112
+ if (containerRef.value) {
113
+ observer.observe(containerRef.value)
114
+ }
115
+
116
+ // Listen for window resize to handle breakpoint changes
117
+ window.addEventListener('resize', handleResize)
118
+ })
119
+
120
+ onUnmounted(() => {
121
+ cleanupAnimation()
122
+
123
+ if (observer && containerRef.value) {
124
+ observer.unobserve(containerRef.value)
125
+ observer.disconnect()
126
+ }
127
+
128
+ window.removeEventListener('resize', handleResize)
129
+ })
130
+ </script>
131
+
132
+ <template>
133
+ <div ref="containerRef" class="pointer-events-none touch-none select-none">
134
+ <canvas
135
+ ref="canvasRef"
136
+ :width="currentWidth"
137
+ :height="currentHeight"
138
+ :class="canvasClass"
139
+ />
140
+ </div>
141
+ </template>
142
+
143
+ <style scoped>
144
+ </style>
@@ -0,0 +1,165 @@
1
+ <script setup lang="ts">
2
+ import {ref, onMounted, onUnmounted} from 'vue'
3
+ import {TabsContent, TabsList, TabsRoot, TabsTrigger} from 'reka-ui'
4
+ import TerminalAnimation1 from "./terminal-animations/TerminalAnimation1.vue";
5
+ import TerminalAnimation2 from "./terminal-animations/TerminalAnimation2.vue";
6
+ import TerminalAnimation3 from "./terminal-animations/TerminalAnimation3.vue";
7
+ import TerminalAnimation4 from "./terminal-animations/TerminalAnimation4.vue";
8
+ import TerminalAnimation5 from "./terminal-animations/TerminalAnimation5.vue";
9
+ import TerminalAnimation6 from "./terminal-animations/TerminalAnimation6.vue";
10
+ import terminalBg from '../assets/terminal-background.jpg';
11
+
12
+ // Auto-progression configuration
13
+ const AUTO_ADVANCE_DELAY = 1500
14
+
15
+ // State management
16
+ const activeTab = ref('tab1')
17
+ const autoPlayEnabled = ref(true)
18
+ let autoAdvanceTimeout: ReturnType<typeof setTimeout> | null = null
19
+
20
+ // Intersection Observer state
21
+ const sectionRef = ref<HTMLElement | null>(null)
22
+ const isVisible = ref(false)
23
+ let observer: IntersectionObserver | null = null
24
+
25
+ // Tab progression logic
26
+ const tabSequence = ['tab1', 'tab2', 'tab3', 'tab4', 'tab5', 'tab6']
27
+
28
+ const goToNextTab = () => {
29
+ const currentIndex = tabSequence.indexOf(activeTab.value)
30
+ const nextIndex = (currentIndex + 1) % tabSequence.length
31
+ activeTab.value = tabSequence[nextIndex]
32
+ }
33
+
34
+ // Handle animation completion
35
+ const onAnimationComplete = () => {
36
+ if (!autoPlayEnabled.value) return
37
+
38
+ // Clear any existing timeout
39
+ if (autoAdvanceTimeout) {
40
+ clearTimeout(autoAdvanceTimeout)
41
+ }
42
+
43
+ // Schedule next tab
44
+ autoAdvanceTimeout = setTimeout(() => {
45
+ goToNextTab()
46
+ }, AUTO_ADVANCE_DELAY)
47
+ }
48
+
49
+ // Handle user interaction with tabs
50
+ const onTabChange = () => {
51
+ // User clicked a tab, disable auto-play
52
+ autoPlayEnabled.value = false
53
+
54
+ // Clear any pending auto-advance
55
+ if (autoAdvanceTimeout) {
56
+ clearTimeout(autoAdvanceTimeout)
57
+ autoAdvanceTimeout = null
58
+ }
59
+ }
60
+
61
+ // Setup Intersection Observer
62
+ onMounted(() => {
63
+ if (!sectionRef.value) return
64
+
65
+ observer = new IntersectionObserver(
66
+ (entries) => {
67
+ entries.forEach((entry) => {
68
+ if (entry.isIntersecting && !isVisible.value) {
69
+ isVisible.value = true
70
+ // Disconnect observer after first intersection
71
+ observer?.disconnect()
72
+ }
73
+ })
74
+ },
75
+ {
76
+ threshold: 0.2, // Trigger when 20% of the element is visible
77
+ rootMargin: '0px'
78
+ }
79
+ )
80
+
81
+ observer.observe(sectionRef.value)
82
+ })
83
+
84
+ // Cleanup
85
+ onUnmounted(() => {
86
+ if (autoAdvanceTimeout) {
87
+ clearTimeout(autoAdvanceTimeout)
88
+ }
89
+ if (observer) {
90
+ observer.disconnect()
91
+ }
92
+ })
93
+ </script>
94
+
95
+ <template>
96
+ <section
97
+ ref="sectionRef"
98
+ :style="{ backgroundImage: `url(${terminalBg})` }"
99
+ class="wrapper border-t h-[40rem] bg-wine bg-cover bg-top flex justify-center pt-28 overflow-clip">
100
+ <div
101
+ :class="[
102
+ 'self-stretch px-4 sm:px-8 py-5 sm:py-7 relative bg-primary rounded-tl-lg rounded-tr-lg inline-flex flex-col justify-start items-start gap-2 overflow-hidden w-[62rem] outline-1 outline-offset-[3px] outline-white/30',
103
+ 'transition-transform duration-1000',
104
+ isVisible ? 'translate-y-0' : 'translate-y-24'
105
+ ]"
106
+ style="transition-timing-function: cubic-bezier(0.16, 1, 0.3, 1);">
107
+ <TabsRoot
108
+ v-if="isVisible"
109
+ v-model="activeTab"
110
+ @update:modelValue="onTabChange"
111
+ >
112
+ <TabsList
113
+ aria-label="features"
114
+ :class="[
115
+ 'absolute bottom-6 left-1/2 -translate-x-1/2 flex items-center p-1 rounded-md border border-white/10',
116
+ 'transition-transform duration-700 delay-300',
117
+ isVisible ? 'translate-y-0' : 'translate-y-12'
118
+ ]"
119
+ style="transition-timing-function: cubic-bezier(0.16, 1, 0.3, 1);">
120
+ <TabsTrigger value="tab1">
121
+ new
122
+ </TabsTrigger>
123
+ <TabsTrigger value="tab2">
124
+ dev
125
+ </TabsTrigger>
126
+ <TabsTrigger value="tab3">
127
+ lint
128
+ </TabsTrigger>
129
+ <TabsTrigger value="tab4">
130
+ fmt
131
+ </TabsTrigger>
132
+ <TabsTrigger value="tab5">
133
+ test
134
+ </TabsTrigger>
135
+ <TabsTrigger value="tab6">
136
+ build
137
+ </TabsTrigger>
138
+ </TabsList>
139
+ <TabsContent value="tab1">
140
+ <TerminalAnimation1 :on-animation-complete="onAnimationComplete"/>
141
+ </TabsContent>
142
+ <TabsContent value="tab2">
143
+ <TerminalAnimation2 :on-animation-complete="onAnimationComplete"/>
144
+ </TabsContent>
145
+ <TabsContent value="tab3">
146
+ <TerminalAnimation3 :on-animation-complete="onAnimationComplete"/>
147
+ </TabsContent>
148
+ <TabsContent value="tab4">
149
+ <TerminalAnimation4 :on-animation-complete="onAnimationComplete"/>
150
+ </TabsContent>
151
+ <TabsContent value="tab5">
152
+ <TerminalAnimation5 :on-animation-complete="onAnimationComplete"/>
153
+ </TabsContent>
154
+ <TabsContent value="tab6">
155
+ <TerminalAnimation6 :on-animation-complete="onAnimationComplete"/>
156
+ </TabsContent>
157
+ </TabsRoot>
158
+
159
+ </div>
160
+ </section>
161
+ </template>
162
+
163
+ <style scoped>
164
+
165
+ </style>
@@ -0,0 +1,53 @@
1
+ <script setup lang="ts">
2
+ import Typewriter from 'typewriter-effect/dist/core'
3
+ import {onMounted, onUnmounted} from "vue";
4
+
5
+ const props = defineProps<{
6
+ onAnimationComplete?: () => void
7
+ }>()
8
+
9
+ let typewriter;
10
+
11
+ onMounted(() => {
12
+ const target = document.getElementById('terminal-code');
13
+ typewriter = new Typewriter(target, {
14
+ loop: false,
15
+ delay: 1,
16
+ })
17
+ typewriter
18
+ .typeString(`<span>$ vite new vite-plus-demo --template react-ts</span>`)
19
+ .pauseFor(500)
20
+ .pasteString(`<span class="block w-full h-[1rem]"></span>`)
21
+ .pasteString(`<span class="text-aqua">◇ Scaffolding project in ~/vite-plus-demo</span>`)
22
+ .pauseFor(500)
23
+ .pasteString(`<span class="text-grey block">|</span>`)
24
+ .pasteString(`<span class="text-zest block">└ Done.</span>`)
25
+ .pasteString(`<span class="block w-full h-[1rem]"></span>`)
26
+ .pauseFor(500)
27
+ .pasteString(`<span class="block"><span class="text-zest">✓</span> Installing dependencies using default package manager: <span class="text-vite">pnpm@v10.16.1</span></span>`)
28
+ .pasteString(`<span class="block w-full h-[1rem]"></span>`)
29
+ .pasteString(`<div class="block"><span class="text-grey">Progress:</span> resolved 1, reused 0, downloaded 0, added 0</div>`)
30
+ .pasteString(`<div class="block"><span class="text-grey">Packages:</span> <span class="text-vite">+31</span></div>`)
31
+ .typeString(`<span class="text-grey block">++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++</span>`)
32
+ .pasteString(`<div class="block"><span class="text-grey">Progress:</span> resolved 31, reused 31, downloaded 0, added 31, <span class="text-zest">done</span></div>`)
33
+ .pasteString(`<span class="block w-full h-[1rem]"></span>`)
34
+ .callFunction(() => {
35
+ if (props.onAnimationComplete) {
36
+ props.onAnimationComplete()
37
+ }
38
+ })
39
+ .start();
40
+ })
41
+
42
+ onUnmounted(() => {
43
+ if(typewriter){
44
+ typewriter.stop()
45
+ }
46
+ })
47
+ </script>
48
+
49
+ <template>
50
+ <p class="font-mono text-sm text-white leading-[1.5rem]">
51
+ <span id="terminal-code"></span>
52
+ </p>
53
+ </template>
@@ -0,0 +1,58 @@
1
+ <script setup lang="ts">
2
+ import Typewriter from 'typewriter-effect/dist/core'
3
+ import {onMounted, onUnmounted} from "vue";
4
+
5
+ const props = defineProps<{
6
+ onAnimationComplete?: () => void
7
+ }>()
8
+
9
+ let typewriter;
10
+
11
+ onMounted(() => {
12
+ // Get current time for easter egg
13
+ const now = new Date()
14
+ let hours = now.getHours()
15
+ const minutes = now.getMinutes().toString().padStart(2, '0')
16
+ const seconds = now.getSeconds().toString().padStart(2, '0')
17
+ const ampm = hours >= 12 ? 'pm' : 'am'
18
+ hours = hours % 12 || 12
19
+ const currentTime = `${hours}:${minutes}:${seconds} ${ampm}`
20
+
21
+ const target = document.getElementById('terminal-code');
22
+ typewriter = new Typewriter(target, {
23
+ loop: false,
24
+ delay: 1,
25
+ })
26
+ typewriter
27
+ .typeString(`<span>$ vite dev</span>`)
28
+ .pauseFor(200)
29
+ .pasteString(`<span class="block w-full h-[1rem]"></span>`)
30
+ .pasteString(`<div class="block text-grey"><span class="text-vite">VITE+ v1.0.0</span> ready in <span class="text-white font-medium">65</span> ms</div>`)
31
+ .pasteString(`<span class="block w-full h-[1rem]"></span>`)
32
+ .pauseFor(500)
33
+ .pasteString(`<div class="block"><span class="text-vite"> → Local: </span><span class="text-aqua">http://localhost:5173/</span></div>`)
34
+ .pasteString(`<div class="block text-grey">→ Network: use <span class="text-white font-medium">--host</span> to expose</div>`)
35
+ .pasteString(`<span class="block w-full h-[1rem]"></span>`)
36
+ .pauseFor(1500)
37
+ .pasteString(`<div class="block text-grey">${currentTime} <span class="text-aqua">[vite]</span> (client) <span class="text-vite">hmr update</span> /src/App.tsx</div>`)
38
+ .pasteString(`<span class="block w-full h-[1rem]"></span>`)
39
+ .callFunction(() => {
40
+ if (props.onAnimationComplete) {
41
+ props.onAnimationComplete()
42
+ }
43
+ })
44
+ .start();
45
+ })
46
+
47
+ onUnmounted(() => {
48
+ if(typewriter){
49
+ typewriter.stop()
50
+ }
51
+ })
52
+ </script>
53
+
54
+ <template>
55
+ <p class="font-mono text-sm text-white leading-[1.5rem]">
56
+ <span id="terminal-code"></span>
57
+ </p>
58
+ </template>
@@ -0,0 +1,45 @@
1
+ <script setup lang="ts">
2
+ import Typewriter from 'typewriter-effect/dist/core'
3
+ import {onMounted, onUnmounted} from "vue";
4
+
5
+ const props = defineProps<{
6
+ onAnimationComplete?: () => void
7
+ }>()
8
+
9
+ let typewriter;
10
+
11
+ onMounted(() => {
12
+ const target = document.getElementById('terminal-code');
13
+ typewriter = new Typewriter(target, {
14
+ loop: false,
15
+ delay: 1,
16
+ })
17
+ typewriter
18
+ .typeString(`<span>$ vite lint</span>`)
19
+ .pauseFor(200)
20
+ .pasteString(`<span class="block w-full h-[1rem]"></span>`)
21
+ .pasteString(`<div class="block text-grey"><span class="text-vite">VITE+ v1.0.0</span> <span class="text-aqua">lint</span></div>`)
22
+ .pauseFor(500)
23
+ .pasteString(`<div class="block text-grey">Found <span class="text-white">0 warnings</span> and <span class="text-white">0 errors</span>.</div>`)
24
+ .pasteString(`<div class="block text-grey"><span class="text-zest">✓</span> Finished in <span class="text-white">1ms</span> on <span class="text-white">3 files</span> with <span class="text-white">88 rules</span> using <span class="text-white">10 threads</span>.</div>`)
25
+ .pasteString(`<span class="block w-full h-[1rem]"></span>`)
26
+ .callFunction(() => {
27
+ if (props.onAnimationComplete) {
28
+ props.onAnimationComplete()
29
+ }
30
+ })
31
+ .start();
32
+ })
33
+
34
+ onUnmounted(() => {
35
+ if(typewriter){
36
+ typewriter.stop()
37
+ }
38
+ })
39
+ </script>
40
+
41
+ <template>
42
+ <p class="font-mono text-sm text-white leading-[1.5rem]">
43
+ <span id="terminal-code"></span>
44
+ </p>
45
+ </template>
@@ -0,0 +1,49 @@
1
+ <script setup lang="ts">
2
+ import Typewriter from 'typewriter-effect/dist/core'
3
+ import {onMounted, onUnmounted} from "vue";
4
+
5
+ const props = defineProps<{
6
+ onAnimationComplete?: () => void
7
+ }>()
8
+
9
+ let typewriter;
10
+
11
+ onMounted(() => {
12
+ const target = document.getElementById('terminal-code');
13
+ typewriter = new Typewriter(target, {
14
+ loop: false,
15
+ delay: 1,
16
+ })
17
+ typewriter
18
+ .typeString(`<span>$ vite fmt</span>`)
19
+ .pauseFor(200)
20
+ .pasteString(`<span class="block w-full h-[1rem]"></span>`)
21
+ .pasteString(`<div class="block text-grey"><span class="text-vite">VITE+ v1.0.0</span> <span class="text-aqua">fmt</span></div>`)
22
+ .pauseFor(500)
23
+ .pasteString(`<div class="block">src/App.css <span class="text-aqua">0ms</span> <span class="text-grey">(unchanged)</span></div>`)
24
+ .pasteString(`<div class="block">src/App.tsx <span class="text-aqua">1ms</span></div>`)
25
+ .pasteString(`<div class="block">src/index.css <span class="text-aqua">0ms</span> <span class="text-grey">(unchanged)</span></div>`)
26
+ .pasteString(`<div class="block">src/main.tsx <span class="text-aqua">1ms</span></div>`)
27
+ .pasteString(`<div class="block">src/vite-env.d.ts <span class="text-aqua">0ms</span> <span class="text-grey">(unchanged)</span></div>`)
28
+ .pasteString(`<div class="block"><span class="text-zest">✓</span> Formatted <span class="text-aqua">2 files</span> in <span class="text-aqua">2ms</span>.</div>`)
29
+ .pasteString(`<span class="block w-full h-[1rem]"></span>`)
30
+ .callFunction(() => {
31
+ if (props.onAnimationComplete) {
32
+ props.onAnimationComplete()
33
+ }
34
+ })
35
+ .start();
36
+ })
37
+
38
+ onUnmounted(() => {
39
+ if(typewriter){
40
+ typewriter.stop()
41
+ }
42
+ })
43
+ </script>
44
+
45
+ <template>
46
+ <p class="font-mono text-sm text-white leading-[1.5rem]">
47
+ <span id="terminal-code"></span>
48
+ </p>
49
+ </template>
@@ -0,0 +1,50 @@
1
+ <script setup lang="ts">
2
+ import Typewriter from 'typewriter-effect/dist/core'
3
+ import {onMounted, onUnmounted} from "vue";
4
+
5
+ const props = defineProps<{
6
+ onAnimationComplete?: () => void
7
+ }>()
8
+
9
+ let typewriter;
10
+
11
+ onMounted(() => {
12
+ const target = document.getElementById('terminal-code');
13
+ typewriter = new Typewriter(target, {
14
+ loop: false,
15
+ delay: 1,
16
+ })
17
+ typewriter
18
+ .typeString(`<span>$ vite test</span>`)
19
+ .pauseFor(200)
20
+ .pasteString(`<span class="block w-full h-[1rem]"></span>`)
21
+ .pasteString(`<div class="block"><span class="text-vite">VITE+ v1.0.0</span> <span class="text-aqua">test</span> RUN ~/vite-plus-demo</div>`)
22
+ .pasteString(`<span class="block w-full h-[1rem]"></span>`)
23
+ .pauseFor(300)
24
+ .pasteString(`<div class="block"><span class="text-zest">✓</span> test/hello.spec.ts <span class="text-grey">(1 test)</span> <span class="text-zest">1ms</span></div>`)
25
+ .pasteString(`<span class="block w-full h-[1rem]"></span>`)
26
+ .pasteString(`<div class="block text-grey">Test Files <span class="text-zest">1 passed</span> <span class="text-grey">(1)</span></div>`)
27
+ .pasteString(`<div class="block text-grey">Tests <span class="text-zest">1 passed</span> <span class="text-grey">(1)</span></div>`)
28
+ .pasteString(`<div class="block text-grey">Start at <span class="text-white">00:13:44</span></div>`)
29
+ .pasteString(`<div class="block text-grey">Duration <span class="text-white">199ms</span> <span class="text-grey">(transform 13ms, setup 0ms, collect 8ms, tests 1ms, environment 0ms, prepare 33ms)</span></div>`)
30
+ .pasteString(`<span class="block w-full h-[1rem]"></span>`)
31
+ .callFunction(() => {
32
+ if (props.onAnimationComplete) {
33
+ props.onAnimationComplete()
34
+ }
35
+ })
36
+ .start();
37
+ })
38
+
39
+ onUnmounted(() => {
40
+ if(typewriter){
41
+ typewriter.stop()
42
+ }
43
+ })
44
+ </script>
45
+
46
+ <template>
47
+ <p class="font-mono text-sm text-white leading-[1.5rem]">
48
+ <span id="terminal-code"></span>
49
+ </p>
50
+ </template>