@fluidframework/react 2.90.0 → 2.91.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.
Files changed (40) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/api-report/react.alpha.api.md +8 -8
  3. package/lib/reactSharedTreeView.d.ts +6 -6
  4. package/lib/reactSharedTreeView.d.ts.map +1 -1
  5. package/lib/reactSharedTreeView.js +16 -18
  6. package/lib/reactSharedTreeView.js.map +1 -1
  7. package/lib/test/reactSharedTreeView.spec.js +3 -3
  8. package/lib/test/reactSharedTreeView.spec.js.map +1 -1
  9. package/lib/test/text/textEditor.test.js +100 -44
  10. package/lib/test/text/textEditor.test.js.map +1 -1
  11. package/lib/test/useObservation.spec.js +8 -8
  12. package/lib/test/useObservation.spec.js.map +1 -1
  13. package/lib/test/useTree.spec.js +15 -15
  14. package/lib/test/useTree.spec.js.map +1 -1
  15. package/lib/text/formatted/quillFormattedView.d.ts +14 -2
  16. package/lib/text/formatted/quillFormattedView.d.ts.map +1 -1
  17. package/lib/text/formatted/quillFormattedView.js +165 -71
  18. package/lib/text/formatted/quillFormattedView.js.map +1 -1
  19. package/lib/text/plain/plainTextView.d.ts +2 -2
  20. package/lib/text/plain/plainTextView.d.ts.map +1 -1
  21. package/lib/text/plain/plainTextView.js +16 -21
  22. package/lib/text/plain/plainTextView.js.map +1 -1
  23. package/lib/text/plain/quillView.d.ts +2 -2
  24. package/lib/text/plain/quillView.d.ts.map +1 -1
  25. package/lib/text/plain/quillView.js +15 -21
  26. package/lib/text/plain/quillView.js.map +1 -1
  27. package/lib/useObservation.js +6 -6
  28. package/lib/useObservation.js.map +1 -1
  29. package/lib/useTree.d.ts +7 -7
  30. package/lib/useTree.d.ts.map +1 -1
  31. package/lib/useTree.js +6 -6
  32. package/lib/useTree.js.map +1 -1
  33. package/package.json +14 -13
  34. package/react.test-files.tar +0 -0
  35. package/src/reactSharedTreeView.tsx +11 -13
  36. package/src/text/formatted/quillFormattedView.tsx +176 -58
  37. package/src/text/plain/plainTextView.tsx +6 -6
  38. package/src/text/plain/quillView.tsx +6 -6
  39. package/src/useObservation.ts +6 -6
  40. package/src/useTree.ts +19 -12
@@ -1,3 +1,4 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
1
2
  /*!
2
3
  * Copyright (c) Microsoft Corporation and contributors. All rights reserved.
3
4
  * Licensed under the MIT License.
@@ -9,9 +10,9 @@ import { independentView, TextAsTree } from "@fluidframework/tree/internal";
9
10
  import { render } from "@testing-library/react";
10
11
  import globalJsdom from "global-jsdom";
11
12
  import DeltaPackage from "quill-delta";
12
- import * as React from "react";
13
+ import { createRef } from "react";
13
14
  import { toPropTreeNode } from "../../propNode.js";
14
- import { clipboardFormatMatcher, FormattedTextAsTree, FormattedMainView, parseCssFontFamily, parseCssFontSize,
15
+ import { clipboardFormatMatcher, FormattedTextAsTree, FormattedMainView, parseCssFontFamily, parseCssFontSize, parseLineTag, buildDeltaFromTree,
15
16
  // Allow import of files being tested
16
17
  // eslint-disable-next-line import-x/no-internal-modules
17
18
  } from "../../text/formatted/quillFormattedView.js";
@@ -69,19 +70,19 @@ describe("textEditor", () => {
69
70
  const ViewComponent = view.component;
70
71
  it("renders MainView with editor container", () => {
71
72
  const text = TextAsTree.Tree.fromString("");
72
- const content = React.createElement(ViewComponent, { root: toPropTreeNode(text) });
73
+ const content = _jsx(ViewComponent, { root: toPropTreeNode(text) });
73
74
  const rendered = render(content, { reactStrictMode });
74
75
  assert.match(rendered.baseElement.textContent ?? "", /Collaborative Text Editor/);
75
76
  });
76
77
  it("renders MainView with initial text content", () => {
77
78
  const text = TextAsTree.Tree.fromString("Hello World");
78
- const content = React.createElement(ViewComponent, { root: toPropTreeNode(text) });
79
+ const content = _jsx(ViewComponent, { root: toPropTreeNode(text) });
79
80
  const rendered = render(content, { reactStrictMode });
80
81
  assert.match(rendered.baseElement.textContent ?? "", /Hello World/);
81
82
  });
82
83
  it("invalidates view when tree is mutated", () => {
83
84
  const text = TextAsTree.Tree.fromString("Hello");
84
- const content = React.createElement(ViewComponent, { root: toPropTreeNode(text) });
85
+ const content = _jsx(ViewComponent, { root: toPropTreeNode(text) });
85
86
  const rendered = render(content, { reactStrictMode });
86
87
  // Mutate the tree by inserting text
87
88
  text.insertAt(5, " World");
@@ -91,7 +92,7 @@ describe("textEditor", () => {
91
92
  });
92
93
  it("invalidates view when text is removed", () => {
93
94
  const text = TextAsTree.Tree.fromString("Hello World");
94
- const content = React.createElement(ViewComponent, { root: toPropTreeNode(text) });
95
+ const content = _jsx(ViewComponent, { root: toPropTreeNode(text) });
95
96
  const rendered = render(content, { reactStrictMode });
96
97
  // Mutate the tree by removing " World" (indices 5 to 11)
97
98
  text.removeRange(5, 11);
@@ -103,7 +104,7 @@ describe("textEditor", () => {
103
104
  });
104
105
  it("invalidates view when text is cleared and replaced", () => {
105
106
  const text = TextAsTree.Tree.fromString("Original");
106
- const content = React.createElement(ViewComponent, { root: toPropTreeNode(text) });
107
+ const content = _jsx(ViewComponent, { root: toPropTreeNode(text) });
107
108
  const rendered = render(content, { reactStrictMode });
108
109
  // Clear all text
109
110
  const length = [...text.characters()].length;
@@ -121,13 +122,13 @@ describe("textEditor", () => {
121
122
  it("renders MainView with surrogate pair characters", () => {
122
123
  // 😀 is a surrogate pair: "😀".length === 2, but [..."😀"].length === 1
123
124
  const text = TextAsTree.Tree.fromString("Hello 😀 World");
124
- const content = React.createElement(ViewComponent, { root: toPropTreeNode(text) });
125
+ const content = _jsx(ViewComponent, { root: toPropTreeNode(text) });
125
126
  const rendered = render(content, { reactStrictMode });
126
127
  assert.match(rendered.baseElement.textContent ?? "", /Hello 😀 World/);
127
128
  });
128
129
  it("inserts text after surrogate pair characters", () => {
129
130
  const text = TextAsTree.Tree.fromString("A😀B");
130
- const content = React.createElement(ViewComponent, { root: toPropTreeNode(text) });
131
+ const content = _jsx(ViewComponent, { root: toPropTreeNode(text) });
131
132
  const rendered = render(content, { reactStrictMode });
132
133
  // Insert after the emoji (index 2 in character count: A, 😀, B)
133
134
  text.insertAt(2, "X");
@@ -136,7 +137,7 @@ describe("textEditor", () => {
136
137
  });
137
138
  it("removes surrogate pair characters", () => {
138
139
  const text = TextAsTree.Tree.fromString("A😀B");
139
- const content = React.createElement(ViewComponent, { root: toPropTreeNode(text) });
140
+ const content = _jsx(ViewComponent, { root: toPropTreeNode(text) });
140
141
  const rendered = render(content, { reactStrictMode });
141
142
  // Remove the emoji (index 1, length 1 in character count)
142
143
  text.removeRange(1, 2);
@@ -147,7 +148,7 @@ describe("textEditor", () => {
147
148
  });
148
149
  it("handles multiple surrogate pair characters", () => {
149
150
  const text = TextAsTree.Tree.fromString("👋🌍🎉");
150
- const content = React.createElement(ViewComponent, { root: toPropTreeNode(text) });
151
+ const content = _jsx(ViewComponent, { root: toPropTreeNode(text) });
151
152
  const rendered = render(content, { reactStrictMode });
152
153
  // Insert between emojis
153
154
  text.insertAt(2, "!");
@@ -166,19 +167,19 @@ describe("textEditor", () => {
166
167
  describe(`StrictMode: ${reactStrictMode}`, () => {
167
168
  it("renders FormattedMainView with editor container", () => {
168
169
  const { tree } = createFormattedTreeView();
169
- const content = React.createElement(FormattedMainView, { root: toPropTreeNode(tree) });
170
+ const content = _jsx(FormattedMainView, { root: toPropTreeNode(tree) });
170
171
  const rendered = render(content, { reactStrictMode });
171
172
  assert.match(rendered.baseElement.textContent ?? "", /Collaborative Formatted Text Editor/);
172
173
  });
173
174
  it("renders FormattedMainView with initial text content", () => {
174
175
  const { tree } = createFormattedTreeView("Hello World");
175
- const content = React.createElement(FormattedMainView, { root: toPropTreeNode(tree) });
176
+ const content = _jsx(FormattedMainView, { root: toPropTreeNode(tree) });
176
177
  const rendered = render(content, { reactStrictMode });
177
178
  assert.match(rendered.baseElement.textContent ?? "", /Hello World/);
178
179
  });
179
180
  it("invalidates view when tree is mutated", () => {
180
181
  const { tree: text } = createFormattedTreeView("Hello");
181
- const content = React.createElement(FormattedMainView, { root: toPropTreeNode(text) });
182
+ const content = _jsx(FormattedMainView, { root: toPropTreeNode(text) });
182
183
  const rendered = render(content, { reactStrictMode });
183
184
  // Mutate the tree by inserting text
184
185
  text.insertAt(5, " World");
@@ -188,7 +189,7 @@ describe("textEditor", () => {
188
189
  });
189
190
  it("invalidates view when text is removed", () => {
190
191
  const { tree: text } = createFormattedTreeView("Hello World");
191
- const content = React.createElement(FormattedMainView, { root: toPropTreeNode(text) });
192
+ const content = _jsx(FormattedMainView, { root: toPropTreeNode(text) });
192
193
  const rendered = render(content, { reactStrictMode });
193
194
  // Mutate the tree by removing " World" (indices 5 to 11)
194
195
  text.removeRange(5, 11);
@@ -200,7 +201,7 @@ describe("textEditor", () => {
200
201
  });
201
202
  it("invalidates view when text is cleared and replaced", () => {
202
203
  const { tree: text } = createFormattedTreeView("Original");
203
- const content = React.createElement(FormattedMainView, { root: toPropTreeNode(text) });
204
+ const content = _jsx(FormattedMainView, { root: toPropTreeNode(text) });
204
205
  const rendered = render(content, { reactStrictMode });
205
206
  // Clear all text
206
207
  const length = [...text.characters()].length;
@@ -218,13 +219,13 @@ describe("textEditor", () => {
218
219
  it("renders FormattedMainView with surrogate pair characters", () => {
219
220
  // 😀 is a surrogate pair: "😀".length === 2, but [..."😀"].length === 1
220
221
  const { tree: text } = createFormattedTreeView("Hello 😀 World");
221
- const content = React.createElement(FormattedMainView, { root: toPropTreeNode(text) });
222
+ const content = _jsx(FormattedMainView, { root: toPropTreeNode(text) });
222
223
  const rendered = render(content, { reactStrictMode });
223
224
  assert.match(rendered.baseElement.textContent ?? "", /Hello 😀 World/);
224
225
  });
225
226
  it("inserts text after surrogate pair characters", () => {
226
227
  const { tree: text } = createFormattedTreeView("A😀B");
227
- const content = React.createElement(FormattedMainView, { root: toPropTreeNode(text) });
228
+ const content = _jsx(FormattedMainView, { root: toPropTreeNode(text) });
228
229
  const rendered = render(content, { reactStrictMode });
229
230
  // Insert after the emoji (index 2 in character count: A, 😀, B)
230
231
  text.insertAt(2, "X");
@@ -233,7 +234,7 @@ describe("textEditor", () => {
233
234
  });
234
235
  it("removes surrogate pair characters", () => {
235
236
  const { tree: text } = createFormattedTreeView("A😀B");
236
- const content = React.createElement(FormattedMainView, { root: toPropTreeNode(text) });
237
+ const content = _jsx(FormattedMainView, { root: toPropTreeNode(text) });
237
238
  const rendered = render(content, { reactStrictMode });
238
239
  // Remove the emoji (index 1, length 1 in character count)
239
240
  text.removeRange(1, 2);
@@ -244,7 +245,7 @@ describe("textEditor", () => {
244
245
  });
245
246
  it("handles multiple surrogate pair characters", () => {
246
247
  const { tree: text } = createFormattedTreeView("👋🌍🎉");
247
- const content = React.createElement(FormattedMainView, { root: toPropTreeNode(text) });
248
+ const content = _jsx(FormattedMainView, { root: toPropTreeNode(text) });
248
249
  const rendered = render(content, { reactStrictMode });
249
250
  // Insert between emojis
250
251
  text.insertAt(2, "!");
@@ -271,7 +272,7 @@ describe("textEditor", () => {
271
272
  describe(`StrictMode: ${reactStrictMode}`, () => {
272
273
  it("delete on empty string does not throw", () => {
273
274
  const { tree: text } = createFormattedTreeView();
274
- const content = React.createElement(FormattedMainView, { root: toPropTreeNode(text) });
275
+ const content = _jsx(FormattedMainView, { root: toPropTreeNode(text) });
275
276
  const rendered = render(content, { reactStrictMode });
276
277
  assert.doesNotThrow(() => {
277
278
  text.removeRange(0, 0);
@@ -281,7 +282,7 @@ describe("textEditor", () => {
281
282
  describe("bold", () => {
282
283
  it("inserts bold text and renders with <strong> tag", () => {
283
284
  const { tree: text } = createFormattedTreeView("Hello");
284
- const content = React.createElement(FormattedMainView, { root: toPropTreeNode(text) });
285
+ const content = _jsx(FormattedMainView, { root: toPropTreeNode(text) });
285
286
  const rendered = render(content, { reactStrictMode });
286
287
  assert.ok(!rendered.container.querySelector("strong"), "Initially: no <strong>");
287
288
  text.defaultFormat = new FormattedTextAsTree.CharacterFormat({
@@ -309,7 +310,7 @@ describe("textEditor", () => {
309
310
  text.insertAt(0, "BOLD");
310
311
  text.defaultFormat = createPlainFormat();
311
312
  text.insertAt(4, "plain");
312
- const content = React.createElement(FormattedMainView, { root: toPropTreeNode(text) });
313
+ const content = _jsx(FormattedMainView, { root: toPropTreeNode(text) });
313
314
  const rendered = render(content, { reactStrictMode });
314
315
  assert.ok(rendered.container.querySelector("strong"), "Initially: has <strong>");
315
316
  text.removeRange(0, 4);
@@ -318,7 +319,7 @@ describe("textEditor", () => {
318
319
  });
319
320
  it("applies bold via formatRange", () => {
320
321
  const { tree: text } = createFormattedTreeView("Hello World");
321
- const content = React.createElement(FormattedMainView, { root: toPropTreeNode(text) });
322
+ const content = _jsx(FormattedMainView, { root: toPropTreeNode(text) });
322
323
  const rendered = render(content, { reactStrictMode });
323
324
  text.formatRange(6, 11, { bold: true });
324
325
  rendered.rerender(content);
@@ -330,7 +331,7 @@ describe("textEditor", () => {
330
331
  describe("italic", () => {
331
332
  it("inserts italic text and renders with <em> tag", () => {
332
333
  const { tree: text } = createFormattedTreeView("Hello");
333
- const content = React.createElement(FormattedMainView, { root: toPropTreeNode(text) });
334
+ const content = _jsx(FormattedMainView, { root: toPropTreeNode(text) });
334
335
  const rendered = render(content, { reactStrictMode });
335
336
  assert.ok(!rendered.container.querySelector("em"), "Initially: no <em>");
336
337
  text.defaultFormat = new FormattedTextAsTree.CharacterFormat({
@@ -358,7 +359,7 @@ describe("textEditor", () => {
358
359
  text.insertAt(0, "ITAL");
359
360
  text.defaultFormat = createPlainFormat();
360
361
  text.insertAt(4, "plain");
361
- const content = React.createElement(FormattedMainView, { root: toPropTreeNode(text) });
362
+ const content = _jsx(FormattedMainView, { root: toPropTreeNode(text) });
362
363
  const rendered = render(content, { reactStrictMode });
363
364
  assert.ok(rendered.container.querySelector("em"), "Initially: has <em>");
364
365
  text.removeRange(0, 4);
@@ -367,7 +368,7 @@ describe("textEditor", () => {
367
368
  });
368
369
  it("applies italic via formatRange", () => {
369
370
  const { tree: text } = createFormattedTreeView("Hello World");
370
- const content = React.createElement(FormattedMainView, { root: toPropTreeNode(text) });
371
+ const content = _jsx(FormattedMainView, { root: toPropTreeNode(text) });
371
372
  const rendered = render(content, { reactStrictMode });
372
373
  text.formatRange(6, 11, { italic: true });
373
374
  rendered.rerender(content);
@@ -379,7 +380,7 @@ describe("textEditor", () => {
379
380
  describe("underline", () => {
380
381
  it("inserts underlined text and renders with <u> tag", () => {
381
382
  const { tree: text } = createFormattedTreeView("Hello");
382
- const content = React.createElement(FormattedMainView, { root: toPropTreeNode(text) });
383
+ const content = _jsx(FormattedMainView, { root: toPropTreeNode(text) });
383
384
  const rendered = render(content, { reactStrictMode });
384
385
  assert.ok(!rendered.container.querySelector("u"), "Initially: no <u>");
385
386
  text.defaultFormat = new FormattedTextAsTree.CharacterFormat({
@@ -407,7 +408,7 @@ describe("textEditor", () => {
407
408
  text.insertAt(0, "UNDER");
408
409
  text.defaultFormat = createPlainFormat();
409
410
  text.insertAt(5, "plain");
410
- const content = React.createElement(FormattedMainView, { root: toPropTreeNode(text) });
411
+ const content = _jsx(FormattedMainView, { root: toPropTreeNode(text) });
411
412
  const rendered = render(content, { reactStrictMode });
412
413
  assert.ok(rendered.container.querySelector("u"), "Initially: has <u>");
413
414
  text.removeRange(0, 5);
@@ -416,7 +417,7 @@ describe("textEditor", () => {
416
417
  });
417
418
  it("applies underline via formatRange", () => {
418
419
  const { tree: text } = createFormattedTreeView("Hello World");
419
- const content = React.createElement(FormattedMainView, { root: toPropTreeNode(text) });
420
+ const content = _jsx(FormattedMainView, { root: toPropTreeNode(text) });
420
421
  const rendered = render(content, { reactStrictMode });
421
422
  text.formatRange(6, 11, { underline: true });
422
423
  rendered.rerender(content);
@@ -428,7 +429,7 @@ describe("textEditor", () => {
428
429
  describe("size", () => {
429
430
  it("inserts huge size text and renders with .ql-size-huge", () => {
430
431
  const { tree: text } = createFormattedTreeView("Hello");
431
- const content = React.createElement(FormattedMainView, { root: toPropTreeNode(text) });
432
+ const content = _jsx(FormattedMainView, { root: toPropTreeNode(text) });
432
433
  const rendered = render(content, { reactStrictMode });
433
434
  assert.ok(!rendered.container.querySelector(".ql-size-huge"), "Initially: no .ql-size-huge");
434
435
  text.defaultFormat = new FormattedTextAsTree.CharacterFormat({
@@ -456,7 +457,7 @@ describe("textEditor", () => {
456
457
  text.insertAt(0, "HUGE");
457
458
  text.defaultFormat = createPlainFormat();
458
459
  text.insertAt(4, "plain");
459
- const content = React.createElement(FormattedMainView, { root: toPropTreeNode(text) });
460
+ const content = _jsx(FormattedMainView, { root: toPropTreeNode(text) });
460
461
  const rendered = render(content, { reactStrictMode });
461
462
  assert.ok(rendered.container.querySelector(".ql-size-huge"), "Initially: has .ql-size-huge");
462
463
  text.removeRange(0, 4);
@@ -465,7 +466,7 @@ describe("textEditor", () => {
465
466
  });
466
467
  it("applies size via formatRange", () => {
467
468
  const { tree: text } = createFormattedTreeView("Hello World");
468
- const content = React.createElement(FormattedMainView, { root: toPropTreeNode(text) });
469
+ const content = _jsx(FormattedMainView, { root: toPropTreeNode(text) });
469
470
  const rendered = render(content, { reactStrictMode });
470
471
  text.formatRange(6, 11, { size: 24 });
471
472
  rendered.rerender(content);
@@ -477,7 +478,7 @@ describe("textEditor", () => {
477
478
  describe("font", () => {
478
479
  it("inserts monospace font text and renders with .ql-font-monospace", () => {
479
480
  const { tree: text } = createFormattedTreeView("Hello");
480
- const content = React.createElement(FormattedMainView, { root: toPropTreeNode(text) });
481
+ const content = _jsx(FormattedMainView, { root: toPropTreeNode(text) });
481
482
  const rendered = render(content, { reactStrictMode });
482
483
  assert.ok(!rendered.container.querySelector(".ql-font-monospace"), "Initially: no .ql-font-monospace");
483
484
  text.defaultFormat = new FormattedTextAsTree.CharacterFormat({
@@ -505,7 +506,7 @@ describe("textEditor", () => {
505
506
  text.insertAt(0, "MONO");
506
507
  text.defaultFormat = createPlainFormat();
507
508
  text.insertAt(4, "plain");
508
- const content = React.createElement(FormattedMainView, { root: toPropTreeNode(text) });
509
+ const content = _jsx(FormattedMainView, { root: toPropTreeNode(text) });
509
510
  const rendered = render(content, { reactStrictMode });
510
511
  assert.ok(rendered.container.querySelector(".ql-font-monospace"), "Initially: has .ql-font-monospace");
511
512
  text.removeRange(0, 4);
@@ -514,7 +515,7 @@ describe("textEditor", () => {
514
515
  });
515
516
  it("applies font via formatRange", () => {
516
517
  const { tree: text } = createFormattedTreeView("Hello World");
517
- const content = React.createElement(FormattedMainView, { root: toPropTreeNode(text) });
518
+ const content = _jsx(FormattedMainView, { root: toPropTreeNode(text) });
518
519
  const rendered = render(content, { reactStrictMode });
519
520
  text.formatRange(6, 11, { font: "monospace" });
520
521
  rendered.rerender(content);
@@ -534,8 +535,8 @@ describe("textEditor", () => {
534
535
  const treeView = createFormattedTreeViewWithEvents();
535
536
  const text = treeView.root;
536
537
  const undoRedo = new UndoRedoStacks(treeView.events);
537
- const editorRef = React.createRef();
538
- const content = (React.createElement(FormattedMainView, { ref: editorRef, root: toPropTreeNode(text), undoRedo: undoRedo }));
538
+ const editorRef = createRef();
539
+ const content = (_jsx(FormattedMainView, { ref: editorRef, root: toPropTreeNode(text), undoRedo: undoRedo }));
539
540
  const rendered = render(content, { reactStrictMode });
540
541
  // Insert a character
541
542
  text.insertAt(0, "A");
@@ -555,8 +556,8 @@ describe("textEditor", () => {
555
556
  const treeView = createFormattedTreeViewWithEvents();
556
557
  const text = treeView.root;
557
558
  const undoRedo = new UndoRedoStacks(treeView.events);
558
- const editorRef = React.createRef();
559
- const content = (React.createElement(FormattedMainView, { ref: editorRef, root: toPropTreeNode(text), undoRedo: undoRedo }));
559
+ const editorRef = createRef();
560
+ const content = (_jsx(FormattedMainView, { ref: editorRef, root: toPropTreeNode(text), undoRedo: undoRedo }));
560
561
  const rendered = render(content, { reactStrictMode });
561
562
  // Insert a character
562
563
  text.insertAt(0, "B");
@@ -577,8 +578,8 @@ describe("textEditor", () => {
577
578
  const treeView = createFormattedTreeViewWithEvents();
578
579
  const text = treeView.root;
579
580
  const undoRedo = new UndoRedoStacks(treeView.events);
580
- const editorRef = React.createRef();
581
- const content = (React.createElement(FormattedMainView, { ref: editorRef, root: toPropTreeNode(text), undoRedo: undoRedo }));
581
+ const editorRef = createRef();
582
+ const content = (_jsx(FormattedMainView, { ref: editorRef, root: toPropTreeNode(text), undoRedo: undoRedo }));
582
583
  const rendered = render(content, { reactStrictMode });
583
584
  // Two operations in one transaction
584
585
  TreeAlpha.branch(text)?.runTransaction(() => {
@@ -668,7 +669,7 @@ describe("textEditor", () => {
668
669
  describe(`StrictMode: ${reactStrictMode}`, () => {
669
670
  it("applies bold to joined emoji and removes it preserving text", () => {
670
671
  const { tree: text } = createFormattedTreeView(`Test ${joinedEmoji} Text`);
671
- const content = React.createElement(FormattedMainView, { root: toPropTreeNode(text) });
672
+ const content = _jsx(FormattedMainView, { root: toPropTreeNode(text) });
672
673
  const rendered = render(content, { reactStrictMode });
673
674
  const emojiStart = 5; // "Test " is 5 chars
674
675
  const emojiLength = [...joinedEmoji].length;
@@ -683,7 +684,7 @@ describe("textEditor", () => {
683
684
  });
684
685
  it("applies size to joined emoji and removes it preserving text", () => {
685
686
  const { tree: text } = createFormattedTreeView(`Test ${joinedEmoji} Text`);
686
- const content = React.createElement(FormattedMainView, { root: toPropTreeNode(text) });
687
+ const content = _jsx(FormattedMainView, { root: toPropTreeNode(text) });
687
688
  const rendered = render(content, { reactStrictMode });
688
689
  const emojiStart = 5;
689
690
  const emojiLength = [...joinedEmoji].length;
@@ -699,6 +700,61 @@ describe("textEditor", () => {
699
700
  });
700
701
  }
701
702
  });
703
+ describe("parseLineTag", () => {
704
+ it("return lineTag for valid header", () => {
705
+ const result = parseLineTag({ header: 1 });
706
+ assert.ok(result, "Expected a line tag for header 1");
707
+ assert.equal(result.value, "h1", "Expected tag to be h1");
708
+ });
709
+ it("returns lineTag for valid bullet list", () => {
710
+ const result = parseLineTag({ list: "bullet" });
711
+ assert.ok(result, "Expected a line tag for bullet list");
712
+ assert.equal(result.value, "li", "Expected tag to be li)");
713
+ });
714
+ // Tests for unsupported parameters - should return default header ("h5"), not throw an error.
715
+ // Also used for when formatting is stripped from a newline and it becomes a default newline
716
+ it("returns undefined for unsupported parameter", () => {
717
+ const result = parseLineTag({ header: 7 });
718
+ assert.ok(result, "Expected a line tag for header 5");
719
+ assert.equal(result.value, "h5", "Expected tag to be h5 for unsupported header level");
720
+ });
721
+ });
722
+ // tests quillFormattedview conversion that feeds into quill delta generation,
723
+ // specifically for line atoms which have special handling for headers and lists.
724
+ // Quill always has a trailing newline, so these tests set up the string with a newline,
725
+ // then replace it with a line atom with the appropriate tag.
726
+ describe("buildDeltaFromTree with line Atoms", () => {
727
+ it("emits header attribute for h1 line atom", () => {
728
+ const { tree } = createFormattedTreeView("Hello\n");
729
+ tree.removeRange(5, 6);
730
+ tree.insertWithFormattingAt(5, [
731
+ new FormattedTextAsTree.StringAtom({
732
+ content: new FormattedTextAsTree.StringLineAtom({
733
+ tag: FormattedTextAsTree.LineTag("h1"),
734
+ }),
735
+ format: createPlainFormat(),
736
+ }),
737
+ ]);
738
+ const ops = buildDeltaFromTree(tree);
739
+ const lineOp = ops.find((op) => op.insert === "\n" && op.attributes?.header === 1);
740
+ assert.ok(lineOp, "Expected { insert : `\\n`, attributes: { header: 1 } } in delta");
741
+ });
742
+ it("emits header attribute for li line atom", () => {
743
+ const { tree } = createFormattedTreeView("item\n");
744
+ tree.removeRange(4, 5);
745
+ tree.insertWithFormattingAt(4, [
746
+ new FormattedTextAsTree.StringAtom({
747
+ content: new FormattedTextAsTree.StringLineAtom({
748
+ tag: FormattedTextAsTree.LineTag("li"),
749
+ }),
750
+ format: createPlainFormat(),
751
+ }),
752
+ ]);
753
+ const ops = buildDeltaFromTree(tree);
754
+ const lineOp = ops.find((op) => op.insert === "\n" && op.attributes?.list === "bullet");
755
+ assert.ok(lineOp, "Expected { insert : `\\n`, attributes: { list: 'bullet' } } in delta");
756
+ });
757
+ });
702
758
  });
703
759
  });
704
760
  //# sourceMappingURL=textEditor.test.js.map