@astryxdesign/lab 0.2.0-canary.ea693ac → 0.2.0-canary.f4c72f9
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/RichTextEditor/RichTextEditor.d.ts +6 -0
- package/dist/RichTextEditor/RichTextEditor.d.ts.map +1 -1
- package/dist/RichTextEditor/RichTextEditor.js +6 -0
- package/package.json +8 -3
- package/src/RichTextEditor/RichTextEditor.doc.mjs +1 -1
- package/src/RichTextEditor/RichTextEditor.test.tsx +13 -0
- package/src/RichTextEditor/RichTextEditor.tsx +12 -0
|
@@ -57,6 +57,12 @@ export interface RichTextEditorRef {
|
|
|
57
57
|
* `$convertToMarkdownString` run in a read context.
|
|
58
58
|
*/
|
|
59
59
|
getMarkdown: () => string;
|
|
60
|
+
/**
|
|
61
|
+
* Serialize the current content to an HTML string via
|
|
62
|
+
* `$generateHtmlFromNodes`. Requires a DOM (available in the browser and in
|
|
63
|
+
* jsdom-based tests). Useful for copy/paste, email, or non-Lexical consumers.
|
|
64
|
+
*/
|
|
65
|
+
getHTML: () => string;
|
|
60
66
|
/**
|
|
61
67
|
* Access the underlying `LexicalEditor` instance for advanced use cases
|
|
62
68
|
* (custom commands, listeners, node transforms).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RichTextEditor.d.ts","sourceRoot":"","sources":["../../src/RichTextEditor/RichTextEditor.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAQL,KAAK,SAAS,EAEf,MAAM,OAAO,CAAC;AAgBf,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,oBAAoB,CAAC;AAElD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,0BAA0B,CAAC;AAkBxD,OAAO,EAGL,KAAK,WAAW,EACjB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EAAC,WAAW,EAAC,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"RichTextEditor.d.ts","sourceRoot":"","sources":["../../src/RichTextEditor/RichTextEditor.tsx"],"names":[],"mappings":"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"}
|
|
@@ -48,6 +48,7 @@ import { ListNode, ListItemNode } from '@lexical/list';
|
|
|
48
48
|
import { HeadingNode, QuoteNode } from '@lexical/rich-text';
|
|
49
49
|
import { LinkNode, AutoLinkNode } from '@lexical/link';
|
|
50
50
|
import { CodeNode, CodeHighlightNode } from '@lexical/code';
|
|
51
|
+
import { $generateHtmlFromNodes } from '@lexical/html';
|
|
51
52
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
52
53
|
/**
|
|
53
54
|
* Serialized state for an empty editor: a root containing a single empty
|
|
@@ -335,6 +336,11 @@ function EditorRefBridge({
|
|
|
335
336
|
// transformers round-trip to Markdown. `@lexical/markdown` is a
|
|
336
337
|
// subpackage (built dist) — safe, unlike a top-level `lexical` import.
|
|
337
338
|
editor.getEditorState().read(() => $convertToMarkdownString(transformers)),
|
|
339
|
+
getHTML: () =>
|
|
340
|
+
// $generateHtmlFromNodes serializes the whole document (null selection)
|
|
341
|
+
// to HTML; must run in a read context and requires a DOM.
|
|
342
|
+
// `@lexical/html` is a subpackage (built dist) — safe.
|
|
343
|
+
editor.getEditorState().read(() => $generateHtmlFromNodes(editor, null)),
|
|
338
344
|
getEditor: () => editor
|
|
339
345
|
}), [editor, editable, transformers]);
|
|
340
346
|
return null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astryxdesign/lab",
|
|
3
|
-
"version": "0.2.0-canary.
|
|
3
|
+
"version": "0.2.0-canary.f4c72f9",
|
|
4
4
|
"description": "Experimental Astryx components — published to npm only under the @canary dist-tag for early testing; never released as a stable (latest) version.",
|
|
5
5
|
"author": "Meta Open Source",
|
|
6
6
|
"license": "MIT",
|
|
@@ -45,12 +45,13 @@
|
|
|
45
45
|
},
|
|
46
46
|
"peerDependencies": {
|
|
47
47
|
"@stylexjs/stylex": ">=0.10.0",
|
|
48
|
-
"@astryxdesign/core": "0.2.0-canary.
|
|
48
|
+
"@astryxdesign/core": "0.2.0-canary.f4c72f9",
|
|
49
49
|
"react": ">=19.0.0",
|
|
50
50
|
"react-dom": ">=19.0.0",
|
|
51
51
|
"lexical": "^0.46.0",
|
|
52
52
|
"@lexical/react": "^0.46.0",
|
|
53
53
|
"@lexical/markdown": "^0.46.0",
|
|
54
|
+
"@lexical/html": "^0.46.0",
|
|
54
55
|
"@lexical/link": "^0.46.0",
|
|
55
56
|
"@lexical/list": "^0.46.0",
|
|
56
57
|
"@lexical/rich-text": "^0.46.0",
|
|
@@ -64,6 +65,7 @@
|
|
|
64
65
|
},
|
|
65
66
|
"devDependencies": {
|
|
66
67
|
"@lexical/code": "^0.46.0",
|
|
68
|
+
"@lexical/html": "^0.46.0",
|
|
67
69
|
"@lexical/link": "^0.46.0",
|
|
68
70
|
"@lexical/list": "^0.46.0",
|
|
69
71
|
"@lexical/markdown": "^0.46.0",
|
|
@@ -85,6 +87,9 @@
|
|
|
85
87
|
"@lexical/markdown": {
|
|
86
88
|
"optional": true
|
|
87
89
|
},
|
|
90
|
+
"@lexical/html": {
|
|
91
|
+
"optional": true
|
|
92
|
+
},
|
|
88
93
|
"@lexical/link": {
|
|
89
94
|
"optional": true
|
|
90
95
|
},
|
|
@@ -102,7 +107,7 @@
|
|
|
102
107
|
}
|
|
103
108
|
},
|
|
104
109
|
"scripts": {
|
|
105
|
-
"build": "rm -rf dist && pnpm build:esm && tsc --project tsconfig.build.json && pnpm build:css && node ../../scripts/check-no-dev-jsx.mjs",
|
|
110
|
+
"build": "rm -rf dist && pnpm build:esm && tsc --project tsconfig.build.json && pnpm build:css && node ../../scripts/check-no-dev-jsx.mjs && node ../../scripts/check-fully-specified.mjs",
|
|
106
111
|
"build:esm": "babel src --out-dir dist --extensions .ts,.tsx --out-file-extension .js --ignore \"**/*.test.ts,**/*.test.tsx,**/__tests__/**,**/*.perf.test.*,**/*.doc.mjs,**/*.d.ts,**/*.css,**/*.css.d.ts\" --config-file ./babel.config.js",
|
|
107
112
|
"build:css": "node ../../scripts/build-css.mjs --package lab",
|
|
108
113
|
"dev": "babel src --watch --out-dir dist --extensions .ts,.tsx --out-file-extension .js --ignore \"**/*.test.*,**/*.doc.mjs,**/*.d.ts,**/*.css*\" --config-file ./babel.config.js",
|
|
@@ -153,7 +153,7 @@ export const docs = {
|
|
|
153
153
|
{
|
|
154
154
|
guidance: true,
|
|
155
155
|
description:
|
|
156
|
-
'Use a ref (RichTextEditorRef) to imperatively focus(), clear(), read the state via getEditorState(), serialize to Markdown via getMarkdown(), or reach the LexicalEditor via getEditor(). The handle is available after mount. getMarkdown() uses the same transformers prop the editor is configured with. focus() and clear() are no-ops when the editor is read-only or disabled, and clear() resets to a single empty paragraph.',
|
|
156
|
+
'Use a ref (RichTextEditorRef) to imperatively focus(), clear(), read the state via getEditorState(), serialize to Markdown via getMarkdown() or HTML via getHTML(), or reach the LexicalEditor via getEditor(). The handle is available after mount. getMarkdown() uses the same transformers prop the editor is configured with. focus() and clear() are no-ops when the editor is read-only or disabled, and clear() resets to a single empty paragraph.',
|
|
157
157
|
},
|
|
158
158
|
{
|
|
159
159
|
guidance: false,
|
|
@@ -342,6 +342,7 @@ describe('RichTextEditor', () => {
|
|
|
342
342
|
expect(typeof ref.current?.clear).toBe('function');
|
|
343
343
|
expect(typeof ref.current?.getEditorState).toBe('function');
|
|
344
344
|
expect(typeof ref.current?.getMarkdown).toBe('function');
|
|
345
|
+
expect(typeof ref.current?.getHTML).toBe('function');
|
|
345
346
|
expect(typeof ref.current?.getEditor).toBe('function');
|
|
346
347
|
});
|
|
347
348
|
|
|
@@ -426,6 +427,18 @@ describe('RichTextEditor', () => {
|
|
|
426
427
|
await waitFor(() => expect(ref.current?.getMarkdown()).toBe('Title'));
|
|
427
428
|
});
|
|
428
429
|
|
|
430
|
+
it('ref.getHTML() serializes content to an HTML string', () => {
|
|
431
|
+
const ref = createRef<RichTextEditorRef>();
|
|
432
|
+
render(
|
|
433
|
+
<RichTextEditor ref={ref} label="Notes" defaultValue={HELLO_STATE} />,
|
|
434
|
+
);
|
|
435
|
+
const html = ref.current?.getHTML();
|
|
436
|
+
expect(typeof html).toBe('string');
|
|
437
|
+
// A paragraph with the seeded text renders as a <p> containing "Hello world".
|
|
438
|
+
expect(html).toContain('<p');
|
|
439
|
+
expect(html).toContain('Hello world');
|
|
440
|
+
});
|
|
441
|
+
|
|
429
442
|
it('ref.clear() resets the editor to a single empty paragraph', async () => {
|
|
430
443
|
const ref = createRef<RichTextEditorRef>();
|
|
431
444
|
render(
|
|
@@ -80,6 +80,7 @@ import {ListNode, ListItemNode} from '@lexical/list';
|
|
|
80
80
|
import {HeadingNode, QuoteNode} from '@lexical/rich-text';
|
|
81
81
|
import {LinkNode, AutoLinkNode} from '@lexical/link';
|
|
82
82
|
import {CodeNode, CodeHighlightNode} from '@lexical/code';
|
|
83
|
+
import {$generateHtmlFromNodes} from '@lexical/html';
|
|
83
84
|
import type {
|
|
84
85
|
EditorState,
|
|
85
86
|
Klass,
|
|
@@ -237,6 +238,12 @@ export interface RichTextEditorRef {
|
|
|
237
238
|
* `$convertToMarkdownString` run in a read context.
|
|
238
239
|
*/
|
|
239
240
|
getMarkdown: () => string;
|
|
241
|
+
/**
|
|
242
|
+
* Serialize the current content to an HTML string via
|
|
243
|
+
* `$generateHtmlFromNodes`. Requires a DOM (available in the browser and in
|
|
244
|
+
* jsdom-based tests). Useful for copy/paste, email, or non-Lexical consumers.
|
|
245
|
+
*/
|
|
246
|
+
getHTML: () => string;
|
|
240
247
|
/**
|
|
241
248
|
* Access the underlying `LexicalEditor` instance for advanced use cases
|
|
242
249
|
* (custom commands, listeners, node transforms).
|
|
@@ -633,6 +640,11 @@ function EditorRefBridge({
|
|
|
633
640
|
editor
|
|
634
641
|
.getEditorState()
|
|
635
642
|
.read(() => $convertToMarkdownString(transformers)),
|
|
643
|
+
getHTML: () =>
|
|
644
|
+
// $generateHtmlFromNodes serializes the whole document (null selection)
|
|
645
|
+
// to HTML; must run in a read context and requires a DOM.
|
|
646
|
+
// `@lexical/html` is a subpackage (built dist) — safe.
|
|
647
|
+
editor.getEditorState().read(() => $generateHtmlFromNodes(editor, null)),
|
|
636
648
|
getEditor: () => editor,
|
|
637
649
|
}),
|
|
638
650
|
[editor, editable, transformers],
|