@zuilib/text-editor 0.5.0 → 0.7.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/CHANGELOG.md +71 -0
- package/DRAWING_FORMAT.md +11 -5
- package/README.md +122 -26
- package/dist/index.d.ts +108 -24
- package/dist/index.js +302 -181
- package/dist/styles.css +190 -163
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,76 @@
|
|
|
1
1
|
# Changelog — @zuilib/text-editor
|
|
2
2
|
|
|
3
|
+
## 0.7.0
|
|
4
|
+
|
|
5
|
+
**Themed drawing canvas.** The canvas chrome now follows the host theme
|
|
6
|
+
instead of shipping its own look.
|
|
7
|
+
|
|
8
|
+
- Tool row and contextual property row are a flat header in the editor's
|
|
9
|
+
own toolbar idiom (in flow, no floating panels over the drawing)
|
|
10
|
+
- Every color, radius, shadow and font of the canvas is a
|
|
11
|
+
`--zui-drawing-*` custom property defaulting to the core theme tokens
|
|
12
|
+
(`--primary`, `--foreground`, `--border`, `--popover`, `--radius`,
|
|
13
|
+
`--shadow-medium`, …), so light and dark mode come from the tokens;
|
|
14
|
+
override them on `.zui-drawing-canvas` or an ancestor. See README,
|
|
15
|
+
"Theming the canvas"
|
|
16
|
+
- Selection frame, handles, marquee, bind highlight and connector label
|
|
17
|
+
plates are drawn in `currentColor`/theme variables; the table selection
|
|
18
|
+
tint uses `--primary` too, so the editor shares one accent
|
|
19
|
+
- `--zui-drawing-dark-filter` exposes the dark-mode inversion of the
|
|
20
|
+
drawing area (`none` opts out)
|
|
21
|
+
|
|
22
|
+
## 0.6.0
|
|
23
|
+
|
|
24
|
+
**Text measure and `text` block width.** Additive: markdown, JSON, class
|
|
25
|
+
names and props keep their meaning; with no configuration the layout is
|
|
26
|
+
unchanged.
|
|
27
|
+
|
|
28
|
+
- **Measure** (opt in): `measure="48rem"` on `MarkdownEditor` /
|
|
29
|
+
`MarkdownEditor.Root`, or `--zui-text-editor-measure: 48rem` in a
|
|
30
|
+
stylesheet — the CSS custom property is the contract, the prop is sugar.
|
|
31
|
+
Text blocks (paragraphs, headings, lists, quotes, code, frontmatter) are
|
|
32
|
+
capped at the measure and centred in the content pane; the placeholder
|
|
33
|
+
and fold chevrons follow the column. The pane itself is never capped and
|
|
34
|
+
full-width blocks stop short of the outline sidebar
|
|
35
|
+
- **`BlockWidth` gains `'text'`**: `'full' | 'text' | 'content'`. `text`
|
|
36
|
+
aligns a table or drawing with the text column; without a measure it is
|
|
37
|
+
visually identical to `full` (resolved in CSS through the variable's
|
|
38
|
+
fallback). `full` (default, omitted) and `content` (shrink to fit) are
|
|
39
|
+
unchanged
|
|
40
|
+
- **Persistence**: tables `<!-- width: text -->` (combinable with
|
|
41
|
+
`density`); drawings and ` ```diagram ` skeletons `"width":"text"`.
|
|
42
|
+
`DRAWING_DATA_JSON_SCHEMA`, `DRAWING_SKELETON_JSON_SCHEMA` and
|
|
43
|
+
`DRAWING_FORMAT.md` updated. Unknown width values are ignored (treated as
|
|
44
|
+
`full`) instead of being rejected, so documents from newer versions still
|
|
45
|
+
open — `parseTableSettingsMarker` now returns `{}` (rather than `null`)
|
|
46
|
+
for a marker whose only known key carries an unknown value, and the
|
|
47
|
+
transformer consumes that line
|
|
48
|
+
- **Insertion defaults**: `defaultBlockWidth={{ table?, drawing? }}` on
|
|
49
|
+
Root applies when the toolbar / `useMarkdownEditor()` inserts a new table
|
|
50
|
+
or drawing. The chosen width is written to the markdown explicitly, even
|
|
51
|
+
`full`, so the document reads the same in an app with other defaults; a
|
|
52
|
+
width named in the source (`<!-- width: full -->`, `"width":"full"`) is
|
|
53
|
+
preserved on round trip
|
|
54
|
+
- **UI / headless**: the floating table toolbar and the drawing toolbar
|
|
55
|
+
offer all three widths with distinct icons (`BLOCK_WIDTH_OPTIONS`).
|
|
56
|
+
`useMarkdownEditor()` gains `blockWidth` / `setBlockWidth` for the block
|
|
57
|
+
containing the selection — the focused drawing or the table the caret is
|
|
58
|
+
in; `insertTable` / `insertDrawing` accept a `width` option. `tableWidth`
|
|
59
|
+
/ `setTableWidth` keep working and are deprecated
|
|
60
|
+
- **CSS**: the new layout lives in zero-specificity `:where()` rules. The
|
|
61
|
+
content pane exposes `--zui-text-editor-gutter` and
|
|
62
|
+
`--zui-text-editor-bleed`; every top-level block reads
|
|
63
|
+
`--zui-text-editor-block-bleed`, so one class rule overrides any block
|
|
64
|
+
kind. New block classes (added next to the existing utility classes):
|
|
65
|
+
`.zui-paragraph`, `.zui-heading` / `.zui-heading-1`…`6`, `.zui-list` /
|
|
66
|
+
`.zui-list-ordered` / `.zui-list-unordered`, `.zui-quote`, `.zui-code`;
|
|
67
|
+
`.zui-drawing-canvas` gains `.is-text-width`. Nothing is renamed
|
|
68
|
+
- New exports: `BLOCK_WIDTHS`, `isBlockWidth`, `BlockWidthDefaults`,
|
|
69
|
+
`TableSettingsOptions`, `$isTableWidthExplicit`; `$setTableSettings` and
|
|
70
|
+
`formatTableSettingsMarker` take an optional `{ explicitWidth }`
|
|
71
|
+
- **Adopting**: set `measure` (or the CSS variable) and delete any external
|
|
72
|
+
`max-width` / `margin-inline` overrides on `.zui-text-editor-content > *`
|
|
73
|
+
|
|
3
74
|
## 0.5.0
|
|
4
75
|
|
|
5
76
|
**Diagram builder rewrite.** The drawing canvas, its payload format and the
|
package/DRAWING_FORMAT.md
CHANGED
|
@@ -41,9 +41,13 @@ skeleton, which is a separate block type.
|
|
|
41
41
|
narrower layouts (SVG viewBox), so coordinates can assume that width.
|
|
42
42
|
When omitted the canvas is fluid and as wide as the editor; keep shapes
|
|
43
43
|
within roughly x in [0, 700] to be safe on typical layouts.
|
|
44
|
-
- `
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
- `width` is the block's horizontal sizing in the page, independent of the
|
|
45
|
+
coordinates: `"full"` (default, omit it) spans the editor pane;
|
|
46
|
+
`"text"` aligns the block with the text column (the same as `"full"`
|
|
47
|
+
unless the app sets a text measure); `"content"` sizes the block to fit
|
|
48
|
+
the rightmost shape (plus a margin), left-aligned with the text. Use
|
|
49
|
+
`"content"` for small diagrams that should not stretch across the page.
|
|
50
|
+
Unknown values are ignored (treated as `"full"`).
|
|
47
51
|
|
|
48
52
|
## Top-level object
|
|
49
53
|
|
|
@@ -52,7 +56,7 @@ skeleton, which is a separate block type.
|
|
|
52
56
|
| `version` | `2` | Literal `2` |
|
|
53
57
|
| `canvasHeight` | `number` | Canvas height in px (min 80) |
|
|
54
58
|
| `canvasWidth` | `number` | Optional logical width in px (min 120); scales to fit when set |
|
|
55
|
-
| `width` | `"full"` \| `"content"` | Optional; default `"full"`. `"content"` fits the shapes' extent |
|
|
59
|
+
| `width` | `"full"` \| `"text"` \| `"content"` | Optional; default `"full"`. `"text"` aligns with the text column, `"content"` fits the shapes' extent |
|
|
56
60
|
| `shapes` | `Shape[]` | Render order: later shapes draw on top |
|
|
57
61
|
|
|
58
62
|
## Shape object
|
|
@@ -197,7 +201,7 @@ one-way: once opened, the document stores the concrete ```drawing block.
|
|
|
197
201
|
```
|
|
198
202
|
{
|
|
199
203
|
"direction"?: "right" | "down", // auto-layout flow, default right
|
|
200
|
-
"canvasWidth"?: n, "canvasHeight"?: n, "width"?: "content",
|
|
204
|
+
"canvasWidth"?: n, "canvasHeight"?: n, "width"?: "full" | "text" | "content",
|
|
201
205
|
"boxes": [ { "id", "type"?: <box type, default rect>, "label"?, "text"?, "footer"?,
|
|
202
206
|
"x"?, "y"?, // omitted: auto layout by connector rank
|
|
203
207
|
"w"?, "h"?, // omitted: sized to fit the text
|
|
@@ -224,6 +228,8 @@ Rules:
|
|
|
224
228
|
them. Boxes without `w`/`h` are sized to fit their text. `canvasHeight`
|
|
225
229
|
is computed when omitted.
|
|
226
230
|
- `texts` are free annotations and need explicit coordinates.
|
|
231
|
+
- `width` is copied to the expanded drawing (see [Coordinate
|
|
232
|
+
system](#coordinate-system)); omit it for `"full"`.
|
|
227
233
|
|
|
228
234
|
A three-box flow:
|
|
229
235
|
|
package/README.md
CHANGED
|
@@ -13,8 +13,9 @@ document outline, and collapsible sections.
|
|
|
13
13
|
blockquotes, links, fenced code (with syntax highlighting), tables
|
|
14
14
|
- **Tables**: GFM pipe tables, edited in place (tab between cells, ranges,
|
|
15
15
|
inline formatting), styled like Claude artifacts
|
|
16
|
-
- **
|
|
17
|
-
|
|
16
|
+
- **Text measure and block width**: an opt-in readable text column
|
|
17
|
+
(`measure="48rem"`); each table and diagram picks *full* / *text* /
|
|
18
|
+
*content* width, Slab-style; row density per table
|
|
18
19
|
- **Diagrams**: a drawing canvas embedded in the document. Eight box
|
|
19
20
|
shapes (rectangle, ellipse, diamond, note, database, cloud, queue, actor)
|
|
20
21
|
with attached text slots, bound arrows that follow their boxes and attach
|
|
@@ -73,6 +74,8 @@ emits. The emitted string is always plain markdown.
|
|
|
73
74
|
| `toolbar` | `boolean \| (items) => ReactNode` | `true` | Formatting/insert toolbar (`edit-md`); function form customises it |
|
|
74
75
|
| `outline` | `boolean` | `false` | Table-of-contents sidebar |
|
|
75
76
|
| `foldable` | `boolean` | `true` | Collapse sections under headings |
|
|
77
|
+
| `measure` | `string` | — | Max width of the text column, a CSS length (`'48rem'` recommended). Sugar for `--zui-text-editor-measure` |
|
|
78
|
+
| `defaultBlockWidth` | `{ table?, drawing? }` | — | `BlockWidth` written when the toolbar inserts a table / drawing |
|
|
76
79
|
|
|
77
80
|
### Modes
|
|
78
81
|
|
|
@@ -101,16 +104,12 @@ Editing is in place: Tab/arrows between cells, cell range selection, inline
|
|
|
101
104
|
formatting inside cells. Cell content is single-line in markdown; newlines
|
|
102
105
|
are escaped as `\n`.
|
|
103
106
|
|
|
104
|
-
### Table
|
|
107
|
+
### Table density
|
|
105
108
|
|
|
106
109
|
Place the caret in a table and a small toolbar floats at its top-right
|
|
107
|
-
corner
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
*content* (the table shrinks to fit its columns, left-aligned with the
|
|
111
|
-
text, never wider than the editor).
|
|
112
|
-
- **Density** — *compact*, *comfortable* (default), or *spacious* cell
|
|
113
|
-
padding and font size.
|
|
110
|
+
corner with the table's width (see [Block width and text
|
|
111
|
+
measure](#block-width-and-text-measure)) and its **density** — *compact*,
|
|
112
|
+
*comfortable* (default), or *spacious* cell padding and font size.
|
|
114
113
|
|
|
115
114
|
Non-default settings are persisted as one HTML comment on the line directly
|
|
116
115
|
above the table — other markdown renderers hide it:
|
|
@@ -122,12 +121,70 @@ above the table — other markdown renderers hide it:
|
|
|
122
121
|
| Region | eu-west-1 |
|
|
123
122
|
```
|
|
124
123
|
|
|
125
|
-
Programmatic access: `useMarkdownEditor().
|
|
126
|
-
|
|
127
|
-
`$
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
124
|
+
Programmatic access: `useMarkdownEditor().tableDensity` / `setTableDensity`
|
|
125
|
+
(for custom toolbars), or `$getTableSettings(node)` /
|
|
126
|
+
`$setTableSettings(node, { width, density })` inside `editor.update`.
|
|
127
|
+
`parseTableSettingsMarker` / `formatTableSettingsMarker` convert between
|
|
128
|
+
the comment line and a `TableSettings` object.
|
|
129
|
+
|
|
130
|
+
## Block width and text measure
|
|
131
|
+
|
|
132
|
+
By default every block spans the content pane. Set a **measure** to get a
|
|
133
|
+
readable text column instead: paragraphs, headings, lists, quotes, code,
|
|
134
|
+
frontmatter are capped at that width and centred in the pane, while each
|
|
135
|
+
table and drawing chooses its own width.
|
|
136
|
+
|
|
137
|
+
```tsx
|
|
138
|
+
<MarkdownEditor value={value} onChange={setValue} measure="48rem" />
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
The prop is sugar for the CSS custom property `--zui-text-editor-measure`,
|
|
142
|
+
which is the actual contract — set it in a stylesheet on `.zui-text-editor`
|
|
143
|
+
(or any ancestor) and never touch the prop:
|
|
144
|
+
|
|
145
|
+
```css
|
|
146
|
+
.zui-text-editor { --zui-text-editor-measure: 48rem; }
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
**Adopting:** set `measure` (or the variable) and delete any external
|
|
150
|
+
`max-width` / `margin-inline` overrides on `.zui-text-editor-content > *`;
|
|
151
|
+
the library now owns that layout.
|
|
152
|
+
|
|
153
|
+
Every table and drawing has a `BlockWidth`, picked from the floating table
|
|
154
|
+
toolbar or the right end of the drawing toolbar:
|
|
155
|
+
|
|
156
|
+
| `BlockWidth` | Layout | Markdown |
|
|
157
|
+
|--------------|--------|----------|
|
|
158
|
+
| `full` | The content pane, edge to edge (never under the outline sidebar). The default | Omitted |
|
|
159
|
+
| `text` | The text column: edges align with the paragraphs. Identical to `full` until a measure is set | `<!-- width: text -->` / `"width":"text"` |
|
|
160
|
+
| `content` | Shrinks to its columns / shapes, left-aligned with the text, never wider than the column | `<!-- width: content -->` / `"width":"content"` |
|
|
161
|
+
|
|
162
|
+
Absence of a marker always means `full`, in every app. `defaultBlockWidth`
|
|
163
|
+
only changes what the toolbar / `insertTable` / `insertDrawing` write into
|
|
164
|
+
*new* blocks — and that value is written explicitly, even when it is
|
|
165
|
+
`full`, so the document reads the same elsewhere:
|
|
166
|
+
|
|
167
|
+
```tsx
|
|
168
|
+
<MarkdownEditor measure="48rem" defaultBlockWidth={{ table: 'text', drawing: 'text' }} … />
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Headless: `useMarkdownEditor().blockWidth` / `setBlockWidth` act on the
|
|
172
|
+
block containing the selection — the focused drawing, or else the table
|
|
173
|
+
the caret is in. (`tableWidth` / `setTableWidth` still work and are
|
|
174
|
+
deprecated in favour of these.)
|
|
175
|
+
|
|
176
|
+
Styling: the layout is driven by low-specificity `:where()` rules and two
|
|
177
|
+
derived custom properties on `.zui-text-editor-main` —
|
|
178
|
+
`--zui-text-editor-gutter` (the pane padding, `2rem` without a measure)
|
|
179
|
+
and `--zui-text-editor-bleed` (how far a full-width block extends past the
|
|
180
|
+
column, `0` without a measure). Each top-level block reads
|
|
181
|
+
`--zui-text-editor-block-bleed`, so a single class rule overrides any block
|
|
182
|
+
kind: `.zui-code { --zui-text-editor-block-bleed: var(--zui-text-editor-bleed) }`
|
|
183
|
+
makes code blocks full width; `.zui-table { --zui-text-editor-block-bleed: 0px }`
|
|
184
|
+
keeps every table inside the column. Block classes: `.zui-paragraph`,
|
|
185
|
+
`.zui-heading` (+ `.zui-heading-1`…`6`), `.zui-list` (+ `-ordered` /
|
|
186
|
+
`-unordered`, `.zui-checklist`), `.zui-quote`, `.zui-code`,
|
|
187
|
+
`.zui-frontmatter`, `.zui-table`, `.zui-drawing`.
|
|
131
188
|
|
|
132
189
|
## Toolbar & custom toolbars
|
|
133
190
|
|
|
@@ -212,10 +269,11 @@ function BoldButton() {
|
|
|
212
269
|
```
|
|
213
270
|
|
|
214
271
|
It returns `editor` (the Lexical instance), `activeFormats`,
|
|
215
|
-
`toggleFormat`, `insertTable`, `insertDrawing`, `
|
|
216
|
-
`
|
|
217
|
-
|
|
218
|
-
`canRedo`, `undo`, `redo`.
|
|
272
|
+
`toggleFormat`, `insertTable`, `insertDrawing`, `blockWidth` /
|
|
273
|
+
`setBlockWidth` (width of the table or drawing containing the selection,
|
|
274
|
+
`null` outside both), `tableDensity` / `setTableDensity` (`null` outside
|
|
275
|
+
tables), `canUndo`, `canRedo`, `undo`, `redo`. `tableWidth` /
|
|
276
|
+
`setTableWidth` remain as deprecated aliases limited to tables.
|
|
219
277
|
|
|
220
278
|
## Diagrams (drawing canvas)
|
|
221
279
|
|
|
@@ -251,10 +309,12 @@ fully specified in **[DRAWING_FORMAT.md](./DRAWING_FORMAT.md)**.
|
|
|
251
309
|
- **Canvas**: resizable height, dot grid, white surface that inverts
|
|
252
310
|
Excalidraw-style in dark mode (`.dark` ancestor class). An optional
|
|
253
311
|
`canvasWidth` scales the drawing to fit narrower layouts.
|
|
254
|
-
- **Width**: the
|
|
255
|
-
between **full
|
|
256
|
-
|
|
257
|
-
|
|
312
|
+
- **Width**: the buttons at the right end of the canvas toolbar switch
|
|
313
|
+
between **full** (spans the pane), **text** (aligns with the text column,
|
|
314
|
+
see [Block width and text measure](#block-width-and-text-measure)) and
|
|
315
|
+
**content** (the canvas fits the rightmost shape and grows as shapes
|
|
316
|
+
move). Stored as `"width":"text"` / `"width":"content"` in the payload;
|
|
317
|
+
omitted when full.
|
|
258
318
|
|
|
259
319
|
A stored drawing looks like this:
|
|
260
320
|
|
|
@@ -293,6 +353,41 @@ The full skeleton spec (attach sides, explicit positions, free texts) is
|
|
|
293
353
|
in [DRAWING_FORMAT.md](./DRAWING_FORMAT.md). Programmatic access:
|
|
294
354
|
`parseDrawingSkeleton`, `expandSkeleton`, `DRAWING_SKELETON_JSON_SCHEMA`.
|
|
295
355
|
|
|
356
|
+
### Theming the canvas
|
|
357
|
+
|
|
358
|
+
The canvas chrome (header, property row, popover, selection handles) is
|
|
359
|
+
styled entirely through `--zui-drawing-*` custom properties. They default
|
|
360
|
+
to the ZUI core tokens (`--primary`, `--foreground`, `--border`,
|
|
361
|
+
`--popover`, `--radius`, `--shadow-medium`, …), so the canvas follows the
|
|
362
|
+
host theme in light and dark mode. Override any of them on
|
|
363
|
+
`.zui-drawing-canvas` or an ancestor:
|
|
364
|
+
|
|
365
|
+
```css
|
|
366
|
+
.my-app .zui-drawing-canvas {
|
|
367
|
+
--zui-drawing-accent: #0f766e; /* selection, active tool, handles */
|
|
368
|
+
--zui-drawing-surface: #fbfbf7; /* drawing area (pre dark-mode filter) */
|
|
369
|
+
--zui-drawing-grid: rgba(0, 0, 0, 0.12);
|
|
370
|
+
--zui-drawing-grid-size: 16px;
|
|
371
|
+
--zui-drawing-font: 'Inter', sans-serif;
|
|
372
|
+
}
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
| Variable | Default | Used for |
|
|
376
|
+
|----------|---------|----------|
|
|
377
|
+
| `--zui-drawing-accent` | `var(--primary)` | Selection frame and handles, active tool, focus ring, bind highlight |
|
|
378
|
+
| `--zui-drawing-foreground` | `var(--foreground)` | Header text and icons |
|
|
379
|
+
| `--zui-drawing-muted-foreground` | `var(--muted-foreground)` | Swatch labels, empty-state hint |
|
|
380
|
+
| `--zui-drawing-border` | `var(--border)` | Block border, header divider, popover border |
|
|
381
|
+
| `--zui-drawing-chrome` | `var(--background)` | Header and property row background |
|
|
382
|
+
| `--zui-drawing-popover` / `-foreground` | `var(--popover)` / `var(--popover-foreground)` | "More shapes" menu |
|
|
383
|
+
| `--zui-drawing-danger` / `--zui-drawing-success` | `var(--destructive)` / `var(--success)` | Delete button, "copied" state |
|
|
384
|
+
| `--zui-drawing-radius` / `--zui-drawing-control-radius` | `var(--radius-lg)` / `var(--radius)` | Block corners / buttons and menus |
|
|
385
|
+
| `--zui-drawing-shadow` | `var(--shadow-medium)` | Popover |
|
|
386
|
+
| `--zui-drawing-font` | system sans | Shape text and the inline editor |
|
|
387
|
+
| `--zui-drawing-surface` / `--zui-drawing-grid` / `--zui-drawing-grid-size` | white / 9% black / `20px` | Drawing area and its dot grid, before the dark filter |
|
|
388
|
+
| `--zui-drawing-dark-filter` | `invert(93%) hue-rotate(180deg)` | Applied to the drawing area under `.dark`; set to `none` to opt out |
|
|
389
|
+
| `--zui-drawing-hover` / `--zui-drawing-active` | `currentColor` 8% / 12% | Button hover and pressed backgrounds |
|
|
390
|
+
|
|
296
391
|
## Outline & section folding
|
|
297
392
|
|
|
298
393
|
`outline` docks a collapsible table-of-contents sidebar: live heading list
|
|
@@ -335,8 +430,9 @@ diagrams:
|
|
|
335
430
|
| `Toolbar`, `ToolbarButton`, `ToolbarDivider`, `FormatButtons`, `InsertButtons`, `HistoryButtons` | Toolbar primitives |
|
|
336
431
|
| `@zuilib/text-editor/styles.css` | Editor chrome + theme styles (required) |
|
|
337
432
|
| `TABLE` | GFM table markdown transformer |
|
|
338
|
-
| `BlockWidth`, `
|
|
339
|
-
|
|
|
433
|
+
| `BlockWidth`, `BLOCK_WIDTHS`, `isBlockWidth`, `BlockWidthDefaults` | Block width (`full` / `text` / `content`) type, values, guard, insertion defaults |
|
|
434
|
+
| `TableDensity`, `TableSettings`, `TableSettingsOptions`, `DEFAULT_TABLE_SETTINGS` | Table setting types |
|
|
435
|
+
| `$getTableSettings`, `$setTableSettings`, `$isTableWidthExplicit`, `$getTableWidth`, `$setTableWidth`, `$getTableDensity`, `$setTableDensity`, `$getSelectedTable` | Table setting helpers (inside `editor.update`/`read`) |
|
|
340
436
|
| `parseTableSettingsMarker`, `formatTableSettingsMarker` | Marker comment ⇄ `TableSettings` |
|
|
341
437
|
| `DRAWING`, `DIAGRAM`, `DrawingNode`, `$createDrawingNode`, `$isDrawingNode` | Drawing node + markdown transformers (` ```drawing ` and ` ```diagram `) |
|
|
342
438
|
| `FRONTMATTER`, `FrontmatterNode`, `$createFrontmatterNode`, `$isFrontmatterNode` | Frontmatter node + transformer |
|
package/dist/index.d.ts
CHANGED
|
@@ -4,7 +4,33 @@ import { LexicalEditor, TextFormatType, ElementNode, NodeKey, EditorConfig, Seri
|
|
|
4
4
|
import { TableNode } from '@lexical/table';
|
|
5
5
|
import { MultilineElementTransformer, ElementTransformer } from '@lexical/markdown';
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Horizontal sizing of a block that would otherwise span the editor:
|
|
9
|
+
*
|
|
10
|
+
* - `full` — the container width (the content pane, minus its gutters).
|
|
11
|
+
* The default; omitted when serialised.
|
|
12
|
+
* - `text` — the text column: the block's edges align with the paragraphs
|
|
13
|
+
* around it. Only differs from `full` when a measure is set
|
|
14
|
+
* (`--zui-text-editor-measure` / the `measure` prop); otherwise the two
|
|
15
|
+
* are visually identical.
|
|
16
|
+
* - `content` — shrinks to fit what is inside (table columns, drawing
|
|
17
|
+
* shapes), left-aligned with the text and never wider than the column.
|
|
18
|
+
*/
|
|
19
|
+
type BlockWidth = 'full' | 'text' | 'content';
|
|
20
|
+
declare const BLOCK_WIDTHS: readonly BlockWidth[];
|
|
21
|
+
declare function isBlockWidth(value: unknown): value is BlockWidth;
|
|
22
|
+
/**
|
|
23
|
+
* Width written into the markdown when a new table / drawing is inserted
|
|
24
|
+
* (`MarkdownEditor.Root`'s `defaultBlockWidth`). Only affects insertion:
|
|
25
|
+
* existing markdown without a width marker always means `full`.
|
|
26
|
+
*/
|
|
27
|
+
type BlockWidthDefaults = Readonly<{
|
|
28
|
+
table?: BlockWidth;
|
|
29
|
+
drawing?: BlockWidth;
|
|
30
|
+
}>;
|
|
31
|
+
|
|
7
32
|
type EditorMode = 'edit-raw' | 'edit-md' | 'view';
|
|
33
|
+
|
|
8
34
|
type EditorRootProps = Readonly<{
|
|
9
35
|
value?: string;
|
|
10
36
|
onChange?: (value: string) => void;
|
|
@@ -12,6 +38,22 @@ type EditorRootProps = Readonly<{
|
|
|
12
38
|
className?: string;
|
|
13
39
|
mode?: EditorMode;
|
|
14
40
|
autoFocus?: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Text measure: the maximum width of the text column, as a CSS length
|
|
43
|
+
* (`'48rem'` recommended). Text blocks are capped at this width and
|
|
44
|
+
* centred; tables and drawings choose per block whether to align with
|
|
45
|
+
* the column (`text`), span the pane (`full`) or hug their content.
|
|
46
|
+
* Sugar for setting `--zui-text-editor-measure` on the root; the
|
|
47
|
+
* variable can equally be set from a stylesheet. Unset: no measure, every
|
|
48
|
+
* block spans the pane.
|
|
49
|
+
*/
|
|
50
|
+
measure?: string;
|
|
51
|
+
/**
|
|
52
|
+
* Width written into the markdown when the toolbar or
|
|
53
|
+
* `useMarkdownEditor()` inserts a new table / drawing. Only affects
|
|
54
|
+
* insertion — markdown without a width marker always means `full`.
|
|
55
|
+
*/
|
|
56
|
+
defaultBlockWidth?: BlockWidthDefaults;
|
|
15
57
|
children: ReactNode;
|
|
16
58
|
}>;
|
|
17
59
|
/**
|
|
@@ -19,7 +61,7 @@ type EditorRootProps = Readonly<{
|
|
|
19
61
|
* beneath it (`Content`, `Toolbar`, `Outline`, or your own components using
|
|
20
62
|
* `useMarkdownEditor`) shares the same editor instance.
|
|
21
63
|
*/
|
|
22
|
-
declare function EditorRoot({ value, onChange, readOnly, className, mode, autoFocus, children, }: EditorRootProps): ReactElement;
|
|
64
|
+
declare function EditorRoot({ value, onChange, readOnly, className, mode, autoFocus, measure, defaultBlockWidth, children, }: EditorRootProps): ReactElement;
|
|
23
65
|
|
|
24
66
|
type EditorContentProps = Readonly<{
|
|
25
67
|
placeholder?: string;
|
|
@@ -41,13 +83,6 @@ declare function EditorContent({ placeholder, foldable, children, }: EditorConte
|
|
|
41
83
|
*/
|
|
42
84
|
declare function OutlinePlugin(): ReactElement;
|
|
43
85
|
|
|
44
|
-
/**
|
|
45
|
-
* Horizontal sizing of a block that would otherwise span the editor:
|
|
46
|
-
* `full` stretches to the content column, `content` shrinks to fit what is
|
|
47
|
-
* inside (table columns, drawing shapes) and left-aligns with the text.
|
|
48
|
-
*/
|
|
49
|
-
type BlockWidth = 'full' | 'content';
|
|
50
|
-
|
|
51
86
|
/** Cell padding / font size preset */
|
|
52
87
|
type TableDensity = 'compact' | 'comfortable' | 'spacious';
|
|
53
88
|
type TableSettings = Readonly<{
|
|
@@ -55,8 +90,14 @@ type TableSettings = Readonly<{
|
|
|
55
90
|
density: TableDensity;
|
|
56
91
|
}>;
|
|
57
92
|
declare const DEFAULT_TABLE_SETTINGS: TableSettings;
|
|
93
|
+
type TableSettingsOptions = Readonly<{
|
|
94
|
+
/** Persist the width even when it is `full` */
|
|
95
|
+
explicitWidth?: boolean;
|
|
96
|
+
}>;
|
|
58
97
|
declare function $getTableSettings(table: TableNode): TableSettings;
|
|
59
|
-
declare function $setTableSettings(table: TableNode, settings: Partial<TableSettings
|
|
98
|
+
declare function $setTableSettings(table: TableNode, settings: Partial<TableSettings>, options?: TableSettingsOptions): void;
|
|
99
|
+
/** Whether the table's width should be persisted even when it is `full` */
|
|
100
|
+
declare function $isTableWidthExplicit(table: TableNode): boolean;
|
|
60
101
|
declare function $getTableWidth(table: TableNode): BlockWidth;
|
|
61
102
|
declare function $setTableWidth(table: TableNode, width: BlockWidth): void;
|
|
62
103
|
declare function $getTableDensity(table: TableNode): TableDensity;
|
|
@@ -65,10 +106,17 @@ declare function $setTableDensity(table: TableNode, density: TableDensity): void
|
|
|
65
106
|
declare function $getSelectedTable(): TableNode | null;
|
|
66
107
|
/** @deprecated Use `formatTableSettingsMarker({ ...DEFAULT_TABLE_SETTINGS, width: 'content' })` */
|
|
67
108
|
declare const TABLE_WIDTH_MARKER = "<!-- width: content -->";
|
|
68
|
-
/**
|
|
109
|
+
/**
|
|
110
|
+
* Settings encoded in a marker line, or null if the text is not a marker.
|
|
111
|
+
* A marker naming a known setting with an unknown value yields that setting
|
|
112
|
+
* omitted (possibly an empty object): the line is still a settings marker.
|
|
113
|
+
*/
|
|
69
114
|
declare function parseTableSettingsMarker(text: string): Partial<TableSettings> | null;
|
|
70
|
-
/**
|
|
71
|
-
|
|
115
|
+
/**
|
|
116
|
+
* Marker line for the given settings, or null when everything is default.
|
|
117
|
+
* With `explicitWidth` the width is listed even when it is `full`.
|
|
118
|
+
*/
|
|
119
|
+
declare function formatTableSettingsMarker(settings: TableSettings, options?: TableSettingsOptions): string | null;
|
|
72
120
|
|
|
73
121
|
type MarkdownEditorApi = Readonly<{
|
|
74
122
|
/** The underlying Lexical editor, for dispatching your own commands */
|
|
@@ -76,14 +124,40 @@ type MarkdownEditorApi = Readonly<{
|
|
|
76
124
|
/** Text formats active at the current selection */
|
|
77
125
|
activeFormats: ReadonlySet<TextFormatType>;
|
|
78
126
|
toggleFormat: (format: TextFormatType) => void;
|
|
127
|
+
/**
|
|
128
|
+
* Insert a table at the selection. `width` defaults to
|
|
129
|
+
* `defaultBlockWidth.table` (Root prop); when given it is written to the
|
|
130
|
+
* markdown explicitly, even when `full`.
|
|
131
|
+
*/
|
|
79
132
|
insertTable: (options?: {
|
|
80
133
|
rows?: number;
|
|
81
134
|
columns?: number;
|
|
135
|
+
width?: BlockWidth;
|
|
82
136
|
}) => void;
|
|
83
|
-
|
|
84
|
-
|
|
137
|
+
/**
|
|
138
|
+
* Insert an empty drawing at the selection. `width` defaults to
|
|
139
|
+
* `defaultBlockWidth.drawing` (Root prop); when given it is written to
|
|
140
|
+
* the markdown explicitly, even when `full`.
|
|
141
|
+
*/
|
|
142
|
+
insertDrawing: (options?: {
|
|
143
|
+
width?: BlockWidth;
|
|
144
|
+
}) => void;
|
|
145
|
+
/**
|
|
146
|
+
* Width of the block containing the selection — the focused drawing, or
|
|
147
|
+
* else the table the caret is in; `null` outside both.
|
|
148
|
+
*/
|
|
149
|
+
blockWidth: BlockWidth | null;
|
|
150
|
+
/** Resize that block; no-op when `blockWidth` is `null` */
|
|
151
|
+
setBlockWidth: (width: BlockWidth) => void;
|
|
152
|
+
/**
|
|
153
|
+
* Width of the table containing the selection; `null` outside tables.
|
|
154
|
+
* @deprecated Use `blockWidth`, which also covers drawings.
|
|
155
|
+
*/
|
|
85
156
|
tableWidth: BlockWidth | null;
|
|
86
|
-
/**
|
|
157
|
+
/**
|
|
158
|
+
* Resize the table containing the selection; no-op outside tables.
|
|
159
|
+
* @deprecated Use `setBlockWidth`, which also covers drawings.
|
|
160
|
+
*/
|
|
87
161
|
setTableWidth: (width: BlockWidth) => void;
|
|
88
162
|
/** Density of the table containing the selection; `null` outside tables */
|
|
89
163
|
tableDensity: TableDensity | null;
|
|
@@ -283,8 +357,10 @@ type DrawingData = Readonly<{
|
|
|
283
357
|
canvasWidth?: number;
|
|
284
358
|
canvasHeight: number;
|
|
285
359
|
/**
|
|
286
|
-
* Block width: `full` (default
|
|
287
|
-
*
|
|
360
|
+
* Block width: `full` (default) spans the editor; `text` aligns with the
|
|
361
|
+
* text column; `content` fits the shapes' horizontal extent. The editor
|
|
362
|
+
* omits `full` unless it was written explicitly (an insertion default or
|
|
363
|
+
* the source payload); unknown values are dropped.
|
|
288
364
|
*/
|
|
289
365
|
width?: BlockWidth;
|
|
290
366
|
shapes: readonly DrawingShape[];
|
|
@@ -350,7 +426,7 @@ declare const DIAGRAM: MultilineElementTransformer;
|
|
|
350
426
|
* Markdown transformer for GFM tables. Adapted from the Lexical playground.
|
|
351
427
|
* Rows are matched line-by-line on import and stitched into a single
|
|
352
428
|
* TableNode; the divider row promotes the row above it to a header row.
|
|
353
|
-
* A `<!-- width:
|
|
429
|
+
* A `<!-- width: text; density: compact -->` settings line directly
|
|
354
430
|
* above the table (see tableSettings.ts) is consumed on import and
|
|
355
431
|
* re-emitted on export.
|
|
356
432
|
*/
|
|
@@ -392,8 +468,8 @@ declare const DRAWING_DATA_JSON_SCHEMA: {
|
|
|
392
468
|
readonly description: "Optional logical canvas width in pixels. When set, the drawing is scaled down to fit narrower layouts (SVG viewBox) so coordinates can assume this width. When omitted the canvas is fluid and coordinates are CSS pixels.";
|
|
393
469
|
};
|
|
394
470
|
readonly width: {
|
|
395
|
-
readonly enum: readonly ["full", "content"];
|
|
396
|
-
readonly description: "Block width: \"full\" (default, omit it) spans the editor; \"content\" fits the shapes' horizontal extent and left-aligns with the text";
|
|
471
|
+
readonly enum: readonly ["full", "text", "content"];
|
|
472
|
+
readonly description: "Block width: \"full\" (default, omit it) spans the editor; \"text\" aligns the block with the text column (same as \"full\" unless the app sets a text measure); \"content\" fits the shapes' horizontal extent and left-aligns with the text";
|
|
397
473
|
};
|
|
398
474
|
readonly shapes: {
|
|
399
475
|
readonly type: "array";
|
|
@@ -595,6 +671,13 @@ type BoxDefinition = Readonly<{
|
|
|
595
671
|
}>;
|
|
596
672
|
declare const BOX_DEFINITIONS: Record<BoxType, BoxDefinition>;
|
|
597
673
|
|
|
674
|
+
/**
|
|
675
|
+
* Skeleton (intent) layer: a compact, LLM-friendly description of a diagram
|
|
676
|
+
* — boxes, connectors between them and loose texts — that expands into a
|
|
677
|
+
* full `DrawingData` document. Sizes, positions and connector geometry are
|
|
678
|
+
* derived, so a generator only needs to say *what* is on the canvas.
|
|
679
|
+
*/
|
|
680
|
+
|
|
598
681
|
type ColorName = 'gray' | 'red' | 'green' | 'blue' | 'orange' | 'purple';
|
|
599
682
|
declare const COLOR_PRESETS: Record<ColorName, {
|
|
600
683
|
stroke: string;
|
|
@@ -648,7 +731,8 @@ type DrawingSkeleton = Readonly<{
|
|
|
648
731
|
direction?: 'right' | 'down';
|
|
649
732
|
canvasWidth?: number;
|
|
650
733
|
canvasHeight?: number;
|
|
651
|
-
width
|
|
734
|
+
/** Block width of the expanded drawing; omit for `full` */
|
|
735
|
+
width?: BlockWidth;
|
|
652
736
|
boxes: readonly SkeletonBox[];
|
|
653
737
|
connectors?: readonly SkeletonConnector[];
|
|
654
738
|
texts?: readonly SkeletonText[];
|
|
@@ -685,8 +769,8 @@ declare const DRAWING_SKELETON_JSON_SCHEMA: {
|
|
|
685
769
|
readonly description: "Canvas height in px. Omit to fit the content";
|
|
686
770
|
};
|
|
687
771
|
readonly width: {
|
|
688
|
-
readonly enum: readonly ["content"];
|
|
689
|
-
readonly description: "Block width: \"content\" fits the drawing to its shapes and left-aligns it with the text; omit to span the editor";
|
|
772
|
+
readonly enum: readonly ["full", "text", "content"];
|
|
773
|
+
readonly description: "Block width: \"text\" aligns the drawing with the text column (same as \"full\" unless the app sets a text measure); \"content\" fits the drawing to its shapes and left-aligns it with the text; omit to span the editor";
|
|
690
774
|
};
|
|
691
775
|
readonly boxes: {
|
|
692
776
|
readonly type: "array";
|
|
@@ -891,4 +975,4 @@ type MermaidOptions = Readonly<{
|
|
|
891
975
|
*/
|
|
892
976
|
declare function drawingToMermaid(data: DrawingData, options?: MermaidOptions): string;
|
|
893
977
|
|
|
894
|
-
export { $createDrawingNode, $createFrontmatterNode, $getSelectedTable, $getTableDensity, $getTableSettings, $getTableWidth, $isDrawingNode, $isFrontmatterNode, $setTableDensity, $setTableSettings, $setTableWidth, BOX_DEFINITIONS, BOX_TYPES, type Binding, type BindingSide, type BlockWidth, type BoxDefinition, type BoxType, COLOR_PRESETS, CONNECTOR_TYPES, type ColorName, type ConnectorType, DEFAULT_TABLE_SETTINGS, DIAGRAM, DRAWING, DRAWING_DATA_JSON_SCHEMA, DRAWING_SKELETON_JSON_SCHEMA, type DrawingData, DrawingNode, type DrawingShape, type DrawingShapeType, type DrawingSkeleton, EMPTY_DRAWING, type EditorContentProps, type EditorMode, type EditorRootProps, FILL_COLORS, FRONTMATTER, FormatButtons, FrontmatterNode, HistoryButtons, InsertButtons, MarkdownEditor, type MarkdownEditorApi, type Props as MarkdownEditorProps, type MermaidDirection, type MermaidOptions, type Point, SHAPE_TYPES, SIDE_FIXED_POINTS, STROKE_COLORS, type SerializedDrawingNode, type SerializedFrontmatterNode, type SkeletonBox, type SkeletonConnector, type SkeletonEnd, type SkeletonText, TABLE, TABLE_WIDTH_MARKER, type TableDensity, type TableSettings, type TextField, Toolbar, ToolbarButton, ToolbarDivider, type ToolbarItems, anchorPoint, bindEndpoints, boxOutline, connectorPoints, drawingToMermaid, expandSkeleton, findBoxAt, fixedPointFor, formatTableSettingsMarker, isDrawingSkeleton, makeBinding, normalizeDrawingData, parseDrawingData, parseDrawingSkeleton, parseTableSettingsMarker, resolveBindings, routeElbow, serializeDrawingData, useMarkdownEditor };
|
|
978
|
+
export { $createDrawingNode, $createFrontmatterNode, $getSelectedTable, $getTableDensity, $getTableSettings, $getTableWidth, $isDrawingNode, $isFrontmatterNode, $isTableWidthExplicit, $setTableDensity, $setTableSettings, $setTableWidth, BLOCK_WIDTHS, BOX_DEFINITIONS, BOX_TYPES, type Binding, type BindingSide, type BlockWidth, type BlockWidthDefaults, type BoxDefinition, type BoxType, COLOR_PRESETS, CONNECTOR_TYPES, type ColorName, type ConnectorType, DEFAULT_TABLE_SETTINGS, DIAGRAM, DRAWING, DRAWING_DATA_JSON_SCHEMA, DRAWING_SKELETON_JSON_SCHEMA, type DrawingData, DrawingNode, type DrawingShape, type DrawingShapeType, type DrawingSkeleton, EMPTY_DRAWING, type EditorContentProps, type EditorMode, type EditorRootProps, FILL_COLORS, FRONTMATTER, FormatButtons, FrontmatterNode, HistoryButtons, InsertButtons, MarkdownEditor, type MarkdownEditorApi, type Props as MarkdownEditorProps, type MermaidDirection, type MermaidOptions, type Point, SHAPE_TYPES, SIDE_FIXED_POINTS, STROKE_COLORS, type SerializedDrawingNode, type SerializedFrontmatterNode, type SkeletonBox, type SkeletonConnector, type SkeletonEnd, type SkeletonText, TABLE, TABLE_WIDTH_MARKER, type TableDensity, type TableSettings, type TableSettingsOptions, type TextField, Toolbar, ToolbarButton, ToolbarDivider, type ToolbarItems, anchorPoint, bindEndpoints, boxOutline, connectorPoints, drawingToMermaid, expandSkeleton, findBoxAt, fixedPointFor, formatTableSettingsMarker, isBlockWidth, isDrawingSkeleton, makeBinding, normalizeDrawingData, parseDrawingData, parseDrawingSkeleton, parseTableSettingsMarker, resolveBindings, routeElbow, serializeDrawingData, useMarkdownEditor };
|