@edv4h/usketch-plugin-shape-markdown 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/dist/plugin.js ADDED
@@ -0,0 +1,223 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { DEFAULT_STYLE, generateId, withRotation, } from "@edv4h/usketch-shared";
3
+ import { createAddShapeCommand } from "@edv4h/usketch-store";
4
+ import { MARKDOWN_DEFAULT_SIZE, MARKDOWN_MIN_SIZE, MARKDOWN_SHORTCUT } from "./constants.js";
5
+ import { createMarkdownTableHandler, createMarkdownTextHandler, } from "./external-content-handler.js";
6
+ import { createMarkdownEditingService } from "./markdown-editing-machine.js";
7
+ import { MD_BLUR_EVENT, MD_ESCAPE_EVENT, MD_INPUT_EVENT, MD_MEASURE_EVENT, renderMarkdown, SimplifiedMarkdown, } from "./render.js";
8
+ import { markdownSelection } from "./selection-store.js";
9
+ import { MARKDOWN_TYPE, readMarkdownMeta } from "./types.js";
10
+ // ── Shape definition helpers ──
11
+ function getBounds(data) {
12
+ return { x: data.x, y: data.y, width: data.width, height: data.height };
13
+ }
14
+ function hitTest(data, point) {
15
+ return (point.x >= data.x &&
16
+ point.x <= data.x + data.width &&
17
+ point.y >= data.y &&
18
+ point.y <= data.y + data.height);
19
+ }
20
+ function resize(data, handle, delta) {
21
+ let { x, y, width, height } = data;
22
+ switch (handle) {
23
+ case "se":
24
+ width += delta.x;
25
+ height += delta.y;
26
+ break;
27
+ case "nw":
28
+ x += delta.x;
29
+ y += delta.y;
30
+ width -= delta.x;
31
+ height -= delta.y;
32
+ break;
33
+ case "ne":
34
+ y += delta.y;
35
+ width += delta.x;
36
+ height -= delta.y;
37
+ break;
38
+ case "sw":
39
+ x += delta.x;
40
+ width -= delta.x;
41
+ height += delta.y;
42
+ break;
43
+ case "e":
44
+ width += delta.x;
45
+ break;
46
+ case "w":
47
+ x += delta.x;
48
+ width -= delta.x;
49
+ break;
50
+ case "n":
51
+ y += delta.y;
52
+ height -= delta.y;
53
+ break;
54
+ case "s":
55
+ height += delta.y;
56
+ break;
57
+ }
58
+ return {
59
+ ...data,
60
+ x,
61
+ y,
62
+ width: Math.max(MARKDOWN_MIN_SIZE.width, width),
63
+ height: Math.max(MARKDOWN_MIN_SIZE.height, height),
64
+ };
65
+ }
66
+ function createDefault(params) {
67
+ return {
68
+ id: params.id,
69
+ type: MARKDOWN_TYPE,
70
+ x: params.x,
71
+ y: params.y,
72
+ width: MARKDOWN_DEFAULT_SIZE.width,
73
+ height: MARKDOWN_DEFAULT_SIZE.height,
74
+ style: { ...DEFAULT_STYLE, fill: "transparent", strokeWidth: 0 },
75
+ meta: { source: "", isEditing: false },
76
+ };
77
+ }
78
+ function serializeForAi(shape) {
79
+ return { source: readMarkdownMeta(shape).source };
80
+ }
81
+ function debugFields(shape) {
82
+ const { source, isEditing } = readMarkdownMeta(shape);
83
+ return {
84
+ source: source.length > 40 ? `${source.slice(0, 40)}…` : source,
85
+ isEditing,
86
+ };
87
+ }
88
+ function MarkdownIcon() {
89
+ return (_jsx("svg", { width: "20", height: "20", viewBox: "0 0 20 20", "aria-hidden": "true", children: _jsx("text", { x: "10", y: "14", textAnchor: "middle", fontSize: "11", fontWeight: "bold", fill: "currentColor", fontFamily: "ui-monospace, monospace", children: "M\u2193" }) }));
90
+ }
91
+ // ── Plugin ──
92
+ export function createMarkdownPlugin() {
93
+ return {
94
+ id: "usketch-plugin-shape-markdown",
95
+ name: "Markdown",
96
+ setup(ctx) {
97
+ const service = createMarkdownEditingService(ctx);
98
+ const { send, matches, stop: stopMachine } = service;
99
+ // ── Editor CustomEvent listeners (dispatched from render.tsx) ──
100
+ const onInput = (e) => {
101
+ const { id, source, scrollHeight } = e.detail;
102
+ send({ type: "EDIT_INPUT", id, source, scrollHeight });
103
+ };
104
+ const onBlur = (e) => {
105
+ const { id } = e.detail;
106
+ requestAnimationFrame(() => send({ type: "EDIT_BLUR", id }));
107
+ };
108
+ const onEscape = (e) => {
109
+ const { id } = e.detail;
110
+ send({ type: "EDIT_ESCAPE", id });
111
+ };
112
+ // Auto-fit shape height to rendered content (view mode only). Applied
113
+ // directly (not via a command) so it never pollutes undo history.
114
+ const onMeasure = (e) => {
115
+ const { id, height } = e.detail;
116
+ const shape = ctx.store.getShape(id);
117
+ if (!shape || shape.type !== MARKDOWN_TYPE)
118
+ return;
119
+ if (readMarkdownMeta(shape).isEditing)
120
+ return;
121
+ if (height > 0 && Math.abs(shape.height - height) > 1) {
122
+ ctx.store.updateShape(id, { height });
123
+ }
124
+ };
125
+ window.addEventListener(MD_INPUT_EVENT, onInput);
126
+ window.addEventListener(MD_BLUR_EVENT, onBlur);
127
+ window.addEventListener(MD_ESCAPE_EVENT, onEscape);
128
+ window.addEventListener(MD_MEASURE_EVENT, onMeasure);
129
+ // ── Outside-click exits edit mode ──
130
+ const onWindowPointerDown = (e) => {
131
+ if (!matches("editing"))
132
+ return;
133
+ const target = e.target instanceof Element ? e.target : e.target?.parentElement;
134
+ if (target?.closest("[data-usketch-md-editor]"))
135
+ return;
136
+ send({ type: "OUTSIDE_CLICK" });
137
+ };
138
+ window.addEventListener("pointerdown", onWindowPointerDown, true);
139
+ // ── Paste / drop → markdown shape ──
140
+ // Table handler (order 10) wins for tabular content; plain text falls
141
+ // through to the catch-all (order 0).
142
+ const offTableHandler = ctx.externalContent.register(createMarkdownTableHandler());
143
+ const offExternal = ctx.externalContent.register(createMarkdownTextHandler());
144
+ // The currently-selected single markdown shape, or null. Used by the
145
+ // "Edit source" action's isEnabled/run.
146
+ const selectedMarkdownId = () => {
147
+ const sel = ctx.store.getSelection();
148
+ if (sel.size !== 1)
149
+ return null;
150
+ const id = [...sel][0];
151
+ return ctx.store.getShape(id)?.type === MARKDOWN_TYPE ? id : null;
152
+ };
153
+ // ── Explicit edit trigger: Control HUD "Edit source" action ──
154
+ // (Editing is intentionally NOT bound to double-click, so rendered
155
+ // content interactions stay free.)
156
+ const offEditAction = ctx.actions.register({
157
+ id: "markdown:edit",
158
+ label: "✎ Edit source",
159
+ group: "Markdown",
160
+ isEnabled: () => selectedMarkdownId() !== null,
161
+ run: () => {
162
+ const id = selectedMarkdownId();
163
+ if (id)
164
+ send({ type: "BEGIN_EDIT", shapeId: id });
165
+ },
166
+ });
167
+ // ── Track selection (drives content interactivity) + exit edit on deselect ──
168
+ markdownSelection.set(ctx.store.getSelection());
169
+ const unsubscribe = ctx.store.subscribe(() => {
170
+ markdownSelection.set(ctx.store.getSelection());
171
+ const editingShapeId = service.context.editingShapeId;
172
+ if (editingShapeId && !ctx.store.getSelection().has(editingShapeId)) {
173
+ send({ type: "DESELECTED" });
174
+ }
175
+ });
176
+ // ── Shape registration ──
177
+ ctx.shapes.register(MARKDOWN_TYPE, {
178
+ render: renderMarkdown,
179
+ getBounds,
180
+ hitTest: withRotation(hitTest),
181
+ resize,
182
+ createDefault,
183
+ renderTarget: "html",
184
+ minSize: MARKDOWN_MIN_SIZE,
185
+ simplifiedComponent: SimplifiedMarkdown,
186
+ serializeForAi,
187
+ debugFields,
188
+ });
189
+ // ── Draw tool ──
190
+ ctx.tools.register("markdown-draw", {
191
+ icon: MarkdownIcon,
192
+ cursor: "text",
193
+ shortcut: MARKDOWN_SHORTCUT,
194
+ order: 26,
195
+ onPointerDown(toolCtx, event) {
196
+ const id = generateId();
197
+ const defaults = createDefault({ id, x: event.worldPoint.x, y: event.worldPoint.y });
198
+ const shape = { ...defaults, y: defaults.y - defaults.height / 2 };
199
+ toolCtx.commands.execute(createAddShapeCommand(toolCtx.store, shape));
200
+ toolCtx.store.setSelection([id]);
201
+ toolCtx.store.resetToDefaultTool();
202
+ send({ type: "CREATE_SHAPE", shapeId: id });
203
+ },
204
+ onPointerMove() { },
205
+ onPointerUp() { },
206
+ });
207
+ // ── Teardown ──
208
+ return () => {
209
+ stopMachine();
210
+ window.removeEventListener(MD_INPUT_EVENT, onInput);
211
+ window.removeEventListener(MD_BLUR_EVENT, onBlur);
212
+ window.removeEventListener(MD_ESCAPE_EVENT, onEscape);
213
+ window.removeEventListener(MD_MEASURE_EVENT, onMeasure);
214
+ window.removeEventListener("pointerdown", onWindowPointerDown, true);
215
+ offEditAction();
216
+ offTableHandler();
217
+ offExternal();
218
+ unsubscribe();
219
+ };
220
+ },
221
+ };
222
+ }
223
+ //# sourceMappingURL=plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { ShapeData } from "@edv4h/usketch-shared";
2
+ export declare const MD_INPUT_EVENT = "usketch:markdown-input";
3
+ export declare const MD_BLUR_EVENT = "usketch:markdown-blur";
4
+ export declare const MD_ESCAPE_EVENT = "usketch:markdown-escape";
5
+ export declare const MD_MEASURE_EVENT = "usketch:markdown-measure";
6
+ export declare function renderMarkdown(shape: ShapeData): import("react").JSX.Element;
7
+ /** LOD: first non-empty line, stripped of common markdown markers. */
8
+ export declare function SimplifiedMarkdown({ shape }: {
9
+ shape: ShapeData;
10
+ }): import("react").JSX.Element;
11
+ //# sourceMappingURL=render.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../src/render.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AASvD,eAAO,MAAM,cAAc,2BAA2B,CAAC;AACvD,eAAO,MAAM,aAAa,0BAA0B,CAAC;AACrD,eAAO,MAAM,eAAe,4BAA4B,CAAC;AACzD,eAAO,MAAM,gBAAgB,6BAA6B,CAAC;AAiQ3D,wBAAgB,cAAc,CAAC,KAAK,EAAE,SAAS,+BAM9C;AAED,sEAAsE;AACtE,wBAAgB,kBAAkB,CAAC,EAAE,KAAK,EAAE,EAAE;IAAE,KAAK,EAAE,SAAS,CAAA;CAAE,+BA+BjE"}
package/dist/render.js ADDED
@@ -0,0 +1,280 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { useEffect, useRef, useState, useSyncExternalStore } from "react";
3
+ import Markdown, {} from "react-markdown";
4
+ import rehypeHighlight from "rehype-highlight";
5
+ import remarkGfm from "remark-gfm";
6
+ import { markdownSelection } from "./selection-store.js";
7
+ import { readMarkdownMeta } from "./types.js";
8
+ // ── Custom events (plugin.tsx listens on window) ──
9
+ export const MD_INPUT_EVENT = "usketch:markdown-input";
10
+ export const MD_BLUR_EVENT = "usketch:markdown-blur";
11
+ export const MD_ESCAPE_EVENT = "usketch:markdown-escape";
12
+ export const MD_MEASURE_EVENT = "usketch:markdown-measure";
13
+ const STYLE_ID = "usketch-markdown-styles";
14
+ /** Inject scoped markdown + highlight.js theme CSS once per document. */
15
+ function ensureStyles() {
16
+ if (typeof document === "undefined")
17
+ return;
18
+ if (document.getElementById(STYLE_ID))
19
+ return;
20
+ const el = document.createElement("style");
21
+ el.id = STYLE_ID;
22
+ el.textContent = MARKDOWN_CSS;
23
+ document.head.appendChild(el);
24
+ }
25
+ function isDarkTheme() {
26
+ if (typeof document === "undefined")
27
+ return false;
28
+ const attr = document.documentElement.getAttribute("data-theme");
29
+ if (attr === "dark")
30
+ return true;
31
+ if (attr === "light")
32
+ return false;
33
+ return (typeof window !== "undefined" && window.matchMedia?.("(prefers-color-scheme: dark)").matches);
34
+ }
35
+ // ── Mermaid block (dynamic import; renders SVG into a ref container) ──
36
+ function MermaidBlock({ code }) {
37
+ const ref = useRef(null);
38
+ const [error, setError] = useState(null);
39
+ useEffect(() => {
40
+ let cancelled = false;
41
+ (async () => {
42
+ try {
43
+ // Dynamic import keeps the (large) mermaid bundle out of the main chunk.
44
+ const mermaid = (await import("mermaid")).default;
45
+ mermaid.initialize({
46
+ startOnLoad: false,
47
+ // strict: mermaid sanitizes labels, disables inline HTML & click handlers.
48
+ securityLevel: "strict",
49
+ theme: isDarkTheme() ? "dark" : "default",
50
+ });
51
+ const id = `usketch-mermaid-${Math.random().toString(36).slice(2)}`;
52
+ const { svg } = await mermaid.render(id, code);
53
+ if (cancelled || !ref.current)
54
+ return;
55
+ // Parse the SVG string and adopt the <svg> node rather than assigning
56
+ // `innerHTML` — avoids a string-HTML sink (CSP / Trusted Types friendly).
57
+ const parsed = new DOMParser().parseFromString(svg, "image/svg+xml");
58
+ const svgEl = parsed.querySelector("svg");
59
+ if (!svgEl)
60
+ throw new Error("Mermaid produced no <svg>");
61
+ ref.current.replaceChildren(document.importNode(svgEl, true));
62
+ setError(null);
63
+ }
64
+ catch (e) {
65
+ if (!cancelled)
66
+ setError(e instanceof Error ? e.message : "Mermaid render error");
67
+ }
68
+ })();
69
+ return () => {
70
+ cancelled = true;
71
+ };
72
+ }, [code]);
73
+ if (error) {
74
+ return (_jsx("pre", { className: "usketch-md-mermaid-error", title: error, children: `⚠ mermaid: ${error}\n\n${code}` }));
75
+ }
76
+ return _jsx("div", { ref: ref, className: "usketch-md-mermaid", role: "img", "aria-label": "mermaid diagram" });
77
+ }
78
+ // ── Rendered (view) mode ──
79
+ const mdComponents = {
80
+ code({ className, children }) {
81
+ const lang = /language-(\w+)/.exec(className ?? "")?.[1];
82
+ if (lang === "mermaid") {
83
+ return _jsx(MermaidBlock, { code: String(children).replace(/\n$/, "") });
84
+ }
85
+ // rehype-highlight has already injected token <span>s into children.
86
+ return _jsx("code", { className: className, children: children });
87
+ },
88
+ // Links open in a new tab; never let a markdown link navigate the whole app.
89
+ a({ href, children }) {
90
+ return (_jsx("a", { href: href, target: "_blank", rel: "noopener noreferrer", children: children }));
91
+ },
92
+ };
93
+ function MarkdownView({ shape }) {
94
+ const { source } = readMarkdownMeta(shape);
95
+ const ref = useRef(null);
96
+ // Content is interactive (links, text selection) only while the shape is
97
+ // selected; unselected shapes stay non-interactive so a click/drag on the
98
+ // canvas selects & moves the shape.
99
+ const selected = useSyncExternalStore(markdownSelection.subscribe, () => markdownSelection.has(shape.id));
100
+ useEffect(() => {
101
+ ensureStyles();
102
+ }, []);
103
+ // Auto-fit the shape height to the rendered content (GFM tables, mermaid
104
+ // diagrams etc. are usually taller than the raw source). Mermaid renders
105
+ // asynchronously, so a ResizeObserver catches the late height change.
106
+ useEffect(() => {
107
+ const el = ref.current;
108
+ if (!el || typeof ResizeObserver === "undefined")
109
+ return;
110
+ const ro = new ResizeObserver(() => {
111
+ window.dispatchEvent(new CustomEvent(MD_MEASURE_EVENT, {
112
+ detail: { id: shape.id, height: el.scrollHeight },
113
+ }));
114
+ });
115
+ ro.observe(el);
116
+ return () => ro.disconnect();
117
+ }, [shape.id]);
118
+ return (_jsx("div", { className: "usketch-md", ref: ref,
119
+ // When selected: links are clickable and Alt+drag selects text (stop
120
+ // propagation so the canvas doesn't move the shape); a plain drag moves
121
+ // the shape (bubbles to the select tool). When unselected the content is
122
+ // pass-through (pointerEvents:none) so the canvas handles select/move —
123
+ // i.e. links are only clickable while the shape is selected.
124
+ onPointerDown: selected
125
+ ? (e) => {
126
+ if (e.altKey) {
127
+ e.currentTarget.style.userSelect = "text";
128
+ e.stopPropagation();
129
+ }
130
+ else {
131
+ e.currentTarget.style.userSelect = "none";
132
+ }
133
+ }
134
+ : undefined,
135
+ // Reset the imperative userSelect after an Alt+drag so it doesn't linger
136
+ // into the next (plain) drag before a re-render clears it.
137
+ onPointerUp: selected ? (e) => (e.currentTarget.style.userSelect = "none") : undefined, onPointerCancel: selected ? (e) => (e.currentTarget.style.userSelect = "none") : undefined, style: {
138
+ width: "100%",
139
+ boxSizing: "border-box",
140
+ padding: 8,
141
+ overflow: "hidden",
142
+ // Selected → interactive content (links clickable, Alt+drag text select).
143
+ // Unselected → transparent to pointers so the canvas handles select/move.
144
+ pointerEvents: selected ? "auto" : "none",
145
+ userSelect: "none",
146
+ color: shape.style.stroke,
147
+ background: shape.style.fill === "transparent" ? "transparent" : shape.style.fill,
148
+ }, children: source.trim() === "" ? (_jsx("span", { className: "usketch-md-empty", children: "\uFF08\u7A7A\u306E Markdown \u2014 HUD \u306E Edit source \u3067\u7DE8\u96C6\uFF09" })) : (_jsx(Markdown, { remarkPlugins: [remarkGfm],
149
+ // ignoreMissing: unsupported languages (incl. our ```mermaid``` blocks,
150
+ // which highlight.js doesn't know) fall back to plain code instead of
151
+ // throwing and breaking the whole render.
152
+ rehypePlugins: [[rehypeHighlight, { ignoreMissing: true }]], components: mdComponents, children: source })) }));
153
+ }
154
+ // ── Editor (raw markdown) mode ──
155
+ function MarkdownEditor({ shape }) {
156
+ const { source } = readMarkdownMeta(shape);
157
+ const ref = useRef(null);
158
+ // Focus + place cursor at end once when entering edit mode. The textarea's
159
+ // own value is uncontrolled after mount so the caret isn't reset on input.
160
+ // biome-ignore lint/correctness/useExhaustiveDependencies: init once per mount (textarea is uncontrolled afterwards)
161
+ useEffect(() => {
162
+ const el = ref.current;
163
+ if (!el)
164
+ return;
165
+ el.value = source;
166
+ autoGrow(el);
167
+ requestAnimationFrame(() => {
168
+ el.focus();
169
+ el.setSelectionRange(el.value.length, el.value.length);
170
+ });
171
+ }, []);
172
+ const emitInput = (el) => {
173
+ autoGrow(el);
174
+ window.dispatchEvent(new CustomEvent(MD_INPUT_EVENT, {
175
+ detail: { id: shape.id, source: el.value, scrollHeight: el.scrollHeight },
176
+ }));
177
+ };
178
+ return (_jsx("textarea", { ref: ref, "data-usketch-md-editor": "1", defaultValue: source, spellCheck: false, onInput: (e) => {
179
+ if (e.nativeEvent.isComposing)
180
+ return;
181
+ emitInput(e.currentTarget);
182
+ }, onCompositionEnd: (e) => emitInput(e.currentTarget), onKeyDown: (e) => {
183
+ e.stopPropagation();
184
+ if (e.key === "Escape" && !e.nativeEvent.isComposing) {
185
+ window.dispatchEvent(new CustomEvent(MD_ESCAPE_EVENT, { detail: { id: shape.id } }));
186
+ }
187
+ }, onBlur: () => {
188
+ window.dispatchEvent(new CustomEvent(MD_BLUR_EVENT, { detail: { id: shape.id } }));
189
+ }, onPointerDown: (e) => e.stopPropagation(), style: {
190
+ width: "100%",
191
+ height: "100%",
192
+ boxSizing: "border-box",
193
+ padding: 8,
194
+ border: "none",
195
+ outline: "none",
196
+ resize: "none",
197
+ background: "var(--bg-input, #1e1e1e)",
198
+ color: "var(--fg-primary, #eee)",
199
+ fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace",
200
+ fontSize: 13,
201
+ lineHeight: 1.5,
202
+ cursor: "text",
203
+ pointerEvents: "auto",
204
+ userSelect: "auto",
205
+ } }));
206
+ }
207
+ function autoGrow(el) {
208
+ el.style.height = "auto";
209
+ el.style.height = `${el.scrollHeight}px`;
210
+ }
211
+ // ── Entry point + LOD ──
212
+ export function renderMarkdown(shape) {
213
+ return readMarkdownMeta(shape).isEditing ? (_jsx(MarkdownEditor, { shape: shape })) : (_jsx(MarkdownView, { shape: shape }));
214
+ }
215
+ /** LOD: first non-empty line, stripped of common markdown markers. */
216
+ export function SimplifiedMarkdown({ shape }) {
217
+ const { source } = readMarkdownMeta(shape);
218
+ const firstLine = source
219
+ .split("\n")
220
+ .map((l) => l.trim())
221
+ .find((l) => l.length > 0) ?? "";
222
+ const plain = firstLine.replace(/^#{1,6}\s+/, "").replace(/[*_`>#-]/g, "");
223
+ return (_jsx("div", { style: {
224
+ position: "absolute",
225
+ left: shape.x,
226
+ top: shape.y,
227
+ width: shape.width,
228
+ height: shape.height,
229
+ padding: 8,
230
+ boxSizing: "border-box",
231
+ fontFamily: "system-ui, sans-serif",
232
+ fontSize: 14,
233
+ fontWeight: 600,
234
+ color: shape.style.stroke || "#222",
235
+ overflow: "hidden",
236
+ whiteSpace: "nowrap",
237
+ textOverflow: "ellipsis",
238
+ pointerEvents: "none",
239
+ }, children: plain || "Markdown" }));
240
+ }
241
+ // ── Scoped CSS (markdown layout + compact highlight.js github theme) ──
242
+ const MARKDOWN_CSS = `
243
+ .usketch-md { font-family: system-ui, -apple-system, sans-serif; font-size: 13px; line-height: 1.55; word-break: break-word; }
244
+ .usketch-md > :first-child { margin-top: 0; }
245
+ .usketch-md > :last-child { margin-bottom: 0; }
246
+ .usketch-md h1, .usketch-md h2, .usketch-md h3 { margin: 0.4em 0 0.3em; line-height: 1.25; font-weight: 700; }
247
+ .usketch-md h1 { font-size: 1.6em; } .usketch-md h2 { font-size: 1.35em; } .usketch-md h3 { font-size: 1.15em; }
248
+ .usketch-md p { margin: 0.4em 0; }
249
+ .usketch-md ul, .usketch-md ol { margin: 0.3em 0; padding-left: 1.4em; }
250
+ .usketch-md li { margin: 0.1em 0; }
251
+ .usketch-md a { color: #2563eb; text-decoration: underline; }
252
+ .usketch-md blockquote { margin: 0.4em 0; padding: 0 0.8em; border-left: 3px solid currentColor; opacity: 0.75; }
253
+ .usketch-md table { border-collapse: collapse; margin: 0.4em 0; font-size: 0.95em; }
254
+ .usketch-md th, .usketch-md td { border: 1px solid rgba(128,128,128,0.4); padding: 3px 8px; }
255
+ .usketch-md th { background: rgba(128,128,128,0.15); font-weight: 600; }
256
+ .usketch-md code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.9em; background: rgba(128,128,128,0.15); padding: 1px 4px; border-radius: 3px; }
257
+ .usketch-md pre { margin: 0.4em 0; padding: 8px 10px; border-radius: 6px; overflow-x: auto; background: #f6f8fa; }
258
+ .usketch-md pre code { background: none; padding: 0; }
259
+ .usketch-md input[type="checkbox"] { margin-right: 6px; }
260
+ .usketch-md-empty { opacity: 0.5; font-style: italic; }
261
+ .usketch-md-mermaid { display: flex; justify-content: center; margin: 0.4em 0; }
262
+ .usketch-md-mermaid svg { max-width: 100%; height: auto; }
263
+ .usketch-md-mermaid-error { color: #dc2626; font-size: 0.85em; white-space: pre-wrap; }
264
+ /* highlight.js (github light) */
265
+ .usketch-md .hljs { color: #24292e; }
266
+ .usketch-md .hljs-comment, .usketch-md .hljs-quote { color: #6a737d; }
267
+ .usketch-md .hljs-keyword, .usketch-md .hljs-selector-tag, .usketch-md .hljs-literal, .usketch-md .hljs-type { color: #d73a49; }
268
+ .usketch-md .hljs-string, .usketch-md .hljs-attr, .usketch-md .hljs-regexp, .usketch-md .hljs-addition { color: #032f62; }
269
+ .usketch-md .hljs-number, .usketch-md .hljs-built_in, .usketch-md .hljs-symbol, .usketch-md .hljs-title { color: #005cc5; }
270
+ .usketch-md .hljs-name, .usketch-md .hljs-section, .usketch-md .hljs-attribute { color: #22863a; }
271
+ .usketch-md .hljs-variable, .usketch-md .hljs-template-variable, .usketch-md .hljs-deletion { color: #b31d28; }
272
+ :root[data-theme="dark"] .usketch-md pre { background: #161b22; }
273
+ :root[data-theme="dark"] .usketch-md .hljs { color: #c9d1d9; }
274
+ :root[data-theme="dark"] .usketch-md .hljs-comment, :root[data-theme="dark"] .usketch-md .hljs-quote { color: #8b949e; }
275
+ :root[data-theme="dark"] .usketch-md .hljs-keyword, :root[data-theme="dark"] .usketch-md .hljs-literal, :root[data-theme="dark"] .usketch-md .hljs-type { color: #ff7b72; }
276
+ :root[data-theme="dark"] .usketch-md .hljs-string, :root[data-theme="dark"] .usketch-md .hljs-attr { color: #a5d6ff; }
277
+ :root[data-theme="dark"] .usketch-md .hljs-number, :root[data-theme="dark"] .usketch-md .hljs-built_in, :root[data-theme="dark"] .usketch-md .hljs-title { color: #79c0ff; }
278
+ :root[data-theme="dark"] .usketch-md .hljs-name, :root[data-theme="dark"] .usketch-md .hljs-section { color: #7ee787; }
279
+ `;
280
+ //# sourceMappingURL=render.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.js","sourceRoot":"","sources":["../src/render.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export declare const markdownSelection: {
2
+ /** Replace the selected-id set and notify subscribers (no-op if unchanged). */
3
+ set(ids: ReadonlySet<string>): void;
4
+ has(id: string): boolean;
5
+ subscribe(listener: () => void): () => void;
6
+ };
7
+ //# sourceMappingURL=selection-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selection-store.d.ts","sourceRoot":"","sources":["../src/selection-store.ts"],"names":[],"mappings":"AAYA,eAAO,MAAM,iBAAiB;IAC7B,+EAA+E;IAC/E,GAAG,MAAM,WAAW,CAAC,MAAM,CAAC,GAAG,IAAI;IAKnC,GAAG,KAAK,MAAM,GAAG,OAAO;IAGxB,SAAS,WAAW,MAAM,IAAI,GAAG,MAAM,IAAI;CAI3C,CAAC"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Tiny observable of "which markdown shapes are currently selected", shared
3
+ * between the plugin (writer, from `store.subscribe`) and the view renderer
4
+ * (reader, via `useSyncExternalStore`).
5
+ *
6
+ * The view uses this to make rendered content interactive (links / checkboxes)
7
+ * only while the shape is selected — unselected shapes stay `pointerEvents:none`
8
+ * so a click selects/moves the shape on the canvas.
9
+ */
10
+ let selectedIds = new Set();
11
+ const listeners = new Set();
12
+ export const markdownSelection = {
13
+ /** Replace the selected-id set and notify subscribers (no-op if unchanged). */
14
+ set(ids) {
15
+ if (sameSet(ids, selectedIds))
16
+ return;
17
+ selectedIds = new Set(ids);
18
+ for (const l of listeners)
19
+ l();
20
+ },
21
+ has(id) {
22
+ return selectedIds.has(id);
23
+ },
24
+ subscribe(listener) {
25
+ listeners.add(listener);
26
+ return () => listeners.delete(listener);
27
+ },
28
+ };
29
+ function sameSet(a, b) {
30
+ if (a.size !== b.size)
31
+ return false;
32
+ for (const v of a)
33
+ if (!b.has(v))
34
+ return false;
35
+ return true;
36
+ }
37
+ //# sourceMappingURL=selection-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selection-store.js","sourceRoot":"","sources":["../src/selection-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,IAAI,WAAW,GAAwB,IAAI,GAAG,EAAE,CAAC;AACjD,MAAM,SAAS,GAAG,IAAI,GAAG,EAAc,CAAC;AAExC,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAChC,+EAA+E;IAC/E,GAAG,CAAC,GAAwB;QAC3B,IAAI,OAAO,CAAC,GAAG,EAAE,WAAW,CAAC;YAAE,OAAO;QACtC,WAAW,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;QAC3B,KAAK,MAAM,CAAC,IAAI,SAAS;YAAE,CAAC,EAAE,CAAC;IAChC,CAAC;IACD,GAAG,CAAC,EAAU;QACb,OAAO,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC5B,CAAC;IACD,SAAS,CAAC,QAAoB;QAC7B,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACxB,OAAO,GAAG,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACzC,CAAC;CACD,CAAC;AAEF,SAAS,OAAO,CAAC,CAAsB,EAAE,CAAsB;IAC9D,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI;QAAE,OAAO,KAAK,CAAC;IACpC,KAAK,MAAM,CAAC,IAAI,CAAC;QAAE,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAAE,OAAO,KAAK,CAAC;IAC/C,OAAO,IAAI,CAAC;AACb,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Pure helpers to detect tabular clipboard content (HTML `<table>` from
3
+ * Excel/Google Sheets/web, or delimited TSV/CSV text) and turn it into a GFM
4
+ * markdown table string. Used by the table external-content handler so a paste
5
+ * of a spreadsheet selection becomes a rendered markdown table shape.
6
+ */
7
+ /** Cheap check for `match`: does the HTML payload contain a table element? */
8
+ export declare function htmlHasTable(html: string | null | undefined): boolean;
9
+ /**
10
+ * Parse an HTML `<table>` (e.g. Excel / Google Sheets rich clipboard) into a
11
+ * grid of cell strings. Browser-only (uses DOMParser); returns null otherwise.
12
+ */
13
+ export declare function parseHtmlTable(html: string | null | undefined): string[][] | null;
14
+ /**
15
+ * Parse delimited plain text (TSV preferred, else CSV) into a grid. Conservative
16
+ * to avoid turning prose into a table: requires ≥2 non-empty lines, ≥2 columns,
17
+ * the delimiter present on *every* line, and a consistent column count.
18
+ * (No CSV quote handling — a pragmatic v1 for spreadsheet copies.)
19
+ */
20
+ export declare function parseDelimited(text: string | null | undefined): string[][] | null;
21
+ /** Render a grid as a GFM table. First row is the header. */
22
+ export declare function toMarkdownTable(rows: string[][]): string;
23
+ //# sourceMappingURL=table-paste.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table-paste.d.ts","sourceRoot":"","sources":["../src/table-paste.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,8EAA8E;AAC9E,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAErE;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,EAAE,EAAE,GAAG,IAAI,CAajF;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,EAAE,EAAE,GAAG,IAAI,CAmBjF;AAED,6DAA6D;AAC7D,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,MAAM,CASxD"}