@zuilib/text-editor 0.2.0 → 0.3.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 +58 -0
- package/DRAWING_FORMAT.md +149 -0
- package/README.md +208 -130
- package/dist/index.d.ts +254 -9
- package/dist/index.js +956 -708
- package/dist/styles.css +6 -0
- package/package.json +10 -8
package/dist/index.d.ts
CHANGED
|
@@ -1,24 +1,135 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import {
|
|
2
|
+
import { ReactNode, ReactElement } from 'react';
|
|
3
|
+
import { LexicalEditor, TextFormatType, ElementNode, NodeKey, EditorConfig, SerializedElementNode, LexicalNode, DecoratorNode, Spread, SerializedLexicalNode, DOMExportOutput, DOMConversionMap } from 'lexical';
|
|
3
4
|
import { MultilineElementTransformer, ElementTransformer } from '@lexical/markdown';
|
|
4
|
-
import { ReactElement } from 'react';
|
|
5
5
|
|
|
6
|
-
type
|
|
6
|
+
type EditorMode = 'edit-raw' | 'edit-md' | 'view';
|
|
7
|
+
type EditorRootProps = Readonly<{
|
|
7
8
|
value?: string;
|
|
8
9
|
onChange?: (value: string) => void;
|
|
9
|
-
placeholder?: string;
|
|
10
10
|
readOnly?: boolean;
|
|
11
11
|
className?: string;
|
|
12
|
-
mode?:
|
|
12
|
+
mode?: EditorMode;
|
|
13
13
|
autoFocus?: boolean;
|
|
14
|
-
|
|
15
|
-
|
|
14
|
+
children: ReactNode;
|
|
15
|
+
}>;
|
|
16
|
+
/**
|
|
17
|
+
* Owns the Lexical composer and every non-visual plugin. Anything rendered
|
|
18
|
+
* beneath it (`Content`, `Toolbar`, `Outline`, or your own components using
|
|
19
|
+
* `useMarkdownEditor`) shares the same editor instance.
|
|
20
|
+
*/
|
|
21
|
+
declare function EditorRoot({ value, onChange, readOnly, className, mode, autoFocus, children, }: EditorRootProps): ReactElement;
|
|
22
|
+
|
|
23
|
+
type EditorContentProps = Readonly<{
|
|
24
|
+
placeholder?: string;
|
|
25
|
+
/** Allow collapsing sections under their headings (default true) */
|
|
26
|
+
foldable?: boolean;
|
|
27
|
+
/** Sidebars docked next to the content, e.g. `<MarkdownEditor.Outline />` */
|
|
28
|
+
children?: ReactNode;
|
|
29
|
+
}>;
|
|
30
|
+
/**
|
|
31
|
+
* The editable surface. Renders a plain textarea in `edit-raw` mode and the
|
|
32
|
+
* Lexical rich-text surface otherwise.
|
|
33
|
+
*/
|
|
34
|
+
declare function EditorContent({ placeholder, foldable, children, }: EditorContentProps): ReactElement;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Docked, collapsible table-of-contents sidebar. Lists the document's
|
|
38
|
+
* headings (live), scrolls to a heading on click, and highlights the section
|
|
39
|
+
* the viewport is currently in. Pure UI — nothing is added to the document.
|
|
40
|
+
*/
|
|
41
|
+
declare function OutlinePlugin(): ReactElement;
|
|
42
|
+
|
|
43
|
+
type MarkdownEditorApi = Readonly<{
|
|
44
|
+
/** The underlying Lexical editor, for dispatching your own commands */
|
|
45
|
+
editor: LexicalEditor;
|
|
46
|
+
/** Text formats active at the current selection */
|
|
47
|
+
activeFormats: ReadonlySet<TextFormatType>;
|
|
48
|
+
toggleFormat: (format: TextFormatType) => void;
|
|
49
|
+
insertTable: (options?: {
|
|
50
|
+
rows?: number;
|
|
51
|
+
columns?: number;
|
|
52
|
+
}) => void;
|
|
53
|
+
insertDrawing: () => void;
|
|
54
|
+
canUndo: boolean;
|
|
55
|
+
canRedo: boolean;
|
|
56
|
+
undo: () => void;
|
|
57
|
+
redo: () => void;
|
|
58
|
+
}>;
|
|
59
|
+
/**
|
|
60
|
+
* Headless access to the editor. Must be rendered under `MarkdownEditor.Root`
|
|
61
|
+
* (or `MarkdownEditor`). Use it to wire editor actions into your own buttons.
|
|
62
|
+
*/
|
|
63
|
+
declare function useMarkdownEditor(): MarkdownEditorApi;
|
|
64
|
+
|
|
65
|
+
/** Default toolbar groups, handed to a `toolbar` render function */
|
|
66
|
+
type ToolbarItems = Readonly<{
|
|
67
|
+
format: ReactElement;
|
|
68
|
+
insert: ReactElement;
|
|
69
|
+
history: ReactElement;
|
|
70
|
+
}>;
|
|
71
|
+
type Props = Omit<EditorRootProps, 'children'> & Readonly<{
|
|
72
|
+
placeholder?: string;
|
|
73
|
+
/**
|
|
74
|
+
* Toolbar in edit-md mode (default true). Pass a function to customise
|
|
75
|
+
* it: it receives the default groups and returns the toolbar to render.
|
|
76
|
+
*/
|
|
77
|
+
toolbar?: boolean | ((items: ToolbarItems) => ReactNode);
|
|
16
78
|
/** Show a table-of-contents sidebar listing the document's headings */
|
|
17
79
|
outline?: boolean;
|
|
18
80
|
/** Allow collapsing sections under their headings (default true) */
|
|
19
81
|
foldable?: boolean;
|
|
20
82
|
}>;
|
|
21
|
-
|
|
83
|
+
/**
|
|
84
|
+
* Toolbar that only shows while the document is editable in `edit-md` mode.
|
|
85
|
+
* Used by `MarkdownEditor` and available as `MarkdownEditor.Toolbar` for
|
|
86
|
+
* compound layouts.
|
|
87
|
+
*/
|
|
88
|
+
declare function EditorToolbar({ children, className, }: Readonly<{
|
|
89
|
+
children?: ReactNode;
|
|
90
|
+
className?: string;
|
|
91
|
+
}>): ReactElement | null;
|
|
92
|
+
declare function MarkdownEditor({ placeholder, toolbar, outline, foldable, ...rootProps }: Props): react_jsx_runtime.JSX.Element;
|
|
93
|
+
declare namespace MarkdownEditor {
|
|
94
|
+
var Root: typeof EditorRoot;
|
|
95
|
+
var Content: typeof EditorContent;
|
|
96
|
+
var Toolbar: typeof EditorToolbar;
|
|
97
|
+
var ToolbarButton: typeof ToolbarButton;
|
|
98
|
+
var ToolbarDivider: typeof ToolbarDivider;
|
|
99
|
+
var FormatButtons: typeof FormatButtons;
|
|
100
|
+
var InsertButtons: typeof InsertButtons;
|
|
101
|
+
var HistoryButtons: typeof HistoryButtons;
|
|
102
|
+
var Outline: typeof OutlinePlugin;
|
|
103
|
+
var useEditor: typeof useMarkdownEditor;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
type ToolbarProps = Readonly<{
|
|
107
|
+
children?: ReactNode;
|
|
108
|
+
className?: string;
|
|
109
|
+
}>;
|
|
110
|
+
/** Toolbar container. Renders the default items when given no children. */
|
|
111
|
+
declare function Toolbar({ children, className }: ToolbarProps): ReactElement;
|
|
112
|
+
declare function ToolbarDivider(): ReactElement;
|
|
113
|
+
type ToolbarButtonProps = Readonly<{
|
|
114
|
+
label: string;
|
|
115
|
+
onClick: () => void;
|
|
116
|
+
/** Icon content — an SVG, emoji, or text. 16px SVGs match the built-ins. */
|
|
117
|
+
children: ReactNode;
|
|
118
|
+
active?: boolean;
|
|
119
|
+
disabled?: boolean;
|
|
120
|
+
className?: string;
|
|
121
|
+
}>;
|
|
122
|
+
/**
|
|
123
|
+
* Button styled like the built-in toolbar buttons. Prevents focus from
|
|
124
|
+
* leaving the editor on click so the selection is preserved.
|
|
125
|
+
*/
|
|
126
|
+
declare function ToolbarButton({ label, onClick, children, active, disabled, className, }: ToolbarButtonProps): ReactElement;
|
|
127
|
+
/** Bold / italic / strikethrough / inline-code buttons */
|
|
128
|
+
declare function FormatButtons(): ReactElement;
|
|
129
|
+
/** Insert-table / insert-drawing buttons */
|
|
130
|
+
declare function InsertButtons(): ReactElement;
|
|
131
|
+
/** Undo / redo buttons */
|
|
132
|
+
declare function HistoryButtons(): ReactElement;
|
|
22
133
|
|
|
23
134
|
type SerializedFrontmatterNode = SerializedElementNode;
|
|
24
135
|
/**
|
|
@@ -104,6 +215,8 @@ type DrawingData = Readonly<{
|
|
|
104
215
|
height: number;
|
|
105
216
|
shapes: readonly DrawingShape[];
|
|
106
217
|
}>;
|
|
218
|
+
declare function serializeDrawingData(data: DrawingData): string;
|
|
219
|
+
declare function parseDrawingData(json: string): DrawingData;
|
|
107
220
|
|
|
108
221
|
type SerializedDrawingNode = Spread<{
|
|
109
222
|
data: string;
|
|
@@ -147,4 +260,136 @@ declare const DRAWING: MultilineElementTransformer;
|
|
|
147
260
|
*/
|
|
148
261
|
declare const TABLE: ElementTransformer;
|
|
149
262
|
|
|
150
|
-
|
|
263
|
+
/**
|
|
264
|
+
* JSON Schema (draft-07) for the payload of a ```drawing fenced block.
|
|
265
|
+
*
|
|
266
|
+
* Use it to validate LLM- or tool-generated drawings before embedding them,
|
|
267
|
+
* or pass it as a structured-output / tool schema so a model is forced to
|
|
268
|
+
* emit valid payloads. Kept in sync with `parseDrawingData` / `isValidShape`
|
|
269
|
+
* in drawingTypes.ts — update both together.
|
|
270
|
+
*/
|
|
271
|
+
declare const DRAWING_DATA_JSON_SCHEMA: {
|
|
272
|
+
readonly $schema: "http://json-schema.org/draft-07/schema#";
|
|
273
|
+
readonly title: "DrawingData";
|
|
274
|
+
readonly description: "Vector drawing embedded in markdown as a ```drawing fenced code block";
|
|
275
|
+
readonly type: "object";
|
|
276
|
+
readonly required: readonly ["version", "height", "shapes"];
|
|
277
|
+
readonly additionalProperties: false;
|
|
278
|
+
readonly properties: {
|
|
279
|
+
readonly version: {
|
|
280
|
+
readonly const: 1;
|
|
281
|
+
};
|
|
282
|
+
readonly height: {
|
|
283
|
+
readonly type: "number";
|
|
284
|
+
readonly minimum: 80;
|
|
285
|
+
readonly description: "Canvas height in pixels (width is fluid)";
|
|
286
|
+
};
|
|
287
|
+
readonly shapes: {
|
|
288
|
+
readonly type: "array";
|
|
289
|
+
readonly items: {
|
|
290
|
+
readonly $ref: "#/definitions/shape";
|
|
291
|
+
};
|
|
292
|
+
readonly description: "Render order: later shapes draw on top";
|
|
293
|
+
};
|
|
294
|
+
};
|
|
295
|
+
readonly definitions: {
|
|
296
|
+
readonly point: {
|
|
297
|
+
readonly type: "object";
|
|
298
|
+
readonly required: readonly ["x", "y"];
|
|
299
|
+
readonly additionalProperties: false;
|
|
300
|
+
readonly properties: {
|
|
301
|
+
readonly x: {
|
|
302
|
+
readonly type: "number";
|
|
303
|
+
};
|
|
304
|
+
readonly y: {
|
|
305
|
+
readonly type: "number";
|
|
306
|
+
};
|
|
307
|
+
};
|
|
308
|
+
};
|
|
309
|
+
readonly shape: {
|
|
310
|
+
readonly type: "object";
|
|
311
|
+
readonly required: readonly ["id", "type", "x", "y", "w", "h", "stroke", "fill", "strokeWidth"];
|
|
312
|
+
readonly additionalProperties: false;
|
|
313
|
+
readonly properties: {
|
|
314
|
+
readonly id: {
|
|
315
|
+
readonly type: "string";
|
|
316
|
+
readonly description: "Unique within the drawing; connector bindings reference it";
|
|
317
|
+
};
|
|
318
|
+
readonly type: {
|
|
319
|
+
readonly enum: readonly ["rect", "ellipse", "triangle", "pentagon", "arrow", "line", "text"];
|
|
320
|
+
};
|
|
321
|
+
readonly x: {
|
|
322
|
+
readonly type: "number";
|
|
323
|
+
readonly description: "Boxes/text: left edge of the bounding box. Connectors: start point x.";
|
|
324
|
+
};
|
|
325
|
+
readonly y: {
|
|
326
|
+
readonly type: "number";
|
|
327
|
+
readonly description: "Boxes/text: top edge of the bounding box. Connectors: start point y.";
|
|
328
|
+
};
|
|
329
|
+
readonly w: {
|
|
330
|
+
readonly type: "number";
|
|
331
|
+
readonly description: "Boxes/text: width (non-negative). Connectors: delta x to the end point (may be negative).";
|
|
332
|
+
};
|
|
333
|
+
readonly h: {
|
|
334
|
+
readonly type: "number";
|
|
335
|
+
readonly description: "Boxes/text: height (non-negative). Connectors: delta y to the end point (may be negative).";
|
|
336
|
+
};
|
|
337
|
+
readonly stroke: {
|
|
338
|
+
readonly type: "string";
|
|
339
|
+
readonly description: "CSS color of the outline (and of any text)";
|
|
340
|
+
};
|
|
341
|
+
readonly fill: {
|
|
342
|
+
readonly type: "string";
|
|
343
|
+
readonly description: "CSS color of the interior; \"transparent\" for none";
|
|
344
|
+
};
|
|
345
|
+
readonly strokeWidth: {
|
|
346
|
+
readonly type: "number";
|
|
347
|
+
readonly description: "Outline width; use 2";
|
|
348
|
+
};
|
|
349
|
+
readonly text: {
|
|
350
|
+
readonly type: "string";
|
|
351
|
+
readonly description: "Standalone text content; center content of a box; midpoint label of a connector";
|
|
352
|
+
};
|
|
353
|
+
readonly label: {
|
|
354
|
+
readonly type: "string";
|
|
355
|
+
readonly description: "Boxes only: small bold heading at the top";
|
|
356
|
+
};
|
|
357
|
+
readonly footer: {
|
|
358
|
+
readonly type: "string";
|
|
359
|
+
readonly description: "Boxes only: small dim line at the bottom";
|
|
360
|
+
};
|
|
361
|
+
readonly startBinding: {
|
|
362
|
+
readonly type: "string";
|
|
363
|
+
readonly description: "Connectors only: id of the box the start attaches to. The editor re-anchors the endpoint onto that box’s border.";
|
|
364
|
+
};
|
|
365
|
+
readonly endBinding: {
|
|
366
|
+
readonly type: "string";
|
|
367
|
+
readonly description: "Connectors only: id of the box the end attaches to";
|
|
368
|
+
};
|
|
369
|
+
readonly bidirectional: {
|
|
370
|
+
readonly type: "boolean";
|
|
371
|
+
readonly description: "Arrows only: arrowheads on both ends";
|
|
372
|
+
};
|
|
373
|
+
readonly routing: {
|
|
374
|
+
readonly const: "elbow";
|
|
375
|
+
readonly description: "Connectors only: orthogonal (right-angled) auto-routing. Ignored when waypoints are present.";
|
|
376
|
+
};
|
|
377
|
+
readonly elbow: {
|
|
378
|
+
readonly type: "number";
|
|
379
|
+
readonly minimum: 0;
|
|
380
|
+
readonly maximum: 1;
|
|
381
|
+
readonly description: "Elbow middle-segment position as a fraction of the span (default 0.5)";
|
|
382
|
+
};
|
|
383
|
+
readonly waypoints: {
|
|
384
|
+
readonly type: "array";
|
|
385
|
+
readonly items: {
|
|
386
|
+
readonly $ref: "#/definitions/point";
|
|
387
|
+
};
|
|
388
|
+
readonly description: "Connectors only: intermediate path points in canvas coordinates, ordered start→end. Takes precedence over routing.";
|
|
389
|
+
};
|
|
390
|
+
};
|
|
391
|
+
};
|
|
392
|
+
};
|
|
393
|
+
};
|
|
394
|
+
|
|
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 };
|