supadeck 0.0.5 → 0.0.6
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/content/rehype-shiki-code-blocks.d.ts +9 -0
- package/dist/content/rehype-shiki-code-blocks.js +139 -0
- package/dist/runtime/default-components.js +23 -2
- package/dist/runtime/themes/base/theme.css +183 -145
- package/dist/runtime/themes/default/components.js +23 -2
- package/dist/runtime/themes/default/theme.css +17 -0
- package/dist/runtime/vite-config.js +2 -0
- package/package.json +2 -1
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { createHighlighter } from "shiki";
|
|
2
|
+
const SHIKI_THEME = "github-dark-default";
|
|
3
|
+
let highlighterPromise;
|
|
4
|
+
function getHighlighter() {
|
|
5
|
+
if (!highlighterPromise) {
|
|
6
|
+
highlighterPromise = createHighlighter({
|
|
7
|
+
themes: [SHIKI_THEME],
|
|
8
|
+
langs: [],
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
return highlighterPromise;
|
|
12
|
+
}
|
|
13
|
+
function isElement(node, tagName) {
|
|
14
|
+
return node?.type === "element" && node.tagName === tagName;
|
|
15
|
+
}
|
|
16
|
+
function toClassNames(value) {
|
|
17
|
+
if (typeof value === "string") {
|
|
18
|
+
return value.split(/\s+/).filter(Boolean);
|
|
19
|
+
}
|
|
20
|
+
if (Array.isArray(value)) {
|
|
21
|
+
return value.flatMap((entry) => toClassNames(entry));
|
|
22
|
+
}
|
|
23
|
+
return [];
|
|
24
|
+
}
|
|
25
|
+
function findLanguage(className) {
|
|
26
|
+
const languageClass = toClassNames(className).find((entry) => entry.startsWith("language-"));
|
|
27
|
+
return languageClass ? languageClass.slice("language-".length) : null;
|
|
28
|
+
}
|
|
29
|
+
function getTextContent(node) {
|
|
30
|
+
if (!node) {
|
|
31
|
+
return "";
|
|
32
|
+
}
|
|
33
|
+
if (node.type === "text") {
|
|
34
|
+
return typeof node.value === "string" ? node.value : "";
|
|
35
|
+
}
|
|
36
|
+
return (node.children ?? []).map((child) => getTextContent(child)).join("");
|
|
37
|
+
}
|
|
38
|
+
function stripBackgroundStyles(style) {
|
|
39
|
+
if (typeof style !== "string") {
|
|
40
|
+
return style;
|
|
41
|
+
}
|
|
42
|
+
const filtered = style
|
|
43
|
+
.split(";")
|
|
44
|
+
.map((entry) => entry.trim())
|
|
45
|
+
.filter(Boolean)
|
|
46
|
+
.filter((entry) => {
|
|
47
|
+
const property = entry.split(":", 1)[0]?.trim().toLowerCase();
|
|
48
|
+
return property !== "background" && property !== "background-color";
|
|
49
|
+
});
|
|
50
|
+
return filtered.length > 0 ? `${filtered.join("; ")};` : undefined;
|
|
51
|
+
}
|
|
52
|
+
function getCodeChild(node) {
|
|
53
|
+
const children = node.children ?? [];
|
|
54
|
+
return children.length === 1 && isElement(children[0], "code")
|
|
55
|
+
? children[0]
|
|
56
|
+
: null;
|
|
57
|
+
}
|
|
58
|
+
function getPreNode(node) {
|
|
59
|
+
if (node && node.type === "element" && node.tagName === "pre") {
|
|
60
|
+
return node;
|
|
61
|
+
}
|
|
62
|
+
const children = node?.children ?? [];
|
|
63
|
+
return children.find((child) => isElement(child, "pre")) ?? null;
|
|
64
|
+
}
|
|
65
|
+
async function highlightCode(code, language) {
|
|
66
|
+
const highlighter = await getHighlighter();
|
|
67
|
+
try {
|
|
68
|
+
await highlighter.loadLanguage(language);
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
return highlighter.codeToHast(code, {
|
|
74
|
+
lang: language,
|
|
75
|
+
theme: SHIKI_THEME,
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
function addClassName(properties, ...classNames) {
|
|
79
|
+
const merged = new Set([
|
|
80
|
+
...toClassNames(properties?.class),
|
|
81
|
+
...toClassNames(properties?.className),
|
|
82
|
+
...classNames.filter(Boolean),
|
|
83
|
+
]);
|
|
84
|
+
return {
|
|
85
|
+
...properties,
|
|
86
|
+
class: undefined,
|
|
87
|
+
className: Array.from(merged),
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
async function transformCodeBlock(node) {
|
|
91
|
+
if (!isElement(node, "pre")) {
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
const codeChild = getCodeChild(node);
|
|
95
|
+
const language = findLanguage(codeChild?.properties?.className);
|
|
96
|
+
if (!codeChild || !language) {
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
const source = getTextContent(codeChild).replace(/\r?\n$/, "");
|
|
100
|
+
const highlightedTree = await highlightCode(source, language);
|
|
101
|
+
const highlightedPre = getPreNode(highlightedTree);
|
|
102
|
+
if (!highlightedPre) {
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
const highlightedCode = getCodeChild(highlightedPre);
|
|
106
|
+
if (!highlightedCode) {
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
highlightedPre.properties = {
|
|
110
|
+
...addClassName(highlightedPre.properties, "deck-code-block", "deck-code-block--highlighted"),
|
|
111
|
+
style: stripBackgroundStyles(highlightedPre.properties?.style),
|
|
112
|
+
"data-language": language,
|
|
113
|
+
"data-code-block": "",
|
|
114
|
+
};
|
|
115
|
+
highlightedCode.properties = {
|
|
116
|
+
...addClassName(highlightedCode.properties, "deck-code-content"),
|
|
117
|
+
style: stripBackgroundStyles(highlightedCode.properties?.style),
|
|
118
|
+
"data-language": language,
|
|
119
|
+
"data-code-block": "",
|
|
120
|
+
};
|
|
121
|
+
return highlightedPre;
|
|
122
|
+
}
|
|
123
|
+
async function visitChildren(node) {
|
|
124
|
+
const children = node.children ?? [];
|
|
125
|
+
for (let index = 0; index < children.length; index += 1) {
|
|
126
|
+
const child = children[index];
|
|
127
|
+
const replacement = await transformCodeBlock(child);
|
|
128
|
+
if (replacement) {
|
|
129
|
+
children[index] = replacement;
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
await visitChildren(child);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
export function rehypeShikiCodeBlocks() {
|
|
136
|
+
return async function transformer(tree) {
|
|
137
|
+
await visitChildren(tree);
|
|
138
|
+
};
|
|
139
|
+
}
|
|
@@ -4,6 +4,25 @@ import { Center } from "./components/Center.js";
|
|
|
4
4
|
function cx(...values) {
|
|
5
5
|
return values.filter(Boolean).join(" ");
|
|
6
6
|
}
|
|
7
|
+
function toClassName(value) {
|
|
8
|
+
if (typeof value === "string") {
|
|
9
|
+
return value;
|
|
10
|
+
}
|
|
11
|
+
if (Array.isArray(value)) {
|
|
12
|
+
const className = value
|
|
13
|
+
.flatMap((entry) => typeof entry === "string" ? entry.split(/\s+/) : [])
|
|
14
|
+
.filter(Boolean)
|
|
15
|
+
.join(" ");
|
|
16
|
+
return className || undefined;
|
|
17
|
+
}
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
function isBlockCode(className, props) {
|
|
21
|
+
const normalizedClassName = toClassName(className) ?? "";
|
|
22
|
+
return ("data-code-block" in props ||
|
|
23
|
+
normalizedClassName.includes("language-") ||
|
|
24
|
+
normalizedClassName.includes("deck-code-content"));
|
|
25
|
+
}
|
|
7
26
|
export function createDefaultComponents() {
|
|
8
27
|
return {
|
|
9
28
|
h1: (props) => (_jsx("h1", { className: "text-6xl font-semibold tracking-tight text-balance", ...props })),
|
|
@@ -14,8 +33,10 @@ export function createDefaultComponents() {
|
|
|
14
33
|
ul: (props) => (_jsx("ul", { className: "list-disc space-y-3 pl-8 text-2xl", ...props })),
|
|
15
34
|
ol: (props) => (_jsx("ol", { className: "list-decimal space-y-3 pl-8 text-2xl", ...props })),
|
|
16
35
|
li: (props) => (_jsx("li", { className: "pl-2", ...props })),
|
|
17
|
-
code: (props) => (_jsx("code", { className:
|
|
18
|
-
|
|
36
|
+
code: ({ className, ...props }) => (_jsx("code", { className: isBlockCode(className, props)
|
|
37
|
+
? toClassName(className)
|
|
38
|
+
: cx("rounded-md bg-black/10 px-2 py-1 font-mono text-[0.9em] dark:bg-white/10", toClassName(className)), ...props })),
|
|
39
|
+
pre: ({ className, ...props }) => (_jsx("pre", { className: cx("overflow-x-auto rounded-[var(--radius-lg)] border border-[color:var(--color-border)] bg-[color:var(--color-code-bg)] p-6 text-lg", toClassName(className)), ...props })),
|
|
19
40
|
table: ({ className, ...props }) => (_jsx("div", { className: "deck-table-wrap", children: _jsx("table", { className: cx("deck-table", className), ...props }) })),
|
|
20
41
|
thead: ({ className, ...props }) => (_jsx("thead", { className: cx("deck-thead", className), ...props })),
|
|
21
42
|
tbody: ({ className, ...props }) => (_jsx("tbody", { className: cx("deck-tbody", className), ...props })),
|
|
@@ -1,245 +1,283 @@
|
|
|
1
1
|
@import "tailwindcss";
|
|
2
2
|
|
|
3
3
|
:root {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
4
|
+
--color-background: #f3f0ea;
|
|
5
|
+
--color-foreground: #1f1b16;
|
|
6
|
+
--color-muted: #6b6257;
|
|
7
|
+
--color-accent: #b85c38;
|
|
8
|
+
--color-border: rgba(31, 27, 22, 0.12);
|
|
9
|
+
--color-code-bg: rgba(31, 27, 22, 0.06);
|
|
10
|
+
--radius-lg: 1.5rem;
|
|
11
|
+
--radius-xl: 2.25rem;
|
|
12
|
+
--font-sans: "Instrument Sans", "Inter", sans-serif;
|
|
13
|
+
--font-display: "Fraunces", "Georgia", serif;
|
|
14
|
+
--slide-aspect-ratio: 16 / 9;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
* {
|
|
18
|
-
|
|
18
|
+
box-sizing: border-box;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
html,
|
|
22
22
|
body,
|
|
23
23
|
#root {
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
min-height: 100%;
|
|
25
|
+
margin: 0;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
body {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
29
|
+
min-height: 100vh;
|
|
30
|
+
font-family: var(--font-sans);
|
|
31
|
+
color: var(--color-foreground);
|
|
32
|
+
background: radial-gradient(
|
|
33
|
+
circle at top left,
|
|
34
|
+
color-mix(in srgb, var(--color-accent) 16%, transparent),
|
|
35
|
+
transparent 28%
|
|
36
|
+
),
|
|
37
|
+
linear-gradient(
|
|
38
|
+
145deg,
|
|
39
|
+
color-mix(in srgb, var(--color-background) 92%, white),
|
|
40
|
+
var(--color-background)
|
|
41
|
+
);
|
|
35
42
|
}
|
|
36
43
|
|
|
37
44
|
button {
|
|
38
|
-
|
|
45
|
+
font: inherit;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.deck-code-block {
|
|
49
|
+
overflow-x: auto;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.deck-code-block,
|
|
53
|
+
.deck-code-block code {
|
|
54
|
+
background: transparent !important;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.deck-code-content {
|
|
58
|
+
display: block;
|
|
59
|
+
min-width: max-content;
|
|
60
|
+
font-family: "SF Mono", "Fira Code", "IBM Plex Mono", monospace;
|
|
61
|
+
font-size: 0.95em;
|
|
62
|
+
line-height: 1;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.deck-code-content .line {
|
|
66
|
+
display: block;
|
|
39
67
|
}
|
|
40
68
|
|
|
41
69
|
.app-shell {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
70
|
+
display: grid;
|
|
71
|
+
min-height: 100vh;
|
|
72
|
+
grid-template-rows: auto 1fr auto;
|
|
73
|
+
gap: 1.5rem;
|
|
74
|
+
padding: 1.5rem;
|
|
47
75
|
}
|
|
48
76
|
|
|
49
77
|
.deck-chrome {
|
|
50
|
-
|
|
51
|
-
|
|
78
|
+
display: grid;
|
|
79
|
+
gap: 0.75rem;
|
|
52
80
|
}
|
|
53
81
|
|
|
54
82
|
.deck-title {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
83
|
+
font-family: var(--font-display);
|
|
84
|
+
font-size: 1rem;
|
|
85
|
+
font-weight: 700;
|
|
86
|
+
letter-spacing: 0.18em;
|
|
87
|
+
text-transform: uppercase;
|
|
88
|
+
color: var(--color-muted);
|
|
61
89
|
}
|
|
62
90
|
|
|
63
91
|
.deck-progress {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
92
|
+
overflow: hidden;
|
|
93
|
+
height: 0.4rem;
|
|
94
|
+
border-radius: 999px;
|
|
95
|
+
background: color-mix(in srgb, var(--color-foreground) 10%, transparent);
|
|
68
96
|
}
|
|
69
97
|
|
|
70
98
|
.deck-progress-bar {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
99
|
+
height: 100%;
|
|
100
|
+
border-radius: inherit;
|
|
101
|
+
background: linear-gradient(
|
|
102
|
+
90deg,
|
|
103
|
+
var(--color-accent),
|
|
104
|
+
color-mix(in srgb, var(--color-accent) 55%, white)
|
|
105
|
+
);
|
|
106
|
+
transition: width 240ms ease;
|
|
75
107
|
}
|
|
76
108
|
|
|
77
109
|
.deck-stage {
|
|
78
|
-
|
|
79
|
-
|
|
110
|
+
display: grid;
|
|
111
|
+
place-items: center;
|
|
80
112
|
}
|
|
81
113
|
|
|
82
114
|
.slide-frame {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
115
|
+
width: min(100%, 1440px);
|
|
116
|
+
aspect-ratio: var(--slide-aspect-ratio);
|
|
117
|
+
transition: transform 220ms ease, opacity 220ms ease;
|
|
86
118
|
}
|
|
87
119
|
|
|
88
120
|
.slide-surface {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
121
|
+
display: grid;
|
|
122
|
+
grid-template-rows: 1fr auto;
|
|
123
|
+
height: 100%;
|
|
124
|
+
overflow: hidden;
|
|
125
|
+
border: 1px solid var(--color-border);
|
|
126
|
+
border-radius: var(--radius-xl);
|
|
127
|
+
background: linear-gradient(
|
|
128
|
+
180deg,
|
|
129
|
+
color-mix(in srgb, var(--color-background) 96%, white),
|
|
130
|
+
color-mix(in srgb, var(--color-background) 86%, transparent)
|
|
131
|
+
),
|
|
132
|
+
radial-gradient(
|
|
133
|
+
circle at top right,
|
|
134
|
+
color-mix(in srgb, var(--color-accent) 10%, transparent),
|
|
135
|
+
transparent 32%
|
|
136
|
+
);
|
|
137
|
+
box-shadow: 0 30px 80px rgba(15, 23, 42, 0.16),
|
|
138
|
+
inset 0 1px 0 rgba(255, 255, 255, 0.45);
|
|
101
139
|
}
|
|
102
140
|
|
|
103
141
|
.slide-content {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
142
|
+
display: flex;
|
|
143
|
+
flex-direction: column;
|
|
144
|
+
justify-content: center;
|
|
145
|
+
gap: 1.5rem;
|
|
146
|
+
padding: clamp(1.5rem, 4vw, 4rem);
|
|
109
147
|
}
|
|
110
148
|
|
|
111
149
|
.slide-content > :first-child {
|
|
112
|
-
|
|
150
|
+
margin-top: 0;
|
|
113
151
|
}
|
|
114
152
|
|
|
115
153
|
.slide-content > :last-child {
|
|
116
|
-
|
|
154
|
+
margin-bottom: 0;
|
|
117
155
|
}
|
|
118
156
|
|
|
119
157
|
.deck-table-wrap {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
158
|
+
width: 100%;
|
|
159
|
+
overflow-x: auto;
|
|
160
|
+
border: 1px solid var(--color-border);
|
|
161
|
+
border-radius: var(--radius-lg);
|
|
162
|
+
background: color-mix(in srgb, var(--color-background) 92%, white);
|
|
163
|
+
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.35);
|
|
126
164
|
}
|
|
127
165
|
|
|
128
166
|
.deck-table {
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
167
|
+
width: 100%;
|
|
168
|
+
min-width: 32rem;
|
|
169
|
+
border-collapse: collapse;
|
|
170
|
+
font-size: clamp(0.95rem, 1.2vw, 1.35rem);
|
|
171
|
+
line-height: 1.45;
|
|
134
172
|
}
|
|
135
173
|
|
|
136
174
|
.deck-thead {
|
|
137
|
-
|
|
175
|
+
background: color-mix(in srgb, var(--color-accent) 8%, transparent);
|
|
138
176
|
}
|
|
139
177
|
|
|
140
178
|
.deck-tr + .deck-tr {
|
|
141
|
-
|
|
179
|
+
border-top: 1px solid var(--color-border);
|
|
142
180
|
}
|
|
143
181
|
|
|
144
182
|
.deck-th,
|
|
145
183
|
.deck-td {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
184
|
+
padding: 0.9rem 1rem;
|
|
185
|
+
text-align: left;
|
|
186
|
+
vertical-align: top;
|
|
149
187
|
}
|
|
150
188
|
|
|
151
189
|
.deck-th {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
190
|
+
font-size: 0.8em;
|
|
191
|
+
font-weight: 700;
|
|
192
|
+
letter-spacing: 0.08em;
|
|
193
|
+
text-transform: uppercase;
|
|
194
|
+
color: var(--color-muted);
|
|
157
195
|
}
|
|
158
196
|
|
|
159
197
|
.slide-footer {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
198
|
+
display: flex;
|
|
199
|
+
justify-content: flex-end;
|
|
200
|
+
padding: 1.25rem 1.5rem;
|
|
201
|
+
color: var(--color-muted);
|
|
202
|
+
font-size: 0.95rem;
|
|
203
|
+
letter-spacing: 0.12em;
|
|
204
|
+
text-transform: uppercase;
|
|
167
205
|
}
|
|
168
206
|
|
|
169
207
|
.deck-nav {
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
208
|
+
display: flex;
|
|
209
|
+
justify-content: flex-end;
|
|
210
|
+
gap: 0.75rem;
|
|
173
211
|
}
|
|
174
212
|
|
|
175
213
|
.deck-button {
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
214
|
+
border: 1px solid var(--color-border);
|
|
215
|
+
border-radius: 999px;
|
|
216
|
+
background: color-mix(in srgb, var(--color-background) 88%, white);
|
|
217
|
+
padding: 0.8rem 1.1rem;
|
|
218
|
+
color: var(--color-foreground);
|
|
219
|
+
transition: transform 160ms ease, background 160ms ease;
|
|
182
220
|
}
|
|
183
221
|
|
|
184
222
|
.deck-button:hover {
|
|
185
|
-
|
|
186
|
-
|
|
223
|
+
transform: translateY(-1px);
|
|
224
|
+
background: color-mix(in srgb, var(--color-background) 80%, white);
|
|
187
225
|
}
|
|
188
226
|
|
|
189
227
|
.print-deck {
|
|
190
|
-
|
|
191
|
-
|
|
228
|
+
display: grid;
|
|
229
|
+
gap: 0;
|
|
192
230
|
}
|
|
193
231
|
|
|
194
232
|
.slide-frame-print {
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
233
|
+
width: 100vw;
|
|
234
|
+
min-height: 100vh;
|
|
235
|
+
page-break-after: always;
|
|
236
|
+
break-after: page;
|
|
237
|
+
padding: 0;
|
|
200
238
|
}
|
|
201
239
|
|
|
202
240
|
.slide-frame-print .slide-surface {
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
241
|
+
border-radius: 0;
|
|
242
|
+
box-shadow: none;
|
|
243
|
+
min-height: 100vh;
|
|
206
244
|
}
|
|
207
245
|
|
|
208
246
|
@media (max-width: 900px) {
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
247
|
+
.app-shell {
|
|
248
|
+
padding: 1rem;
|
|
249
|
+
}
|
|
212
250
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
251
|
+
.slide-frame {
|
|
252
|
+
width: 100%;
|
|
253
|
+
}
|
|
216
254
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
255
|
+
.slide-content {
|
|
256
|
+
padding: 1.25rem;
|
|
257
|
+
}
|
|
220
258
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
259
|
+
.deck-table {
|
|
260
|
+
min-width: 26rem;
|
|
261
|
+
}
|
|
224
262
|
}
|
|
225
263
|
|
|
226
264
|
@media print {
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
265
|
+
@page {
|
|
266
|
+
size: landscape;
|
|
267
|
+
margin: 0;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
body {
|
|
271
|
+
background: white;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
.slide-frame-print {
|
|
275
|
+
width: 100%;
|
|
276
|
+
height: 100vh;
|
|
277
|
+
min-height: 100vh;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
.slide-frame-print .slide-surface {
|
|
281
|
+
border: none;
|
|
282
|
+
}
|
|
245
283
|
}
|
|
@@ -3,6 +3,25 @@ import { useId } from 'react';
|
|
|
3
3
|
function cx(...values) {
|
|
4
4
|
return values.filter(Boolean).join(' ');
|
|
5
5
|
}
|
|
6
|
+
function toClassName(value) {
|
|
7
|
+
if (typeof value === 'string') {
|
|
8
|
+
return value;
|
|
9
|
+
}
|
|
10
|
+
if (Array.isArray(value)) {
|
|
11
|
+
const className = value
|
|
12
|
+
.flatMap((entry) => (typeof entry === 'string' ? entry.split(/\s+/) : []))
|
|
13
|
+
.filter(Boolean)
|
|
14
|
+
.join(' ');
|
|
15
|
+
return className || undefined;
|
|
16
|
+
}
|
|
17
|
+
return undefined;
|
|
18
|
+
}
|
|
19
|
+
function isBlockCode(className, props) {
|
|
20
|
+
const normalizedClassName = toClassName(className) ?? '';
|
|
21
|
+
return ('data-code-block' in props ||
|
|
22
|
+
normalizedClassName.includes('language-') ||
|
|
23
|
+
normalizedClassName.includes('deck-code-content'));
|
|
24
|
+
}
|
|
6
25
|
export function SupabaseMark({ size = 'footer', className, ...props }) {
|
|
7
26
|
const id = useId();
|
|
8
27
|
const primaryGradientId = `${id}-primary`;
|
|
@@ -58,8 +77,10 @@ export function createSupabaseComponents() {
|
|
|
58
77
|
ul: ({ className, ...props }) => (_jsx("ul", { className: cx('supabase-list', className), ...props })),
|
|
59
78
|
ol: ({ className, ...props }) => (_jsx("ol", { className: cx('supabase-list', 'supabase-list-ordered', className), ...props })),
|
|
60
79
|
li: (props) => _jsx("li", { ...props }),
|
|
61
|
-
code: ({ className, ...props }) => (_jsx("code", { className:
|
|
62
|
-
|
|
80
|
+
code: ({ className, ...props }) => (_jsx("code", { className: isBlockCode(className, props)
|
|
81
|
+
? toClassName(className)
|
|
82
|
+
: cx('supabase-inline-code', toClassName(className)), ...props })),
|
|
83
|
+
pre: ({ className, ...props }) => (_jsx("pre", { className: cx('supabase-pre', toClassName(className)), ...props })),
|
|
63
84
|
table: ({ className, ...props }) => (_jsx("table", { className: cx('supabase-table', className), ...props })),
|
|
64
85
|
th: ({ className, ...props }) => (_jsx("th", { className: cx('supabase-th', className), ...props })),
|
|
65
86
|
td: ({ className, ...props }) => (_jsx("td", { className: cx('supabase-td', className), ...props })),
|
|
@@ -452,6 +452,23 @@ tr:last-child td {
|
|
|
452
452
|
padding: 22px 24px;
|
|
453
453
|
}
|
|
454
454
|
|
|
455
|
+
.supabase-pre.deck-code-block,
|
|
456
|
+
.supabase-pre.deck-code-block code {
|
|
457
|
+
background: transparent !important;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
.supabase-pre .deck-code-content {
|
|
461
|
+
display: block;
|
|
462
|
+
min-width: max-content;
|
|
463
|
+
font-family: "SF Mono", "Fira Code", "IBM Plex Mono", monospace;
|
|
464
|
+
font-size: 0.95em;
|
|
465
|
+
line-height: 1;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
.supabase-pre .deck-code-content .line {
|
|
469
|
+
display: block;
|
|
470
|
+
}
|
|
471
|
+
|
|
455
472
|
.supabase-pre code {
|
|
456
473
|
background: transparent;
|
|
457
474
|
padding: 0;
|
|
@@ -7,6 +7,7 @@ import mdx from "@mdx-js/rollup";
|
|
|
7
7
|
import { normalizePath } from "vite";
|
|
8
8
|
import remarkGfm from "remark-gfm";
|
|
9
9
|
import { parseDeck } from "../content/parse-deck.js";
|
|
10
|
+
import { rehypeShikiCodeBlocks } from "../content/rehype-shiki-code-blocks.js";
|
|
10
11
|
import { remarkUnwrapJsxParagraphs } from "../content/remark-unwrap-jsx-paragraphs.js";
|
|
11
12
|
import { injectTailwindSources, isTailwindSourceFile, } from "./tailwind-sources.js";
|
|
12
13
|
import { collectImportedCssModules, dispatchTailwindCssUpdates, } from "./tailwind-hmr.js";
|
|
@@ -194,6 +195,7 @@ export function createSupadeckViteConfig({ deckPath, port, open, themeOverride,
|
|
|
194
195
|
mdx({
|
|
195
196
|
include: [/\.mdx$/, /\.mdx\?.*$/],
|
|
196
197
|
remarkPlugins: [remarkGfm, remarkUnwrapJsxParagraphs],
|
|
198
|
+
rehypePlugins: [rehypeShikiCodeBlocks],
|
|
197
199
|
}),
|
|
198
200
|
react(),
|
|
199
201
|
tailwindcss(),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "supadeck",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.6",
|
|
4
4
|
"description": "Zero-config MDX presentations with hot reload and PDF export.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -46,6 +46,7 @@
|
|
|
46
46
|
"remark-gfm": "^4.0.1",
|
|
47
47
|
"remark-mdx": "^3.1.0",
|
|
48
48
|
"remark-parse": "^11.0.0",
|
|
49
|
+
"shiki": "^3.14.0",
|
|
49
50
|
"tailwindcss": "^4.1.0",
|
|
50
51
|
"unified": "^11.0.5",
|
|
51
52
|
"vite": "^7.0.0"
|