@kadal/deck 0.0.0-stage → 0.1.0
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/LICENSING.md +40 -0
- package/README.md +170 -2
- package/dist/_virtual/_rolldown/runtime.js +13 -0
- package/dist/audience/index.d.ts +14 -0
- package/dist/audience/index.js +680 -0
- package/dist/backgrounds/index.d.ts +65 -0
- package/dist/backgrounds/index.js +604 -0
- package/dist/backgrounds/shared.d.ts +7 -0
- package/dist/backgrounds/shared.js +89 -0
- package/dist/cli/bin.d.ts +1 -0
- package/dist/cli/bin.js +8 -0
- package/dist/cli/host.js +111 -0
- package/dist/cli/index.d.ts +4 -0
- package/dist/cli/index.js +140 -0
- package/dist/cli/login.js +56 -0
- package/dist/cli/publish.js +159 -0
- package/dist/cli/vite.js +39 -0
- package/dist/compiler/code-meta.d.ts +33 -0
- package/dist/compiler/code-meta.js +81 -0
- package/dist/compiler/index.d.ts +8 -0
- package/dist/compiler/index.js +8 -0
- package/dist/compiler/magic-move.d.ts +26 -0
- package/dist/compiler/magic-move.js +33 -0
- package/dist/compiler/plain-text.js +7 -0
- package/dist/compiler/rehype-code.d.ts +18 -0
- package/dist/compiler/rehype-code.js +66 -0
- package/dist/compiler/rehype-glossary.d.ts +35 -0
- package/dist/compiler/rehype-glossary.js +211 -0
- package/dist/compiler/slots.d.ts +3 -0
- package/dist/compiler/slots.js +36 -0
- package/dist/compiler/split.d.ts +63 -0
- package/dist/compiler/split.js +195 -0
- package/dist/components/Background.d.ts +15 -0
- package/dist/components/Background.js +24 -0
- package/dist/components/Click.d.ts +54 -0
- package/dist/components/Click.js +129 -0
- package/dist/components/Code.d.ts +27 -0
- package/dist/components/Code.js +124 -0
- package/dist/components/Motion.d.ts +25 -0
- package/dist/components/Motion.js +45 -0
- package/dist/components/Sketch.d.ts +44 -0
- package/dist/components/Sketch.js +141 -0
- package/dist/components/Term.d.ts +63 -0
- package/dist/components/Term.js +492 -0
- package/dist/components/bling.d.ts +75 -0
- package/dist/components/bling.js +146 -0
- package/dist/components/content.d.ts +232 -0
- package/dist/components/content.js +637 -0
- package/dist/components/index.d.ts +10 -0
- package/dist/components/index.js +88 -0
- package/dist/core/clicks.d.ts +45 -0
- package/dist/core/clicks.js +75 -0
- package/dist/core/hash.d.ts +33 -0
- package/dist/core/hash.js +49 -0
- package/dist/core/keyboard.d.ts +17 -0
- package/dist/core/keyboard.js +198 -0
- package/dist/core/layout.d.ts +16 -0
- package/dist/core/layout.js +25 -0
- package/dist/core/model.d.ts +259 -0
- package/dist/core/model.js +377 -0
- package/dist/core/navigation.d.ts +74 -0
- package/dist/core/navigation.js +244 -0
- package/dist/core/poster.js +30 -0
- package/dist/core/store.d.ts +20 -0
- package/dist/core/store.js +64 -0
- package/dist/core/touch.js +27 -0
- package/dist/draw/DrawingLayer.js +315 -0
- package/dist/draw/strokes.js +188 -0
- package/dist/export/index.d.ts +68 -0
- package/dist/export/index.js +251 -0
- package/dist/export/run.js +81 -0
- package/dist/glossary/model.d.ts +81 -0
- package/dist/glossary/model.js +156 -0
- package/dist/glossary/parse.d.ts +27 -0
- package/dist/glossary/parse.js +90 -0
- package/dist/index.d.ts +31 -0
- package/dist/index.js +30 -0
- package/dist/live/LiveProvider.d.ts +20 -0
- package/dist/live/LiveProvider.js +450 -0
- package/dist/live/analytics.d.ts +15 -0
- package/dist/live/analytics.js +103 -0
- package/dist/live/client.d.ts +51 -0
- package/dist/live/client.js +193 -0
- package/dist/live/components.d.ts +64 -0
- package/dist/live/components.js +471 -0
- package/dist/live/context.d.ts +15 -0
- package/dist/live/context.js +28 -0
- package/dist/live/index.d.ts +7 -0
- package/dist/live/index.js +7 -0
- package/dist/live/protocol.d.ts +284 -0
- package/dist/live/protocol.js +42 -0
- package/dist/live/turnstile.js +49 -0
- package/dist/presenter/index.d.ts +20 -0
- package/dist/presenter/index.js +1211 -0
- package/dist/react/AutoAnimate.js +92 -0
- package/dist/react/Backgrounds.d.ts +11 -0
- package/dist/react/Backgrounds.js +154 -0
- package/dist/react/ConfettiLayer.js +85 -0
- package/dist/react/Deck.d.ts +35 -0
- package/dist/react/Deck.js +983 -0
- package/dist/react/Frame.d.ts +16 -0
- package/dist/react/Frame.js +174 -0
- package/dist/react/Hints.d.ts +3 -0
- package/dist/react/Hints.js +201 -0
- package/dist/react/Lightbox.js +54 -0
- package/dist/react/Overview.js +93 -0
- package/dist/react/PrintView.js +128 -0
- package/dist/react/ScrollView.js +128 -0
- package/dist/react/SlideFrame.d.ts +51 -0
- package/dist/react/SlideFrame.js +323 -0
- package/dist/react/Stage.js +151 -0
- package/dist/react/ThemeMenu.d.ts +5 -0
- package/dist/react/ThemeMenu.js +124 -0
- package/dist/react/Zoom.js +23 -0
- package/dist/react/chrome.js +339 -0
- package/dist/react/context.d.ts +165 -0
- package/dist/react/context.js +19 -0
- package/dist/react/hooks.d.ts +33 -0
- package/dist/react/hooks.js +70 -0
- package/dist/react/layouts.d.ts +21 -0
- package/dist/react/layouts.js +104 -0
- package/dist/react/mdx.d.ts +4 -0
- package/dist/react/mdx.js +33 -0
- package/dist/react/terms.d.ts +6 -0
- package/dist/react/terms.js +66 -0
- package/dist/renderers/Island.d.ts +57 -0
- package/dist/renderers/Island.js +223 -0
- package/dist/renderers/contract.d.ts +173 -0
- package/dist/renderers/contract.js +152 -0
- package/dist/renderers/index.d.ts +12 -0
- package/dist/renderers/index.js +16 -0
- package/dist/renderers/react.d.ts +16 -0
- package/dist/renderers/react.js +32 -0
- package/dist/renderers/web-components.d.ts +4 -0
- package/dist/renderers/web-components.js +103 -0
- package/dist/sketch/Canvas.js +49 -0
- package/dist/sketch/dsl.d.ts +131 -0
- package/dist/sketch/dsl.js +281 -0
- package/dist/sketch/index.d.ts +4 -0
- package/dist/sketch/index.js +3 -0
- package/dist/sketch/palette.d.ts +21 -0
- package/dist/sketch/palette.js +66 -0
- package/dist/sketch/render.d.ts +43 -0
- package/dist/sketch/render.js +198 -0
- package/dist/themes/base.css +1704 -0
- package/dist/themes/bling.css +592 -0
- package/dist/themes/glossary.css +317 -0
- package/dist/themes/live.css +1557 -0
- package/dist/themes/minimal.css +83 -0
- package/dist/themes/rla.css +92 -0
- package/dist/themes/sketch.css +121 -0
- package/dist/themes/stack.css +62 -0
- package/dist/vite/index.d.ts +15 -0
- package/dist/vite/index.js +320 -0
- package/package.json +159 -4
- package/tools/verify-island.mjs +150 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { SketchScene } from "../sketch/dsl.js";
|
|
2
|
+
import { ExcalidrawFile } from "../sketch/render.js";
|
|
3
|
+
import { ReactNode } from "react";
|
|
4
|
+
//#region src/components/Sketch.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* ─────────────────────────────────────────────────────────────────────────────
|
|
7
|
+
* <Sketch> — a hand-drawn Excalidraw diagram on a slide
|
|
8
|
+
* ─────────────────────────────────────────────────────────────────────────────
|
|
9
|
+
*
|
|
10
|
+
* <Sketch scene={architecture} /> drawn in code with the `sketch()` DSL
|
|
11
|
+
* <Sketch src="diagrams/flow.excalidraw" /> a file saved from excalidraw.com (public/)
|
|
12
|
+
* <Sketch src={fileObject} /> the same, already loaded
|
|
13
|
+
* <Sketch>{`flowchart LR; a --> b`}</Sketch> Mermaid, converted to a sketch
|
|
14
|
+
*
|
|
15
|
+
* The drawing is a static SVG recoloured with the theme's tokens, so it follows the theme menu
|
|
16
|
+
* and the dark scheme. `steps` turns clicks into a tour: the whole diagram shows first, then
|
|
17
|
+
* each click lights one region (a `region` from the DSL, a frame or group from a file) and dims
|
|
18
|
+
* the rest, with an optional caption — the notes' `[click]` markers line up with them. The
|
|
19
|
+
* corner button (or its F-hint) opens the real Excalidraw canvas in view mode, to pan and zoom.
|
|
20
|
+
* ─────────────────────────────────────────────────────────────────────────────
|
|
21
|
+
*/
|
|
22
|
+
export type SketchStep = string | null | {
|
|
23
|
+
focus?: string | string[] | null;
|
|
24
|
+
caption?: ReactNode;
|
|
25
|
+
};
|
|
26
|
+
export interface SketchProps {
|
|
27
|
+
scene?: SketchScene;
|
|
28
|
+
src?: string | ExcalidrawFile;
|
|
29
|
+
mermaid?: string;
|
|
30
|
+
children?: ReactNode;
|
|
31
|
+
/** Regions to light up, one per click, after the whole diagram has shown. */
|
|
32
|
+
steps?: SketchStep[];
|
|
33
|
+
/** Shown under the diagram when no step's caption is. */
|
|
34
|
+
caption?: ReactNode;
|
|
35
|
+
/** CSS size limits for the drawing. */
|
|
36
|
+
width?: string;
|
|
37
|
+
height?: string;
|
|
38
|
+
/** Font size for Mermaid conversions. */
|
|
39
|
+
fontSize?: number;
|
|
40
|
+
zoomable?: boolean;
|
|
41
|
+
className?: string;
|
|
42
|
+
}
|
|
43
|
+
export declare function Sketch({ scene, src, mermaid, children, steps, caption, width, height, fontSize, zoomable, className }: SketchProps): import("react").JSX.Element;
|
|
44
|
+
//#endregion
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { useActions, useClick, useUi } from "../react/hooks.js";
|
|
2
|
+
import { hashInput, renderSketch } from "../sketch/render.js";
|
|
3
|
+
import { useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
//#region src/components/Sketch.tsx
|
|
6
|
+
function stepOf(s) {
|
|
7
|
+
if (s == null) return { focus: null };
|
|
8
|
+
if (typeof s === "string") return { focus: [s] };
|
|
9
|
+
const f = s.focus;
|
|
10
|
+
return {
|
|
11
|
+
focus: f == null ? null : Array.isArray(f) ? f : [f],
|
|
12
|
+
caption: s.caption
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
function Sketch({ scene, src, mermaid, children, steps = [], caption, width, height, fontSize, zoomable = true, className }) {
|
|
16
|
+
const text = mermaid ?? (typeof children === "string" ? children : Array.isArray(children) ? children.join("") : "");
|
|
17
|
+
const input = useMemo(() => {
|
|
18
|
+
if (scene) return scene;
|
|
19
|
+
if (typeof src === "string") return {
|
|
20
|
+
kind: "url",
|
|
21
|
+
src
|
|
22
|
+
};
|
|
23
|
+
if (src) return {
|
|
24
|
+
kind: "file",
|
|
25
|
+
data: src
|
|
26
|
+
};
|
|
27
|
+
return {
|
|
28
|
+
kind: "mermaid",
|
|
29
|
+
source: text.trim(),
|
|
30
|
+
fontSize
|
|
31
|
+
};
|
|
32
|
+
}, [
|
|
33
|
+
scene,
|
|
34
|
+
src,
|
|
35
|
+
text,
|
|
36
|
+
fontSize
|
|
37
|
+
]);
|
|
38
|
+
const key = useMemo(() => hashInput(input), [input]);
|
|
39
|
+
const [out, setOut] = useState(null);
|
|
40
|
+
const [error, setError] = useState(null);
|
|
41
|
+
useEffect(() => {
|
|
42
|
+
let alive = true;
|
|
43
|
+
setError(null);
|
|
44
|
+
renderSketch(input, key).then((r) => alive && setOut(r), (e) => alive && setError(String(e)));
|
|
45
|
+
return () => {
|
|
46
|
+
alive = false;
|
|
47
|
+
};
|
|
48
|
+
}, [input, key]);
|
|
49
|
+
const n = steps.length;
|
|
50
|
+
const { range, click } = useClick(n ? { span: n } : { at: 0 });
|
|
51
|
+
const idx = n && click >= range.start ? Math.min(click - range.start, n - 1) : -1;
|
|
52
|
+
const step = idx >= 0 ? stepOf(steps[idx]) : { focus: null };
|
|
53
|
+
const focus = step.focus;
|
|
54
|
+
const shownCaption = step.caption ?? caption;
|
|
55
|
+
const actions = useActions();
|
|
56
|
+
const hints = useUi((s) => s.hints);
|
|
57
|
+
const body = useRef(null);
|
|
58
|
+
const open = useRef(null);
|
|
59
|
+
useLayoutEffect(() => {
|
|
60
|
+
const place = () => {
|
|
61
|
+
const svg = body.current?.querySelector("svg");
|
|
62
|
+
const btn = open.current;
|
|
63
|
+
const fig = btn?.parentElement;
|
|
64
|
+
if (!svg || !btn || !fig) return;
|
|
65
|
+
const s = svg.getBoundingClientRect();
|
|
66
|
+
const f = fig.getBoundingClientRect();
|
|
67
|
+
const scale = f.width / Math.max(1, fig.offsetWidth);
|
|
68
|
+
btn.style.left = `${(s.right - f.left) / scale - btn.offsetWidth - 4}px`;
|
|
69
|
+
btn.style.top = `${(s.top - f.top) / scale + 4}px`;
|
|
70
|
+
};
|
|
71
|
+
place();
|
|
72
|
+
window.addEventListener("resize", place);
|
|
73
|
+
return () => window.removeEventListener("resize", place);
|
|
74
|
+
}, [out]);
|
|
75
|
+
useLayoutEffect(() => {
|
|
76
|
+
const root = body.current;
|
|
77
|
+
if (!root) return;
|
|
78
|
+
for (const g of root.querySelectorAll(".sk-el")) {
|
|
79
|
+
const rs = (g.getAttribute("data-region") ?? "").split("|").filter(Boolean);
|
|
80
|
+
const dim = !!focus && rs.length > 0 && !rs.some((r) => focus.includes(r));
|
|
81
|
+
g.classList.toggle("is-dim", dim);
|
|
82
|
+
g.classList.toggle("is-lit", !!focus && !dim && rs.length > 0);
|
|
83
|
+
}
|
|
84
|
+
}, [out, focus]);
|
|
85
|
+
return /* @__PURE__ */ jsxs("figure", {
|
|
86
|
+
className: [
|
|
87
|
+
"deck-sketch",
|
|
88
|
+
focus ? "has-focus" : "",
|
|
89
|
+
hints ? "hints-on" : "",
|
|
90
|
+
className
|
|
91
|
+
].filter(Boolean).join(" "),
|
|
92
|
+
"data-sketch": key,
|
|
93
|
+
style: {
|
|
94
|
+
...width ? { maxWidth: width } : {},
|
|
95
|
+
...height ? { "--sk-max-h": height } : {},
|
|
96
|
+
...out ? { "--sk-ratio": (out.width / Math.max(1, out.height)).toFixed(4) } : {}
|
|
97
|
+
},
|
|
98
|
+
children: [
|
|
99
|
+
/* @__PURE__ */ jsx("div", {
|
|
100
|
+
ref: body,
|
|
101
|
+
className: "deck-sketch-body",
|
|
102
|
+
dangerouslySetInnerHTML: { __html: out?.svg ?? "" }
|
|
103
|
+
}),
|
|
104
|
+
!out && !error ? /* @__PURE__ */ jsx("div", {
|
|
105
|
+
className: "deck-sketch-loading",
|
|
106
|
+
children: "drawing…"
|
|
107
|
+
}) : null,
|
|
108
|
+
error ? /* @__PURE__ */ jsx("pre", {
|
|
109
|
+
className: "deck-sketch-error",
|
|
110
|
+
children: error
|
|
111
|
+
}) : null,
|
|
112
|
+
zoomable && out ? /* @__PURE__ */ jsx("button", {
|
|
113
|
+
ref: open,
|
|
114
|
+
type: "button",
|
|
115
|
+
className: "deck-sketch-open",
|
|
116
|
+
"data-hint": "canvas",
|
|
117
|
+
title: "Open on the canvas (pan and zoom)",
|
|
118
|
+
"aria-label": "Open on the canvas",
|
|
119
|
+
onClick: () => actions.openLightbox("sketch", key, "sketch"),
|
|
120
|
+
children: /* @__PURE__ */ jsx("svg", {
|
|
121
|
+
viewBox: "0 0 24 24",
|
|
122
|
+
width: "16",
|
|
123
|
+
height: "16",
|
|
124
|
+
fill: "none",
|
|
125
|
+
stroke: "currentColor",
|
|
126
|
+
strokeWidth: "2",
|
|
127
|
+
strokeLinecap: "round",
|
|
128
|
+
strokeLinejoin: "round",
|
|
129
|
+
"aria-hidden": true,
|
|
130
|
+
children: /* @__PURE__ */ jsx("path", { d: "M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7" })
|
|
131
|
+
})
|
|
132
|
+
}) : null,
|
|
133
|
+
shownCaption ? /* @__PURE__ */ jsx("figcaption", {
|
|
134
|
+
className: "deck-sketch-caption",
|
|
135
|
+
children: shownCaption
|
|
136
|
+
}, idx) : null
|
|
137
|
+
]
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
//#endregion
|
|
141
|
+
export { Sketch };
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { ReactNode } from "react";
|
|
2
|
+
//#region src/components/Term.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* ─────────────────────────────────────────────────────────────────────────────
|
|
5
|
+
* <Term> — a key concept or abbreviation that can explain itself
|
|
6
|
+
* ─────────────────────────────────────────────────────────────────────────────
|
|
7
|
+
*
|
|
8
|
+
* At rest a term reads like the text around it, with a faint dotted underline. Rest the pointer
|
|
9
|
+
* on it and a countdown runs — the cursor becomes a filling pie and the underline draws itself
|
|
10
|
+
* solid — so sweeping the mouse across a slide never sets cards off; when it completes, the
|
|
11
|
+
* definition opens in a card anchored to the word. A click, a tap or an `f` hint label opens it
|
|
12
|
+
* at once and pins it while you talk. Escape, a press elsewhere or the next step closes it.
|
|
13
|
+
*
|
|
14
|
+
* Most terms are never written by hand: the compiler wraps the first mention of every glossary
|
|
15
|
+
* entry on each slide (`compiler/rehype-glossary.ts`). By hand:
|
|
16
|
+
*
|
|
17
|
+
* <Term>UTM</Term> the glossary's entry, found by name or alias
|
|
18
|
+
* <Term id="utm">projected metres</Term> other words, same entry
|
|
19
|
+
* <Term def="Root-mean-square error, in metres.">RMSE</Term> a one-off, no entry needed
|
|
20
|
+
* <Term def="…" title="Thiessen polygon" full="…" tag="Geometry" link="https://…">cells</Term>
|
|
21
|
+
*
|
|
22
|
+
* The card lives inside the slide's canvas, in stage pixels, so it is part of the picture every
|
|
23
|
+
* screen shows — and it never lets its type fall below a readable size: on a small window or a
|
|
24
|
+
* phone the card grows against the canvas's scale instead of shrinking with it.
|
|
25
|
+
* ─────────────────────────────────────────────────────────────────────────────
|
|
26
|
+
*/
|
|
27
|
+
export interface TermProps {
|
|
28
|
+
/** The glossary entry (its id, name or alias). Without it the children's text is looked up. */
|
|
29
|
+
id?: string;
|
|
30
|
+
/** A one-off definition (inline Markdown). With it, the glossary is not consulted. */
|
|
31
|
+
def?: string;
|
|
32
|
+
more?: string;
|
|
33
|
+
/** The card's title for a one-off; defaults to the children's text. */
|
|
34
|
+
title?: string;
|
|
35
|
+
full?: string;
|
|
36
|
+
tag?: string;
|
|
37
|
+
link?: string;
|
|
38
|
+
/** Set by the compiler: `def`/`more` already rendered (with KaTeX), and an automatic link. */
|
|
39
|
+
html?: string;
|
|
40
|
+
moreHtml?: string;
|
|
41
|
+
auto?: boolean;
|
|
42
|
+
children?: ReactNode;
|
|
43
|
+
}
|
|
44
|
+
export declare function Term({ id, def, more, title, full, tag, link, html, moreHtml, auto, children }: TermProps): import("react").JSX.Element;
|
|
45
|
+
/**
|
|
46
|
+
* Links the glossary's mentions inside a plain string, at render time — for a component whose
|
|
47
|
+
* words arrive as a prop (`<Stat label="quantisation RMSE" />`), where the compiler, which only
|
|
48
|
+
* sees a slide's children, cannot reach. The first mention of each term in the string is linked.
|
|
49
|
+
*
|
|
50
|
+
* <small><Terms>{note}</Terms></small>
|
|
51
|
+
*/
|
|
52
|
+
export declare function Terms({ children }: {
|
|
53
|
+
children?: string | null;
|
|
54
|
+
}): import("react").JSX.Element;
|
|
55
|
+
/**
|
|
56
|
+
* The window's open definition as ordinary page content, at reading size — for a page whose slide
|
|
57
|
+
* is too small to carry a card (the audience's phone). Put the mirror inside an element with
|
|
58
|
+
* `data-term-cards="off"` and this beside it.
|
|
59
|
+
*/
|
|
60
|
+
export declare function TermReadout({ className }: {
|
|
61
|
+
className?: string;
|
|
62
|
+
}): import("react").JSX.Element | null;
|
|
63
|
+
//#endregion
|