@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.
@@ -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;AAKnD,OAAO,KAAK,EACV,WAAW,EACX,KAAK,EACL,aAAa,EACb,WAAW,EAEZ,MAAM,SAAS,CAAC;AAoHjB,MAAM,MAAM,wBAAwB,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;AAEvE,MAAM,MAAM,kBAAkB,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAEpD,MAAM,WAAW,oBAAoB;IACnC,qCAAqC;IACrC,IAAI,EAAE,wBAAwB,CAAC;IAC/B,oDAAoD;IACpD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB;;;OAGG;IACH,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,6EAA6E;IAC7E,cAAc,EAAE,MAAM,WAAW,CAAC;IAClC;;;;;OAKG;IACH,WAAW,EAAE,MAAM,MAAM,CAAC;IAC1B;;;OAGG;IACH,SAAS,EAAE,MAAM,aAAa,CAAC;CAChC;AAED,MAAM,WAAW,mBAAoB,SAAQ,IAAI,CAC/C,SAAS,EACT,UAAU,GAAG,cAAc,CAC5B;IACC,qEAAqE;IACrE,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,+DAA+D;IAC/D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,CAAC,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,KAAK,IAAI,CAAC;IACrE,uDAAuD;IACvD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;OAGG;IACH,MAAM,CAAC,EAAE,oBAAoB,CAAC;IAC9B;;;OAGG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,uEAAuE;IACvE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,IAAI,CAAC,EAAE,kBAAkB,CAAC;IAC1B;;;;OAIG;IACH,KAAK,CAAC,EAAE,aAAa,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC;IAC1C;;;;OAIG;IACH,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB;;;;;OAKG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;;;;;;;;;;;;;;;OAgBG;IACH,YAAY,CAAC,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC;IAC1C,yEAAyE;IACzE,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,cAAc,mHAuLzB,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.ea693ac",
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.ea693ac",
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],