@itwin/core-common 5.2.0-dev.8 → 5.3.0-dev.2

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 (82) hide show
  1. package/CHANGELOG.md +38 -1
  2. package/lib/cjs/BriefcaseTypes.d.ts +2 -0
  3. package/lib/cjs/BriefcaseTypes.d.ts.map +1 -1
  4. package/lib/cjs/BriefcaseTypes.js.map +1 -1
  5. package/lib/cjs/ElementProps.d.ts +8 -0
  6. package/lib/cjs/ElementProps.d.ts.map +1 -1
  7. package/lib/cjs/ElementProps.js.map +1 -1
  8. package/lib/cjs/FeatureSymbology.d.ts.map +1 -1
  9. package/lib/cjs/FeatureSymbology.js +0 -2
  10. package/lib/cjs/FeatureSymbology.js.map +1 -1
  11. package/lib/cjs/annotation/TextAnnotation.d.ts +1 -1
  12. package/lib/cjs/annotation/TextAnnotation.d.ts.map +1 -1
  13. package/lib/cjs/annotation/TextAnnotation.js +1 -1
  14. package/lib/cjs/annotation/TextAnnotation.js.map +1 -1
  15. package/lib/cjs/annotation/TextBlock.d.ts +114 -104
  16. package/lib/cjs/annotation/TextBlock.d.ts.map +1 -1
  17. package/lib/cjs/annotation/TextBlock.js +227 -108
  18. package/lib/cjs/annotation/TextBlock.js.map +1 -1
  19. package/lib/cjs/annotation/TextBlockLayoutResult.d.ts +3 -5
  20. package/lib/cjs/annotation/TextBlockLayoutResult.d.ts.map +1 -1
  21. package/lib/cjs/annotation/TextBlockLayoutResult.js.map +1 -1
  22. package/lib/cjs/annotation/TextField.d.ts +86 -0
  23. package/lib/cjs/annotation/TextField.d.ts.map +1 -0
  24. package/lib/cjs/annotation/TextField.js +10 -0
  25. package/lib/cjs/annotation/TextField.js.map +1 -0
  26. package/lib/cjs/annotation/TextStyle.d.ts +63 -1
  27. package/lib/cjs/annotation/TextStyle.d.ts.map +1 -1
  28. package/lib/cjs/annotation/TextStyle.js +44 -4
  29. package/lib/cjs/annotation/TextStyle.js.map +1 -1
  30. package/lib/cjs/core-common.d.ts +1 -0
  31. package/lib/cjs/core-common.d.ts.map +1 -1
  32. package/lib/cjs/core-common.js +1 -0
  33. package/lib/cjs/core-common.js.map +1 -1
  34. package/lib/cjs/internal/annotations/FieldFormatter.d.ts +18 -0
  35. package/lib/cjs/internal/annotations/FieldFormatter.d.ts.map +1 -0
  36. package/lib/cjs/internal/annotations/FieldFormatter.js +66 -0
  37. package/lib/cjs/internal/annotations/FieldFormatter.js.map +1 -0
  38. package/lib/cjs/internal/cross-package.d.ts +1 -0
  39. package/lib/cjs/internal/cross-package.d.ts.map +1 -1
  40. package/lib/cjs/internal/cross-package.js +4 -1
  41. package/lib/cjs/internal/cross-package.js.map +1 -1
  42. package/lib/esm/BriefcaseTypes.d.ts +2 -0
  43. package/lib/esm/BriefcaseTypes.d.ts.map +1 -1
  44. package/lib/esm/BriefcaseTypes.js.map +1 -1
  45. package/lib/esm/ElementProps.d.ts +8 -0
  46. package/lib/esm/ElementProps.d.ts.map +1 -1
  47. package/lib/esm/ElementProps.js.map +1 -1
  48. package/lib/esm/FeatureSymbology.d.ts.map +1 -1
  49. package/lib/esm/FeatureSymbology.js +0 -2
  50. package/lib/esm/FeatureSymbology.js.map +1 -1
  51. package/lib/esm/annotation/TextAnnotation.d.ts +1 -1
  52. package/lib/esm/annotation/TextAnnotation.d.ts.map +1 -1
  53. package/lib/esm/annotation/TextAnnotation.js +1 -1
  54. package/lib/esm/annotation/TextAnnotation.js.map +1 -1
  55. package/lib/esm/annotation/TextBlock.d.ts +114 -104
  56. package/lib/esm/annotation/TextBlock.d.ts.map +1 -1
  57. package/lib/esm/annotation/TextBlock.js +223 -107
  58. package/lib/esm/annotation/TextBlock.js.map +1 -1
  59. package/lib/esm/annotation/TextBlockLayoutResult.d.ts +3 -5
  60. package/lib/esm/annotation/TextBlockLayoutResult.d.ts.map +1 -1
  61. package/lib/esm/annotation/TextBlockLayoutResult.js.map +1 -1
  62. package/lib/esm/annotation/TextField.d.ts +86 -0
  63. package/lib/esm/annotation/TextField.d.ts.map +1 -0
  64. package/lib/esm/annotation/TextField.js +9 -0
  65. package/lib/esm/annotation/TextField.js.map +1 -0
  66. package/lib/esm/annotation/TextStyle.d.ts +63 -1
  67. package/lib/esm/annotation/TextStyle.d.ts.map +1 -1
  68. package/lib/esm/annotation/TextStyle.js +43 -3
  69. package/lib/esm/annotation/TextStyle.js.map +1 -1
  70. package/lib/esm/core-common.d.ts +1 -0
  71. package/lib/esm/core-common.d.ts.map +1 -1
  72. package/lib/esm/core-common.js +1 -0
  73. package/lib/esm/core-common.js.map +1 -1
  74. package/lib/esm/internal/annotations/FieldFormatter.d.ts +18 -0
  75. package/lib/esm/internal/annotations/FieldFormatter.d.ts.map +1 -0
  76. package/lib/esm/internal/annotations/FieldFormatter.js +62 -0
  77. package/lib/esm/internal/annotations/FieldFormatter.js.map +1 -0
  78. package/lib/esm/internal/cross-package.d.ts +1 -0
  79. package/lib/esm/internal/cross-package.d.ts.map +1 -1
  80. package/lib/esm/internal/cross-package.js +1 -0
  81. package/lib/esm/internal/cross-package.js.map +1 -1
  82. package/package.json +6 -6
@@ -7,10 +7,22 @@
7
7
  * @module Annotation
8
8
  */
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.TextBlock = exports.Paragraph = exports.FieldRun = exports.TabRun = exports.LineBreakRun = exports.FractionRun = exports.TextRun = exports.Run = exports.TextBlockComponent = void 0;
10
+ exports.TextBlock = exports.List = exports.Paragraph = exports.FieldRun = exports.TabRun = exports.LineBreakRun = exports.FractionRun = exports.TextRun = exports.Run = exports.TextBlockComponent = void 0;
11
+ exports.traverseTextBlockComponent = traverseTextBlockComponent;
12
+ exports.getMarkerText = getMarkerText;
11
13
  const TextStyle_1 = require("./TextStyle");
12
- /** Abstract representation of any of the building blocks that make up a [[TextBlock]] document - namely [[Run]]s, [[Paragraph]]s, and [[TextBlock]] itself.
13
- * The [[TextBlock]] can specify an [AnnotationTextStyle]($backend) that formats its contents. Each component can specify an optional [[styleOverrides]] to customize that formatting.
14
+ function clearStyleOverrides(component, options) {
15
+ component.styleOverrides = {};
16
+ if (!options?.preserveChildrenOverrides) {
17
+ for (const child of component.children) {
18
+ child.clearStyleOverrides(options);
19
+ }
20
+ }
21
+ }
22
+ /**
23
+ * Abstract representation of any of the building blocks that make up a [[TextBlock]] document - namely [[Run]]s and [[StructuralTextBlockComponent]]s.
24
+ * The [[TextBlock]] can specify an [AnnotationTextStyle]($backend) that formats its contents.
25
+ * Each component can specify an optional [[styleOverrides]] to customize that formatting.
14
26
  * @beta
15
27
  */
16
28
  class TextBlockComponent {
@@ -19,7 +31,7 @@ class TextBlockComponent {
19
31
  constructor(props) {
20
32
  this._styleOverrides = TextStyle_1.TextStyleSettings.cloneProps(props?.styleOverrides ?? {});
21
33
  }
22
- /** Deviations in individual properties of the [[TextStyleSettings]] in the [AnnotationTextStyle]($backend) specified by `styleId` on the [[TextBlock]].
34
+ /** Deviations in individual properties of the [[TextStyleSettings]] in the [AnnotationTextStyle]($backend).
23
35
  * For example, if the style uses the "Arial" font, you can override that by settings `styleOverrides.fontName` to "Comic Sans".
24
36
  * @see [[clearStyleOverrides]] to reset this to an empty object.
25
37
  */
@@ -76,15 +88,15 @@ exports.TextBlockComponent = TextBlockComponent;
76
88
  var Run;
77
89
  (function (Run) {
78
90
  /** Create a run from its JSON representation.
79
- * @see [[TextRun.create]], [[FractionRun.create]], and [[LineBreakRun.create]] to create a run directly.
91
+ * @see [[TextRun.create]], [[FractionRun.create]], [[FieldRun.create]], [[TabRun.create]], and [[LineBreakRun.create]] to create a run directly.
80
92
  */
81
93
  function fromJSON(props) {
82
94
  switch (props.type) {
83
- case "text": return TextRun.create(props);
95
+ case "field": return FieldRun.create(props);
84
96
  case "fraction": return FractionRun.create(props);
85
- case "tab": return TabRun.create(props);
86
97
  case "linebreak": return LineBreakRun.create(props);
87
- case "field": return FieldRun.create(props);
98
+ case "tab": return TabRun.create(props);
99
+ case "text": return TextRun.create(props);
88
100
  }
89
101
  }
90
102
  Run.fromJSON = fromJSON;
@@ -116,7 +128,10 @@ class TextRun extends TextBlockComponent {
116
128
  };
117
129
  }
118
130
  static create(props) {
119
- return new TextRun(props);
131
+ return new TextRun({ ...props, type: "text" });
132
+ }
133
+ get isEmpty() {
134
+ return this.stringify().length === 0;
120
135
  }
121
136
  /** Simply returns [[content]]. */
122
137
  stringify() {
@@ -155,7 +170,10 @@ class FractionRun extends TextBlockComponent {
155
170
  return new FractionRun(this.toJSON());
156
171
  }
157
172
  static create(props) {
158
- return new FractionRun(props);
173
+ return new FractionRun({ ...props, type: "fraction" });
174
+ }
175
+ get isEmpty() {
176
+ return this.stringify().length === 0;
159
177
  }
160
178
  /** Formats the fraction as a string with the [[numerator]] and [[denominator]] separated by [[TextBlockStringifyOptions.fractionSeparator]]. */
161
179
  stringify(options) {
@@ -183,11 +201,14 @@ class LineBreakRun extends TextBlockComponent {
183
201
  };
184
202
  }
185
203
  static create(props) {
186
- return new LineBreakRun(props);
204
+ return new LineBreakRun({ ...props, type: "linebreak" });
187
205
  }
188
206
  clone() {
189
207
  return new LineBreakRun(this.toJSON());
190
208
  }
209
+ get isEmpty() {
210
+ return this.stringify().length === 0;
211
+ }
191
212
  /** Simply returns [[TextBlockStringifyOptions.lineBreak]]. */
192
213
  stringify(options) {
193
214
  return options?.lineBreak ?? " ";
@@ -216,6 +237,9 @@ class TabRun extends TextBlockComponent {
216
237
  static create(props) {
217
238
  return new TabRun(props);
218
239
  }
240
+ get isEmpty() {
241
+ return this.stringify().length === 0;
242
+ }
219
243
  /**
220
244
  * Converts a [[TabRun]] to its string representation.
221
245
  * If the `tabsAsSpaces` option is provided, returns a string of spaces of the specified length.
@@ -235,7 +259,8 @@ exports.TabRun = TabRun;
235
259
  /** A [[Run]] that displays the formatted value of a property of some [Element]($backend).
236
260
  * When a [[TextBlock]] containing a [[FieldRun]] is written into the iModel as an [ITextAnnotation]($backend) element,
237
261
  * a dependency is established between the two elements via the [ElementDrivesTextAnnotation]($backend) relationship such that
238
- * whenever the source element specified by [[propertyHost]] is modified, the field(s) in the `ITextAnnotation` element are automatically
262
+ * whenever the source element specified by [[propertyHost]] is modified or the `ITextAnnotation` element is inserted or updated in the iModel,
263
+ * the field(s) in the `ITextAnnotation` element are automatically
239
264
  * recalculated, causing their [[cachedContent]] to update. If the field's display string cannot be evaluated (for example, because the specified element or
240
265
  * property does not exist), then its cached content is set to [[FieldRun.invalidContentIndicator]].
241
266
  * A [[FieldRun]] displays its [[cachedContent]] in the same way that [[TextRun]]s display their `content`, including word wrapping where appropriate.
@@ -250,8 +275,10 @@ class FieldRun extends TextBlockComponent {
250
275
  propertyHost;
251
276
  /** Describes how to obtain the property value from [[propertyHost]]. */
252
277
  propertyPath;
253
- /** Specifies how to format the property value obtained from [[propertyPath]] into a string to be stored in [[cachedContent]]. */
254
- formatter;
278
+ /** Specifies how to format the property value obtained from [[propertyPath]] into a string to be stored in [[cachedContent]].
279
+ * The specific options used depend upon the [[FieldPropertyType]].
280
+ */
281
+ formatOptions;
255
282
  _cachedContent;
256
283
  /** The field's most recently evaluated display string. */
257
284
  get cachedContent() {
@@ -266,7 +293,7 @@ class FieldRun extends TextBlockComponent {
266
293
  this._cachedContent = props.cachedContent ?? FieldRun.invalidContentIndicator;
267
294
  this.propertyHost = props.propertyHost;
268
295
  this.propertyPath = props.propertyPath;
269
- this.formatter = props.formatter;
296
+ this.formatOptions = props.formatOptions;
270
297
  }
271
298
  /** Create a FieldRun from its JSON representation. */
272
299
  static create(props) {
@@ -274,7 +301,8 @@ class FieldRun extends TextBlockComponent {
274
301
  ...props,
275
302
  propertyHost: { ...props.propertyHost },
276
303
  propertyPath: structuredClone(props.propertyPath),
277
- formatter: structuredClone(props.formatter),
304
+ formatOptions: structuredClone(props.formatOptions),
305
+ type: "field",
278
306
  });
279
307
  }
280
308
  /** Convert the FieldRun to its JSON representation. */
@@ -288,8 +316,8 @@ class FieldRun extends TextBlockComponent {
288
316
  if (this.cachedContent !== FieldRun.invalidContentIndicator) {
289
317
  json.cachedContent = this.cachedContent;
290
318
  }
291
- if (this.formatter) {
292
- json.formatter = structuredClone(this.formatter);
319
+ if (this.formatOptions) {
320
+ json.formatOptions = structuredClone(this.formatOptions);
293
321
  }
294
322
  return json;
295
323
  }
@@ -297,6 +325,9 @@ class FieldRun extends TextBlockComponent {
297
325
  clone() {
298
326
  return new FieldRun(this.toJSON());
299
327
  }
328
+ get isEmpty() {
329
+ return this.stringify().length === 0;
330
+ }
300
331
  /** Convert this FieldRun to a simple string representation. */
301
332
  stringify() {
302
333
  return this.cachedContent;
@@ -316,93 +347,119 @@ class FieldRun extends TextBlockComponent {
316
347
  }
317
348
  const thisAccessors = this.propertyPath.accessors ?? [];
318
349
  const otherAccessors = other.propertyPath.accessors ?? [];
319
- const thisJsonAccessors = this.propertyPath.jsonAccessors ?? [];
320
- const otherJsonAccessors = other.propertyPath.jsonAccessors ?? [];
321
- if (thisAccessors.length !== otherAccessors.length || thisJsonAccessors.length !== otherJsonAccessors.length) {
350
+ if (thisAccessors.length !== otherAccessors.length) {
322
351
  return false;
323
352
  }
324
353
  if (!thisAccessors.every((value, index) => value === otherAccessors[index])) {
325
354
  return false;
326
355
  }
327
- if (!thisJsonAccessors.every((value, index) => value === otherJsonAccessors[index])) {
328
- return false;
329
- }
330
- if (this.formatter && other.formatter) {
331
- // ###TODO better comparison of formatter objects.
332
- if (JSON.stringify(this.formatter) !== JSON.stringify(other.formatter)) {
356
+ if (this.formatOptions && other.formatOptions) {
357
+ // We anticipate new formatting options being added in the future.
358
+ // So to account for properties we don't know about, just compare the string representations.
359
+ if (JSON.stringify(this.formatOptions) !== JSON.stringify(other.formatOptions)) {
333
360
  return false;
334
361
  }
335
362
  }
336
- else if (this.formatter || other.formatter) {
363
+ else if (this.formatOptions || other.formatOptions) {
337
364
  return false;
338
365
  }
339
366
  return true;
340
367
  }
341
368
  }
342
369
  exports.FieldRun = FieldRun;
343
- /** A collection of [[Run]]s within a [[TextBlock]]. Each paragraph within a text block is laid out on a separate line.
370
+ /** A collection of [[Run]]s and [[List]]s. Paragraphs can be appended to [[List]]s and [[TextBlock]]s.
371
+ * Each paragraph is laid out on a separate line. If included in a [[List]], the paragraph will be treated as a list item.
344
372
  * @beta
345
373
  */
346
374
  class Paragraph extends TextBlockComponent {
347
- /** The runs within the paragraph. You can modify the contents of this array to change the content of the paragraph. */
348
- runs;
375
+ type = "paragraph";
376
+ children;
349
377
  constructor(props) {
350
378
  super(props);
351
- this.runs = props?.runs?.map((run) => Run.fromJSON(run)) ?? [];
379
+ this.children = props?.children?.map((child) => child.type === "list" ? List.create(child) : Run.fromJSON(child)) ?? [];
380
+ }
381
+ /** Create a paragraph from its JSON representation. */
382
+ static create(props) {
383
+ return new Paragraph(props);
384
+ }
385
+ clearStyleOverrides(options) {
386
+ clearStyleOverrides(this, options);
387
+ }
388
+ get isEmpty() {
389
+ return this.children.length === 0;
390
+ }
391
+ clone() {
392
+ return new Paragraph(this.toJSON());
352
393
  }
353
394
  toJSON() {
354
395
  return {
355
396
  ...super.toJSON(),
356
- runs: this.runs.map((run) => run.toJSON()),
397
+ children: this.children.map((child) => child.toJSON()),
357
398
  };
358
399
  }
359
- /** Create a paragraph from its JSON representation. */
400
+ /** Compute a string representation of this paragraph by concatenating the string representations of all of its children. */
401
+ stringify(options, context) {
402
+ return this.children.map((x, index) => (index > 0 && x.type === "list") ? `${options?.paragraphBreak ?? " "}${x.stringify(options, context)}` : x.stringify(options, context)).join("") ?? "";
403
+ }
404
+ equals(other) {
405
+ return (other instanceof Paragraph) && super.equals(other);
406
+ }
407
+ }
408
+ exports.Paragraph = Paragraph;
409
+ /** A collection of list items ([[Paragraph]]s). Lists can be appended to [[Paragraph]]s.
410
+ * Lists will be laid out on a new line. Each item in a list is laid out on a separate line.
411
+ * @beta
412
+ */
413
+ class List extends TextBlockComponent {
414
+ type = "list";
415
+ children;
416
+ constructor(props) {
417
+ super(props);
418
+ this.children = props?.children?.map((child) => Paragraph.create(child)) ?? [];
419
+ }
420
+ /** Create a list from its JSON representation. */
360
421
  static create(props) {
361
- return new Paragraph(props);
422
+ return new List({ ...props, type: "list" });
423
+ }
424
+ clearStyleOverrides(options) {
425
+ clearStyleOverrides(this, options);
426
+ }
427
+ get isEmpty() {
428
+ return this.children.length === 0;
362
429
  }
363
430
  clone() {
364
- return new Paragraph(this.toJSON());
431
+ return new List(this.toJSON());
365
432
  }
366
- /**
367
- * Clears any [[styleOverrides]] applied to this Paragraph.
368
- * Will also clear [[styleOverrides]] from all child components unless [[ClearTextStyleOptions.preserveChildrenOverrides]] is `true`.
369
- */
370
- clearStyleOverrides(options) {
371
- super.clearStyleOverrides();
372
- if (options?.preserveChildrenOverrides)
373
- return;
374
- for (const run of this.runs) {
375
- run.clearStyleOverrides();
376
- }
433
+ toJSON() {
434
+ return {
435
+ ...super.toJSON(),
436
+ type: "list",
437
+ children: this.children.map((run) => run.toJSON()),
438
+ };
377
439
  }
378
- /** Compute a string representation of this paragraph by concatenating the string representations of all of its [[runs]]. */
379
- stringify(options) {
380
- return this.runs.map((x) => x.stringify(options)).join("");
440
+ /** Compute a string representation of this list by concatenating the string representations of all of its [[children]]. */
441
+ stringify(options, context) {
442
+ const children = this.children.map((x, index) => {
443
+ const depth = context?.depth ?? 0;
444
+ const marker = getMarkerText(this.styleOverrides.listMarker ?? TextStyle_1.TextStyleSettings.defaultProps.listMarker, index + 1);
445
+ const tab = (options?.tabsAsSpaces ? " ".repeat(options.tabsAsSpaces) : "\t").repeat(depth);
446
+ return `${tab}${marker}${options?.listMarkerBreak ?? " "}${x.stringify(options, { depth: depth + 1 })}`;
447
+ });
448
+ return children.join(options?.paragraphBreak ?? " ") ?? "";
381
449
  }
382
450
  equals(other) {
383
- if (!(other instanceof Paragraph)) {
384
- return false;
385
- }
386
- if (this.runs.length !== other.runs.length || !super.equals(other)) {
387
- return false;
388
- }
389
- return this.runs.every((run, index) => run.equals(other.runs[index]));
451
+ return (other instanceof List) && super.equals(other);
390
452
  }
391
453
  }
392
- exports.Paragraph = Paragraph;
454
+ exports.List = List;
393
455
  ;
394
- /** Represents a formatted text document consisting of a series of [[Paragraph]]s, each laid out on a separate line and containing their own content in the form of [[Run]]s.
395
- * You can change the content of the document by directly modifying the contents of its [[paragraphs]], or via [[appendParagraph]] and [[appendRun]].
456
+ /** Represents a formatted text document consisting of a series of [[Paragraph]]s, each laid out on a separate line and containing their own content.
396
457
  * No word-wrapping is applied to the document unless a [[width]] greater than zero is specified.
397
458
  * @see [[TextAnnotation]] to position a text block as an annotation in 2d or 3d space.
398
459
  * @beta
399
460
  */
400
461
  class TextBlock extends TextBlockComponent {
401
- /** The ID of the [AnnotationTextStyle]($backend) that provides the base formatting for the contents of this TextBlock.
402
- * @note Assigning to this property retains all style overrides on the TextBlock and its child components.
403
- * Call [[clearStyleOverrides]] to clear the TextBlock's and optionally all children's style overrides.
404
- */
405
- styleId;
462
+ children;
406
463
  /** The width of the document in meters. Lines that would exceed this width are instead wrapped around to the next line if possible.
407
464
  * A value less than or equal to zero indicates no wrapping is to be applied.
408
465
  * Default: 0
@@ -412,11 +469,8 @@ class TextBlock extends TextBlockComponent {
412
469
  justification;
413
470
  /** The margins of the document. */
414
471
  margins;
415
- /** The ordered list of paragraphs within the document. */
416
- paragraphs;
417
472
  constructor(props) {
418
473
  super(props);
419
- this.styleId = props.styleId;
420
474
  this.width = props.width ?? 0;
421
475
  this.justification = props.justification ?? "left";
422
476
  // Assign default margins if not provided
@@ -426,87 +480,152 @@ class TextBlock extends TextBlockComponent {
426
480
  top: props.margins?.top ?? 0,
427
481
  bottom: props.margins?.bottom ?? 0,
428
482
  };
429
- this.paragraphs = props.paragraphs?.map((x) => Paragraph.create(x)) ?? [];
483
+ this.children = props?.children?.map((para) => Paragraph.create(para)) ?? [];
484
+ }
485
+ clearStyleOverrides(options) {
486
+ clearStyleOverrides(this, options);
430
487
  }
431
488
  toJSON() {
432
489
  return {
433
490
  ...super.toJSON(),
434
- styleId: this.styleId,
435
491
  width: this.width,
436
492
  justification: this.justification,
437
493
  margins: this.margins,
438
- paragraphs: this.paragraphs.map((x) => x.toJSON()),
494
+ children: this.children.map((x) => x.toJSON()),
439
495
  };
440
496
  }
441
497
  /** Create a text block from its JSON representation. */
442
498
  static create(props) {
443
- return new TextBlock(props);
444
- }
445
- /** Create an empty text block containing no [[paragraphs]] and an empty [[styleId]]. */
446
- static createEmpty() {
447
- return TextBlock.create({ styleId: "" });
499
+ return new TextBlock(props ?? {});
448
500
  }
449
501
  /** Returns true if every paragraph in this text block is empty. */
450
502
  get isEmpty() {
451
- return this.paragraphs.every((p) => p.runs.length === 0);
503
+ return !this.children || this.children.every((child) => child.isEmpty);
452
504
  }
453
505
  clone() {
454
506
  return new TextBlock(this.toJSON());
455
507
  }
456
- /**
457
- * Clears any [[styleOverrides]] applied to this TextBlock.
458
- * Will also clear [[styleOverrides]] from all child components unless [[ClearTextStyleOptions.preserveChildrenOverrides]] is `true`.
459
- */
460
- clearStyleOverrides(options) {
461
- super.clearStyleOverrides();
462
- if (options?.preserveChildrenOverrides)
463
- return;
464
- for (const paragraph of this.paragraphs) {
465
- paragraph.clearStyleOverrides();
466
- }
467
- }
468
- /** Compute a string representation of the document's contents by concatenating the string representations of each of its [[paragraphs]], separated by [[TextBlockStringifyOptions.paragraphBreak]]. */
508
+ /** Compute a string representation of the document's contents by concatenating the string representations of each of its [[children]], separated by [[TextBlockStringifyOptions.paragraphBreak]]. */
469
509
  stringify(options) {
470
- return this.paragraphs.map((x) => x.stringify(options)).join(options?.paragraphBreak ?? " ");
510
+ return this.children.map((x) => x.stringify(options)).join(options?.paragraphBreak ?? " ") || "";
471
511
  }
472
512
  /** Add and return a new paragraph.
473
513
  * By default, the paragraph will be created with no [[styleOverrides]], so that it inherits the style of this block.
474
- * @param seedFromLast If true and [[paragraphs]] is not empty, the new paragraph will inherit the style overrides of the last [[Paragraph]] in this block.
514
+ * @param seedFromLast If true and [[children]] is not empty, the new paragraph will inherit the style overrides of the last child in this block.
515
+ * @note Be sure you pass in [[ParagraphProps]] and not [[Paragraph]] or style overrides will be ignored.
475
516
  */
476
- appendParagraph(seedFromLast = false) {
477
- let styleOverrides = {};
478
- if (seedFromLast && this.paragraphs.length > 0) {
479
- const seed = this.paragraphs[this.paragraphs.length - 1];
480
- styleOverrides = { ...seed.styleOverrides };
481
- }
482
- const paragraph = Paragraph.create({
483
- styleOverrides
484
- });
485
- this.paragraphs.push(paragraph);
517
+ appendParagraph(props, seedFromLast = false) {
518
+ const seed = seedFromLast ? this.children[this.children.length - 1] : undefined;
519
+ const styleOverrides = { ...seed?.styleOverrides, ...props?.styleOverrides };
520
+ const paragraph = Paragraph.create({ ...props, styleOverrides });
521
+ this.children.push(paragraph);
486
522
  return paragraph;
487
523
  }
488
524
  /** Append a run to the last [[Paragraph]] in this block.
489
- * If the block contains no [[paragraphs]], a new one will first be created using [[appendParagraph]].
525
+ * If the block contains no [[children]], a new [[Paragraph]] will first be created using [[appendParagraph]].
490
526
  */
491
527
  appendRun(run) {
492
- const paragraph = this.paragraphs[this.paragraphs.length - 1] ?? this.appendParagraph();
493
- paragraph.runs.push(run);
528
+ const paragraph = this.children[this.children.length - 1] ?? this.appendParagraph();
529
+ paragraph.children.push(run);
494
530
  }
495
531
  equals(other) {
496
532
  if (!(other instanceof TextBlock)) {
497
533
  return false;
498
534
  }
499
- if (this.styleId !== other.styleId || !super.equals(other)) {
535
+ if (!super.equals(other)) {
500
536
  return false;
501
537
  }
502
- if (this.width !== other.width || this.justification !== other.justification || this.paragraphs.length !== other.paragraphs.length) {
538
+ if (this.width !== other.width || this.justification !== other.justification) {
503
539
  return false;
504
540
  }
505
541
  const marginsAreEqual = Object.entries(this.margins).every(([key, value]) => value === other.margins[key]);
506
542
  if (!marginsAreEqual)
507
543
  return false;
508
- return this.paragraphs.every((paragraph, index) => paragraph.equals(other.paragraphs[index]));
544
+ if (this.children && other.children) {
545
+ if (this.children.length !== other.children.length) {
546
+ return false;
547
+ }
548
+ return this.children.every((child, index) => other.children && child.equals(other.children[index]));
549
+ }
550
+ return true;
509
551
  }
510
552
  }
511
553
  exports.TextBlock = TextBlock;
554
+ /**
555
+ * Recursively traverses a [[StructuralTextBlockComponent]] tree, yielding each child component along with its parent container.
556
+ * This generator enables depth-first iteration over all components in a text block structure, including paragraphs, lists, and runs.
557
+ *
558
+ * @param parent The root container whose children should be traversed.
559
+ * @returns An IterableIterator yielding objects with the child component and its parent container.
560
+ * @beta
561
+ */
562
+ function* traverseTextBlockComponent(parent) {
563
+ for (const child of parent.children) {
564
+ yield { parent, child };
565
+ if (child.type === "list" || child.type === "paragraph") {
566
+ yield* traverseTextBlockComponent(child);
567
+ }
568
+ }
569
+ }
570
+ /**
571
+ * Returns the formatted marker text for a list item based on the marker type and item number.
572
+ * Supports ordered and unordered list markers, including alphabetic, Roman numeral, and numeric formats.
573
+ * @param marker The type of list marker to use.
574
+ * @param num The item number in the list.
575
+ * @returns The formatted marker string for the list item.
576
+ * @beta
577
+ */
578
+ function getMarkerText(marker, num) {
579
+ let markerString = "";
580
+ switch (marker.enumerator) {
581
+ case undefined:
582
+ case TextStyle_1.ListMarkerEnumerator.Number:
583
+ markerString = `${num}`;
584
+ break;
585
+ case TextStyle_1.ListMarkerEnumerator.Letter:
586
+ markerString = integerToAlpha(num);
587
+ break;
588
+ case TextStyle_1.ListMarkerEnumerator.RomanNumeral:
589
+ markerString = integerToRoman(num);
590
+ break;
591
+ default:
592
+ markerString = marker.enumerator;
593
+ break;
594
+ }
595
+ if (marker.case) {
596
+ markerString = marker.case === "upper" ? markerString.toUpperCase() : markerString.toLowerCase();
597
+ }
598
+ const terminator = marker.terminator === "period" ? "." : marker.terminator === "parenthesis" ? ")" : "";
599
+ return `${markerString}${terminator}`;
600
+ }
601
+ /**
602
+ * Converts an integer to its Roman numeral representation.
603
+ * Supports numbers from 1 and above.
604
+ * @param num The integer to convert.
605
+ * @returns The Roman numeral string.
606
+ */
607
+ function integerToRoman(num) {
608
+ const values = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1];
609
+ const symbols = ['M', 'CM', 'D', 'CD', 'C', 'XC', 'L', 'XL', 'X', 'IX', 'V', 'IV', 'I'];
610
+ let roman = '';
611
+ for (let i = 0; i < values.length; i++) {
612
+ while (num >= values[i]) {
613
+ roman += symbols[i];
614
+ num -= values[i];
615
+ }
616
+ }
617
+ return roman;
618
+ }
619
+ /**
620
+ * Converts an integer to its alphabetic representation (A-Z, AA-ZZ, etc.).
621
+ * Used for ordered list markers with alphabetic styles.
622
+ * @param num The integer to convert (1-based).
623
+ * @returns The alphabetic string for the given number.
624
+ */
625
+ function integerToAlpha(num) {
626
+ const letterOffset = (num - 1) % 26;
627
+ const letter = String.fromCharCode(65 + letterOffset);
628
+ const depth = Math.ceil(num / 26);
629
+ return letter.repeat(depth);
630
+ }
512
631
  //# sourceMappingURL=TextBlock.js.map