@zuilib/text-editor 0.3.0 → 0.3.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/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # Changelog — @zuilib/text-editor
2
2
 
3
+ ## 0.4.0
4
+
5
+ - **Block width** for tables and drawings: switch any table or drawing
6
+ between *full width* (spans the editor, the previous behaviour) and
7
+ *content width* (shrinks to fit its columns / shapes, left-aligned with
8
+ the text), Slab-style
9
+ - Tables: a floating toggle docks to the top-right of the table the caret
10
+ is in; content width sizes columns by their content. Persisted as a
11
+ `<!-- width: content -->` line directly above the GFM table (hidden by
12
+ other markdown renderers)
13
+ - Drawings: toggle at the right end of the canvas toolbar; content width
14
+ fits the rightmost shape and grows as shapes move. Persisted as a
15
+ top-level `"width":"content"` field in the ```drawing payload
16
+ (`DrawingData.width`, `DRAWING_DATA_JSON_SCHEMA` updated; omitted when
17
+ full, so existing payloads are unchanged)
18
+ - `useMarkdownEditor()` gains `tableWidth` / `setTableWidth` for custom
19
+ toolbars
20
+ - New exports: `BlockWidth`, `$getTableWidth`, `$setTableWidth`,
21
+ `$getSelectedTable`, `TABLE_WIDTH_MARKER`
22
+
3
23
  ## 0.3.0
4
24
 
5
25
  - **Custom toolbars**
package/DRAWING_FORMAT.md CHANGED
@@ -22,8 +22,12 @@ degrades to an empty canvas (invalid shapes are dropped individually).
22
22
 
23
23
  - Origin `(0,0)` is the canvas's top-left; x grows right, y grows down.
24
24
  - Units are CSS pixels.
25
- - The canvas is as wide as the editor (fluid). Keep shapes within roughly
26
- x ∈ [0, 700] to be safe on typical layouts.
25
+ - The canvas is as wide as the editor by default (`width` omitted or
26
+ `"full"`). Keep shapes within roughly x ∈ [0, 700] to be safe on typical
27
+ layouts.
28
+ - `"width":"content"` instead sizes the canvas to fit the rightmost shape
29
+ (plus a margin, never narrower than 240px), left-aligned with the text —
30
+ use it for small diagrams that shouldn't stretch across the page.
27
31
  - `height` is the canvas height in pixels (minimum 80; 300–400 is typical).
28
32
 
29
33
  ## Top-level object
@@ -32,6 +36,7 @@ degrades to an empty canvas (invalid shapes are dropped individually).
32
36
  |-----------|-----------|-----------------------------------------|
33
37
  | `version` | `1` | Literal `1` |
34
38
  | `height` | `number` | Canvas height in px |
39
+ | `width` | `"full"` \| `"content"` | Optional; default `"full"`. `"content"` fits the shapes' extent |
35
40
  | `shapes` | `Shape[]` | Render order: later shapes draw on top |
36
41
 
37
42
  ## Shape object
package/README.md CHANGED
@@ -13,6 +13,8 @@ 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
+ - **Block width**: tables and diagrams switch between full width and
17
+ content width, Slab-style
16
18
  - **Diagrams**: a drawing canvas embedded in the document — cards with
17
19
  attached text slots, bound arrows that follow their cards, elbow and
18
20
  multi-waypoint routing, labels, color palettes, dark mode
@@ -96,6 +98,27 @@ Editing is in place: Tab/arrows between cells, cell range selection, inline
96
98
  formatting inside cells. Cell content is single-line in markdown; newlines
97
99
  are escaped as `\n`.
98
100
 
101
+ ### Full width vs content width
102
+
103
+ Tables span the editor by default. Place the caret in a table and a small
104
+ toggle floats at its top-right corner: **full width** (columns share the
105
+ editor width) or **content width** (the table shrinks to fit its columns,
106
+ left-aligned with the text, never wider than the editor). The setting is
107
+ persisted as an HTML comment on the line directly above the table — other
108
+ markdown renderers hide it:
109
+
110
+ ```md
111
+ <!-- width: content -->
112
+ | Key | Value |
113
+ | --- | --- |
114
+ | Region | eu-west-1 |
115
+ ```
116
+
117
+ Programmatic access: `useMarkdownEditor().tableWidth` / `setTableWidth`
118
+ (for custom toolbars), or `$getTableWidth(node)` / `$setTableWidth(node,
119
+ width)` inside `editor.update`. The marker string is exported as
120
+ `TABLE_WIDTH_MARKER`.
121
+
99
122
  ## Toolbar & custom toolbars
100
123
 
101
124
  In `edit-md` mode a toolbar offers inline formatting (bold, italic,
@@ -179,8 +202,9 @@ function BoldButton() {
179
202
  ```
180
203
 
181
204
  It returns `editor` (the Lexical instance), `activeFormats`,
182
- `toggleFormat`, `insertTable`, `insertDrawing`, `canUndo`, `canRedo`,
183
- `undo`, `redo`.
205
+ `toggleFormat`, `insertTable`, `insertDrawing`, `tableWidth` /
206
+ `setTableWidth` (width of the table containing the selection, `null`
207
+ outside tables), `canUndo`, `canRedo`, `undo`, `redo`.
184
208
 
185
209
  ## Diagrams (drawing canvas)
186
210
 
@@ -203,6 +227,10 @@ in the markdown as a ` ```drawing ` fenced JSON block, fully specified in
203
227
  bends). One-way / two-way arrowhead toggle; midpoint **labels**.
204
228
  - **Canvas**: resizable height, dot grid, white surface that inverts
205
229
  Excalidraw-style in dark mode (`.dark` ancestor class).
230
+ - **Width**: the toggle at the right end of the canvas toolbar switches
231
+ between **full width** (spans the editor) and **content width** (the
232
+ canvas fits the rightmost shape and grows as shapes move). Stored as
233
+ `"width":"content"` in the payload; omitted when full.
206
234
 
207
235
  ## Outline & section folding
208
236
 
@@ -241,6 +269,7 @@ diagrams:
241
269
  | `Toolbar`, `ToolbarButton`, `ToolbarDivider`, `FormatButtons`, `InsertButtons`, `HistoryButtons` | Toolbar primitives |
242
270
  | `@zuilib/text-editor/styles.css` | Editor chrome + theme styles (required) |
243
271
  | `TABLE` | GFM table markdown transformer |
272
+ | `BlockWidth`, `$getTableWidth`, `$setTableWidth`, `$getSelectedTable`, `TABLE_WIDTH_MARKER` | Table full/content width helpers |
244
273
  | `DRAWING`, `DrawingNode`, `$createDrawingNode`, `$isDrawingNode` | Drawing node + markdown transformer |
245
274
  | `FRONTMATTER`, `FrontmatterNode`, `$createFrontmatterNode`, `$isFrontmatterNode` | Frontmatter node + transformer |
246
275
  | `DrawingData`, `DrawingShape`, `DrawingShapeType` | Drawing payload types |
package/dist/index.d.ts CHANGED
@@ -2,6 +2,7 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { ReactNode, ReactElement } from 'react';
3
3
  import { LexicalEditor, TextFormatType, ElementNode, NodeKey, EditorConfig, SerializedElementNode, LexicalNode, DecoratorNode, Spread, SerializedLexicalNode, DOMExportOutput, DOMConversionMap } from 'lexical';
4
4
  import { MultilineElementTransformer, ElementTransformer } from '@lexical/markdown';
5
+ import { TableNode } from '@lexical/table';
5
6
 
6
7
  type EditorMode = 'edit-raw' | 'edit-md' | 'view';
7
8
  type EditorRootProps = Readonly<{
@@ -40,6 +41,13 @@ declare function EditorContent({ placeholder, foldable, children, }: EditorConte
40
41
  */
41
42
  declare function OutlinePlugin(): ReactElement;
42
43
 
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
+
43
51
  type MarkdownEditorApi = Readonly<{
44
52
  /** The underlying Lexical editor, for dispatching your own commands */
45
53
  editor: LexicalEditor;
@@ -51,6 +59,10 @@ type MarkdownEditorApi = Readonly<{
51
59
  columns?: number;
52
60
  }) => void;
53
61
  insertDrawing: () => void;
62
+ /** Width of the table containing the selection; `null` outside tables */
63
+ tableWidth: BlockWidth | null;
64
+ /** Resize the table containing the selection; no-op outside tables */
65
+ setTableWidth: (width: BlockWidth) => void;
54
66
  canUndo: boolean;
55
67
  canRedo: boolean;
56
68
  undo: () => void;
@@ -213,6 +225,11 @@ type DrawingShape = Readonly<{
213
225
  type DrawingData = Readonly<{
214
226
  version: 1;
215
227
  height: number;
228
+ /**
229
+ * Canvas width: `full` (default, omitted when serialized) spans the editor;
230
+ * `content` fits the shapes' horizontal extent.
231
+ */
232
+ width?: BlockWidth;
216
233
  shapes: readonly DrawingShape[];
217
234
  }>;
218
235
  declare function serializeDrawingData(data: DrawingData): string;
@@ -257,9 +274,23 @@ declare const DRAWING: MultilineElementTransformer;
257
274
  * Markdown transformer for GFM tables. Adapted from the Lexical playground.
258
275
  * Rows are matched line-by-line on import and stitched into a single
259
276
  * TableNode; the divider row promotes the row above it to a header row.
277
+ * A `<!-- width: content -->` line directly above the table marks it as
278
+ * content-width (see tableWidth.ts); it is consumed on import and re-emitted
279
+ * on export.
260
280
  */
261
281
  declare const TABLE: ElementTransformer;
262
282
 
283
+ /**
284
+ * A content-width table is persisted in markdown as a GFM table preceded by
285
+ * this HTML comment on its own line. Renderers that don't know the marker
286
+ * simply hide the comment.
287
+ */
288
+ declare const TABLE_WIDTH_MARKER = "<!-- width: content -->";
289
+ declare function $getTableWidth(table: TableNode): BlockWidth;
290
+ declare function $setTableWidth(table: TableNode, width: BlockWidth): void;
291
+ /** The table containing the current selection (caret or cell range), if any */
292
+ declare function $getSelectedTable(): TableNode | null;
293
+
263
294
  /**
264
295
  * JSON Schema (draft-07) for the payload of a ```drawing fenced block.
265
296
  *
@@ -282,7 +313,11 @@ declare const DRAWING_DATA_JSON_SCHEMA: {
282
313
  readonly height: {
283
314
  readonly type: "number";
284
315
  readonly minimum: 80;
285
- readonly description: "Canvas height in pixels (width is fluid)";
316
+ readonly description: "Canvas height in pixels";
317
+ };
318
+ readonly width: {
319
+ readonly enum: readonly ["full", "content"];
320
+ readonly description: "Canvas width: \"full\" (default) spans the editor; \"content\" fits the shapes' horizontal extent and left-aligns with the text";
286
321
  };
287
322
  readonly shapes: {
288
323
  readonly type: "array";
@@ -392,4 +427,4 @@ declare const DRAWING_DATA_JSON_SCHEMA: {
392
427
  };
393
428
  };
394
429
 
395
- export { $createDrawingNode, $createFrontmatterNode, $isDrawingNode, $isFrontmatterNode, DRAWING, DRAWING_DATA_JSON_SCHEMA, type DrawingData, DrawingNode, type DrawingShape, type DrawingShapeType, type EditorContentProps, type EditorMode, type EditorRootProps, FRONTMATTER, FormatButtons, FrontmatterNode, HistoryButtons, InsertButtons, MarkdownEditor, type MarkdownEditorApi, type Props as MarkdownEditorProps, type SerializedDrawingNode, type SerializedFrontmatterNode, TABLE, Toolbar, ToolbarButton, ToolbarDivider, type ToolbarItems, parseDrawingData, serializeDrawingData, useMarkdownEditor };
430
+ export { $createDrawingNode, $createFrontmatterNode, $getSelectedTable, $getTableWidth, $isDrawingNode, $isFrontmatterNode, $setTableWidth, type BlockWidth, DRAWING, DRAWING_DATA_JSON_SCHEMA, type DrawingData, DrawingNode, type DrawingShape, type DrawingShapeType, type EditorContentProps, type EditorMode, type EditorRootProps, FRONTMATTER, FormatButtons, FrontmatterNode, HistoryButtons, InsertButtons, MarkdownEditor, type MarkdownEditorApi, type Props as MarkdownEditorProps, type SerializedDrawingNode, type SerializedFrontmatterNode, TABLE, TABLE_WIDTH_MARKER, Toolbar, ToolbarButton, ToolbarDivider, type ToolbarItems, parseDrawingData, serializeDrawingData, useMarkdownEditor };