@alphacifer/slidev-addon-theme 0.0.1

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/README.md ADDED
@@ -0,0 +1,47 @@
1
+ # @alphacifer/slidev-addon-theme
2
+
3
+ Shared Slidev components and layouts for Alpha presentations.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pnpm add -D @alphacifer/slidev-addon-theme
9
+ ```
10
+
11
+ ```yaml
12
+ ---
13
+ addons:
14
+ - '@alphacifer/slidev-addon-theme'
15
+ ---
16
+ ```
17
+
18
+ ## Core
19
+
20
+ - Components: `Date`, `QnA`, `Quote`, `ReflectedTitle`, `Speaker`
21
+ - Layouts: `bg-center`, `table-of-contents`
22
+
23
+ ## Shifting heading
24
+
25
+ - Component: `TransitionHeading`
26
+ - Layout: `shifting-intro`
27
+ - Utilities: `mergeUno`, `createUnoClassMerger`
28
+
29
+ ## Thanks
30
+
31
+ - Components: `ThanksContent`, `ThanksOutlineSquare`, `ThanksSquare`
32
+ - Layout: `thanks`
33
+
34
+ ## Preview
35
+
36
+ ```bash
37
+ pnpm --filter @alphacifer/slidev-addon-theme dev
38
+ ```
39
+
40
+ The preview deck is defined in `slides.md` and loads this package locally as a
41
+ Slidev addon.
42
+
43
+ Build the preview without opening a browser:
44
+
45
+ ```bash
46
+ pnpm --filter @alphacifer/slidev-addon-theme preview:build
47
+ ```
@@ -0,0 +1,31 @@
1
+ <script setup lang="ts">
2
+ import { formatDate } from '@alphacifer/core-utils/dateUtils';
3
+
4
+ import { useMergedUnoAttrs } from '../../utils/useMergedUnoAttrs';
5
+
6
+ defineOptions({
7
+ inheritAttrs: false,
8
+ });
9
+
10
+ const props = defineProps({
11
+ date: {
12
+ type: String,
13
+ required: false,
14
+ },
15
+ });
16
+
17
+ const formattedDate = formatDate(props.date, {
18
+ format: 'dd/MM/yyyy',
19
+ });
20
+
21
+ const { className, forwardedAttrs } = useMergedUnoAttrs('slidev-addon-date');
22
+ </script>
23
+
24
+ <template>
25
+ <div
26
+ v-bind="forwardedAttrs()"
27
+ :class="className()"
28
+ >
29
+ Date: {{ formattedDate }}
30
+ </div>
31
+ </template>
@@ -0,0 +1,83 @@
1
+ <script setup lang="ts">
2
+ import { useMergedUnoAttrs } from '../../utils/useMergedUnoAttrs';
3
+
4
+ defineOptions({
5
+ inheritAttrs: false,
6
+ });
7
+
8
+ defineProps({
9
+ startDelay: {
10
+ type: Number,
11
+ default: 11_500,
12
+ },
13
+ });
14
+
15
+ const { className, forwardedAttrs } = useMergedUnoAttrs(
16
+ 'slidev-addon-qna flex items-center gap-8 text-8xl font-bold color-[#2b90b6]',
17
+ );
18
+ </script>
19
+
20
+ <template>
21
+ <div
22
+ v-bind="forwardedAttrs()"
23
+ :class="className()"
24
+ >
25
+ <span
26
+ v-motion
27
+ :initial="{
28
+ opacity: 0,
29
+ x: -500,
30
+ rotate: -360,
31
+ }"
32
+ :enter="{
33
+ opacity: 1,
34
+ x: 0,
35
+ rotate: 0,
36
+ transition: {
37
+ duration: 800,
38
+ ease: 'easeOut',
39
+ delay: 400 + startDelay,
40
+ }
41
+ }"
42
+ >
43
+ Q
44
+ </span>
45
+ <span
46
+ v-motion
47
+ :initial="{
48
+ opacity: 1,
49
+ y: -1_000
50
+ }"
51
+ :enter="{
52
+ y: [-1_000, 0],
53
+ transition: {
54
+ y: {
55
+ duration: 1_000,
56
+ type: 'spring',
57
+ stiffness: 200,
58
+ damping: 15,
59
+ delay: 0 + startDelay,
60
+ }
61
+ }
62
+ }"
63
+ >
64
+ &
65
+ </span>
66
+ <span
67
+ v-motion
68
+ :initial="{ opacity: 0, x: 500, rotate: 360 }"
69
+ :enter="{
70
+ opacity: 1,
71
+ x: 0,
72
+ rotate: 0,
73
+ transition: {
74
+ duration: 800,
75
+ ease: 'easeOut',
76
+ delay: 600 + startDelay,
77
+ },
78
+ }"
79
+ >
80
+ A
81
+ </span>
82
+ </div>
83
+ </template>
@@ -0,0 +1,42 @@
1
+ <script setup lang="ts">
2
+ import { computed } from 'vue';
3
+
4
+ import { mergeUno } from '../../utils/mergeUno';
5
+ import { useMergedUnoAttrs } from '../../utils/useMergedUnoAttrs';
6
+
7
+ defineOptions({
8
+ inheritAttrs: false,
9
+ });
10
+
11
+ const props = defineProps({
12
+ text: {
13
+ type: String,
14
+ required: true,
15
+ },
16
+ author: {
17
+ type: String,
18
+ required: false,
19
+ },
20
+ titleClass: {
21
+ type: String,
22
+ required: false,
23
+ },
24
+ });
25
+
26
+ const { className, forwardedAttrs } = useMergedUnoAttrs(
27
+ 'slidev-addon-quote flex flex-col',
28
+ );
29
+ const titleClasses = computed(() => {
30
+ return mergeUno('text-center', props.titleClass);
31
+ });
32
+ </script>
33
+
34
+ <template>
35
+ <div
36
+ v-bind="forwardedAttrs()"
37
+ :class="className()"
38
+ >
39
+ <h1 :class="titleClasses">"{{ text }}"</h1>
40
+ <p v-if="author" class="self-end">— {{ author }}</p>
41
+ </div>
42
+ </template>
@@ -0,0 +1,50 @@
1
+ <script setup lang="ts">
2
+ import { useMergedUnoAttrs } from '../../utils/useMergedUnoAttrs';
3
+
4
+ defineOptions({
5
+ inheritAttrs: false,
6
+ });
7
+
8
+ defineProps({
9
+ title: {
10
+ type: String,
11
+ required: true,
12
+ },
13
+ });
14
+
15
+ const { className, forwardedAttrs } = useMergedUnoAttrs(`
16
+ slidev-addon-reflected-title
17
+ relative
18
+ text-5xl
19
+ font-bold
20
+ tracking-tight
21
+ !text-[#a5f3fc]
22
+ after:content-[var(--title)]
23
+ after:block
24
+ after:mt-2
25
+ after:absolute
26
+ after:text-current
27
+ after:opacity-60
28
+ after:text-3xl
29
+ after:font-light
30
+ after:tracking-normal
31
+ after:w-full
32
+ after:text-center
33
+ after:overflow-hidden
34
+ after:mask-[linear-gradient(to_bottom,black_0%,transparent_100%)]
35
+ after:animate-slide-in-down
36
+ after:animate-duration-1000
37
+ `);
38
+ </script>
39
+
40
+ <template>
41
+ <h1
42
+ v-bind="forwardedAttrs()"
43
+ :style="{
44
+ '--title': `'${title}'`,
45
+ }"
46
+ :class="className()"
47
+ >
48
+ {{ title }}
49
+ </h1>
50
+ </template>
@@ -0,0 +1,46 @@
1
+ <script setup lang="ts">
2
+ import { useMergedUnoAttrs } from '../../utils/useMergedUnoAttrs';
3
+
4
+ defineOptions({
5
+ inheritAttrs: false,
6
+ });
7
+
8
+ const props = defineProps({
9
+ author: {
10
+ type: String,
11
+ required: false,
12
+ default: 'Alpha',
13
+ },
14
+ team: {
15
+ type: Array,
16
+ required: false,
17
+ default: () => [],
18
+ },
19
+ date: {
20
+ type: String,
21
+ required: true,
22
+ },
23
+ });
24
+
25
+ const { className, forwardedAttrs } = useMergedUnoAttrs(() => [
26
+ 'slidev-addon-speaker flex absolute bottom-[15px] right-[30px] flex-col',
27
+ props.team.length ? 'text-left gap-2' : undefined,
28
+ ]);
29
+ </script>
30
+
31
+ <template>
32
+ <div
33
+ v-bind="forwardedAttrs()"
34
+ :class="className()"
35
+ >
36
+ <div v-if="team.length">
37
+ <div v-for="member in team" :key="member as string">
38
+ {{ member }}
39
+ </div>
40
+ </div>
41
+ <div v-else>
42
+ Author: {{ author }}
43
+ </div>
44
+ <Date :date="date" />
45
+ </div>
46
+ </template>
@@ -0,0 +1,80 @@
1
+ <script setup lang="ts">
2
+ import { useMergedUnoAttrs } from '../../utils/useMergedUnoAttrs';
3
+
4
+ defineOptions({
5
+ inheritAttrs: false,
6
+ });
7
+
8
+ defineProps({
9
+ center: {
10
+ type: Boolean,
11
+ default: false,
12
+ },
13
+ idle: {
14
+ type: Boolean,
15
+ default: false,
16
+ },
17
+ });
18
+
19
+ const { className, forwardedAttrs } = useMergedUnoAttrs(`
20
+ shifting-heading
21
+ absolute
22
+ z-1
23
+ start-[var(--shifting-heading-inline,3.5rem)]
24
+ top-[var(--shifting-heading-top,2.5rem)]
25
+ w-max
26
+ translate-x-0
27
+ translate-y-0
28
+ origin-left
29
+ `);
30
+ </script>
31
+
32
+ <template>
33
+ <div
34
+ v-bind="forwardedAttrs()"
35
+ :class="className()"
36
+ :data-shifting-heading-state="center && !idle ? 'centered' : 'shifted'"
37
+ >
38
+ <slot />
39
+ </div>
40
+ </template>
41
+
42
+ <style>
43
+ .shifting-heading {
44
+ max-width: calc(
45
+ 100% - var(--shifting-heading-inline, 3.5rem) -
46
+ var(--shifting-heading-inline, 3.5rem)
47
+ );
48
+ transition:
49
+ inset-inline-start var(--shifting-heading-duration, 700ms) ease-in-out,
50
+ top var(--shifting-heading-duration, 700ms) ease-in-out,
51
+ transform var(--shifting-heading-duration, 700ms) ease-in-out;
52
+ will-change: inset-inline-start, top, transform;
53
+ }
54
+
55
+ .shifting-heading > :is(h1, h2, h3, h4, h5, h6) {
56
+ max-width: 100%;
57
+ margin: 0;
58
+ overflow-wrap: anywhere;
59
+ text-wrap: balance;
60
+ }
61
+
62
+ .shifting-heading[data-shifting-heading-state='centered'] {
63
+ inset-inline-start: 50%;
64
+ top: 50%;
65
+ text-align: center;
66
+ transform: translate(-50%, -50%);
67
+ transform-origin: center;
68
+ }
69
+
70
+ :where([dir='rtl'])
71
+ .shifting-heading[data-shifting-heading-state='centered'] {
72
+ transform: translate(50%, -50%);
73
+ }
74
+
75
+ @media (prefers-reduced-motion: reduce) {
76
+ .shifting-heading {
77
+ transition-duration: 1ms;
78
+ }
79
+ }
80
+ </style>
@@ -0,0 +1,235 @@
1
+ <script setup lang="ts">
2
+ import type { MotionVariants, Variant } from '@vueuse/motion';
3
+
4
+ import { useMergedUnoAttrs } from '../../utils/useMergedUnoAttrs';
5
+
6
+ defineOptions({
7
+ inheritAttrs: false,
8
+ });
9
+
10
+ const { animation } = defineProps({
11
+ animation: {
12
+ type: Boolean,
13
+ default: true,
14
+ },
15
+ });
16
+
17
+ const begin = {
18
+ scale: 1.5,
19
+ rotate: -50,
20
+ };
21
+
22
+ const final = {
23
+ scale: 1,
24
+ rotate: 45,
25
+ translateX: '-50%',
26
+ translateY: '-50%',
27
+ transition: {
28
+ mass: 4,
29
+ damping: 10,
30
+ stiffness: 20,
31
+ type: 'spring',
32
+ },
33
+ };
34
+
35
+ interface IGetMotionPropsParams {
36
+ enter: Variant;
37
+ initial: Variant;
38
+ }
39
+
40
+ const getMotionProps = ({
41
+ enter,
42
+ initial,
43
+ }: IGetMotionPropsParams): MotionVariants<string> => {
44
+ if (!animation) {
45
+ const state = {
46
+ ...enter,
47
+ transition: {
48
+ duration: 0,
49
+ },
50
+ };
51
+
52
+ return {
53
+ enter: state,
54
+ initial: state,
55
+ };
56
+ }
57
+
58
+ return {
59
+ enter,
60
+ initial,
61
+ };
62
+ };
63
+
64
+ const { className, forwardedAttrs } = useMergedUnoAttrs(
65
+ 'slidev-addon-thanks-content relative h-full w-full',
66
+ );
67
+ </script>
68
+
69
+ <template>
70
+ <div
71
+ v-bind="forwardedAttrs()"
72
+ :class="className()"
73
+ >
74
+ <ThanksSquare
75
+ v-motion
76
+ v-bind="getMotionProps({
77
+ enter: {
78
+ ...final,
79
+ x: -78,
80
+ y: 30,
81
+ },
82
+ initial: {
83
+ ...begin,
84
+ x: 900,
85
+ y: -100,
86
+ },
87
+ })"
88
+ class="absolute w-[150px] h-[150px] rotate-45 top-[50%] left-[40%] z-10"
89
+ />
90
+ <ThanksSquare
91
+ v-motion
92
+ v-bind="getMotionProps({
93
+ initial: {
94
+ y: -150,
95
+ opacity: 0,
96
+ },
97
+ enter:{
98
+ x: -50,
99
+ y: -60,
100
+ rotate: 45,
101
+ opacity: 0.4,
102
+ transition: {
103
+ delay: 2_500,
104
+ duration: 700,
105
+ }
106
+ },
107
+ })"
108
+ class="w-[100px] h-[100px] top-[20%] rotate-45 left-[48%] translate-x-[-50%] translate-y-[-50%] opacity-[0.4]"
109
+ />
110
+ <ThanksSquare
111
+ v-motion
112
+ v-bind="getMotionProps({
113
+ initial: {
114
+ x: -150,
115
+ opacity: 0,
116
+ },
117
+ enter: {
118
+ x: -50,
119
+ y: -65,
120
+ rotate: 45,
121
+ opacity: 0.4,
122
+ transition: {
123
+ delay: 2_500,
124
+ duration: 700,
125
+ }
126
+ },
127
+ })"
128
+ class="w-[100px] h-[100px] top-[45%] rotate-45 left-[22%] translate-x-[-50%] translate-y-[-50%] opacity-[0.4]"
129
+ />
130
+ <ThanksSquare
131
+ v-motion
132
+ v-bind="getMotionProps({
133
+ initial: {
134
+ y: 150,
135
+ opacity: 0,
136
+ },
137
+ enter: {
138
+ x: -50,
139
+ y: -45,
140
+ rotate: 45,
141
+ opacity: 0.4,
142
+ transition: {
143
+ delay: 2_500,
144
+ duration: 700,
145
+ }
146
+ },
147
+ })"
148
+ class="w-[100px] h-[100px] bottom-0 rotate-45 left-[48%] translate-x-[-50%] translate-y-[-50%] opacity-[0.4]"
149
+ />
150
+ <ThanksOutlineSquare
151
+ v-motion
152
+ v-bind="getMotionProps({
153
+ initial: {
154
+ ...begin,
155
+ x: 0,
156
+ y: -1000,
157
+ },
158
+ enter: {
159
+ ...final,
160
+ x: -2,
161
+ y: 72,
162
+ transition: {
163
+ delay: 700,
164
+ duration: 2_000,
165
+ },
166
+ },
167
+ })"
168
+ class="w-[120px] h-[120px] rotate-45 top-[25%] left-[31%]"
169
+ />
170
+ <ThanksOutlineSquare
171
+ v-motion
172
+ v-bind="getMotionProps({
173
+ initial: {
174
+ ...begin,
175
+ x: 0,
176
+ y: 1000,
177
+ },
178
+ enter: {
179
+ ...final,
180
+ x: -3,
181
+ y: 45,
182
+ transition: {
183
+ delay: 700,
184
+ duration: 2_000,
185
+ },
186
+ },
187
+ })"
188
+ class="w-[70px] h-[70px] rotate-45 top-[52%] left-[30%]"
189
+ />
190
+ <ThanksOutlineSquare
191
+ v-motion
192
+ v-bind="getMotionProps({
193
+ initial: {
194
+ ...begin,
195
+ x: 1000,
196
+ y: 200,
197
+ },
198
+ enter: {
199
+ ...final,
200
+ x: -2,
201
+ y: 72,
202
+ transition: {
203
+ delay: 700,
204
+ duration: 2_000,
205
+ },
206
+ },
207
+ })"
208
+ class="w-[100px] h-[100px] rotate-45 top-[42%] left-[43%]"
209
+ />
210
+
211
+ <div
212
+ v-motion
213
+ v-bind="getMotionProps({
214
+ initial: {
215
+ x: -80,
216
+ opacity: 0,
217
+ },
218
+ enter: {
219
+ x: -130,
220
+ y: -46,
221
+ opacity: 1,
222
+ transition: {
223
+ delay: 2_800,
224
+ duration: 1_000,
225
+ }
226
+ },
227
+ })"
228
+ class="color-[#2b90b6] text-3xl absolute top-[50%] left-[69%] translate-x-[-50%] translate-y-[-50%]"
229
+ >
230
+ Thank You
231
+ <br />
232
+ for your attention!
233
+ </div>
234
+ </div>
235
+ </template>
@@ -0,0 +1,18 @@
1
+ <script setup lang="ts">
2
+ import { useMergedUnoAttrs } from '../../utils/useMergedUnoAttrs';
3
+
4
+ defineOptions({
5
+ inheritAttrs: false,
6
+ });
7
+
8
+ const { className, forwardedAttrs } = useMergedUnoAttrs(
9
+ 'slidev-addon-thanks-outline-square absolute rounded-2xl border-2 border-color-cyan-500',
10
+ );
11
+ </script>
12
+
13
+ <template>
14
+ <div
15
+ v-bind="forwardedAttrs()"
16
+ :class="className()"
17
+ />
18
+ </template>
@@ -0,0 +1,18 @@
1
+ <script setup lang="ts">
2
+ import { useMergedUnoAttrs } from '../../utils/useMergedUnoAttrs';
3
+
4
+ defineOptions({
5
+ inheritAttrs: false,
6
+ });
7
+
8
+ const { className, forwardedAttrs } = useMergedUnoAttrs(
9
+ 'slidev-addon-thanks-square absolute bg-gradient-to-br from-cyan-500 to-blue-500 rounded-3xl',
10
+ );
11
+ </script>
12
+
13
+ <template>
14
+ <div
15
+ v-bind="forwardedAttrs()"
16
+ :class="className()"
17
+ />
18
+ </template>
@@ -0,0 +1,34 @@
1
+ <script setup lang="ts">
2
+ import { handleBackground } from '@slidev/client';
3
+ import { computed } from 'vue';
4
+
5
+ import { useMergedUnoAttrs } from '../../utils/useMergedUnoAttrs';
6
+
7
+ defineOptions({
8
+ inheritAttrs: false,
9
+ });
10
+
11
+ const { background } = defineProps({
12
+ background: {
13
+ default: '',
14
+ },
15
+ });
16
+
17
+ const style = computed(() => {
18
+ return handleBackground(background, true);
19
+ });
20
+
21
+ const { className, forwardedAttrs } = useMergedUnoAttrs(
22
+ 'slidev-layout bg-center h-full grid place-content-center',
23
+ );
24
+ </script>
25
+
26
+ <template>
27
+ <div
28
+ v-bind="forwardedAttrs()"
29
+ :class="className()"
30
+ :style="style"
31
+ >
32
+ <slot />
33
+ </div>
34
+ </template>