@damiro/stylo 0.13.6 → 0.15.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.
- package/dist/{InPlaceView-BccqyOao.js → InPlaceView-BLlGJ9mh.js} +3 -2
- package/dist/{InPlaceView-BccqyOao.js.map → InPlaceView-BLlGJ9mh.js.map} +1 -1
- package/dist/Preview-DKOoZ-vr.js +295 -0
- package/dist/Preview-DKOoZ-vr.js.map +1 -0
- package/dist/SplitView.d.ts +4 -2
- package/dist/SplitView.d.ts.map +1 -1
- package/dist/Stylo.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/inplace/theme-table-gizmos.d.ts +1 -0
- package/dist/inplace/theme-table-gizmos.d.ts.map +1 -1
- package/dist/{markdown-BYXs9Tj8.js → markdown-DcS6jMel.js} +484 -469
- package/dist/markdown-DcS6jMel.js.map +1 -0
- package/dist/render/Preview.d.ts +20 -2
- package/dist/render/Preview.d.ts.map +1 -1
- package/dist/render/taskCheckbox.d.ts +13 -0
- package/dist/render/taskCheckbox.d.ts.map +1 -0
- package/dist/stylo.js +63 -57
- package/dist/stylo.js.map +1 -1
- package/dist/types.d.ts +36 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -1
- package/dist/Preview-ClaSJYJW.js +0 -238
- package/dist/Preview-ClaSJYJW.js.map +0 -1
- package/dist/markdown-BYXs9Tj8.js.map +0 -1
package/dist/render/Preview.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { CodeLanguages, EmbedSource, FrontmatterDisplay, ResolveErrorInfo } from "../types";
|
|
1
|
+
import type { CodeLanguages, EmbedSource, FrontmatterDisplay, ResolveErrorInfo, TaskToggleInfo } from "../types";
|
|
2
2
|
export interface PreviewProps {
|
|
3
3
|
value: string;
|
|
4
4
|
onWikiLinkClick?: (target: string) => void;
|
|
@@ -15,7 +15,25 @@ export interface PreviewProps {
|
|
|
15
15
|
* un-highlighted text — today's behaviour.
|
|
16
16
|
*/
|
|
17
17
|
codeLanguages?: CodeLanguages;
|
|
18
|
+
/**
|
|
19
|
+
* Turn a single line ending into a real line break (`<br>`) instead of
|
|
20
|
+
* CommonMark's default — a blank line required to start a new paragraph,
|
|
21
|
+
* otherwise consecutive lines join into one run. Obsidian's Live Preview
|
|
22
|
+
* reads this way. Off by default: every existing `preview` render keeps
|
|
23
|
+
* today's paragraph-joining behaviour unless a host opts in. Has no effect
|
|
24
|
+
* on `in-place` / `source` — CodeMirror already decorates each source line
|
|
25
|
+
* independently there.
|
|
26
|
+
*/
|
|
27
|
+
softBreaks?: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Makes task-list checkboxes clickable instead of `disabled`. Fired with
|
|
30
|
+
* raw `value` offsets bracketing the clicked marker and its new state; the
|
|
31
|
+
* host owns splicing `value` and calling its own `onChange`. Off by
|
|
32
|
+
* default — every checkbox stays `disabled`, today's behaviour, until a
|
|
33
|
+
* host opts in.
|
|
34
|
+
*/
|
|
35
|
+
onTaskToggle?: (info: TaskToggleInfo) => void;
|
|
18
36
|
}
|
|
19
37
|
/** Rendered Markdown + KaTeX view. A pure function of the string. */
|
|
20
|
-
export declare function Preview({ value, onWikiLinkClick, embedSource, onResolveError, frontmatter, codeLanguages, }: PreviewProps): import("react").JSX.Element;
|
|
38
|
+
export declare function Preview({ value, onWikiLinkClick, embedSource, onResolveError, frontmatter, codeLanguages, softBreaks, onTaskToggle, }: PreviewProps): import("react").JSX.Element;
|
|
21
39
|
//# sourceMappingURL=Preview.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Preview.d.ts","sourceRoot":"","sources":["../../src/render/Preview.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Preview.d.ts","sourceRoot":"","sources":["../../src/render/Preview.tsx"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EACV,aAAa,EACb,WAAW,EACX,kBAAkB,EAClB,gBAAgB,EAChB,cAAc,EACf,MAAM,UAAU,CAAA;AAoEjB,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAA;IACb,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;IAC1C,mEAAmE;IACnE,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,+EAA+E;IAC/E,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,gBAAgB,KAAK,IAAI,CAAA;IACjE,2FAA2F;IAC3F,WAAW,CAAC,EAAE,kBAAkB,CAAA;IAChC;;;;;OAKG;IACH,aAAa,CAAC,EAAE,aAAa,CAAA;IAC7B;;;;;;;;OAQG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,cAAc,KAAK,IAAI,CAAA;CAC9C;AAED,qEAAqE;AACrE,wBAAgB,OAAO,CAAC,EACtB,KAAK,EACL,eAAe,EACf,WAAW,EACX,cAAc,EACd,WAAsB,EACtB,aAAa,EACb,UAAU,EACV,YAAY,GACb,EAAE,YAAY,+BAqHd"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Locates the exact `[ ]` / `[x]` substring of a task-list item within
|
|
3
|
+
* `value`, given the raw offset where the item itself starts (a GFM
|
|
4
|
+
* `listItem`'s `position.start.offset`, as parsed by `remark-gfm`).
|
|
5
|
+
* Returns `null` if the prefix doesn't match a checkbox — it always should
|
|
6
|
+
* for a node `remark-gfm` marked `checked`, but a raw markdown edit racing
|
|
7
|
+
* the render is not impossible.
|
|
8
|
+
*/
|
|
9
|
+
export declare function findCheckboxOffsets(value: string, itemStart: number): {
|
|
10
|
+
start: number;
|
|
11
|
+
end: number;
|
|
12
|
+
} | null;
|
|
13
|
+
//# sourceMappingURL=taskCheckbox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"taskCheckbox.d.ts","sourceRoot":"","sources":["../../src/render/taskCheckbox.ts"],"names":[],"mappings":"AASA;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,GAChB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAMvC"}
|
package/dist/stylo.js
CHANGED
|
@@ -35,25 +35,25 @@ function C({ value: e, onChange: r, readOnly: a, placeholder: o, codeLanguages:
|
|
|
35
35
|
}
|
|
36
36
|
//#endregion
|
|
37
37
|
//#region src/inplace/lazyInPlace.ts
|
|
38
|
-
var w = l(async () => ({ default: (await import("./InPlaceView-
|
|
38
|
+
var w = l(async () => ({ default: (await import("./InPlaceView-BLlGJ9mh.js")).InPlaceView })), T = l(async () => ({ default: (await import("./Preview-DKOoZ-vr.js")).Preview }));
|
|
39
39
|
//#endregion
|
|
40
40
|
//#region src/SplitView.tsx
|
|
41
|
-
function E({ value: e, onChange: n, onWikiLinkClick: r, readOnly: i, placeholder: a, codeLanguages: o, wikiLinkSource: c, tagSource: l, embedSource: d, onResolveError: f, frontmatter: h,
|
|
42
|
-
let [
|
|
41
|
+
function E({ value: e, onChange: n, onWikiLinkClick: r, readOnly: i, placeholder: a, codeLanguages: o, wikiLinkSource: c, tagSource: l, embedSource: d, onResolveError: f, frontmatter: h, softBreaks: g, onTaskToggle: _, onSave: v, onViewChange: x, canvasHeader: S }) {
|
|
42
|
+
let [w, E] = m(null), D = p(null), O = p(!1);
|
|
43
43
|
return u(() => {
|
|
44
|
-
let e =
|
|
44
|
+
let e = w?.scrollDOM, t = D.current;
|
|
45
45
|
if (!e || !t) return;
|
|
46
46
|
let n = (e, t) => {
|
|
47
|
-
if (
|
|
47
|
+
if (O.current) return;
|
|
48
48
|
let n = e.scrollHeight - e.clientHeight;
|
|
49
|
-
n <= 0 || (
|
|
50
|
-
|
|
49
|
+
n <= 0 || (O.current = !0, t.scrollTop = e.scrollTop / n * (t.scrollHeight - t.clientHeight), requestAnimationFrame(() => {
|
|
50
|
+
O.current = !1;
|
|
51
51
|
}));
|
|
52
52
|
}, r = () => n(e, t), i = () => n(t, e);
|
|
53
53
|
return e.addEventListener("scroll", r, { passive: !0 }), t.addEventListener("scroll", i, { passive: !0 }), () => {
|
|
54
54
|
e.removeEventListener("scroll", r), t.removeEventListener("scroll", i);
|
|
55
55
|
};
|
|
56
|
-
}, [
|
|
56
|
+
}, [w]), /* @__PURE__ */ b("div", {
|
|
57
57
|
className: t.split,
|
|
58
58
|
children: [/* @__PURE__ */ y("div", {
|
|
59
59
|
className: t.splitPane,
|
|
@@ -66,15 +66,15 @@ function E({ value: e, onChange: n, onWikiLinkClick: r, readOnly: i, placeholder
|
|
|
66
66
|
wikiLinkSource: c,
|
|
67
67
|
tagSource: l,
|
|
68
68
|
onResolveError: f,
|
|
69
|
-
onSave:
|
|
69
|
+
onSave: v,
|
|
70
70
|
onViewChange: (e) => {
|
|
71
|
-
|
|
71
|
+
E(e), x?.(e);
|
|
72
72
|
},
|
|
73
|
-
canvasHeader:
|
|
73
|
+
canvasHeader: S
|
|
74
74
|
})
|
|
75
75
|
}), /* @__PURE__ */ y("div", {
|
|
76
76
|
className: t.splitPane,
|
|
77
|
-
ref:
|
|
77
|
+
ref: D,
|
|
78
78
|
children: /* @__PURE__ */ y(s, {
|
|
79
79
|
fallback: /* @__PURE__ */ y("div", {
|
|
80
80
|
className: t.preview,
|
|
@@ -86,7 +86,9 @@ function E({ value: e, onChange: n, onWikiLinkClick: r, readOnly: i, placeholder
|
|
|
86
86
|
embedSource: d,
|
|
87
87
|
onResolveError: f,
|
|
88
88
|
frontmatter: h,
|
|
89
|
-
codeLanguages: o
|
|
89
|
+
codeLanguages: o,
|
|
90
|
+
softBreaks: g,
|
|
91
|
+
onTaskToggle: _
|
|
90
92
|
})
|
|
91
93
|
})
|
|
92
94
|
})]
|
|
@@ -220,59 +222,59 @@ function j({ view: e, items: n, icons: r, disabled: i, sticky: a, stickyVisibili
|
|
|
220
222
|
}
|
|
221
223
|
//#endregion
|
|
222
224
|
//#region src/Stylo.tsx
|
|
223
|
-
var M = c(function({ value: n, onChange: r, mode: i = "in-place", onSave: o, onFrontmatter: c, onWikiLinkClick: l, onLinkClick: f, readOnly: h, placeholder: _, className: v, inPlace: x, codeLanguages: S, wikiLinkSource: D, tagSource: O, embedSource: k, onResolveError: A, toolbar: M, icons: N, frontmatter: P,
|
|
224
|
-
let
|
|
225
|
-
|
|
226
|
-
let
|
|
227
|
-
|
|
228
|
-
let
|
|
229
|
-
|
|
230
|
-
}).current,
|
|
225
|
+
var M = c(function({ value: n, onChange: r, mode: i = "in-place", onSave: o, onFrontmatter: c, onWikiLinkClick: l, onLinkClick: f, readOnly: h, placeholder: _, className: v, inPlace: x, codeLanguages: S, wikiLinkSource: D, tagSource: O, embedSource: k, onResolveError: A, toolbar: M, icons: N, frontmatter: P, softBreaks: F, onTaskToggle: I, canvasHeader: L }, R) {
|
|
226
|
+
let z = i === "preview" || i === "split" || i === "in-place" ? i : "source", [B, V] = m(null), H = z === "preview" ? null : a(M), U = M && typeof M == "object" ? M.render : void 0, W = M && typeof M == "object" ? M.sticky : void 0, G = W === "top" ? "top" : W ? "bottom" : !1, K = M && typeof M == "object" ? M.stickyVisibility : void 0, q = p(c);
|
|
227
|
+
q.current = c;
|
|
228
|
+
let J = p(A);
|
|
229
|
+
J.current = A;
|
|
230
|
+
let Y = p((e, t) => {
|
|
231
|
+
J.current?.(e, t);
|
|
232
|
+
}).current, X = p(void 0);
|
|
231
233
|
u(() => {
|
|
232
234
|
let t = e(n)?.frontmatter ?? null;
|
|
233
|
-
t !==
|
|
234
|
-
}, [n]), d(
|
|
235
|
-
focus: () =>
|
|
236
|
-
getView: () =>
|
|
235
|
+
t !== X.current && (X.current = t, q.current?.(t));
|
|
236
|
+
}, [n]), d(R, () => ({
|
|
237
|
+
focus: () => B?.focus(),
|
|
238
|
+
getView: () => B,
|
|
237
239
|
insertAtCursor: (e) => {
|
|
238
|
-
|
|
240
|
+
B && (B.dispatch(B.state.replaceSelection(e)), B.focus());
|
|
239
241
|
},
|
|
240
242
|
scrollToHeading: (e) => {
|
|
241
|
-
if (!
|
|
242
|
-
let t = e.trim().toLowerCase(), { doc: n } =
|
|
243
|
+
if (!B) return !1;
|
|
244
|
+
let t = e.trim().toLowerCase(), { doc: n } = B.state;
|
|
243
245
|
for (let e = 1; e <= n.lines; e++) {
|
|
244
246
|
let r = n.line(e), i = /^ {0,3}#{1,6}[ \t]+(.*?)(?:[ \t]+#+)?[ \t]*$/.exec(r.text);
|
|
245
|
-
if (!(!i || i[1] === void 0) && i[1].trim().toLowerCase() === t) return
|
|
247
|
+
if (!(!i || i[1] === void 0) && i[1].trim().toLowerCase() === t) return B.dispatch({
|
|
246
248
|
selection: { anchor: r.from },
|
|
247
249
|
effects: g.scrollIntoView(r.from, { y: "start" })
|
|
248
|
-
}),
|
|
250
|
+
}), B.focus(), !0;
|
|
249
251
|
}
|
|
250
252
|
return !1;
|
|
251
253
|
}
|
|
252
|
-
}), [
|
|
253
|
-
let
|
|
254
|
+
}), [B]);
|
|
255
|
+
let Z = [
|
|
254
256
|
t.root,
|
|
255
|
-
|
|
256
|
-
|
|
257
|
+
G === "bottom" && t.stickyToolbarRootBottom,
|
|
258
|
+
G === "top" && t.stickyToolbarRootTop,
|
|
257
259
|
"stylo",
|
|
258
260
|
v
|
|
259
261
|
].filter(Boolean).join(" ");
|
|
260
262
|
return /* @__PURE__ */ b("div", {
|
|
261
|
-
className:
|
|
262
|
-
"data-stylo-mode":
|
|
263
|
+
className: Z,
|
|
264
|
+
"data-stylo-mode": z,
|
|
263
265
|
children: [
|
|
264
|
-
|
|
266
|
+
H && (() => {
|
|
265
267
|
let e = /* @__PURE__ */ y(j, {
|
|
266
|
-
view:
|
|
267
|
-
items:
|
|
268
|
+
view: B,
|
|
269
|
+
items: H,
|
|
268
270
|
icons: N,
|
|
269
271
|
disabled: h,
|
|
270
|
-
sticky:
|
|
271
|
-
stickyVisibility:
|
|
272
|
+
sticky: G,
|
|
273
|
+
stickyVisibility: K
|
|
272
274
|
});
|
|
273
|
-
return
|
|
275
|
+
return U ? U(e, { view: B }) : e;
|
|
274
276
|
})(),
|
|
275
|
-
|
|
277
|
+
z === "source" && /* @__PURE__ */ y(C, {
|
|
276
278
|
value: n,
|
|
277
279
|
onChange: r,
|
|
278
280
|
readOnly: h,
|
|
@@ -280,12 +282,12 @@ var M = c(function({ value: n, onChange: r, mode: i = "in-place", onSave: o, onF
|
|
|
280
282
|
codeLanguages: S,
|
|
281
283
|
wikiLinkSource: D,
|
|
282
284
|
tagSource: O,
|
|
283
|
-
onResolveError:
|
|
285
|
+
onResolveError: Y,
|
|
284
286
|
onSave: o,
|
|
285
|
-
onViewChange:
|
|
286
|
-
canvasHeader:
|
|
287
|
+
onViewChange: V,
|
|
288
|
+
canvasHeader: L
|
|
287
289
|
}),
|
|
288
|
-
|
|
290
|
+
z === "preview" && /* @__PURE__ */ y(s, {
|
|
289
291
|
fallback: /* @__PURE__ */ y("div", {
|
|
290
292
|
className: t.preview,
|
|
291
293
|
"aria-busy": "true"
|
|
@@ -294,12 +296,14 @@ var M = c(function({ value: n, onChange: r, mode: i = "in-place", onSave: o, onF
|
|
|
294
296
|
value: n,
|
|
295
297
|
onWikiLinkClick: l,
|
|
296
298
|
embedSource: k,
|
|
297
|
-
onResolveError:
|
|
299
|
+
onResolveError: Y,
|
|
298
300
|
frontmatter: P,
|
|
299
|
-
codeLanguages: S
|
|
301
|
+
codeLanguages: S,
|
|
302
|
+
softBreaks: F,
|
|
303
|
+
onTaskToggle: I
|
|
300
304
|
})
|
|
301
305
|
}),
|
|
302
|
-
|
|
306
|
+
z === "split" && /* @__PURE__ */ y(E, {
|
|
303
307
|
value: n,
|
|
304
308
|
onChange: r,
|
|
305
309
|
onWikiLinkClick: l,
|
|
@@ -309,13 +313,15 @@ var M = c(function({ value: n, onChange: r, mode: i = "in-place", onSave: o, onF
|
|
|
309
313
|
wikiLinkSource: D,
|
|
310
314
|
tagSource: O,
|
|
311
315
|
embedSource: k,
|
|
312
|
-
onResolveError:
|
|
316
|
+
onResolveError: Y,
|
|
313
317
|
frontmatter: P,
|
|
318
|
+
softBreaks: F,
|
|
319
|
+
onTaskToggle: I,
|
|
314
320
|
onSave: o,
|
|
315
|
-
onViewChange:
|
|
316
|
-
canvasHeader:
|
|
321
|
+
onViewChange: V,
|
|
322
|
+
canvasHeader: L
|
|
317
323
|
}),
|
|
318
|
-
|
|
324
|
+
z === "in-place" && /* @__PURE__ */ y(s, {
|
|
319
325
|
fallback: /* @__PURE__ */ y("div", {
|
|
320
326
|
className: t.inplace,
|
|
321
327
|
"aria-busy": "true"
|
|
@@ -332,10 +338,10 @@ var M = c(function({ value: n, onChange: r, mode: i = "in-place", onSave: o, onF
|
|
|
332
338
|
wikiLinkSource: D,
|
|
333
339
|
tagSource: O,
|
|
334
340
|
embedSource: k,
|
|
335
|
-
onResolveError:
|
|
341
|
+
onResolveError: Y,
|
|
336
342
|
onSave: o,
|
|
337
|
-
onViewChange:
|
|
338
|
-
canvasHeader:
|
|
343
|
+
onViewChange: V,
|
|
344
|
+
canvasHeader: L
|
|
339
345
|
})
|
|
340
346
|
})
|
|
341
347
|
]
|
package/dist/stylo.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stylo.js","names":[],"sources":["../src/editor/SourceView.tsx","../src/inplace/lazyInPlace.ts","../src/render/lazyPreview.ts","../src/SplitView.tsx","../src/toolbar/floating-watchdog.ts","../src/toolbar/keyboard-inset.ts","../src/toolbar/Toolbar.tsx","../src/Stylo.tsx"],"sourcesContent":["import { useRef, useState, useSyncExternalStore } from \"react\"\nimport type { ReactNode } from \"react\"\nimport { createPortal } from \"react-dom\"\nimport { showPanel } from \"@codemirror/view\"\nimport type { EditorView } from \"@codemirror/view\"\nimport styles from \"../styles/stylo.module.css\"\nimport type { CodeLanguages, ResolveErrorInfo, TagSource, WikiLinkSource } from \"../types\"\nimport { CanvasHeaderHost } from \"./canvas-header-panel\"\nimport { useCodeMirror } from \"./useCodeMirror\"\n\nconst noopSubscribe = () => () => {}\nconst noopSnapshot = () => null\n\nexport interface SourceViewProps {\n value: string\n onChange: (next: string) => void\n readOnly?: boolean\n placeholder?: string\n /** Fenced-code grammars, forwarded to the Markdown language. Read once. */\n codeLanguages?: CodeLanguages\n /** `[[wikilink]]` autocomplete source. Read once. */\n wikiLinkSource?: WikiLinkSource\n /** `#tag` autocomplete source. Read once. */\n tagSource?: TagSource\n /** Notified when `wikiLinkSource` or `tagSource` rejects. */\n onResolveError?: (error: unknown, info: ResolveErrorInfo) => void\n /** Called with the doc string on `Mod-s`. */\n onSave?: (value: string) => void\n /** Called with the `EditorView` once created, and with `null` on teardown. */\n onViewChange?: (view: EditorView | null) => void\n /** Host content docked after the search panel, before the document. Read once. */\n canvasHeader?: (ctx: { view: EditorView | null }) => ReactNode\n}\n\n/** Raw CodeMirror 6 Markdown surface bound to the canonical string. */\nexport function SourceView({\n value,\n onChange,\n readOnly,\n placeholder,\n codeLanguages,\n wikiLinkSource,\n tagSource,\n onResolveError,\n onSave,\n onViewChange,\n canvasHeader,\n}: SourceViewProps) {\n const [editorView, setEditorView] = useState<EditorView | null>(null)\n const onViewChangeRef = useRef(onViewChange)\n onViewChangeRef.current = onViewChange\n const handleViewChange = useRef((view: EditorView | null) => {\n setEditorView(view)\n onViewChangeRef.current?.(view)\n }).current\n\n // `canvasHeader` itself is read through a ref (a changed render prop needs\n // no editor rebuild); whether it was passed at all is read once, at mount,\n // to decide whether the panel extension exists at all.\n const canvasHeaderRef = useRef(canvasHeader)\n canvasHeaderRef.current = canvasHeader\n const [headerHost] = useState(() => (canvasHeader ? new CanvasHeaderHost() : null))\n const headerDom = useSyncExternalStore(\n headerHost?.subscribe ?? noopSubscribe,\n headerHost?.getSnapshot ?? noopSnapshot,\n )\n const [extensions] = useState(() => (headerHost ? [showPanel.of(headerHost.panel)] : []))\n\n const ref = useCodeMirror({\n value,\n onChange,\n readOnly,\n placeholder,\n codeLanguages,\n wikiLinkSource,\n tagSource,\n onResolveError,\n onSave,\n onViewChange: handleViewChange,\n extensions,\n })\n return (\n <div className={styles.source} ref={ref}>\n {headerDom &&\n canvasHeaderRef.current &&\n createPortal(canvasHeaderRef.current({ view: editorView }), headerDom)}\n </div>\n )\n}\n","import { lazy } from \"react\"\n\n/**\n * The in-place canvas carries the decoration plugin (and, in later increments,\n * its KaTeX widgets). It loads only when `mode` resolves to `in-place`, so\n * `source` consumers never fetch it.\n */\nexport const LazyInPlaceView = lazy(async () => ({\n default: (await import(\"./InPlaceView\")).InPlaceView,\n}))\n","import { lazy } from \"react\"\n\n/**\n * Preview pulls in react-markdown + remark/rehype + KaTeX. It is loaded only\n * when a rendered mode (`preview`, `split`) is actually used, so `mode=\"source\"`\n * consumers never pay for it. Both callers share this one wrapper, so the render\n * pipeline stays a single lazy chunk.\n */\nexport const LazyPreview = lazy(async () => ({\n default: (await import(\"./Preview\")).Preview,\n}))\n","import { Suspense, useEffect, useRef, useState } from \"react\"\nimport type { ReactNode } from \"react\"\nimport type { EditorView } from \"@codemirror/view\"\nimport { SourceView } from \"./editor/SourceView\"\nimport { LazyPreview } from \"./render/lazyPreview\"\nimport styles from \"./styles/stylo.module.css\"\nimport type {\n CodeLanguages,\n EmbedSource,\n FrontmatterDisplay,\n ResolveErrorInfo,\n TagSource,\n WikiLinkSource,\n} from \"./types\"\n\nexport interface SplitViewProps {\n value: string\n onChange: (next: string) => void\n onWikiLinkClick?: (target: string) => void\n readOnly?: boolean\n placeholder?: string\n codeLanguages?: CodeLanguages\n wikiLinkSource?: WikiLinkSource\n tagSource?: TagSource\n embedSource?: EmbedSource\n onResolveError?: (error: unknown, info: ResolveErrorInfo) => void\n frontmatter?: FrontmatterDisplay\n /** Called with the doc string on `Mod-s`. */\n onSave?: (value: string) => void\n /** Forwarded the source pane's `EditorView` for the shared toolbar. */\n onViewChange?: (view: EditorView | null) => void\n /** Host content docked in the source pane, after its search panel. Read once. */\n canvasHeader?: (ctx: { view: EditorView | null }) => ReactNode\n}\n\n/**\n * Source and preview side by side. Both panes are a pure function of the same\n * string; the only link between them is a proportional scroll sync. Expects the\n * Stylo root to have a bounded height — otherwise both panes grow and the page\n * scrolls instead.\n */\nexport function SplitView({\n value,\n onChange,\n onWikiLinkClick,\n readOnly,\n placeholder,\n codeLanguages,\n wikiLinkSource,\n tagSource,\n embedSource,\n onResolveError,\n frontmatter,\n onSave,\n onViewChange,\n canvasHeader,\n}: SplitViewProps) {\n const [view, setView] = useState<EditorView | null>(null)\n const previewPane = useRef<HTMLDivElement | null>(null)\n const syncing = useRef(false)\n\n const handleView = (next: EditorView | null) => {\n setView(next)\n onViewChange?.(next)\n }\n\n useEffect(() => {\n const source = view?.scrollDOM\n const preview = previewPane.current\n if (!source || !preview) return\n\n const sync = (from: HTMLElement, to: HTMLElement) => {\n if (syncing.current) return\n const range = from.scrollHeight - from.clientHeight\n if (range <= 0) return\n syncing.current = true\n to.scrollTop = (from.scrollTop / range) * (to.scrollHeight - to.clientHeight)\n requestAnimationFrame(() => {\n syncing.current = false\n })\n }\n\n const fromSource = () => sync(source, preview)\n const fromPreview = () => sync(preview, source)\n source.addEventListener(\"scroll\", fromSource, { passive: true })\n preview.addEventListener(\"scroll\", fromPreview, { passive: true })\n return () => {\n source.removeEventListener(\"scroll\", fromSource)\n preview.removeEventListener(\"scroll\", fromPreview)\n }\n }, [view])\n\n return (\n <div className={styles.split}>\n <div className={styles.splitPane}>\n <SourceView\n value={value}\n onChange={onChange}\n readOnly={readOnly}\n placeholder={placeholder}\n codeLanguages={codeLanguages}\n wikiLinkSource={wikiLinkSource}\n tagSource={tagSource}\n onResolveError={onResolveError}\n onSave={onSave}\n onViewChange={handleView}\n canvasHeader={canvasHeader}\n />\n </div>\n <div className={styles.splitPane} ref={previewPane}>\n <Suspense fallback={<div className={styles.preview} aria-busy=\"true\" />}>\n <LazyPreview\n value={value}\n onWikiLinkClick={onWikiLinkClick}\n embedSource={embedSource}\n onResolveError={onResolveError}\n frontmatter={frontmatter}\n codeLanguages={codeLanguages}\n />\n </Suspense>\n </div>\n </div>\n )\n}\n","import { useEffect, type RefObject } from \"react\"\n\n/**\n * Continuously re-asserts a `transform` on a `position: fixed` element,\n * alternating an imperceptible sub-pixel jitter every animation frame,\n * instead of trusting the browser to keep it correctly composited on its\n * own. Several rounds of on-device testing found iOS Safari losing track of\n * this exact kind of element — across its own address-bar animation, and in\n * at least one report tied to the keyboard opening — in ways a one-time\n * static fix (a plain `translateZ(0)`) did not reliably prevent. A value\n * that never changes gives the browser nothing to recompute; alternating it\n * every frame forces a fresh compositor pass regardless of what triggered\n * the drift, so it can't stay wrong for more than one frame (~16ms).\n *\n * Writes to the DOM directly rather than through React state, so this never\n * causes a re-render — the transform is the only thing touched.\n */\nexport function useFloatingWatchdog(ref: RefObject<HTMLElement | null>, enabled: boolean): void {\n useEffect(() => {\n if (!enabled) return\n let raf = 0\n let jitter = false\n const tick = () => {\n const el = ref.current\n if (el) {\n jitter = !jitter\n el.style.transform = jitter ? \"translate3d(0, 0.01px, 0)\" : \"translate3d(0, 0, 0)\"\n }\n raf = requestAnimationFrame(tick)\n }\n raf = requestAnimationFrame(tick)\n return () => cancelAnimationFrame(raf)\n }, [ref, enabled])\n}\n","import { useEffect, useState } from \"react\"\n\n/**\n * How far the on-screen keyboard eats into the window, tracked through the\n * `visualViewport` API. 0 when `enabled` is false or the browser has no\n * `visualViewport` (older Safari, SSR, most desktop browsers). A mobile\n * keyboard shrinks the *visual* viewport, not the layout viewport a plain\n * `position: fixed` bottom offset is computed against — this is what lets the\n * sticky toolbar ride up above the keyboard instead of hiding behind it.\n */\nexport function useKeyboardInset(enabled: boolean): number {\n const [inset, setInset] = useState(0)\n\n useEffect(() => {\n const vv = typeof window === \"undefined\" ? null : window.visualViewport\n if (!enabled || !vv) {\n setInset(0)\n return\n }\n const update = () => setInset(Math.max(0, window.innerHeight - vv.height - vv.offsetTop))\n update()\n vv.addEventListener(\"resize\", update)\n vv.addEventListener(\"scroll\", update)\n return () => {\n vv.removeEventListener(\"resize\", update)\n vv.removeEventListener(\"scroll\", update)\n }\n }, [enabled])\n\n return inset\n}\n","import { useEffect, useReducer, useRef, useState } from \"react\"\nimport type { ReactNode } from \"react\"\nimport type { EditorState } from \"@codemirror/state\"\nimport type { EditorView } from \"@codemirror/view\"\nimport styles from \"../styles/stylo.module.css\"\nimport type { ToolbarCommandId } from \"../types\"\nimport { BUILTIN_BY_ID } from \"./commands\"\nimport type { ToolbarItem } from \"./config\"\nimport { useFloatingWatchdog } from \"./floating-watchdog\"\nimport { DEFAULT_ICONS } from \"./icons\"\nimport { useKeyboardInset } from \"./keyboard-inset\"\n\nexport interface ToolbarProps {\n /** The surface the commands act on. `null` while a lazy view is mounting. */\n view: EditorView | null\n /** Ordered items to render; `\"|\"` is a separator. */\n items: ToolbarItem[]\n /** Per-id glyph overrides; any id left out keeps its built-in icon. */\n icons?: Partial<Record<ToolbarCommandId, ReactNode>>\n /** Render every button inert (e.g. a read-only surface). */\n disabled?: boolean\n /** Fix the bar to a window edge (normalised from `ToolbarConfig.sticky`; the\n * caller resolves `true` to `\"bottom\"`). */\n sticky?: \"top\" | \"bottom\" | false\n /** Fade the bar out while the editing surface is unfocused (`ToolbarConfig.stickyVisibility`). */\n stickyVisibility?: \"consistent\" | \"dynamic\"\n}\n\n/** A button to render, normalised from a built-in id or a custom item. */\ninterface Btn {\n key: string\n icon: ReactNode\n title: string\n run: (view: EditorView) => unknown\n isActive?: (state: EditorState) => boolean\n disabled?: (state: EditorState) => boolean\n}\n\n/**\n * Splits `items` into the runs a `\"|\"` already delimits, keeping each\n * separator as its own entry. A run renders as one flex child so wrapping\n * (on narrow hosts) breaks between groups, never in the middle of one — the\n * default bar's `undo, redo | h1, h2, h3 | ...` shape becomes the wrap unit\n * for free, no separate grouping config needed.\n */\nfunction groupItems(items: ToolbarItem[]): (Exclude<ToolbarItem, \"|\">[] | \"|\")[] {\n const groups: (Exclude<ToolbarItem, \"|\">[] | \"|\")[] = []\n let run: Exclude<ToolbarItem, \"|\">[] = []\n for (const item of items) {\n if (item !== \"|\") {\n run.push(item)\n continue\n }\n if (run.length) groups.push(run)\n run = []\n groups.push(\"|\")\n }\n if (run.length) groups.push(run)\n return groups\n}\n\n/** Resolve one non-separator item to a renderable button, or `null` to skip it. */\nfunction toButton(item: Exclude<ToolbarItem, \"|\">, icons: ToolbarProps[\"icons\"]): Btn | null {\n if (typeof item !== \"string\") {\n const { id, icon, title, run, isActive, disabled } = item\n return { key: id, icon, title, run, isActive, disabled }\n }\n const cmd = BUILTIN_BY_ID[item]\n if (!cmd) return null\n return {\n key: item,\n icon: icons?.[item] ?? DEFAULT_ICONS[item],\n title: cmd.title,\n run: cmd.run,\n isActive: cmd.isActive,\n disabled: cmd.disabled,\n }\n}\n\n/**\n * Formatting bar above the editing surface. It holds no document state — each\n * button runs a command against the live `EditorView`. Pressed states are read\n * back from the view whenever the selection, keys, or pointer move. Built-in\n * ids and consumer-supplied {@link ToolbarCustomItem}s render through the same\n * button path.\n */\nexport function Toolbar({ view, items, icons, disabled, sticky, stickyVisibility }: ToolbarProps) {\n const [, refresh] = useReducer((n: number) => n + 1, 0)\n const [focused, setFocused] = useState(false)\n // Only \"bottom\" needs keyboard tracking — nothing eats into the top of the\n // screen the way a keyboard eats the bottom.\n const keyboardInset = useKeyboardInset(sticky === \"bottom\")\n const barRef = useRef<HTMLDivElement>(null)\n useFloatingWatchdog(barRef, sticky === \"top\")\n\n useEffect(() => {\n if (!view) return\n const el = view.contentDOM\n setFocused(view.hasFocus)\n const onFocus = () => {\n setFocused(true)\n refresh()\n }\n const onBlur = () => {\n setFocused(false)\n refresh()\n }\n const events = [\"keyup\", \"mouseup\", \"input\"] as const\n for (const ev of events) el.addEventListener(ev, refresh)\n el.addEventListener(\"focus\", onFocus)\n el.addEventListener(\"blur\", onBlur)\n return () => {\n for (const ev of events) el.removeEventListener(ev, refresh)\n el.removeEventListener(\"focus\", onFocus)\n el.removeEventListener(\"blur\", onBlur)\n }\n }, [view])\n\n // \"dynamic\" fades the bar out while nothing is focused, so it doesn't sit\n // over the content while the caret is elsewhere (e.g. scrolling to read).\n const dynamicHidden = Boolean(sticky) && stickyVisibility === \"dynamic\" && !focused\n\n const className = [\n styles.toolbar,\n sticky && styles.toolbarSticky,\n sticky === \"top\" && styles.toolbarStickyTop,\n sticky === \"bottom\" && styles.toolbarStickyBottom,\n dynamicHidden && styles.toolbarStickyHidden,\n ]\n .filter(Boolean)\n .join(\" \")\n // `transform`, not `bottom` — a `position: fixed` element repositioned via\n // `bottom` doesn't reliably repaint in step with the keyboard animation on\n // iOS Safari; `translateY` forces a compositor update on every\n // `visualViewport` event instead. The bar's resting position (keyboard\n // closed) is `bottom: 0` in CSS; this only nudges it up. `\"top\"` needs no\n // offset at all.\n const stickyStyle =\n sticky === \"bottom\" ? { transform: `translateY(-${keyboardInset}px)` } : undefined\n\n return (\n <div\n ref={barRef}\n className={className}\n role=\"toolbar\"\n aria-label=\"Formatting\"\n aria-hidden={dynamicHidden || undefined}\n style={stickyStyle}\n >\n {groupItems(items).map((group, i) => {\n if (group === \"|\") {\n return <span key={`sep-${i}`} className={styles.toolbarSep} aria-hidden=\"true\" />\n }\n return (\n <div key={`group-${i}`} className={styles.toolbarGroup}>\n {group.map((item) => {\n const btn = toButton(item, icons)\n if (!btn) return null\n const off = disabled || !view || Boolean(btn.disabled?.(view.state))\n const active = Boolean(!off && view && btn.isActive?.(view.state))\n return (\n <button\n key={btn.key}\n type=\"button\"\n className={styles.toolbarButton}\n data-command={btn.key}\n title={btn.title}\n aria-label={btn.title}\n aria-pressed={btn.isActive ? active : undefined}\n data-active={active ? \"\" : undefined}\n disabled={off}\n onMouseDown={(e) => e.preventDefault()}\n onClick={() => {\n if (!view) return\n btn.run(view)\n refresh()\n }}\n >\n {btn.icon}\n </button>\n )\n })}\n </div>\n )\n })}\n </div>\n )\n}\n","import { forwardRef, Suspense, useEffect, useImperativeHandle, useRef, useState } from \"react\"\nimport { EditorView } from \"@codemirror/view\"\nimport { SourceView } from \"./editor/SourceView\"\nimport { LazyInPlaceView } from \"./inplace/lazyInPlace\"\nimport { LazyPreview } from \"./render/lazyPreview\"\nimport { SplitView } from \"./SplitView\"\nimport styles from \"./styles/stylo.module.css\"\nimport { Toolbar } from \"./toolbar/Toolbar\"\nimport { resolveToolbarItems } from \"./toolbar/config\"\nimport { splitFrontmatter } from \"./frontmatter\"\nimport \"./styles/tokens.css\"\nimport type { ResolveErrorInfo, StyloHandle, StyloProps } from \"./types\"\n\n/**\n * Plain-text-first Markdown editor. `value` is the canonical Markdown string;\n * every view is a pure function of it.\n *\n * The default `mode` is `in-place`, the live decoration canvas (ADR-002 §1,\n * ADR-004). Pass `mode=\"source\"` for the plain surface with no lazy render\n * chunk. `preview` and `split` are also available.\n *\n * A formatting `toolbar` sits above every editing surface (all modes but\n * `preview`); pass `toolbar={false}` to drop it or a `ToolbarConfig` to trim it.\n */\nexport const Stylo = forwardRef<StyloHandle, StyloProps>(function Stylo(\n {\n value,\n onChange,\n mode = \"in-place\",\n onSave,\n onFrontmatter,\n onWikiLinkClick,\n onLinkClick,\n readOnly,\n placeholder,\n className,\n inPlace,\n codeLanguages,\n wikiLinkSource,\n tagSource,\n embedSource,\n onResolveError,\n toolbar,\n icons,\n frontmatter,\n canvasHeader,\n },\n ref,\n) {\n const resolved = mode === \"preview\" || mode === \"split\" || mode === \"in-place\" ? mode : \"source\"\n\n const [view, setView] = useState<EditorView | null>(null)\n const toolbarItems = resolved === \"preview\" ? null : resolveToolbarItems(toolbar)\n const toolbarRender = toolbar && typeof toolbar === \"object\" ? toolbar.render : undefined\n const stickyConfig = toolbar && typeof toolbar === \"object\" ? toolbar.sticky : undefined\n const stickyToolbar: \"top\" | \"bottom\" | false =\n stickyConfig === \"top\" ? \"top\" : stickyConfig ? \"bottom\" : false\n const stickyVisibility =\n toolbar && typeof toolbar === \"object\" ? toolbar.stickyVisibility : undefined\n\n // Report the raw frontmatter block on mount and whenever it changes. Stylo\n // does not parse it — the host passes `raw` to its own YAML parser.\n const onFrontmatterRef = useRef(onFrontmatter)\n onFrontmatterRef.current = onFrontmatter\n\n // Stable wrapper so a changed `onResolveError` needs no editor rebuild and\n // does not thrash the embed effect. Passed to every surface.\n const onResolveErrorRef = useRef(onResolveError)\n onResolveErrorRef.current = onResolveError\n const resolveError = useRef((error: unknown, info: ResolveErrorInfo) => {\n onResolveErrorRef.current?.(error, info)\n }).current\n const lastFrontmatter = useRef<string | null | undefined>(undefined)\n useEffect(() => {\n const raw = splitFrontmatter(value)?.frontmatter ?? null\n if (raw === lastFrontmatter.current) return\n lastFrontmatter.current = raw\n onFrontmatterRef.current?.(raw)\n }, [value])\n\n useImperativeHandle(\n ref,\n () => ({\n focus: () => view?.focus(),\n getView: () => view,\n insertAtCursor: (md) => {\n if (!view) return\n view.dispatch(view.state.replaceSelection(md))\n view.focus()\n },\n scrollToHeading: (text) => {\n if (!view) return false\n const target = text.trim().toLowerCase()\n const { doc } = view.state\n for (let n = 1; n <= doc.lines; n++) {\n const line = doc.line(n)\n const m = /^ {0,3}#{1,6}[ \\t]+(.*?)(?:[ \\t]+#+)?[ \\t]*$/.exec(line.text)\n if (!m || m[1] === undefined) continue\n if (m[1].trim().toLowerCase() !== target) continue\n view.dispatch({\n selection: { anchor: line.from },\n effects: EditorView.scrollIntoView(line.from, { y: \"start\" }),\n })\n view.focus()\n return true\n }\n return false\n },\n }),\n [view],\n )\n\n const rootClass = [\n styles.root,\n stickyToolbar === \"bottom\" && styles.stickyToolbarRootBottom,\n stickyToolbar === \"top\" && styles.stickyToolbarRootTop,\n \"stylo\",\n className,\n ]\n .filter(Boolean)\n .join(\" \")\n\n return (\n <div className={rootClass} data-stylo-mode={resolved}>\n {toolbarItems &&\n (() => {\n const bar = (\n <Toolbar\n view={view}\n items={toolbarItems}\n icons={icons}\n disabled={readOnly}\n sticky={stickyToolbar}\n stickyVisibility={stickyVisibility}\n />\n )\n return toolbarRender ? toolbarRender(bar, { view }) : bar\n })()}\n\n {resolved === \"source\" && (\n <SourceView\n value={value}\n onChange={onChange}\n readOnly={readOnly}\n placeholder={placeholder}\n codeLanguages={codeLanguages}\n wikiLinkSource={wikiLinkSource}\n tagSource={tagSource}\n onResolveError={resolveError}\n onSave={onSave}\n onViewChange={setView}\n canvasHeader={canvasHeader}\n />\n )}\n\n {resolved === \"preview\" && (\n <Suspense fallback={<div className={styles.preview} aria-busy=\"true\" />}>\n <LazyPreview\n value={value}\n onWikiLinkClick={onWikiLinkClick}\n embedSource={embedSource}\n onResolveError={resolveError}\n frontmatter={frontmatter}\n codeLanguages={codeLanguages}\n />\n </Suspense>\n )}\n\n {resolved === \"split\" && (\n <SplitView\n value={value}\n onChange={onChange}\n onWikiLinkClick={onWikiLinkClick}\n readOnly={readOnly}\n placeholder={placeholder}\n codeLanguages={codeLanguages}\n wikiLinkSource={wikiLinkSource}\n tagSource={tagSource}\n embedSource={embedSource}\n onResolveError={resolveError}\n frontmatter={frontmatter}\n onSave={onSave}\n onViewChange={setView}\n canvasHeader={canvasHeader}\n />\n )}\n\n {resolved === \"in-place\" && (\n <Suspense fallback={<div className={styles.inplace} aria-busy=\"true\" />}>\n <LazyInPlaceView\n value={value}\n onChange={onChange}\n readOnly={readOnly}\n placeholder={placeholder}\n onWikiLinkClick={onWikiLinkClick}\n onLinkClick={onLinkClick}\n inPlace={inPlace}\n codeLanguages={codeLanguages}\n wikiLinkSource={wikiLinkSource}\n tagSource={tagSource}\n embedSource={embedSource}\n onResolveError={resolveError}\n onSave={onSave}\n onViewChange={setView}\n canvasHeader={canvasHeader}\n />\n </Suspense>\n )}\n </div>\n )\n})\n\nStylo.displayName = \"Stylo\"\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"stylo.js","names":[],"sources":["../src/editor/SourceView.tsx","../src/inplace/lazyInPlace.ts","../src/render/lazyPreview.ts","../src/SplitView.tsx","../src/toolbar/floating-watchdog.ts","../src/toolbar/keyboard-inset.ts","../src/toolbar/Toolbar.tsx","../src/Stylo.tsx"],"sourcesContent":["import { useRef, useState, useSyncExternalStore } from \"react\"\nimport type { ReactNode } from \"react\"\nimport { createPortal } from \"react-dom\"\nimport { showPanel } from \"@codemirror/view\"\nimport type { EditorView } from \"@codemirror/view\"\nimport styles from \"../styles/stylo.module.css\"\nimport type { CodeLanguages, ResolveErrorInfo, TagSource, WikiLinkSource } from \"../types\"\nimport { CanvasHeaderHost } from \"./canvas-header-panel\"\nimport { useCodeMirror } from \"./useCodeMirror\"\n\nconst noopSubscribe = () => () => {}\nconst noopSnapshot = () => null\n\nexport interface SourceViewProps {\n value: string\n onChange: (next: string) => void\n readOnly?: boolean\n placeholder?: string\n /** Fenced-code grammars, forwarded to the Markdown language. Read once. */\n codeLanguages?: CodeLanguages\n /** `[[wikilink]]` autocomplete source. Read once. */\n wikiLinkSource?: WikiLinkSource\n /** `#tag` autocomplete source. Read once. */\n tagSource?: TagSource\n /** Notified when `wikiLinkSource` or `tagSource` rejects. */\n onResolveError?: (error: unknown, info: ResolveErrorInfo) => void\n /** Called with the doc string on `Mod-s`. */\n onSave?: (value: string) => void\n /** Called with the `EditorView` once created, and with `null` on teardown. */\n onViewChange?: (view: EditorView | null) => void\n /** Host content docked after the search panel, before the document. Read once. */\n canvasHeader?: (ctx: { view: EditorView | null }) => ReactNode\n}\n\n/** Raw CodeMirror 6 Markdown surface bound to the canonical string. */\nexport function SourceView({\n value,\n onChange,\n readOnly,\n placeholder,\n codeLanguages,\n wikiLinkSource,\n tagSource,\n onResolveError,\n onSave,\n onViewChange,\n canvasHeader,\n}: SourceViewProps) {\n const [editorView, setEditorView] = useState<EditorView | null>(null)\n const onViewChangeRef = useRef(onViewChange)\n onViewChangeRef.current = onViewChange\n const handleViewChange = useRef((view: EditorView | null) => {\n setEditorView(view)\n onViewChangeRef.current?.(view)\n }).current\n\n // `canvasHeader` itself is read through a ref (a changed render prop needs\n // no editor rebuild); whether it was passed at all is read once, at mount,\n // to decide whether the panel extension exists at all.\n const canvasHeaderRef = useRef(canvasHeader)\n canvasHeaderRef.current = canvasHeader\n const [headerHost] = useState(() => (canvasHeader ? new CanvasHeaderHost() : null))\n const headerDom = useSyncExternalStore(\n headerHost?.subscribe ?? noopSubscribe,\n headerHost?.getSnapshot ?? noopSnapshot,\n )\n const [extensions] = useState(() => (headerHost ? [showPanel.of(headerHost.panel)] : []))\n\n const ref = useCodeMirror({\n value,\n onChange,\n readOnly,\n placeholder,\n codeLanguages,\n wikiLinkSource,\n tagSource,\n onResolveError,\n onSave,\n onViewChange: handleViewChange,\n extensions,\n })\n return (\n <div className={styles.source} ref={ref}>\n {headerDom &&\n canvasHeaderRef.current &&\n createPortal(canvasHeaderRef.current({ view: editorView }), headerDom)}\n </div>\n )\n}\n","import { lazy } from \"react\"\n\n/**\n * The in-place canvas carries the decoration plugin (and, in later increments,\n * its KaTeX widgets). It loads only when `mode` resolves to `in-place`, so\n * `source` consumers never fetch it.\n */\nexport const LazyInPlaceView = lazy(async () => ({\n default: (await import(\"./InPlaceView\")).InPlaceView,\n}))\n","import { lazy } from \"react\"\n\n/**\n * Preview pulls in react-markdown + remark/rehype + KaTeX. It is loaded only\n * when a rendered mode (`preview`, `split`) is actually used, so `mode=\"source\"`\n * consumers never pay for it. Both callers share this one wrapper, so the render\n * pipeline stays a single lazy chunk.\n */\nexport const LazyPreview = lazy(async () => ({\n default: (await import(\"./Preview\")).Preview,\n}))\n","import { Suspense, useEffect, useRef, useState } from \"react\"\nimport type { ReactNode } from \"react\"\nimport type { EditorView } from \"@codemirror/view\"\nimport { SourceView } from \"./editor/SourceView\"\nimport { LazyPreview } from \"./render/lazyPreview\"\nimport styles from \"./styles/stylo.module.css\"\nimport type {\n CodeLanguages,\n EmbedSource,\n FrontmatterDisplay,\n ResolveErrorInfo,\n TagSource,\n TaskToggleInfo,\n WikiLinkSource,\n} from \"./types\"\n\nexport interface SplitViewProps {\n value: string\n onChange: (next: string) => void\n onWikiLinkClick?: (target: string) => void\n readOnly?: boolean\n placeholder?: string\n codeLanguages?: CodeLanguages\n wikiLinkSource?: WikiLinkSource\n tagSource?: TagSource\n embedSource?: EmbedSource\n onResolveError?: (error: unknown, info: ResolveErrorInfo) => void\n frontmatter?: FrontmatterDisplay\n softBreaks?: boolean\n onTaskToggle?: (info: TaskToggleInfo) => void\n /** Called with the doc string on `Mod-s`. */\n onSave?: (value: string) => void\n /** Forwarded the source pane's `EditorView` for the shared toolbar. */\n onViewChange?: (view: EditorView | null) => void\n /** Host content docked in the source pane, after its search panel. Read once. */\n canvasHeader?: (ctx: { view: EditorView | null }) => ReactNode\n}\n\n/**\n * Source and preview side by side. Both panes are a pure function of the same\n * string; the only link between them is a proportional scroll sync. Expects the\n * Stylo root to have a bounded height — otherwise both panes grow and the page\n * scrolls instead.\n */\nexport function SplitView({\n value,\n onChange,\n onWikiLinkClick,\n readOnly,\n placeholder,\n codeLanguages,\n wikiLinkSource,\n tagSource,\n embedSource,\n onResolveError,\n frontmatter,\n softBreaks,\n onTaskToggle,\n onSave,\n onViewChange,\n canvasHeader,\n}: SplitViewProps) {\n const [view, setView] = useState<EditorView | null>(null)\n const previewPane = useRef<HTMLDivElement | null>(null)\n const syncing = useRef(false)\n\n const handleView = (next: EditorView | null) => {\n setView(next)\n onViewChange?.(next)\n }\n\n useEffect(() => {\n const source = view?.scrollDOM\n const preview = previewPane.current\n if (!source || !preview) return\n\n const sync = (from: HTMLElement, to: HTMLElement) => {\n if (syncing.current) return\n const range = from.scrollHeight - from.clientHeight\n if (range <= 0) return\n syncing.current = true\n to.scrollTop = (from.scrollTop / range) * (to.scrollHeight - to.clientHeight)\n requestAnimationFrame(() => {\n syncing.current = false\n })\n }\n\n const fromSource = () => sync(source, preview)\n const fromPreview = () => sync(preview, source)\n source.addEventListener(\"scroll\", fromSource, { passive: true })\n preview.addEventListener(\"scroll\", fromPreview, { passive: true })\n return () => {\n source.removeEventListener(\"scroll\", fromSource)\n preview.removeEventListener(\"scroll\", fromPreview)\n }\n }, [view])\n\n return (\n <div className={styles.split}>\n <div className={styles.splitPane}>\n <SourceView\n value={value}\n onChange={onChange}\n readOnly={readOnly}\n placeholder={placeholder}\n codeLanguages={codeLanguages}\n wikiLinkSource={wikiLinkSource}\n tagSource={tagSource}\n onResolveError={onResolveError}\n onSave={onSave}\n onViewChange={handleView}\n canvasHeader={canvasHeader}\n />\n </div>\n <div className={styles.splitPane} ref={previewPane}>\n <Suspense fallback={<div className={styles.preview} aria-busy=\"true\" />}>\n <LazyPreview\n value={value}\n onWikiLinkClick={onWikiLinkClick}\n embedSource={embedSource}\n onResolveError={onResolveError}\n frontmatter={frontmatter}\n codeLanguages={codeLanguages}\n softBreaks={softBreaks}\n onTaskToggle={onTaskToggle}\n />\n </Suspense>\n </div>\n </div>\n )\n}\n","import { useEffect, type RefObject } from \"react\"\n\n/**\n * Continuously re-asserts a `transform` on a `position: fixed` element,\n * alternating an imperceptible sub-pixel jitter every animation frame,\n * instead of trusting the browser to keep it correctly composited on its\n * own. Several rounds of on-device testing found iOS Safari losing track of\n * this exact kind of element — across its own address-bar animation, and in\n * at least one report tied to the keyboard opening — in ways a one-time\n * static fix (a plain `translateZ(0)`) did not reliably prevent. A value\n * that never changes gives the browser nothing to recompute; alternating it\n * every frame forces a fresh compositor pass regardless of what triggered\n * the drift, so it can't stay wrong for more than one frame (~16ms).\n *\n * Writes to the DOM directly rather than through React state, so this never\n * causes a re-render — the transform is the only thing touched.\n */\nexport function useFloatingWatchdog(ref: RefObject<HTMLElement | null>, enabled: boolean): void {\n useEffect(() => {\n if (!enabled) return\n let raf = 0\n let jitter = false\n const tick = () => {\n const el = ref.current\n if (el) {\n jitter = !jitter\n el.style.transform = jitter ? \"translate3d(0, 0.01px, 0)\" : \"translate3d(0, 0, 0)\"\n }\n raf = requestAnimationFrame(tick)\n }\n raf = requestAnimationFrame(tick)\n return () => cancelAnimationFrame(raf)\n }, [ref, enabled])\n}\n","import { useEffect, useState } from \"react\"\n\n/**\n * How far the on-screen keyboard eats into the window, tracked through the\n * `visualViewport` API. 0 when `enabled` is false or the browser has no\n * `visualViewport` (older Safari, SSR, most desktop browsers). A mobile\n * keyboard shrinks the *visual* viewport, not the layout viewport a plain\n * `position: fixed` bottom offset is computed against — this is what lets the\n * sticky toolbar ride up above the keyboard instead of hiding behind it.\n */\nexport function useKeyboardInset(enabled: boolean): number {\n const [inset, setInset] = useState(0)\n\n useEffect(() => {\n const vv = typeof window === \"undefined\" ? null : window.visualViewport\n if (!enabled || !vv) {\n setInset(0)\n return\n }\n const update = () => setInset(Math.max(0, window.innerHeight - vv.height - vv.offsetTop))\n update()\n vv.addEventListener(\"resize\", update)\n vv.addEventListener(\"scroll\", update)\n return () => {\n vv.removeEventListener(\"resize\", update)\n vv.removeEventListener(\"scroll\", update)\n }\n }, [enabled])\n\n return inset\n}\n","import { useEffect, useReducer, useRef, useState } from \"react\"\nimport type { ReactNode } from \"react\"\nimport type { EditorState } from \"@codemirror/state\"\nimport type { EditorView } from \"@codemirror/view\"\nimport styles from \"../styles/stylo.module.css\"\nimport type { ToolbarCommandId } from \"../types\"\nimport { BUILTIN_BY_ID } from \"./commands\"\nimport type { ToolbarItem } from \"./config\"\nimport { useFloatingWatchdog } from \"./floating-watchdog\"\nimport { DEFAULT_ICONS } from \"./icons\"\nimport { useKeyboardInset } from \"./keyboard-inset\"\n\nexport interface ToolbarProps {\n /** The surface the commands act on. `null` while a lazy view is mounting. */\n view: EditorView | null\n /** Ordered items to render; `\"|\"` is a separator. */\n items: ToolbarItem[]\n /** Per-id glyph overrides; any id left out keeps its built-in icon. */\n icons?: Partial<Record<ToolbarCommandId, ReactNode>>\n /** Render every button inert (e.g. a read-only surface). */\n disabled?: boolean\n /** Fix the bar to a window edge (normalised from `ToolbarConfig.sticky`; the\n * caller resolves `true` to `\"bottom\"`). */\n sticky?: \"top\" | \"bottom\" | false\n /** Fade the bar out while the editing surface is unfocused (`ToolbarConfig.stickyVisibility`). */\n stickyVisibility?: \"consistent\" | \"dynamic\"\n}\n\n/** A button to render, normalised from a built-in id or a custom item. */\ninterface Btn {\n key: string\n icon: ReactNode\n title: string\n run: (view: EditorView) => unknown\n isActive?: (state: EditorState) => boolean\n disabled?: (state: EditorState) => boolean\n}\n\n/**\n * Splits `items` into the runs a `\"|\"` already delimits, keeping each\n * separator as its own entry. A run renders as one flex child so wrapping\n * (on narrow hosts) breaks between groups, never in the middle of one — the\n * default bar's `undo, redo | h1, h2, h3 | ...` shape becomes the wrap unit\n * for free, no separate grouping config needed.\n */\nfunction groupItems(items: ToolbarItem[]): (Exclude<ToolbarItem, \"|\">[] | \"|\")[] {\n const groups: (Exclude<ToolbarItem, \"|\">[] | \"|\")[] = []\n let run: Exclude<ToolbarItem, \"|\">[] = []\n for (const item of items) {\n if (item !== \"|\") {\n run.push(item)\n continue\n }\n if (run.length) groups.push(run)\n run = []\n groups.push(\"|\")\n }\n if (run.length) groups.push(run)\n return groups\n}\n\n/** Resolve one non-separator item to a renderable button, or `null` to skip it. */\nfunction toButton(item: Exclude<ToolbarItem, \"|\">, icons: ToolbarProps[\"icons\"]): Btn | null {\n if (typeof item !== \"string\") {\n const { id, icon, title, run, isActive, disabled } = item\n return { key: id, icon, title, run, isActive, disabled }\n }\n const cmd = BUILTIN_BY_ID[item]\n if (!cmd) return null\n return {\n key: item,\n icon: icons?.[item] ?? DEFAULT_ICONS[item],\n title: cmd.title,\n run: cmd.run,\n isActive: cmd.isActive,\n disabled: cmd.disabled,\n }\n}\n\n/**\n * Formatting bar above the editing surface. It holds no document state — each\n * button runs a command against the live `EditorView`. Pressed states are read\n * back from the view whenever the selection, keys, or pointer move. Built-in\n * ids and consumer-supplied {@link ToolbarCustomItem}s render through the same\n * button path.\n */\nexport function Toolbar({ view, items, icons, disabled, sticky, stickyVisibility }: ToolbarProps) {\n const [, refresh] = useReducer((n: number) => n + 1, 0)\n const [focused, setFocused] = useState(false)\n // Only \"bottom\" needs keyboard tracking — nothing eats into the top of the\n // screen the way a keyboard eats the bottom.\n const keyboardInset = useKeyboardInset(sticky === \"bottom\")\n const barRef = useRef<HTMLDivElement>(null)\n useFloatingWatchdog(barRef, sticky === \"top\")\n\n useEffect(() => {\n if (!view) return\n const el = view.contentDOM\n setFocused(view.hasFocus)\n const onFocus = () => {\n setFocused(true)\n refresh()\n }\n const onBlur = () => {\n setFocused(false)\n refresh()\n }\n const events = [\"keyup\", \"mouseup\", \"input\"] as const\n for (const ev of events) el.addEventListener(ev, refresh)\n el.addEventListener(\"focus\", onFocus)\n el.addEventListener(\"blur\", onBlur)\n return () => {\n for (const ev of events) el.removeEventListener(ev, refresh)\n el.removeEventListener(\"focus\", onFocus)\n el.removeEventListener(\"blur\", onBlur)\n }\n }, [view])\n\n // \"dynamic\" fades the bar out while nothing is focused, so it doesn't sit\n // over the content while the caret is elsewhere (e.g. scrolling to read).\n const dynamicHidden = Boolean(sticky) && stickyVisibility === \"dynamic\" && !focused\n\n const className = [\n styles.toolbar,\n sticky && styles.toolbarSticky,\n sticky === \"top\" && styles.toolbarStickyTop,\n sticky === \"bottom\" && styles.toolbarStickyBottom,\n dynamicHidden && styles.toolbarStickyHidden,\n ]\n .filter(Boolean)\n .join(\" \")\n // `transform`, not `bottom` — a `position: fixed` element repositioned via\n // `bottom` doesn't reliably repaint in step with the keyboard animation on\n // iOS Safari; `translateY` forces a compositor update on every\n // `visualViewport` event instead. The bar's resting position (keyboard\n // closed) is `bottom: 0` in CSS; this only nudges it up. `\"top\"` needs no\n // offset at all.\n const stickyStyle =\n sticky === \"bottom\" ? { transform: `translateY(-${keyboardInset}px)` } : undefined\n\n return (\n <div\n ref={barRef}\n className={className}\n role=\"toolbar\"\n aria-label=\"Formatting\"\n aria-hidden={dynamicHidden || undefined}\n style={stickyStyle}\n >\n {groupItems(items).map((group, i) => {\n if (group === \"|\") {\n return <span key={`sep-${i}`} className={styles.toolbarSep} aria-hidden=\"true\" />\n }\n return (\n <div key={`group-${i}`} className={styles.toolbarGroup}>\n {group.map((item) => {\n const btn = toButton(item, icons)\n if (!btn) return null\n const off = disabled || !view || Boolean(btn.disabled?.(view.state))\n const active = Boolean(!off && view && btn.isActive?.(view.state))\n return (\n <button\n key={btn.key}\n type=\"button\"\n className={styles.toolbarButton}\n data-command={btn.key}\n title={btn.title}\n aria-label={btn.title}\n aria-pressed={btn.isActive ? active : undefined}\n data-active={active ? \"\" : undefined}\n disabled={off}\n onMouseDown={(e) => e.preventDefault()}\n onClick={() => {\n if (!view) return\n btn.run(view)\n refresh()\n }}\n >\n {btn.icon}\n </button>\n )\n })}\n </div>\n )\n })}\n </div>\n )\n}\n","import { forwardRef, Suspense, useEffect, useImperativeHandle, useRef, useState } from \"react\"\nimport { EditorView } from \"@codemirror/view\"\nimport { SourceView } from \"./editor/SourceView\"\nimport { LazyInPlaceView } from \"./inplace/lazyInPlace\"\nimport { LazyPreview } from \"./render/lazyPreview\"\nimport { SplitView } from \"./SplitView\"\nimport styles from \"./styles/stylo.module.css\"\nimport { Toolbar } from \"./toolbar/Toolbar\"\nimport { resolveToolbarItems } from \"./toolbar/config\"\nimport { splitFrontmatter } from \"./frontmatter\"\nimport \"./styles/tokens.css\"\nimport type { ResolveErrorInfo, StyloHandle, StyloProps } from \"./types\"\n\n/**\n * Plain-text-first Markdown editor. `value` is the canonical Markdown string;\n * every view is a pure function of it.\n *\n * The default `mode` is `in-place`, the live decoration canvas (ADR-002 §1,\n * ADR-004). Pass `mode=\"source\"` for the plain surface with no lazy render\n * chunk. `preview` and `split` are also available.\n *\n * A formatting `toolbar` sits above every editing surface (all modes but\n * `preview`); pass `toolbar={false}` to drop it or a `ToolbarConfig` to trim it.\n */\nexport const Stylo = forwardRef<StyloHandle, StyloProps>(function Stylo(\n {\n value,\n onChange,\n mode = \"in-place\",\n onSave,\n onFrontmatter,\n onWikiLinkClick,\n onLinkClick,\n readOnly,\n placeholder,\n className,\n inPlace,\n codeLanguages,\n wikiLinkSource,\n tagSource,\n embedSource,\n onResolveError,\n toolbar,\n icons,\n frontmatter,\n softBreaks,\n onTaskToggle,\n canvasHeader,\n },\n ref,\n) {\n const resolved = mode === \"preview\" || mode === \"split\" || mode === \"in-place\" ? mode : \"source\"\n\n const [view, setView] = useState<EditorView | null>(null)\n const toolbarItems = resolved === \"preview\" ? null : resolveToolbarItems(toolbar)\n const toolbarRender = toolbar && typeof toolbar === \"object\" ? toolbar.render : undefined\n const stickyConfig = toolbar && typeof toolbar === \"object\" ? toolbar.sticky : undefined\n const stickyToolbar: \"top\" | \"bottom\" | false =\n stickyConfig === \"top\" ? \"top\" : stickyConfig ? \"bottom\" : false\n const stickyVisibility =\n toolbar && typeof toolbar === \"object\" ? toolbar.stickyVisibility : undefined\n\n // Report the raw frontmatter block on mount and whenever it changes. Stylo\n // does not parse it — the host passes `raw` to its own YAML parser.\n const onFrontmatterRef = useRef(onFrontmatter)\n onFrontmatterRef.current = onFrontmatter\n\n // Stable wrapper so a changed `onResolveError` needs no editor rebuild and\n // does not thrash the embed effect. Passed to every surface.\n const onResolveErrorRef = useRef(onResolveError)\n onResolveErrorRef.current = onResolveError\n const resolveError = useRef((error: unknown, info: ResolveErrorInfo) => {\n onResolveErrorRef.current?.(error, info)\n }).current\n const lastFrontmatter = useRef<string | null | undefined>(undefined)\n useEffect(() => {\n const raw = splitFrontmatter(value)?.frontmatter ?? null\n if (raw === lastFrontmatter.current) return\n lastFrontmatter.current = raw\n onFrontmatterRef.current?.(raw)\n }, [value])\n\n useImperativeHandle(\n ref,\n () => ({\n focus: () => view?.focus(),\n getView: () => view,\n insertAtCursor: (md) => {\n if (!view) return\n view.dispatch(view.state.replaceSelection(md))\n view.focus()\n },\n scrollToHeading: (text) => {\n if (!view) return false\n const target = text.trim().toLowerCase()\n const { doc } = view.state\n for (let n = 1; n <= doc.lines; n++) {\n const line = doc.line(n)\n const m = /^ {0,3}#{1,6}[ \\t]+(.*?)(?:[ \\t]+#+)?[ \\t]*$/.exec(line.text)\n if (!m || m[1] === undefined) continue\n if (m[1].trim().toLowerCase() !== target) continue\n view.dispatch({\n selection: { anchor: line.from },\n effects: EditorView.scrollIntoView(line.from, { y: \"start\" }),\n })\n view.focus()\n return true\n }\n return false\n },\n }),\n [view],\n )\n\n const rootClass = [\n styles.root,\n stickyToolbar === \"bottom\" && styles.stickyToolbarRootBottom,\n stickyToolbar === \"top\" && styles.stickyToolbarRootTop,\n \"stylo\",\n className,\n ]\n .filter(Boolean)\n .join(\" \")\n\n return (\n <div className={rootClass} data-stylo-mode={resolved}>\n {toolbarItems &&\n (() => {\n const bar = (\n <Toolbar\n view={view}\n items={toolbarItems}\n icons={icons}\n disabled={readOnly}\n sticky={stickyToolbar}\n stickyVisibility={stickyVisibility}\n />\n )\n return toolbarRender ? toolbarRender(bar, { view }) : bar\n })()}\n\n {resolved === \"source\" && (\n <SourceView\n value={value}\n onChange={onChange}\n readOnly={readOnly}\n placeholder={placeholder}\n codeLanguages={codeLanguages}\n wikiLinkSource={wikiLinkSource}\n tagSource={tagSource}\n onResolveError={resolveError}\n onSave={onSave}\n onViewChange={setView}\n canvasHeader={canvasHeader}\n />\n )}\n\n {resolved === \"preview\" && (\n <Suspense fallback={<div className={styles.preview} aria-busy=\"true\" />}>\n <LazyPreview\n value={value}\n onWikiLinkClick={onWikiLinkClick}\n embedSource={embedSource}\n onResolveError={resolveError}\n frontmatter={frontmatter}\n codeLanguages={codeLanguages}\n softBreaks={softBreaks}\n onTaskToggle={onTaskToggle}\n />\n </Suspense>\n )}\n\n {resolved === \"split\" && (\n <SplitView\n value={value}\n onChange={onChange}\n onWikiLinkClick={onWikiLinkClick}\n readOnly={readOnly}\n placeholder={placeholder}\n codeLanguages={codeLanguages}\n wikiLinkSource={wikiLinkSource}\n tagSource={tagSource}\n embedSource={embedSource}\n onResolveError={resolveError}\n frontmatter={frontmatter}\n softBreaks={softBreaks}\n onTaskToggle={onTaskToggle}\n onSave={onSave}\n onViewChange={setView}\n canvasHeader={canvasHeader}\n />\n )}\n\n {resolved === \"in-place\" && (\n <Suspense fallback={<div className={styles.inplace} aria-busy=\"true\" />}>\n <LazyInPlaceView\n value={value}\n onChange={onChange}\n readOnly={readOnly}\n placeholder={placeholder}\n onWikiLinkClick={onWikiLinkClick}\n onLinkClick={onLinkClick}\n inPlace={inPlace}\n codeLanguages={codeLanguages}\n wikiLinkSource={wikiLinkSource}\n tagSource={tagSource}\n embedSource={embedSource}\n onResolveError={resolveError}\n onSave={onSave}\n onViewChange={setView}\n canvasHeader={canvasHeader}\n />\n </Suspense>\n )}\n </div>\n )\n})\n\nStylo.displayName = \"Stylo\"\n"],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -154,6 +154,22 @@ export interface ResolveErrorInfo {
|
|
|
154
154
|
/** What it was asked to resolve — an `![[ref]]` reference, or the `[[` query. */
|
|
155
155
|
input: string;
|
|
156
156
|
}
|
|
157
|
+
/**
|
|
158
|
+
* Reported by `onTaskToggle` when a `preview` task-list checkbox is clicked.
|
|
159
|
+
* `start`/`end` are raw offsets into `value` bracketing the `[ ]` / `[x]`
|
|
160
|
+
* marker itself (`end - start === 3`); splice in the new marker text to apply
|
|
161
|
+
* the toggle: `value.slice(0, start) + (checked ? "[x]" : "[ ]") +
|
|
162
|
+
* value.slice(end)`. `checked` is the box's new state, not its state before
|
|
163
|
+
* the click.
|
|
164
|
+
*/
|
|
165
|
+
export interface TaskToggleInfo {
|
|
166
|
+
/** Offset of the marker's opening `[` in `value`. */
|
|
167
|
+
start: number;
|
|
168
|
+
/** Offset just past the marker's closing `]` in `value`. */
|
|
169
|
+
end: number;
|
|
170
|
+
/** The checkbox's new state. */
|
|
171
|
+
checked: boolean;
|
|
172
|
+
}
|
|
157
173
|
/**
|
|
158
174
|
* Per-construct on/off switches for the in-place canvas. Each key defaults to
|
|
159
175
|
* `true`; setting one `false` leaves that construct as plain source — no
|
|
@@ -282,6 +298,26 @@ export interface StyloProps {
|
|
|
282
298
|
* `<pre class="stylo-frontmatter">`.
|
|
283
299
|
*/
|
|
284
300
|
frontmatter?: FrontmatterDisplay;
|
|
301
|
+
/**
|
|
302
|
+
* Turn a single line ending into a real `<br>` in `preview` (and `split`'s
|
|
303
|
+
* preview pane), instead of CommonMark's default — a blank line required to
|
|
304
|
+
* start a new paragraph, so consecutive lines join into one run. Obsidian's
|
|
305
|
+
* Live Preview reads this way. Off by default: a real, visible change to
|
|
306
|
+
* every existing render, so a host opts in deliberately rather than
|
|
307
|
+
* inheriting it. No effect on `in-place` / `source` — CodeMirror already
|
|
308
|
+
* decorates each source line independently there.
|
|
309
|
+
*/
|
|
310
|
+
softBreaks?: boolean;
|
|
311
|
+
/**
|
|
312
|
+
* Makes `preview` (and `split`'s preview pane) task-list checkboxes
|
|
313
|
+
* clickable instead of `disabled`. Fired with a {@link TaskToggleInfo} — raw
|
|
314
|
+
* offsets into `value` bracketing the clicked `[ ]` / `[x]` marker, and its
|
|
315
|
+
* new state. Stylo never mutates `value` itself; splice the marker and pass
|
|
316
|
+
* the result to `onChange`, same division of labour as `onWikiLinkClick`.
|
|
317
|
+
* Off by default: every checkbox stays `disabled`, exactly like today,
|
|
318
|
+
* until a host opts in.
|
|
319
|
+
*/
|
|
320
|
+
onTaskToggle?: (info: TaskToggleInfo) => void;
|
|
285
321
|
/**
|
|
286
322
|
* Grammars for fenced-code sub-highlighting on the CodeMirror surfaces
|
|
287
323
|
* (`source`, `split`, `in-place`). None by default. Read once, at mount.
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@damiro/stylo",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.1",
|
|
4
4
|
"description": "A plain-text-first Markdown editor for React, with first-class LaTeX (KaTeX) support.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -90,6 +90,7 @@
|
|
|
90
90
|
"katex": "^0.16.47",
|
|
91
91
|
"react-markdown": "^10.1.0",
|
|
92
92
|
"rehype-katex": "^7.0.1",
|
|
93
|
+
"remark-breaks": "^4.0.0",
|
|
93
94
|
"remark-frontmatter": "^5.0.0",
|
|
94
95
|
"remark-gfm": "^4.0.1",
|
|
95
96
|
"remark-math": "^6.0.0",
|