@codehz/draw-call 0.5.0 → 0.5.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.
package/node/index.mjs CHANGED
@@ -78,6 +78,19 @@ function normalizeBorderRadius(value) {
78
78
 
79
79
  //#endregion
80
80
  //#region src/layout/components/box.ts
81
+ /**
82
+ * 安全获取元素的 margin
83
+ * Transform 元素没有 margin,返回默认 spacing
84
+ */
85
+ function getElementMargin$2(element) {
86
+ if (element.type === "transform") return {
87
+ top: 0,
88
+ right: 0,
89
+ bottom: 0,
90
+ left: 0
91
+ };
92
+ return normalizeSpacing(element.margin);
93
+ }
81
94
  function calcEffectiveSize(element, padding, availableWidth) {
82
95
  return {
83
96
  width: typeof element.width === "number" ? element.width - padding.left - padding.right : availableWidth > 0 ? availableWidth : 0,
@@ -87,7 +100,7 @@ function calcEffectiveSize(element, padding, availableWidth) {
87
100
  function collectChildSizes(children, ctx, availableWidth, padding, measureChild) {
88
101
  const childSizes = [];
89
102
  for (const child of children) {
90
- const childMargin = normalizeSpacing(child.margin);
103
+ const childMargin = getElementMargin$2(child);
91
104
  const childSize = measureChild(child, ctx, availableWidth - padding.left - padding.right - childMargin.left - childMargin.right);
92
105
  childSizes.push({
93
106
  width: childSize.width,
@@ -156,7 +169,7 @@ function measureBoxSize(element, ctx, availableWidth, measureChild) {
156
169
  contentHeight = wrapped.height;
157
170
  } else for (let i = 0; i < children.length; i++) {
158
171
  const child = children[i];
159
- const childMargin = normalizeSpacing(child.margin);
172
+ const childMargin = getElementMargin$2(child);
160
173
  const childSize = measureChild(child, ctx, availableWidth - padding.left - padding.right - childMargin.left - childMargin.right);
161
174
  if (isRow) {
162
175
  contentWidth += childSize.width + childMargin.left + childMargin.right;
@@ -390,6 +403,19 @@ function wrapRichText(ctx, spans, maxWidth, lineHeightScale = 1.2, elementStyle
390
403
  //#endregion
391
404
  //#region src/layout/components/stack.ts
392
405
  /**
406
+ * 安全获取元素的 margin
407
+ * Transform 元素没有 margin,返回默认 spacing
408
+ */
409
+ function getElementMargin$1(element) {
410
+ if (element.type === "transform") return {
411
+ top: 0,
412
+ right: 0,
413
+ bottom: 0,
414
+ left: 0
415
+ };
416
+ return normalizeSpacing(element.margin);
417
+ }
418
+ /**
393
419
  * 测量 Stack 元素的固有尺寸
394
420
  */
395
421
  function measureStackSize(element, ctx, availableWidth, measureChild) {
@@ -398,7 +424,7 @@ function measureStackSize(element, ctx, availableWidth, measureChild) {
398
424
  let contentHeight = 0;
399
425
  const children = element.children ?? [];
400
426
  for (const child of children) {
401
- const childMargin = normalizeSpacing(child.margin);
427
+ const childMargin = getElementMargin$1(child);
402
428
  const childSize = measureChild(child, ctx, availableWidth - padding.left - padding.right - childMargin.left - childMargin.right);
403
429
  contentWidth = Math.max(contentWidth, childSize.width + childMargin.left + childMargin.right);
404
430
  contentHeight = Math.max(contentHeight, childSize.height + childMargin.top + childMargin.bottom);
@@ -637,18 +663,79 @@ function sizeNeedsParent(size) {
637
663
 
638
664
  //#endregion
639
665
  //#region src/layout/engine.ts
666
+ /**
667
+ * 类型守卫:检查 Element 是否为 LayoutElement(非 Transform)
668
+ * 由于 Transform 元素在 computeLayoutImpl 开始时被处理,
669
+ * 此时只应处理 LayoutElement
670
+ */
671
+ function assertLayoutElement(element) {
672
+ if (element.type === "transform") throw new Error("Transform elements should be handled at entry point");
673
+ }
674
+ /**
675
+ * 安全获取元素的 margin
676
+ * Transform 元素没有 margin,返回默认 spacing
677
+ */
678
+ function getElementMargin(element) {
679
+ if (element.type === "transform") return {
680
+ top: 0,
681
+ right: 0,
682
+ bottom: 0,
683
+ left: 0
684
+ };
685
+ return normalizeSpacing(element.margin);
686
+ }
687
+ /**
688
+ * 安全获取元素的布局属性(width, height, flex等)
689
+ * Transform 元素这些属性为 undefined
690
+ */
691
+ function getElementLayoutProps(element) {
692
+ if (element.type === "transform") return {
693
+ width: void 0,
694
+ height: void 0,
695
+ flex: void 0,
696
+ minWidth: void 0,
697
+ maxWidth: void 0,
698
+ minHeight: void 0,
699
+ maxHeight: void 0,
700
+ alignSelf: void 0
701
+ };
702
+ const le = element;
703
+ return {
704
+ width: le.width,
705
+ height: le.height,
706
+ flex: le.flex,
707
+ minWidth: le.minWidth,
708
+ maxWidth: le.maxWidth,
709
+ minHeight: le.minHeight,
710
+ maxHeight: le.maxHeight,
711
+ alignSelf: le.alignSelf
712
+ };
713
+ }
714
+ /**
715
+ * 布局计算主函数
716
+ * 内部使用 Element 类型以支持 Transform,外部通过 LayoutElement 约束类型
717
+ */
640
718
  function computeLayout(element, ctx, constraints, x = 0, y = 0) {
641
- const margin = normalizeSpacing(element.margin);
642
- const padding = normalizeSpacing("padding" in element ? element.padding : void 0);
719
+ return computeLayoutImpl(element, ctx, constraints, x, y);
720
+ }
721
+ /**
722
+ * 内部实现函数,处理所有元素类型包括 Transform
723
+ */
724
+ function computeLayoutImpl(element, ctx, constraints, x = 0, y = 0) {
725
+ if (element.type === "transform") return computeLayoutImpl(element.children, ctx, constraints, x, y);
726
+ assertLayoutElement(element);
727
+ const layoutElement = element;
728
+ const margin = normalizeSpacing(layoutElement.margin);
729
+ const padding = normalizeSpacing("padding" in layoutElement ? layoutElement.padding : void 0);
643
730
  const availableWidth = constraints.maxWidth - margin.left - margin.right;
644
731
  const availableHeight = constraints.maxHeight - margin.top - margin.bottom;
645
- const intrinsic = measureIntrinsicSize(element, ctx, availableWidth);
646
- let width = constraints.minWidth === constraints.maxWidth && constraints.minWidth > 0 ? constraints.maxWidth - margin.left - margin.right : resolveSize(element.width, availableWidth, intrinsic.width);
647
- let height = constraints.minHeight === constraints.maxHeight && constraints.minHeight > 0 ? constraints.maxHeight - margin.top - margin.bottom : resolveSize(element.height, availableHeight, intrinsic.height);
648
- if (element.minWidth !== void 0) width = Math.max(width, element.minWidth);
649
- if (element.maxWidth !== void 0) width = Math.min(width, element.maxWidth);
650
- if (element.minHeight !== void 0) height = Math.max(height, element.minHeight);
651
- if (element.maxHeight !== void 0) height = Math.min(height, element.maxHeight);
732
+ const intrinsic = measureIntrinsicSize(layoutElement, ctx, availableWidth);
733
+ let width = constraints.minWidth === constraints.maxWidth && constraints.minWidth > 0 ? constraints.maxWidth - margin.left - margin.right : resolveSize(layoutElement.width, availableWidth, intrinsic.width);
734
+ let height = constraints.minHeight === constraints.maxHeight && constraints.minHeight > 0 ? constraints.maxHeight - margin.top - margin.bottom : resolveSize(layoutElement.height, availableHeight, intrinsic.height);
735
+ if (layoutElement.minWidth !== void 0) width = Math.max(width, layoutElement.minWidth);
736
+ if (layoutElement.maxWidth !== void 0) width = Math.min(width, layoutElement.maxWidth);
737
+ if (layoutElement.minHeight !== void 0) height = Math.max(height, layoutElement.minHeight);
738
+ if (layoutElement.maxHeight !== void 0) height = Math.min(height, layoutElement.maxHeight);
652
739
  const actualX = x + margin.left;
653
740
  const actualY = y + margin.top;
654
741
  const contentX = actualX + padding.left;
@@ -656,7 +743,7 @@ function computeLayout(element, ctx, constraints, x = 0, y = 0) {
656
743
  const contentWidth = width - padding.left - padding.right;
657
744
  const contentHeight = height - padding.top - padding.bottom;
658
745
  const node = {
659
- element,
746
+ element: layoutElement,
660
747
  layout: {
661
748
  x: actualX,
662
749
  y: actualY,
@@ -669,14 +756,14 @@ function computeLayout(element, ctx, constraints, x = 0, y = 0) {
669
756
  },
670
757
  children: []
671
758
  };
672
- if (element.type === "text") {
673
- const font = element.font ?? {};
674
- if (element.wrap && contentWidth > 0) {
675
- let { lines, offsets } = wrapText(ctx, element.content, contentWidth, font);
676
- if (element.maxLines && lines.length > element.maxLines) {
677
- lines = lines.slice(0, element.maxLines);
678
- offsets = offsets.slice(0, element.maxLines);
679
- if (element.ellipsis && lines.length > 0) {
759
+ if (layoutElement.type === "text") {
760
+ const font = layoutElement.font ?? {};
761
+ if (layoutElement.wrap && contentWidth > 0) {
762
+ let { lines, offsets } = wrapText(ctx, layoutElement.content, contentWidth, font);
763
+ if (layoutElement.maxLines && lines.length > layoutElement.maxLines) {
764
+ lines = lines.slice(0, layoutElement.maxLines);
765
+ offsets = offsets.slice(0, layoutElement.maxLines);
766
+ if (layoutElement.ellipsis && lines.length > 0) {
680
767
  const lastIdx = lines.length - 1;
681
768
  const truncated = truncateText(ctx, lines[lastIdx], contentWidth, font);
682
769
  lines[lastIdx] = truncated.text;
@@ -686,17 +773,17 @@ function computeLayout(element, ctx, constraints, x = 0, y = 0) {
686
773
  node.lines = lines;
687
774
  node.lineOffsets = offsets;
688
775
  } else {
689
- const { text, offset } = truncateText(ctx, element.content, contentWidth > 0 && element.ellipsis ? contentWidth : Infinity, font);
776
+ const { text, offset } = truncateText(ctx, layoutElement.content, contentWidth > 0 && layoutElement.ellipsis ? contentWidth : Infinity, font);
690
777
  node.lines = [text];
691
778
  node.lineOffsets = [offset];
692
779
  }
693
780
  }
694
- if (element.type === "richtext") {
695
- const lineHeight = element.lineHeight ?? 1.2;
696
- let lines = wrapRichText(ctx, element.spans, contentWidth, lineHeight);
697
- if (element.maxLines && lines.length > element.maxLines) {
698
- lines = lines.slice(0, element.maxLines);
699
- if (element.ellipsis && lines.length > 0) {
781
+ if (layoutElement.type === "richtext") {
782
+ const lineHeight = layoutElement.lineHeight ?? 1.2;
783
+ let lines = wrapRichText(ctx, layoutElement.spans, contentWidth, lineHeight);
784
+ if (layoutElement.maxLines && lines.length > layoutElement.maxLines) {
785
+ lines = lines.slice(0, layoutElement.maxLines);
786
+ if (layoutElement.ellipsis && lines.length > 0) {
700
787
  const lastLine = lines[lines.length - 1];
701
788
  if (lastLine.segments.length > 0) {
702
789
  const lastSeg = lastLine.segments[lastLine.segments.length - 1];
@@ -708,19 +795,19 @@ function computeLayout(element, ctx, constraints, x = 0, y = 0) {
708
795
  }
709
796
  node.richLines = lines;
710
797
  }
711
- if (element.type === "box" || element.type === "stack") {
712
- const children = element.children ?? [];
713
- if (element.type === "stack") {
714
- const stackAlign = element.align ?? "start";
715
- const stackJustify = element.justify ?? "start";
798
+ if (layoutElement.type === "box" || layoutElement.type === "stack") {
799
+ const children = layoutElement.children ?? [];
800
+ if (layoutElement.type === "stack") {
801
+ const stackAlign = layoutElement.align ?? "start";
802
+ const stackJustify = layoutElement.justify ?? "start";
716
803
  for (const child of children) {
717
- const childNode = computeLayout(child, ctx, {
804
+ const childNode = computeLayoutImpl(child, ctx, {
718
805
  minWidth: 0,
719
806
  maxWidth: contentWidth,
720
807
  minHeight: 0,
721
808
  maxHeight: contentHeight
722
809
  }, contentX, contentY);
723
- const childMargin = normalizeSpacing(child.margin);
810
+ const childMargin = getElementMargin(child);
724
811
  const childOuterWidth = childNode.layout.width + childMargin.left + childMargin.right;
725
812
  const childOuterHeight = childNode.layout.height + childMargin.top + childMargin.bottom;
726
813
  let offsetX = 0;
@@ -733,19 +820,21 @@ function computeLayout(element, ctx, constraints, x = 0, y = 0) {
733
820
  node.children.push(childNode);
734
821
  }
735
822
  } else {
736
- const direction = element.direction ?? "row";
737
- const justify = element.justify ?? "start";
738
- const align = element.align ?? "stretch";
739
- const gap = element.gap ?? 0;
740
- const wrap = element.wrap ?? false;
823
+ const boxElement = layoutElement;
824
+ const direction = boxElement.direction ?? "row";
825
+ const justify = boxElement.justify ?? "start";
826
+ const align = boxElement.align ?? "stretch";
827
+ const gap = boxElement.gap ?? 0;
828
+ const wrap = boxElement.wrap ?? false;
741
829
  const isRow = direction === "row" || direction === "row-reverse";
742
830
  const isReverse = direction === "row-reverse" || direction === "column-reverse";
743
831
  const getContentMainSize = () => isRow ? contentWidth : contentHeight;
744
832
  const getContentCrossSize = () => isRow ? contentHeight : contentWidth;
745
833
  const childInfos = [];
746
834
  for (const child of children) {
747
- const childMargin = normalizeSpacing(child.margin);
748
- const childFlex = child.flex ?? 0;
835
+ const childMargin = getElementMargin(child);
836
+ const childProps = getElementLayoutProps(child);
837
+ const childFlex = childProps.flex ?? 0;
749
838
  if (childFlex > 0) childInfos.push({
750
839
  element: child,
751
840
  width: 0,
@@ -755,10 +844,10 @@ function computeLayout(element, ctx, constraints, x = 0, y = 0) {
755
844
  });
756
845
  else {
757
846
  const size = measureIntrinsicSize(child, ctx, contentWidth - childMargin.left - childMargin.right);
758
- const shouldStretchWidth = !isRow && child.width === void 0 && align === "stretch";
759
- const shouldStretchHeight = isRow && child.height === void 0 && align === "stretch";
760
- let w = sizeNeedsParent(child.width) ? resolveSize(child.width, contentWidth - childMargin.left - childMargin.right, size.width) : resolveSize(child.width, 0, size.width);
761
- let h = sizeNeedsParent(child.height) ? resolveSize(child.height, contentHeight - childMargin.top - childMargin.bottom, size.height) : resolveSize(child.height, 0, size.height);
847
+ const shouldStretchWidth = !isRow && childProps.width === void 0 && align === "stretch";
848
+ const shouldStretchHeight = isRow && childProps.height === void 0 && align === "stretch";
849
+ let w = sizeNeedsParent(childProps.width) ? resolveSize(childProps.width, contentWidth - childMargin.left - childMargin.right, size.width) : resolveSize(childProps.width, 0, size.width);
850
+ let h = sizeNeedsParent(childProps.height) ? resolveSize(childProps.height, contentHeight - childMargin.top - childMargin.bottom, size.height) : resolveSize(childProps.height, 0, size.height);
762
851
  if (shouldStretchWidth && !wrap) w = contentWidth - childMargin.left - childMargin.right;
763
852
  if (shouldStretchHeight && !wrap) h = contentHeight - childMargin.top - childMargin.bottom;
764
853
  childInfos.push({
@@ -799,14 +888,15 @@ function computeLayout(element, ctx, constraints, x = 0, y = 0) {
799
888
  const availableForFlex = Math.max(0, mainAxisSize - totalFixed - totalGap);
800
889
  for (const info of lineInfos) if (info.flex > 0) {
801
890
  const flexSize = totalFlex > 0 ? availableForFlex * info.flex / totalFlex : 0;
891
+ const childProps = getElementLayoutProps(info.element);
802
892
  if (isRow) {
803
893
  info.width = flexSize;
804
894
  const size = measureIntrinsicSize(info.element, ctx, flexSize);
805
- info.height = sizeNeedsParent(info.element.height) ? resolveSize(info.element.height, contentHeight - info.margin.top - info.margin.bottom, size.height) : resolveSize(info.element.height, 0, size.height);
895
+ info.height = sizeNeedsParent(childProps.height) ? resolveSize(childProps.height, contentHeight - info.margin.top - info.margin.bottom, size.height) : resolveSize(childProps.height, 0, size.height);
806
896
  } else {
807
897
  info.height = flexSize;
808
898
  const size = measureIntrinsicSize(info.element, ctx, contentWidth - info.margin.left - info.margin.right);
809
- info.width = sizeNeedsParent(info.element.width) ? resolveSize(info.element.width, contentWidth - info.margin.left - info.margin.right, size.width) : resolveSize(info.element.width, 0, size.width);
899
+ info.width = sizeNeedsParent(childProps.width) ? resolveSize(childProps.width, contentWidth - info.margin.left - info.margin.right, size.width) : resolveSize(childProps.width, 0, size.width);
810
900
  }
811
901
  }
812
902
  }
@@ -857,17 +947,18 @@ function computeLayout(element, ctx, constraints, x = 0, y = 0) {
857
947
  const orderedInfos = isReverse ? [...lineInfos].reverse() : lineInfos;
858
948
  for (let i = 0; i < orderedInfos.length; i++) {
859
949
  const info = orderedInfos[i];
950
+ const childProps = getElementLayoutProps(info.element);
860
951
  const crossAxisSize = wrap ? lineCrossSize : getContentCrossSize();
861
952
  const childCrossSize = isRow ? info.height + info.margin.top + info.margin.bottom : info.width + info.margin.left + info.margin.right;
862
953
  let itemCrossOffset = 0;
863
- const effectiveAlign = info.element.alignSelf ?? align;
954
+ const effectiveAlign = childProps.alignSelf ?? align;
864
955
  if (effectiveAlign === "start") itemCrossOffset = 0;
865
956
  else if (effectiveAlign === "end") itemCrossOffset = crossAxisSize - childCrossSize;
866
957
  else if (effectiveAlign === "center") itemCrossOffset = (crossAxisSize - childCrossSize) / 2;
867
958
  else if (effectiveAlign === "stretch") {
868
959
  itemCrossOffset = 0;
869
- if (isRow && info.element.height === void 0) info.height = crossAxisSize - info.margin.top - info.margin.bottom;
870
- else if (!isRow && info.element.width === void 0) info.width = crossAxisSize - info.margin.left - info.margin.right;
960
+ if (isRow && childProps.height === void 0) info.height = crossAxisSize - info.margin.top - info.margin.bottom;
961
+ else if (!isRow && childProps.width === void 0) info.width = crossAxisSize - info.margin.left - info.margin.right;
871
962
  }
872
963
  const childX = isRow ? contentX + mainOffset + info.margin.left : contentX + crossOffset + itemCrossOffset + info.margin.left;
873
964
  const childY = isRow ? contentY + crossOffset + itemCrossOffset + info.margin.top : contentY + mainOffset + info.margin.top;
@@ -876,26 +967,29 @@ function computeLayout(element, ctx, constraints, x = 0, y = 0) {
876
967
  let minHeight = 0;
877
968
  let maxHeight = info.height;
878
969
  let shouldStretchCross = false;
879
- if (info.flex > 0) if (isRow) {
880
- minWidth = maxWidth = info.width;
881
- if (info.element.height === void 0 && align === "stretch") {
882
- minHeight = info.height;
883
- maxHeight = element.height !== void 0 ? info.height : Infinity;
884
- shouldStretchCross = true;
970
+ if (info.flex > 0) {
971
+ const childProps = getElementLayoutProps(info.element);
972
+ if (isRow) {
973
+ minWidth = maxWidth = info.width;
974
+ if (childProps.height === void 0 && align === "stretch") {
975
+ minHeight = info.height;
976
+ maxHeight = boxElement.height !== void 0 ? info.height : Infinity;
977
+ shouldStretchCross = true;
978
+ }
979
+ } else {
980
+ minHeight = maxHeight = info.height;
981
+ if (childProps.width === void 0 && align === "stretch") {
982
+ minWidth = info.width;
983
+ maxWidth = boxElement.width !== void 0 ? info.width : Infinity;
984
+ shouldStretchCross = true;
985
+ }
885
986
  }
886
987
  } else {
887
- minHeight = maxHeight = info.height;
888
- if (info.element.width === void 0 && align === "stretch") {
889
- minWidth = info.width;
890
- maxWidth = element.width !== void 0 ? info.width : Infinity;
891
- shouldStretchCross = true;
892
- }
988
+ const childProps = getElementLayoutProps(info.element);
989
+ if (!isRow && childProps.width === void 0 && align === "stretch") minWidth = maxWidth = crossAxisSize - info.margin.left - info.margin.right;
990
+ if (isRow && childProps.height === void 0 && align === "stretch") minHeight = maxHeight = crossAxisSize - info.margin.top - info.margin.bottom;
893
991
  }
894
- else {
895
- if (!isRow && info.element.width === void 0 && align === "stretch") minWidth = maxWidth = crossAxisSize - info.margin.left - info.margin.right;
896
- if (isRow && info.element.height === void 0 && align === "stretch") minHeight = maxHeight = crossAxisSize - info.margin.top - info.margin.bottom;
897
- }
898
- const childNode = computeLayout(info.element, ctx, {
992
+ const childNode = computeLayoutImpl(info.element, ctx, {
899
993
  minWidth,
900
994
  maxWidth,
901
995
  minHeight,
@@ -918,12 +1012,12 @@ function computeLayout(element, ctx, constraints, x = 0, y = 0) {
918
1012
  crossOffset += lineCrossSize;
919
1013
  if (lineIndex < lines.length - 1) crossOffset += gap;
920
1014
  }
921
- if (wrap && element.height === void 0 && isRow) {
1015
+ if (wrap && boxElement.height === void 0 && isRow) {
922
1016
  const actualContentHeight = crossOffset;
923
1017
  const actualHeight = actualContentHeight + padding.top + padding.bottom;
924
1018
  node.layout.height = actualHeight;
925
1019
  node.layout.contentHeight = actualContentHeight;
926
- } else if (wrap && element.width === void 0 && !isRow) {
1020
+ } else if (wrap && boxElement.width === void 0 && !isRow) {
927
1021
  const actualContentWidth = crossOffset;
928
1022
  const actualWidth = actualContentWidth + padding.left + padding.right;
929
1023
  node.layout.width = actualWidth;
@@ -932,7 +1026,7 @@ function computeLayout(element, ctx, constraints, x = 0, y = 0) {
932
1026
  if (!wrap) {
933
1027
  let maxChildCrossSize = 0;
934
1028
  for (const childNode of node.children) {
935
- const childMargin = normalizeSpacing(childNode.element.margin);
1029
+ const childMargin = getElementMargin(childNode.element);
936
1030
  if (isRow) {
937
1031
  const childOuterHeight = childNode.layout.height + childMargin.top + childMargin.bottom;
938
1032
  maxChildCrossSize = Math.max(maxChildCrossSize, childOuterHeight);
@@ -941,13 +1035,13 @@ function computeLayout(element, ctx, constraints, x = 0, y = 0) {
941
1035
  maxChildCrossSize = Math.max(maxChildCrossSize, childOuterWidth);
942
1036
  }
943
1037
  }
944
- if (isRow && element.height === void 0) {
1038
+ if (isRow && boxElement.height === void 0) {
945
1039
  const actualHeight = maxChildCrossSize + padding.top + padding.bottom;
946
1040
  if (actualHeight > node.layout.height) {
947
1041
  node.layout.height = actualHeight;
948
1042
  node.layout.contentHeight = maxChildCrossSize;
949
1043
  }
950
- } else if (!isRow && element.width === void 0) {
1044
+ } else if (!isRow && boxElement.width === void 0) {
951
1045
  const actualWidth = maxChildCrossSize + padding.left + padding.right;
952
1046
  if (actualWidth > node.layout.width) {
953
1047
  node.layout.width = actualWidth;
@@ -957,48 +1051,24 @@ function computeLayout(element, ctx, constraints, x = 0, y = 0) {
957
1051
  }
958
1052
  if (isReverse) node.children.reverse();
959
1053
  }
960
- } else if (element.type === "transform") {
961
- const child = element.children;
962
- if (child) {
963
- const childMargin = normalizeSpacing(child.margin);
964
- const childNode = computeLayout(child, ctx, {
965
- minWidth: 0,
966
- maxWidth: contentWidth,
967
- minHeight: 0,
968
- maxHeight: contentHeight
969
- }, contentX, contentY);
970
- node.children.push(childNode);
971
- if (element.width === void 0) {
972
- const childOuterWidth = childNode.layout.width + childMargin.left + childMargin.right;
973
- const actualWidth = childOuterWidth + padding.left + padding.right;
974
- node.layout.width = actualWidth;
975
- node.layout.contentWidth = childOuterWidth;
976
- }
977
- if (element.height === void 0) {
978
- const childOuterHeight = childNode.layout.height + childMargin.top + childMargin.bottom;
979
- const actualHeight = childOuterHeight + padding.top + padding.bottom;
980
- node.layout.height = actualHeight;
981
- node.layout.contentHeight = childOuterHeight;
982
- }
983
- }
984
- } else if (element.type === "customdraw") {
985
- const child = element.children;
1054
+ } else if (layoutElement.type === "customdraw") {
1055
+ const child = layoutElement.children;
986
1056
  if (child) {
987
1057
  const childMargin = normalizeSpacing(child.margin);
988
- const childNode = computeLayout(child, ctx, {
1058
+ const childNode = computeLayoutImpl(child, ctx, {
989
1059
  minWidth: 0,
990
1060
  maxWidth: contentWidth,
991
1061
  minHeight: 0,
992
1062
  maxHeight: contentHeight
993
1063
  }, contentX, contentY);
994
1064
  node.children.push(childNode);
995
- if (element.width === void 0) {
1065
+ if (layoutElement.width === void 0) {
996
1066
  const childOuterWidth = childNode.layout.width + childMargin.left + childMargin.right;
997
1067
  const actualWidth = childOuterWidth + padding.left + padding.right;
998
1068
  node.layout.width = actualWidth;
999
1069
  node.layout.contentWidth = childOuterWidth;
1000
1070
  }
1001
- if (element.height === void 0) {
1071
+ if (layoutElement.height === void 0) {
1002
1072
  const childOuterHeight = childNode.layout.height + childMargin.top + childMargin.bottom;
1003
1073
  const actualHeight = childOuterHeight + padding.top + padding.bottom;
1004
1074
  node.layout.height = actualHeight;
@@ -2008,10 +2078,12 @@ function getElementType(element) {
2008
2078
  switch (element.type) {
2009
2079
  case "box": return "Box";
2010
2080
  case "text": return `Text "${element.content.slice(0, 20)}${element.content.length > 20 ? "..." : ""}"`;
2081
+ case "richtext": return "RichText";
2011
2082
  case "stack": return "Stack";
2012
2083
  case "image": return "Image";
2013
2084
  case "svg": return "Svg";
2014
- default: return element.type;
2085
+ case "transform": return "Transform";
2086
+ case "customdraw": return "CustomDraw";
2015
2087
  }
2016
2088
  }
2017
2089
  /**
package/package.json CHANGED
@@ -17,7 +17,7 @@
17
17
  "lint-staged": "^15.0.0",
18
18
  "prettier": "^3.0.0",
19
19
  "prettier-plugin-organize-imports": "^4.0.0",
20
- "tsdown": "^0.20.1"
20
+ "tsdown": "^0.21.0-beta.2"
21
21
  },
22
22
  "peerDependencies": {
23
23
  "typescript": "^5"
@@ -25,7 +25,7 @@
25
25
  "optionalDependencies": {
26
26
  "@napi-rs/canvas": "^0.1.88"
27
27
  },
28
- "version": "0.5.0",
28
+ "version": "0.5.2",
29
29
  "main": "./node/index.cjs",
30
30
  "types": "./node/index.d.cts",
31
31
  "exports": {