@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.
@@ -0,0 +1,30 @@
1
+ <script setup lang="ts">
2
+ import { useMergedUnoAttrs } from '../../utils/useMergedUnoAttrs';
3
+
4
+ defineOptions({
5
+ inheritAttrs: false,
6
+ });
7
+
8
+ defineProps({
9
+ maxDepth: {
10
+ type: [Number, String],
11
+ default: 1,
12
+ },
13
+ });
14
+
15
+ const { className, forwardedAttrs } = useMergedUnoAttrs(
16
+ 'slidev-layout default toc-layout',
17
+ );
18
+ </script>
19
+
20
+ <template>
21
+ <div
22
+ v-bind="forwardedAttrs()"
23
+ :class="className()"
24
+ >
25
+ <slot>
26
+ <h1>Table of Contents</h1>
27
+ </slot>
28
+ <Toc :maxDepth="maxDepth" />
29
+ </div>
30
+ </template>
@@ -0,0 +1,111 @@
1
+ <script setup lang="ts">
2
+ import { useSlideContext } from '@slidev/client';
3
+ import { computed, Fragment, isVNode, useSlots, type VNode } from 'vue';
4
+
5
+ import { useMergedUnoAttrs } from '../../utils/useMergedUnoAttrs';
6
+
7
+ defineOptions({
8
+ inheritAttrs: false,
9
+ });
10
+
11
+ const slots = useSlots();
12
+ const { $clicks } = useSlideContext();
13
+
14
+ function flattenTopLevel(nodes: VNode[]): VNode[] {
15
+ return nodes.flatMap((node) => {
16
+ if (node.type === Fragment && Array.isArray(node.children))
17
+ return flattenTopLevel(node.children.filter(isVNode));
18
+
19
+ return node;
20
+ });
21
+ }
22
+
23
+ const nodes = computed(() => {
24
+ const children = flattenTopLevel(slots.default?.() ?? []);
25
+ const titleIndex = children.findIndex((node) => node.type === 'h1');
26
+
27
+ return {
28
+ title: titleIndex >= 0 ? children[titleIndex] : null,
29
+ contents:
30
+ titleIndex >= 0
31
+ ? children.filter((_, index) => index !== titleIndex)
32
+ : children,
33
+ };
34
+ });
35
+
36
+ const isRevealed = computed(() => !nodes.value.title || $clicks.value > 0);
37
+ const { className, forwardedAttrs } = useMergedUnoAttrs(
38
+ 'slidev-layout shifting-intro-layout relative',
39
+ );
40
+ </script>
41
+
42
+ <template>
43
+ <div
44
+ v-bind="forwardedAttrs()"
45
+ :class="className()"
46
+ >
47
+ <TransitionHeading
48
+ v-if="nodes.title"
49
+ :center="!isRevealed"
50
+ :idle="isRevealed"
51
+ >
52
+ <component :is="nodes.title" />
53
+ </TransitionHeading>
54
+
55
+ <VClickGap
56
+ v-if="nodes.title"
57
+ :size="1"
58
+ />
59
+
60
+ <div
61
+ class="shifting-intro-content"
62
+ :class="{ 'is-revealed': isRevealed }"
63
+ :aria-hidden="!isRevealed"
64
+ :inert="!isRevealed || undefined"
65
+ >
66
+ <component
67
+ :is="content"
68
+ v-for="(content, index) in nodes.contents"
69
+ :key="content.key ?? index"
70
+ />
71
+ </div>
72
+ </div>
73
+ </template>
74
+
75
+ <style>
76
+ .shifting-intro-content {
77
+ box-sizing: border-box;
78
+ min-height: 100%;
79
+ padding-top: var(--shifting-heading-content-offset, 4.25rem);
80
+ visibility: hidden;
81
+ opacity: 0;
82
+ transition:
83
+ opacity var(--shifting-content-exit-duration, 250ms) ease-out,
84
+ visibility 0s linear var(--shifting-content-exit-duration, 250ms);
85
+ }
86
+
87
+ .shifting-intro-content.is-revealed {
88
+ visibility: visible;
89
+ opacity: 1;
90
+ transition:
91
+ opacity var(--shifting-content-duration, 700ms) ease-out
92
+ var(--shifting-content-delay, 450ms),
93
+ visibility 0s linear;
94
+ }
95
+
96
+ @media (prefers-reduced-motion: reduce) {
97
+ .shifting-intro-content,
98
+ .shifting-intro-content.is-revealed {
99
+ transition-duration: 1ms;
100
+ transition-delay: 0ms;
101
+ }
102
+ }
103
+
104
+ @media print {
105
+ .shifting-heading,
106
+ .shifting-intro-content,
107
+ .shifting-intro-content.is-revealed {
108
+ transition: none;
109
+ }
110
+ }
111
+ </style>
@@ -0,0 +1,20 @@
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-layout thanks relative',
10
+ );
11
+ </script>
12
+
13
+ <template>
14
+ <div
15
+ v-bind="forwardedAttrs()"
16
+ :class="className()"
17
+ >
18
+ <ThanksContent />
19
+ </div>
20
+ </template>
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "@alphacifer/slidev-addon-theme",
3
+ "version": "0.0.1",
4
+ "description": "All Slidev addons for Alpha presentations",
5
+ "type": "module",
6
+ "keywords": [
7
+ "slidev-addon",
8
+ "slidev"
9
+ ],
10
+ "files": [
11
+ "components",
12
+ "layouts",
13
+ "utils",
14
+ "README.md"
15
+ ],
16
+ "publishConfig": {
17
+ "access": "public",
18
+ "registry": "https://registry.npmjs.org/"
19
+ },
20
+ "author": "Alpha",
21
+ "repository": {
22
+ "type": "git",
23
+ "url": "git+https://github.com/zgid123/alpha-dx.git",
24
+ "directory": "packages/slidev-addon-theme"
25
+ },
26
+ "license": "MIT",
27
+ "peerDependencies": {
28
+ "@slidev/client": ">=52.18.0",
29
+ "vue": "^3.5.40"
30
+ },
31
+ "dependencies": {
32
+ "@vueuse/motion": "3.0.3",
33
+ "@alphacifer/core-utils": "^0.0.10"
34
+ },
35
+ "devDependencies": {
36
+ "@slidev/client": "52.19.0",
37
+ "@slidev/cli": "52.19.0",
38
+ "@slidev/theme-seriph": "0.25.0",
39
+ "vue": "3.5.40"
40
+ },
41
+ "scripts": {
42
+ "dev": "slidev slides.md --open",
43
+ "preview:build": "slidev build slides.md"
44
+ }
45
+ }
@@ -0,0 +1,245 @@
1
+ import type { IClassifyUtilityParams, TUtilityConflictKeys } from './types';
2
+
3
+ const DISPLAY_VALUES = new Set([
4
+ 'block',
5
+ 'contents',
6
+ 'flow-root',
7
+ 'flex',
8
+ 'grid',
9
+ 'hidden',
10
+ 'inline',
11
+ 'inline-block',
12
+ 'inline-flex',
13
+ 'inline-grid',
14
+ 'list-item',
15
+ 'table',
16
+ 'table-caption',
17
+ 'table-cell',
18
+ 'table-column',
19
+ 'table-column-group',
20
+ 'table-footer-group',
21
+ 'table-header-group',
22
+ 'table-row',
23
+ 'table-row-group',
24
+ ]);
25
+
26
+ const POSITION_VALUES = new Set([
27
+ 'absolute',
28
+ 'fixed',
29
+ 'relative',
30
+ 'static',
31
+ 'sticky',
32
+ ]);
33
+
34
+ const SPACING_SIDES: Readonly<Record<string, readonly string[]>> = {
35
+ '': ['top', 'right', 'bottom', 'left'],
36
+ b: ['bottom'],
37
+ e: ['inline-end'],
38
+ l: ['left'],
39
+ r: ['right'],
40
+ s: ['inline-start'],
41
+ t: ['top'],
42
+ x: ['left', 'right'],
43
+ y: ['top', 'bottom'],
44
+ };
45
+
46
+ function directionKeys(property: string, direction: string): string[] {
47
+ return (SPACING_SIDES[direction] ?? []).map((side) => `${property}-${side}`);
48
+ }
49
+
50
+ export function classifyLayout({
51
+ utility,
52
+ }: IClassifyUtilityParams): TUtilityConflictKeys {
53
+ if (DISPLAY_VALUES.has(utility)) {
54
+ return ['display'];
55
+ }
56
+
57
+ if (POSITION_VALUES.has(utility)) {
58
+ return ['position'];
59
+ }
60
+
61
+ const spacing = utility.match(/^([mp])([trblesxy]?)-/);
62
+
63
+ if (spacing) {
64
+ const property = spacing[1] === 'm' ? 'margin' : 'padding';
65
+ return directionKeys(property, spacing[2] || '');
66
+ }
67
+
68
+ if (utility.startsWith('inset-x-')) {
69
+ return ['left', 'right'];
70
+ }
71
+
72
+ if (utility.startsWith('inset-y-')) {
73
+ return ['top', 'bottom'];
74
+ }
75
+
76
+ if (utility.startsWith('inset-')) {
77
+ return ['top', 'right', 'bottom', 'left'];
78
+ }
79
+
80
+ if (/^(?:top|right|bottom|left|start|end)-/.test(utility)) {
81
+ return [utility.slice(0, utility.indexOf('-'))];
82
+ }
83
+
84
+ if (/^(?:size)-/.test(utility)) {
85
+ return ['width', 'height'];
86
+ }
87
+
88
+ if (/^(?:w|min-w|max-w)-/.test(utility)) {
89
+ return [utility.slice(0, utility.indexOf('-'))];
90
+ }
91
+
92
+ if (/^(?:h|min-h|max-h)-/.test(utility)) {
93
+ return [utility.slice(0, utility.indexOf('-'))];
94
+ }
95
+
96
+ if (utility.startsWith('z-')) {
97
+ return ['z-index'];
98
+ }
99
+
100
+ if (utility.startsWith('opacity-')) {
101
+ return ['opacity'];
102
+ }
103
+
104
+ if (utility.startsWith('overflow-x-')) {
105
+ return ['overflow-x'];
106
+ }
107
+
108
+ if (utility.startsWith('overflow-y-')) {
109
+ return ['overflow-y'];
110
+ }
111
+
112
+ if (utility.startsWith('overflow-')) {
113
+ return ['overflow-x', 'overflow-y'];
114
+ }
115
+
116
+ if (utility.startsWith('overscroll-x-')) {
117
+ return ['overscroll-x'];
118
+ }
119
+
120
+ if (utility.startsWith('overscroll-y-')) {
121
+ return ['overscroll-y'];
122
+ }
123
+
124
+ if (utility.startsWith('overscroll-')) {
125
+ return ['overscroll-x', 'overscroll-y'];
126
+ }
127
+
128
+ if (/^flex-(?:row|row-reverse|col|col-reverse)$/.test(utility)) {
129
+ return ['flex-direction'];
130
+ }
131
+
132
+ if (/^flex-(?:wrap|wrap-reverse|nowrap)$/.test(utility)) {
133
+ return ['flex-wrap'];
134
+ }
135
+
136
+ if (/^flex-(?:grow|shrink)(?:-|$)/.test(utility)) {
137
+ return [utility.startsWith('flex-grow') ? 'flex-grow' : 'flex-shrink'];
138
+ }
139
+
140
+ if (utility.startsWith('flex-')) {
141
+ return ['flex'];
142
+ }
143
+
144
+ if (utility.startsWith('basis-')) {
145
+ return ['flex-basis'];
146
+ }
147
+
148
+ if (utility.startsWith('order-')) {
149
+ return ['order'];
150
+ }
151
+
152
+ if (utility.startsWith('grid-cols-')) {
153
+ return ['grid-template-columns'];
154
+ }
155
+
156
+ if (utility.startsWith('grid-rows-')) {
157
+ return ['grid-template-rows'];
158
+ }
159
+
160
+ if (utility.startsWith('col-span-') || utility.startsWith('col-auto')) {
161
+ return ['grid-column'];
162
+ }
163
+
164
+ if (utility.startsWith('col-start-')) {
165
+ return ['grid-column-start'];
166
+ }
167
+
168
+ if (utility.startsWith('col-end-')) {
169
+ return ['grid-column-end'];
170
+ }
171
+
172
+ if (utility.startsWith('row-span-') || utility.startsWith('row-auto')) {
173
+ return ['grid-row'];
174
+ }
175
+
176
+ if (utility.startsWith('row-start-')) {
177
+ return ['grid-row-start'];
178
+ }
179
+
180
+ if (utility.startsWith('row-end-')) {
181
+ return ['grid-row-end'];
182
+ }
183
+
184
+ if (utility.startsWith('grid-flow-')) {
185
+ return ['grid-auto-flow'];
186
+ }
187
+
188
+ if (utility.startsWith('auto-cols-')) {
189
+ return ['grid-auto-columns'];
190
+ }
191
+
192
+ if (utility.startsWith('auto-rows-')) {
193
+ return ['grid-auto-rows'];
194
+ }
195
+
196
+ if (utility.startsWith('gap-x-')) {
197
+ return ['column-gap'];
198
+ }
199
+
200
+ if (utility.startsWith('gap-y-')) {
201
+ return ['row-gap'];
202
+ }
203
+
204
+ if (utility.startsWith('gap-')) {
205
+ return ['column-gap', 'row-gap'];
206
+ }
207
+
208
+ if (utility.startsWith('justify-items-')) {
209
+ return ['justify-items'];
210
+ }
211
+
212
+ if (utility.startsWith('justify-self-')) {
213
+ return ['justify-self'];
214
+ }
215
+
216
+ if (utility.startsWith('justify-')) {
217
+ return ['justify-content'];
218
+ }
219
+
220
+ if (utility.startsWith('items-')) {
221
+ return ['align-items'];
222
+ }
223
+
224
+ if (utility.startsWith('content-')) {
225
+ return ['align-content'];
226
+ }
227
+
228
+ if (utility.startsWith('self-')) {
229
+ return ['align-self'];
230
+ }
231
+
232
+ if (utility.startsWith('place-content-')) {
233
+ return ['place-content'];
234
+ }
235
+
236
+ if (utility.startsWith('place-items-')) {
237
+ return ['place-items'];
238
+ }
239
+
240
+ if (utility.startsWith('place-self-')) {
241
+ return ['place-self'];
242
+ }
243
+
244
+ return null;
245
+ }
@@ -0,0 +1,42 @@
1
+ import type { IClassifyUtilityParams, TUtilityConflictKeys } from './types';
2
+
3
+ const SIMPLE_PREFIXES: ReadonlyArray<readonly [string, string]> = [
4
+ ['accent-', 'accent-color'],
5
+ ['appearance-', 'appearance'],
6
+ ['aspect-', 'aspect-ratio'],
7
+ ['backdrop-', 'backdrop-filter'],
8
+ ['blur-', 'filter:blur'],
9
+ ['brightness-', 'filter:brightness'],
10
+ ['caption-', 'caption-side'],
11
+ ['caret-', 'caret-color'],
12
+ ['columns-', 'columns'],
13
+ ['contrast-', 'filter:contrast'],
14
+ ['cursor-', 'cursor'],
15
+ ['decoration-', 'text-decoration'],
16
+ ['drop-shadow-', 'filter:drop-shadow'],
17
+ ['fill-', 'fill'],
18
+ ['grayscale-', 'filter:grayscale'],
19
+ ['hue-rotate-', 'filter:hue-rotate'],
20
+ ['list-', 'list-style'],
21
+ ['object-', 'object-fit-position'],
22
+ ['outline-', 'outline'],
23
+ ['pointer-events-', 'pointer-events'],
24
+ ['resize-', 'resize'],
25
+ ['saturate-', 'filter:saturate'],
26
+ ['select-', 'user-select'],
27
+ ['sepia-', 'filter:sepia'],
28
+ ['stroke-', 'stroke'],
29
+ ['table-', 'table-layout'],
30
+ ];
31
+
32
+ export function classifySimple({
33
+ utility,
34
+ }: IClassifyUtilityParams): TUtilityConflictKeys {
35
+ for (const [prefix, key] of SIMPLE_PREFIXES) {
36
+ if (utility.startsWith(prefix)) {
37
+ return [key];
38
+ }
39
+ }
40
+
41
+ return null;
42
+ }
@@ -0,0 +1,96 @@
1
+ import type { IClassifyUtilityParams, TUtilityConflictKeys } from './types';
2
+
3
+ const TEXT_ALIGNMENTS = new Set([
4
+ 'text-center',
5
+ 'text-end',
6
+ 'text-justify',
7
+ 'text-left',
8
+ 'text-right',
9
+ 'text-start',
10
+ ]);
11
+
12
+ const FONT_SIZES = /^(?:xs|sm|base|lg|xl|\d+xl)$/;
13
+
14
+ function classifyText(utility: string): string[] {
15
+ if (TEXT_ALIGNMENTS.has(utility)) {
16
+ return ['text-align'];
17
+ }
18
+
19
+ if (/^text-(?:ellipsis|clip)$/.test(utility)) {
20
+ return ['text-overflow'];
21
+ }
22
+
23
+ if (/^text-(?:wrap|nowrap|balance|pretty)$/.test(utility)) {
24
+ return ['text-wrap'];
25
+ }
26
+
27
+ if (/^text-opacity-/.test(utility)) {
28
+ return ['text-opacity'];
29
+ }
30
+
31
+ const value = utility.slice(5);
32
+
33
+ if (FONT_SIZES.test(value)) {
34
+ return ['font-size', 'line-height'];
35
+ }
36
+
37
+ if (/^\[(?:[-+]?\d|length:|size:)/.test(value)) {
38
+ return ['font-size', 'line-height'];
39
+ }
40
+
41
+ return ['text-color'];
42
+ }
43
+
44
+ export function classifyTypography({
45
+ utility,
46
+ }: IClassifyUtilityParams): TUtilityConflictKeys {
47
+ if (utility.startsWith('font-')) {
48
+ if (/^font-(?:sans|serif|mono|\[)/.test(utility)) {
49
+ return ['font-family'];
50
+ }
51
+
52
+ return ['font-weight'];
53
+ }
54
+
55
+ if (utility.startsWith('text-')) {
56
+ return classifyText(utility);
57
+ }
58
+
59
+ if (utility.startsWith('leading-')) {
60
+ return ['line-height'];
61
+ }
62
+
63
+ if (utility.startsWith('tracking-')) {
64
+ return ['letter-spacing'];
65
+ }
66
+
67
+ if (/^(?:italic|not-italic)$/.test(utility)) {
68
+ return ['font-style'];
69
+ }
70
+
71
+ if (/^(?:uppercase|lowercase|capitalize|normal-case)$/.test(utility)) {
72
+ return ['text-transform'];
73
+ }
74
+
75
+ if (utility.startsWith('indent-')) {
76
+ return ['text-indent'];
77
+ }
78
+
79
+ if (utility.startsWith('align-')) {
80
+ return ['vertical-align'];
81
+ }
82
+
83
+ if (utility.startsWith('whitespace-')) {
84
+ return ['white-space'];
85
+ }
86
+
87
+ if (utility.startsWith('break-')) {
88
+ return ['word-break'];
89
+ }
90
+
91
+ if (utility.startsWith('hyphens-')) {
92
+ return ['hyphens'];
93
+ }
94
+
95
+ return null;
96
+ }
@@ -0,0 +1,36 @@
1
+ import { classifyLayout } from './classifyLayout';
2
+ import { classifySimple } from './classifySimple';
3
+ import { classifyTypography } from './classifyTypography';
4
+ import { classifyVisual } from './classifyVisual';
5
+
6
+ interface IClassifyUtilityParams {
7
+ readonly rawUtility: string;
8
+ }
9
+
10
+ export function classifyUtility({
11
+ rawUtility,
12
+ }: IClassifyUtilityParams): readonly string[] {
13
+ const utility = rawUtility.startsWith('-') ? rawUtility.slice(1) : rawUtility;
14
+
15
+ const arbitraryProperty = utility.match(/^\[([^:]+):.+\]$/);
16
+
17
+ if (arbitraryProperty) {
18
+ return [`property:${arbitraryProperty[1]}`];
19
+ }
20
+
21
+ const conflictKeys =
22
+ classifyLayout({
23
+ utility,
24
+ }) ??
25
+ classifyTypography({
26
+ utility,
27
+ }) ??
28
+ classifyVisual({
29
+ utility,
30
+ }) ??
31
+ classifySimple({
32
+ utility,
33
+ });
34
+
35
+ return conflictKeys ?? [`token:${utility}`];
36
+ }