@kadal/theme-terminal 0.0.0-stage → 0.4.2
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/LICENSE +661 -0
- package/README.md +64 -2
- package/index.tsx +100 -0
- package/package.json +101 -4
- package/style.css +753 -0
package/README.md
CHANGED
|
@@ -1,3 +1,65 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @kadal/theme-terminal
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**Terminal**, a theme for [Kadal Deck](https://deck.kadal.cc). A developer theme for code-heavy talks. Mono-forward: JetBrains Mono for headings, labels and code, IBM Plex Sans for reading text. Dark first (a deck starts dark unless it says `colorScheme: light`) with a light variant made to the same standard; the palette is Ayu's, so the slide and the code colours agree. Code blocks are editor windows: a bar with three lights, line numbers, a lit active line, a clear dim. Headings keep their markdown (`#`), lists use `›`, the table of contents prints like `tree`, callouts read like log lines.
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
## Use it
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @kadal/theme-terminal
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
```yaml
|
|
14
|
+
---
|
|
15
|
+
theme: terminal
|
|
16
|
+
themeConfig: # all optional
|
|
17
|
+
cursor: true
|
|
18
|
+
accent: "#aad94c"
|
|
19
|
+
accentLight: "#477a0b"
|
|
20
|
+
---
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
The deck plugin brings the stylesheet and the module in; nothing to import. The prebuilt shell (the hosted builder, published decks) bundles this theme already. Schemes: light and dark. Fonts: JetBrains Mono (headings and code), IBM Plex Sans (text), loaded through the theme's `config.fonts`. Code colours: Shiki's ayu-light / ayu-dark. To show it beside other themes in the theme menu (<kbd>T</kbd>), list it: `themes: [terminal, minimal]`.
|
|
24
|
+
|
|
25
|
+
## themeConfig
|
|
26
|
+
|
|
27
|
+
Every key arrives on the deck root as a CSS variable (`accentDark` → `--theme-accent-dark`); the theme reads them with fallbacks, so set only what you change.
|
|
28
|
+
|
|
29
|
+
| key | type | default | what it does |
|
|
30
|
+
| --- | --- | --- | --- |
|
|
31
|
+
| `cursor` | boolean | `true` | The blinking block cursor after the cover's and the last slide's title (still under `prefers-reduced-motion` and in print). |
|
|
32
|
+
| `accent` | colour | `#aad94c` | The dark scheme's prompt green. |
|
|
33
|
+
| `accentLight` | colour | `#477a0b` | The light scheme's. Without it, a set `accent` is darkened for the light page. |
|
|
34
|
+
|
|
35
|
+
## Layouts
|
|
36
|
+
|
|
37
|
+
Every built-in layout is styled (`default`, `center`, `cover`, `intro`, `section`, `end`, `fact`, `quote`, `statement`, `full`, `two-cols`, `two-cols-header`, `image`, `image-left`, `image-right`, `iframe`, `iframe-left`, `iframe-right`), and the theme adds:
|
|
38
|
+
|
|
39
|
+
| layout | what |
|
|
40
|
+
| --- | --- |
|
|
41
|
+
| `code` | The heading small and the code block as tall as the slide allows; a `::side::` slot puts notes in a column beside it. |
|
|
42
|
+
| `shell` | The whole slide is a terminal window (`title:` names its bar, default `zsh`); the slide's markdown and code run inside it, in mono. |
|
|
43
|
+
|
|
44
|
+
## Components
|
|
45
|
+
|
|
46
|
+
| component | what |
|
|
47
|
+
| --- | --- |
|
|
48
|
+
| `<Terminal title lines prompt />` | A session, line by line: `$ ` starts a command, `# ` a comment, `! ` an error, `✓ ` a success, anything else is output. Lines come from `lines` or the children, one per line. |
|
|
49
|
+
|
|
50
|
+
## Preview
|
|
51
|
+
|
|
52
|
+
`preview/deck.mdx` walks through every layout and component (`theme: ../`). In this repository:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
bun run --filter @kadal/theme-terminal dev # the preview deck, live
|
|
56
|
+
node tools/theme-shots.mjs terminal # screenshots in light and dark, contrast and overflow checks
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Accessibility and print
|
|
60
|
+
|
|
61
|
+
Body and muted text meet WCAG AA (4.5:1) on the page and on cards in every scheme the theme draws (checked by `tools/theme-shots.mjs`). Anything that moves stands still under `prefers-reduced-motion` and on a still copy; printed pages and exports drop shadows and glows.
|
|
62
|
+
|
|
63
|
+
## Licence
|
|
64
|
+
|
|
65
|
+
AGPL-3.0-or-later, like the engine (see LICENSE); a commercial licence is available — see [LICENSING](https://github.com/kadalcc/deck/blob/main/LICENSING.md).
|
package/index.tsx
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
|
|
3
|
+
import type { LayoutProps } from "@kadal/deck";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* ─────────────────────────────────────────────────────────────────────────────
|
|
7
|
+
* Terminal's module: two layouts for live-coding talks, and a session component.
|
|
8
|
+
*
|
|
9
|
+
* layout: code the heading small and the code block as tall as the slide allows;
|
|
10
|
+
* `::side::` puts notes in a column beside it
|
|
11
|
+
* layout: shell the whole slide is a terminal window (`title:` names its bar, default
|
|
12
|
+
* "zsh"); the slide's markdown and code run inside it, in mono
|
|
13
|
+
* <Terminal> a session, line by line: `lines` (or children, one line each) where
|
|
14
|
+
* `$ ` starts a command, `# ` a comment, `! ` an error, `✓ ` a success,
|
|
15
|
+
* and anything else is output. `title` names the bar, `prompt` the prompt.
|
|
16
|
+
* ─────────────────────────────────────────────────────────────────────────────
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
const str = (v: unknown) => (typeof v === "string" && v.trim() ? v.trim() : null);
|
|
20
|
+
|
|
21
|
+
function Code({ children }: LayoutProps) {
|
|
22
|
+
return <div className="deck-layout deck-layout-code">{children}</div>;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function Bar({ title }: { title: string }) {
|
|
26
|
+
return (
|
|
27
|
+
<div className="terminal-bar" aria-hidden="true">
|
|
28
|
+
{title}
|
|
29
|
+
</div>
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function Shell({ children, frontmatter }: LayoutProps) {
|
|
34
|
+
const title = str(frontmatter.title) ?? "zsh";
|
|
35
|
+
return (
|
|
36
|
+
<div className="deck-layout deck-layout-shell">
|
|
37
|
+
<div className="terminal-window">
|
|
38
|
+
<Bar title={title} />
|
|
39
|
+
<div className="terminal-screen">{children}</div>
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** The text of whatever MDX passed: strings, and the strings inside elements, joined. */
|
|
46
|
+
function textOf(node: ReactNode): string {
|
|
47
|
+
if (node == null || typeof node === "boolean") return "";
|
|
48
|
+
if (typeof node === "string" || typeof node === "number") return String(node);
|
|
49
|
+
if (Array.isArray(node)) return node.map(textOf).join("");
|
|
50
|
+
const props = (node as { props?: { children?: ReactNode } }).props;
|
|
51
|
+
return props ? textOf(props.children) : "";
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
type Kind = "command" | "comment" | "error" | "ok" | "output";
|
|
55
|
+
|
|
56
|
+
function parseLine(line: string): { kind: Kind; text: string } {
|
|
57
|
+
if (line.startsWith("$ ")) return { kind: "command", text: line.slice(2) };
|
|
58
|
+
if (line.startsWith("# ")) return { kind: "comment", text: line };
|
|
59
|
+
if (line.startsWith("! ")) return { kind: "error", text: line.slice(2) };
|
|
60
|
+
if (line.startsWith("✓ ")) return { kind: "ok", text: line };
|
|
61
|
+
return { kind: "output", text: line };
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function Terminal({
|
|
65
|
+
lines,
|
|
66
|
+
title = "zsh",
|
|
67
|
+
prompt = "❯",
|
|
68
|
+
children,
|
|
69
|
+
}: {
|
|
70
|
+
lines?: string[];
|
|
71
|
+
title?: string;
|
|
72
|
+
prompt?: string;
|
|
73
|
+
children?: ReactNode;
|
|
74
|
+
}) {
|
|
75
|
+
const all = lines ?? textOf(children).split("\n");
|
|
76
|
+
const shown = all
|
|
77
|
+
.map((l) => l.replace(/\s+$/, ""))
|
|
78
|
+
.filter((l, i, a) => l || (i > 0 && i < a.length - 1));
|
|
79
|
+
return (
|
|
80
|
+
<figure className="terminal-window is-inline" aria-label={`Terminal: ${title}`}>
|
|
81
|
+
<Bar title={title} />
|
|
82
|
+
<pre className="terminal-lines">
|
|
83
|
+
{shown.map((line, i) => {
|
|
84
|
+
const { kind, text } = parseLine(line);
|
|
85
|
+
return (
|
|
86
|
+
<span key={i} className={`terminal-line is-${kind}`}>
|
|
87
|
+
{kind === "command" ? <span className="terminal-prompt">{prompt} </span> : null}
|
|
88
|
+
{text || " "}
|
|
89
|
+
</span>
|
|
90
|
+
);
|
|
91
|
+
})}
|
|
92
|
+
</pre>
|
|
93
|
+
</figure>
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export default {
|
|
98
|
+
layouts: { code: Code, shell: Shell },
|
|
99
|
+
components: { Terminal },
|
|
100
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,103 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kadal/theme-terminal",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.4.2",
|
|
4
|
+
"description": "Terminal, a theme for Kadal Deck (@kadal/deck). A developer theme for code-heavy talks: mono-forward type, superb code blocks, dark first with a good light variant, and the matching Ayu code colours.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"kadal-theme",
|
|
7
|
+
"kadal-deck",
|
|
8
|
+
"presentation",
|
|
9
|
+
"slides",
|
|
10
|
+
"theme",
|
|
11
|
+
"developer",
|
|
12
|
+
"terminal",
|
|
13
|
+
"code",
|
|
14
|
+
"monospace"
|
|
15
|
+
],
|
|
16
|
+
"homepage": "https://deck.kadal.cc/docs/",
|
|
17
|
+
"funding": {
|
|
18
|
+
"type": "github",
|
|
19
|
+
"url": "https://github.com/sponsors/pmithunish"
|
|
20
|
+
},
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "git+https://github.com/kadalcc/deck.git",
|
|
24
|
+
"directory": "packages/theme-terminal"
|
|
25
|
+
},
|
|
26
|
+
"bugs": {
|
|
27
|
+
"url": "https://github.com/kadalcc/deck/issues"
|
|
28
|
+
},
|
|
29
|
+
"license": "AGPL-3.0-or-later",
|
|
30
|
+
"author": "Mithunish Prabhakaran <pmithunish@gmail.com>",
|
|
31
|
+
"type": "module",
|
|
32
|
+
"sideEffects": [
|
|
33
|
+
"*.css"
|
|
34
|
+
],
|
|
35
|
+
"files": [
|
|
36
|
+
"style.css",
|
|
37
|
+
"index.tsx",
|
|
38
|
+
"README.md",
|
|
39
|
+
"LICENSE"
|
|
40
|
+
],
|
|
41
|
+
"exports": {
|
|
42
|
+
".": "./index.tsx",
|
|
43
|
+
"./style.css": "./style.css",
|
|
44
|
+
"./package.json": "./package.json"
|
|
45
|
+
},
|
|
46
|
+
"publishConfig": {
|
|
47
|
+
"access": "public",
|
|
48
|
+
"provenance": true
|
|
49
|
+
},
|
|
50
|
+
"kadal": {
|
|
51
|
+
"theme": {
|
|
52
|
+
"name": "terminal",
|
|
53
|
+
"title": "Terminal",
|
|
54
|
+
"description": "A developer theme for code-heavy talks: mono-forward type, superb code blocks, dark first with a good light variant, and the matching Ayu code colours.",
|
|
55
|
+
"colorScheme": "both",
|
|
56
|
+
"config": {
|
|
57
|
+
"transition": "fade",
|
|
58
|
+
"colorScheme": "dark",
|
|
59
|
+
"fonts": {
|
|
60
|
+
"heading": "JetBrains Mono",
|
|
61
|
+
"sans": "IBM Plex Sans",
|
|
62
|
+
"mono": "JetBrains Mono",
|
|
63
|
+
"weights": "400,500,700"
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
"themeConfig": {
|
|
67
|
+
"cursor": true
|
|
68
|
+
},
|
|
69
|
+
"shiki": {
|
|
70
|
+
"light": "ayu-light",
|
|
71
|
+
"dark": "ayu-dark"
|
|
72
|
+
},
|
|
73
|
+
"defaults": {},
|
|
74
|
+
"layouts": [
|
|
75
|
+
"code",
|
|
76
|
+
"shell"
|
|
77
|
+
],
|
|
78
|
+
"components": [
|
|
79
|
+
"Terminal"
|
|
80
|
+
]
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
"scripts": {
|
|
84
|
+
"dev": "kadal-deck dev -C preview",
|
|
85
|
+
"check": "kadal-deck check -C preview",
|
|
86
|
+
"typecheck": "tsc --noEmit",
|
|
87
|
+
"test": "bun test"
|
|
88
|
+
},
|
|
89
|
+
"peerDependencies": {
|
|
90
|
+
"@kadal/deck": "^0.4.2",
|
|
91
|
+
"react": "^19.2.0"
|
|
92
|
+
},
|
|
93
|
+
"devDependencies": {
|
|
94
|
+
"@kadal/deck": "workspace:*",
|
|
95
|
+
"@types/react": "^19.2.0",
|
|
96
|
+
"@types/react-dom": "^19.2.0",
|
|
97
|
+
"@vitejs/plugin-react": "^6.0.2",
|
|
98
|
+
"react": "^19.2.7",
|
|
99
|
+
"react-dom": "^19.2.7",
|
|
100
|
+
"typescript": "^6.0.3",
|
|
101
|
+
"vite": "^8.0.16"
|
|
102
|
+
}
|
|
103
|
+
}
|