@opentui/core 0.1.19-snapshot5-5ed8b651 → 0.1.20

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/index.js CHANGED
@@ -1,6 +1,7 @@
1
1
  // @bun
2
2
  import {
3
3
  ASCIIFontSelectionHelper,
4
+ BaseRenderable,
4
5
  BorderCharArrays,
5
6
  BorderChars,
6
7
  CliRenderEvents,
@@ -80,6 +81,7 @@ import {
80
81
  isPositionTypeType,
81
82
  isRenderable,
82
83
  isSizeType,
84
+ isStyledText,
83
85
  isVNode,
84
86
  isValidPercentage,
85
87
  italic,
@@ -113,12 +115,11 @@ import {
113
115
  strikethrough,
114
116
  stringToStyledText,
115
117
  t,
116
- tn,
117
118
  underline,
118
119
  white,
119
120
  wrapWithDelegates,
120
121
  yellow
121
- } from "./index-grak7z0n.js";
122
+ } from "./index-23dkhv32.js";
122
123
  // src/post/filters.ts
123
124
  function applyScanlines(buffer, strength = 0.8, step = 2) {
124
125
  const width = buffer.width;
@@ -1444,6 +1445,192 @@ class FrameBufferRenderable extends Renderable {
1444
1445
  super.destroySelf();
1445
1446
  }
1446
1447
  }
1448
+ // src/renderables/TextNode.ts
1449
+ var BrandedTextNodeRenderable = Symbol.for("@opentui/core/TextNodeRenderable");
1450
+ function isTextNodeRenderable(obj) {
1451
+ return !!obj?.[BrandedTextNodeRenderable];
1452
+ }
1453
+ function styledTextToTextNodes(styledText) {
1454
+ return styledText.chunks.map((chunk) => {
1455
+ const node = new TextNodeRenderable({
1456
+ fg: chunk.fg,
1457
+ bg: chunk.bg,
1458
+ attributes: chunk.attributes
1459
+ });
1460
+ node.add(chunk.text);
1461
+ return node;
1462
+ });
1463
+ }
1464
+
1465
+ class TextNodeRenderable extends BaseRenderable {
1466
+ [BrandedTextNodeRenderable] = true;
1467
+ fg;
1468
+ bg;
1469
+ attributes;
1470
+ _children = [];
1471
+ parent = null;
1472
+ constructor(options) {
1473
+ super(options);
1474
+ this.fg = options.fg ? parseColor(options.fg) : undefined;
1475
+ this.bg = options.bg ? parseColor(options.bg) : undefined;
1476
+ this.attributes = options.attributes ?? 0;
1477
+ }
1478
+ get children() {
1479
+ return this._children;
1480
+ }
1481
+ set children(children) {
1482
+ this._children = children;
1483
+ this.requestRender();
1484
+ }
1485
+ requestRender() {
1486
+ this.markDirty();
1487
+ this.parent?.requestRender();
1488
+ }
1489
+ add(obj, index) {
1490
+ if (typeof obj === "string") {
1491
+ if (index !== undefined) {
1492
+ this._children.splice(index, 0, obj);
1493
+ this.requestRender();
1494
+ return index;
1495
+ }
1496
+ const insertIndex = this._children.length;
1497
+ this._children.push(obj);
1498
+ this.requestRender();
1499
+ return insertIndex;
1500
+ }
1501
+ if (isTextNodeRenderable(obj)) {
1502
+ if (index !== undefined) {
1503
+ this._children.splice(index, 0, obj);
1504
+ obj.parent = this;
1505
+ this.requestRender();
1506
+ return index;
1507
+ }
1508
+ const insertIndex = this._children.length;
1509
+ this._children.push(obj);
1510
+ obj.parent = this;
1511
+ this.requestRender();
1512
+ return insertIndex;
1513
+ }
1514
+ if (isStyledText(obj)) {
1515
+ const textNodes = styledTextToTextNodes(obj);
1516
+ if (index !== undefined) {
1517
+ this._children.splice(index, 0, ...textNodes);
1518
+ textNodes.forEach((node) => node.parent = this);
1519
+ this.requestRender();
1520
+ return index;
1521
+ }
1522
+ const insertIndex = this._children.length;
1523
+ this._children.push(...textNodes);
1524
+ textNodes.forEach((node) => node.parent = this);
1525
+ this.requestRender();
1526
+ return insertIndex;
1527
+ }
1528
+ throw new Error("TextNodeRenderable only accepts strings, TextNodeRenderable instances, or StyledText instances");
1529
+ }
1530
+ insertBefore(child, anchorNode) {
1531
+ if (!anchorNode || !isTextNodeRenderable(anchorNode)) {
1532
+ throw new Error("Anchor must be a TextNodeRenderable");
1533
+ }
1534
+ const anchorIndex = this._children.indexOf(anchorNode);
1535
+ if (anchorIndex === -1) {
1536
+ throw new Error("Anchor node not found in children");
1537
+ }
1538
+ if (typeof child === "string") {
1539
+ this._children.splice(anchorIndex, 0, child);
1540
+ } else if (isTextNodeRenderable(child)) {
1541
+ this._children.splice(anchorIndex, 0, child);
1542
+ child.parent = this;
1543
+ } else if (child instanceof StyledText) {
1544
+ const textNodes = styledTextToTextNodes(child);
1545
+ this._children.splice(anchorIndex, 0, ...textNodes);
1546
+ textNodes.forEach((node) => node.parent = this);
1547
+ } else {
1548
+ throw new Error("Child must be a string, TextNodeRenderable, or StyledText instance");
1549
+ }
1550
+ this.requestRender();
1551
+ return this;
1552
+ }
1553
+ remove(child) {
1554
+ const childIndex = this._children.indexOf(child);
1555
+ if (childIndex === -1) {
1556
+ throw new Error("Child not found in children");
1557
+ }
1558
+ this._children.splice(childIndex, 1);
1559
+ if (typeof child !== "string") {
1560
+ child.parent = null;
1561
+ }
1562
+ this.requestRender();
1563
+ return this;
1564
+ }
1565
+ clear() {
1566
+ this._children = [];
1567
+ this.requestRender();
1568
+ }
1569
+ mergeStyles(parentStyle) {
1570
+ return {
1571
+ fg: this.fg ?? parentStyle.fg,
1572
+ bg: this.bg ?? parentStyle.bg,
1573
+ attributes: this.attributes | parentStyle.attributes
1574
+ };
1575
+ }
1576
+ gatherWithInheritedStyle(parentStyle = { fg: undefined, bg: undefined, attributes: 0 }) {
1577
+ const currentStyle = this.mergeStyles(parentStyle);
1578
+ const chunks = [];
1579
+ for (const child of this._children) {
1580
+ if (typeof child === "string") {
1581
+ chunks.push({
1582
+ __isChunk: true,
1583
+ text: child,
1584
+ fg: currentStyle.fg,
1585
+ bg: currentStyle.bg,
1586
+ attributes: currentStyle.attributes
1587
+ });
1588
+ } else {
1589
+ const childChunks = child.gatherWithInheritedStyle(currentStyle);
1590
+ chunks.push(...childChunks);
1591
+ }
1592
+ }
1593
+ this.markClean();
1594
+ return chunks;
1595
+ }
1596
+ static fromString(text, options = {}) {
1597
+ const node = new TextNodeRenderable(options);
1598
+ node.add(text);
1599
+ return node;
1600
+ }
1601
+ static fromNodes(nodes, options = {}) {
1602
+ const node = new TextNodeRenderable(options);
1603
+ for (const childNode of nodes) {
1604
+ node.add(childNode);
1605
+ }
1606
+ return node;
1607
+ }
1608
+ toChunks(parentStyle = { fg: undefined, bg: undefined, attributes: 0 }) {
1609
+ return this.gatherWithInheritedStyle(parentStyle);
1610
+ }
1611
+ getChildren() {
1612
+ return this._children.filter((child) => typeof child !== "string");
1613
+ }
1614
+ getChildrenCount() {
1615
+ return this._children.length;
1616
+ }
1617
+ getRenderable(id) {
1618
+ return this._children.find((child) => typeof child !== "string" && child.id === id);
1619
+ }
1620
+ }
1621
+
1622
+ class RootTextNodeRenderable extends TextNodeRenderable {
1623
+ ctx;
1624
+ constructor(ctx, options) {
1625
+ super(options);
1626
+ this.ctx = ctx;
1627
+ }
1628
+ requestRender() {
1629
+ this.markDirty();
1630
+ this.ctx.requestRender();
1631
+ }
1632
+ }
1633
+
1447
1634
  // src/renderables/Text.ts
1448
1635
  class TextRenderable extends Renderable {
1449
1636
  selectable = true;
@@ -1456,6 +1643,7 @@ class TextRenderable extends Renderable {
1456
1643
  lastLocalSelection = null;
1457
1644
  textBuffer;
1458
1645
  _lineInfo = { lineStarts: [], lineWidths: [] };
1646
+ rootTextNode;
1459
1647
  _defaultOptions = {
1460
1648
  content: "",
1461
1649
  fg: RGBA.fromValues(1, 1, 1, 1),
@@ -1481,15 +1669,41 @@ class TextRenderable extends Renderable {
1481
1669
  this.textBuffer.setDefaultBg(this._defaultBg);
1482
1670
  this.textBuffer.setDefaultAttributes(this._defaultAttributes);
1483
1671
  this.setupMeasureFunc();
1484
- this.updateTextInfo(styledText);
1672
+ this.rootTextNode = new RootTextNodeRenderable(ctx, {
1673
+ id: `${this.id}-root`,
1674
+ fg: this._defaultFg,
1675
+ bg: this._defaultBg,
1676
+ attributes: this._defaultAttributes
1677
+ });
1678
+ this.updateTextBuffer(styledText);
1679
+ this._text.mount(this);
1680
+ this.updateTextInfo();
1681
+ }
1682
+ updateTextBuffer(styledText) {
1683
+ this.textBuffer.setStyledText(styledText);
1684
+ this.clearChunks(styledText);
1485
1685
  }
1686
+ clearChunks(styledText) {}
1486
1687
  get content() {
1487
1688
  return this._text;
1488
1689
  }
1690
+ get plainText() {
1691
+ return this.textBuffer.getPlainText();
1692
+ }
1693
+ get textLength() {
1694
+ return this.textBuffer.length;
1695
+ }
1696
+ get chunks() {
1697
+ return this._text.chunks;
1698
+ }
1489
1699
  set content(value) {
1490
1700
  const styledText = typeof value === "string" ? stringToStyledText(value) : value;
1491
- this._text = styledText;
1492
- this.updateTextInfo(styledText);
1701
+ if (this._text !== styledText) {
1702
+ this._text = styledText;
1703
+ styledText.mount(this);
1704
+ this.updateTextBuffer(styledText);
1705
+ this.updateTextInfo();
1706
+ }
1493
1707
  }
1494
1708
  get fg() {
1495
1709
  return this._defaultFg;
@@ -1564,8 +1778,7 @@ class TextRenderable extends Renderable {
1564
1778
  }
1565
1779
  return this.textBuffer.setLocalSelection(localSelection.anchorX, localSelection.anchorY, localSelection.focusX, localSelection.focusY, this._selectionBg, this._selectionFg);
1566
1780
  }
1567
- updateTextInfo(styledText) {
1568
- this.updateTextBuffer(styledText);
1781
+ updateTextInfo() {
1569
1782
  const lineInfo = this.textBuffer.lineInfo;
1570
1783
  this._lineInfo.lineStarts = lineInfo.lineStarts;
1571
1784
  this._lineInfo.lineWidths = lineInfo.lineWidths;
@@ -1601,6 +1814,60 @@ class TextRenderable extends Renderable {
1601
1814
  };
1602
1815
  this.layoutNode.yogaNode.setMeasureFunc(measureFunc);
1603
1816
  }
1817
+ insertChunk(chunk, index) {
1818
+ this.textBuffer.insertChunkGroup(index ?? this.textBuffer.chunkGroupCount, chunk.text, chunk.fg, chunk.bg, chunk.attributes);
1819
+ this.updateTextInfo();
1820
+ this.clearChunks(this._text);
1821
+ }
1822
+ removeChunk(chunk) {
1823
+ const index = this._text.chunks.indexOf(chunk);
1824
+ if (index === -1)
1825
+ return;
1826
+ this.textBuffer.removeChunkGroup(index);
1827
+ this.updateTextInfo();
1828
+ this.clearChunks(this._text);
1829
+ }
1830
+ replaceChunk(chunk, oldChunk) {
1831
+ const index = this._text.chunks.indexOf(oldChunk);
1832
+ if (index === -1)
1833
+ return;
1834
+ this.textBuffer.replaceChunkGroup(index, chunk.text, chunk.fg, chunk.bg, chunk.attributes);
1835
+ this.updateTextInfo();
1836
+ this.clearChunks(this._text);
1837
+ }
1838
+ updateTextFromNodes() {
1839
+ if (this.rootTextNode.isDirty) {
1840
+ const chunks = this.rootTextNode.gatherWithInheritedStyle({
1841
+ fg: this._defaultFg,
1842
+ bg: this._defaultBg,
1843
+ attributes: this._defaultAttributes
1844
+ });
1845
+ this.textBuffer.setStyledText(new StyledText(chunks));
1846
+ this.updateTextInfo();
1847
+ }
1848
+ }
1849
+ add(obj, index) {
1850
+ return this.rootTextNode.add(obj, index);
1851
+ }
1852
+ remove(id) {
1853
+ const child = this.rootTextNode.getRenderable(id);
1854
+ if (child && isTextNodeRenderable(child)) {
1855
+ this.rootTextNode.remove(child);
1856
+ }
1857
+ }
1858
+ insertBefore(obj, anchor) {
1859
+ this.rootTextNode.insertBefore(obj, anchor);
1860
+ return this.rootTextNode.children.indexOf(obj);
1861
+ }
1862
+ clear() {
1863
+ this.rootTextNode.clear();
1864
+ const emptyStyledText = stringToStyledText("");
1865
+ this._text = emptyStyledText;
1866
+ emptyStyledText.mount(this);
1867
+ this.updateTextBuffer(emptyStyledText);
1868
+ this.updateTextInfo();
1869
+ this.requestRender();
1870
+ }
1604
1871
  shouldStartSelection(x, y) {
1605
1872
  if (!this.selectable)
1606
1873
  return false;
@@ -1626,8 +1893,15 @@ class TextRenderable extends Renderable {
1626
1893
  getSelection() {
1627
1894
  return this.textBuffer.getSelection();
1628
1895
  }
1629
- updateTextBuffer(styledText) {
1630
- this.textBuffer.setStyledText(styledText);
1896
+ render(buffer, deltaTime) {
1897
+ if (!this.visible)
1898
+ return;
1899
+ this.onUpdate(deltaTime);
1900
+ this.updateFromLayout();
1901
+ this.updateTextFromNodes();
1902
+ this.markClean();
1903
+ this._ctx.addToHitGrid(this.x, this.y, this.width, this.height, this.num);
1904
+ this.renderSelf(buffer);
1631
1905
  }
1632
1906
  renderSelf(buffer) {
1633
1907
  if (this.textBuffer.ptr) {
@@ -1642,6 +1916,7 @@ class TextRenderable extends Renderable {
1642
1916
  }
1643
1917
  destroy() {
1644
1918
  this.textBuffer.destroy();
1919
+ this.rootTextNode.children.length = 0;
1645
1920
  super.destroy();
1646
1921
  }
1647
1922
  }
@@ -3509,6 +3784,37 @@ function TabSelect(props, ...children) {
3509
3784
  function FrameBuffer(props, ...children) {
3510
3785
  return h(FrameBufferRenderable, props, ...children);
3511
3786
  }
3787
+ function StyledText2(props, ...children) {
3788
+ const styledProps = props;
3789
+ const textNodeOptions = {
3790
+ ...styledProps,
3791
+ attributes: styledProps?.attributes ?? 0
3792
+ };
3793
+ const textNode = new TextNodeRenderable(textNodeOptions);
3794
+ for (const child of children) {
3795
+ textNode.add(child);
3796
+ }
3797
+ return textNode;
3798
+ }
3799
+ var vstyles = {
3800
+ bold: (...children) => StyledText2({ attributes: TextAttributes.BOLD }, ...children),
3801
+ italic: (...children) => StyledText2({ attributes: TextAttributes.ITALIC }, ...children),
3802
+ underline: (...children) => StyledText2({ attributes: TextAttributes.UNDERLINE }, ...children),
3803
+ dim: (...children) => StyledText2({ attributes: TextAttributes.DIM }, ...children),
3804
+ blink: (...children) => StyledText2({ attributes: TextAttributes.BLINK }, ...children),
3805
+ inverse: (...children) => StyledText2({ attributes: TextAttributes.INVERSE }, ...children),
3806
+ hidden: (...children) => StyledText2({ attributes: TextAttributes.HIDDEN }, ...children),
3807
+ strikethrough: (...children) => StyledText2({ attributes: TextAttributes.STRIKETHROUGH }, ...children),
3808
+ boldItalic: (...children) => StyledText2({ attributes: TextAttributes.BOLD | TextAttributes.ITALIC }, ...children),
3809
+ boldUnderline: (...children) => StyledText2({ attributes: TextAttributes.BOLD | TextAttributes.UNDERLINE }, ...children),
3810
+ italicUnderline: (...children) => StyledText2({ attributes: TextAttributes.ITALIC | TextAttributes.UNDERLINE }, ...children),
3811
+ boldItalicUnderline: (...children) => StyledText2({ attributes: TextAttributes.BOLD | TextAttributes.ITALIC | TextAttributes.UNDERLINE }, ...children),
3812
+ color: (color, ...children) => StyledText2({ fg: color }, ...children),
3813
+ bgColor: (bgColor, ...children) => StyledText2({ bg: bgColor }, ...children),
3814
+ fg: (color, ...children) => StyledText2({ fg: color }, ...children),
3815
+ bg: (bgColor, ...children) => StyledText2({ bg: bgColor }, ...children),
3816
+ styled: (attributes = 0, ...children) => StyledText2({ attributes }, ...children)
3817
+ };
3512
3818
  // src/renderables/composition/VRenderable.ts
3513
3819
  class VRenderable extends Renderable {
3514
3820
  options;
@@ -3526,8 +3832,8 @@ export {
3526
3832
  yellow,
3527
3833
  wrapWithDelegates,
3528
3834
  white,
3835
+ vstyles,
3529
3836
  underline,
3530
- tn,
3531
3837
  t,
3532
3838
  stringToStyledText,
3533
3839
  strikethrough,
@@ -3561,6 +3867,8 @@ export {
3561
3867
  italic,
3562
3868
  isValidPercentage,
3563
3869
  isVNode,
3870
+ isTextNodeRenderable,
3871
+ isStyledText,
3564
3872
  isSizeType,
3565
3873
  isRenderable,
3566
3874
  isPositionTypeType,
@@ -3627,6 +3935,7 @@ export {
3627
3935
  TrackedNode,
3628
3936
  Timeline,
3629
3937
  TextRenderable,
3938
+ TextNodeRenderable,
3630
3939
  TextBuffer,
3631
3940
  TextAttributes,
3632
3941
  Text,
@@ -3642,6 +3951,7 @@ export {
3642
3951
  Select,
3643
3952
  ScrollBoxRenderable,
3644
3953
  ScrollBarRenderable,
3954
+ RootTextNodeRenderable,
3645
3955
  RootRenderable,
3646
3956
  RenderableEvents,
3647
3957
  Renderable,
@@ -3671,11 +3981,12 @@ export {
3671
3981
  BorderCharArrays,
3672
3982
  BlurEffect,
3673
3983
  BloomEffect,
3984
+ BaseRenderable,
3674
3985
  ArrowRenderable,
3675
3986
  ASCIIFontSelectionHelper,
3676
3987
  ASCIIFontRenderable,
3677
3988
  ASCIIFont
3678
3989
  };
3679
3990
 
3680
- //# debugId=288AEFAF1D35CBD764756E2164756E21
3991
+ //# debugId=1EBF2F0C32EEED6E64756E2164756E21
3681
3992
  //# sourceMappingURL=index.js.map