@effing/canvas 0.21.0 → 0.22.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.
package/dist/index.js CHANGED
@@ -880,37 +880,133 @@ function drawBorders(ctx, x, y, width, height, style, borderRadius) {
880
880
  }
881
881
  return;
882
882
  }
883
- if (tw > 0) {
884
- ctx.strokeStyle = tc;
885
- ctx.lineWidth = tw;
886
- ctx.beginPath();
887
- ctx.moveTo(x, y + tw / 2);
888
- ctx.lineTo(x + width, y + tw / 2);
889
- ctx.stroke();
890
- }
891
- if (rw > 0) {
892
- ctx.strokeStyle = rc;
893
- ctx.lineWidth = rw;
894
- ctx.beginPath();
895
- ctx.moveTo(x + width - rw / 2, y);
896
- ctx.lineTo(x + width - rw / 2, y + height);
897
- ctx.stroke();
898
- }
899
- if (bw > 0) {
900
- ctx.strokeStyle = bc;
901
- ctx.lineWidth = bw;
902
- ctx.beginPath();
903
- ctx.moveTo(x, y + height - bw / 2);
904
- ctx.lineTo(x + width, y + height - bw / 2);
905
- ctx.stroke();
906
- }
907
- if (lw > 0) {
908
- ctx.strokeStyle = lc;
909
- ctx.lineWidth = lw;
910
- ctx.beginPath();
911
- ctx.moveTo(x + lw / 2, y);
912
- ctx.lineTo(x + lw / 2, y + height);
913
- ctx.stroke();
883
+ if (hasRoundedCorners) {
884
+ const maxR = Math.min(width, height) / 2;
885
+ const tl = Math.min(borderRadius.topLeft, maxR);
886
+ const tr = Math.min(borderRadius.topRight, maxR);
887
+ const br = Math.min(borderRadius.bottomRight, maxR);
888
+ const bl = Math.min(borderRadius.bottomLeft, maxR);
889
+ const top = y + tw / 2;
890
+ const right = x + width - rw / 2;
891
+ const bottom = y + height - bw / 2;
892
+ const left = x + lw / 2;
893
+ const eTL = Math.max(0, tl - Math.max(tw, lw) / 2);
894
+ const eTR = Math.max(0, tr - Math.max(tw, rw) / 2);
895
+ const eBR = Math.max(0, br - Math.max(bw, rw) / 2);
896
+ const eBL = Math.max(0, bl - Math.max(bw, lw) / 2);
897
+ if (tw > 0) {
898
+ ctx.strokeStyle = tc;
899
+ ctx.lineWidth = tw;
900
+ ctx.beginPath();
901
+ if (eTL > 0 && lw === 0) {
902
+ ctx.moveTo(left, top + eTL);
903
+ ctx.arcTo(left, top, left + eTL, top, eTL);
904
+ } else if (eTL > 0) {
905
+ ctx.moveTo(left + eTL, top);
906
+ } else {
907
+ ctx.moveTo(x, top);
908
+ }
909
+ if (eTR > 0) {
910
+ ctx.lineTo(right - eTR, top);
911
+ ctx.arcTo(right, top, right, top + eTR, eTR);
912
+ } else {
913
+ ctx.lineTo(x + width, top);
914
+ }
915
+ ctx.stroke();
916
+ }
917
+ if (rw > 0) {
918
+ ctx.strokeStyle = rc;
919
+ ctx.lineWidth = rw;
920
+ ctx.beginPath();
921
+ if (eTR > 0 && tw === 0) {
922
+ ctx.moveTo(right - eTR, top);
923
+ ctx.arcTo(right, top, right, top + eTR, eTR);
924
+ } else if (eTR > 0) {
925
+ ctx.moveTo(right, top + eTR);
926
+ } else {
927
+ ctx.moveTo(right, y);
928
+ }
929
+ if (eBR > 0) {
930
+ ctx.lineTo(right, bottom - eBR);
931
+ ctx.arcTo(right, bottom, right - eBR, bottom, eBR);
932
+ } else {
933
+ ctx.lineTo(right, y + height);
934
+ }
935
+ ctx.stroke();
936
+ }
937
+ if (bw > 0) {
938
+ ctx.strokeStyle = bc;
939
+ ctx.lineWidth = bw;
940
+ ctx.beginPath();
941
+ if (eBR > 0 && rw === 0) {
942
+ ctx.moveTo(right, bottom - eBR);
943
+ ctx.arcTo(right, bottom, right - eBR, bottom, eBR);
944
+ } else if (eBR > 0) {
945
+ ctx.moveTo(right - eBR, bottom);
946
+ } else {
947
+ ctx.moveTo(x + width, bottom);
948
+ }
949
+ if (eBL > 0) {
950
+ ctx.lineTo(left + eBL, bottom);
951
+ ctx.arcTo(left, bottom, left, bottom - eBL, eBL);
952
+ } else {
953
+ ctx.lineTo(x, bottom);
954
+ }
955
+ ctx.stroke();
956
+ }
957
+ if (lw > 0) {
958
+ ctx.strokeStyle = lc;
959
+ ctx.lineWidth = lw;
960
+ ctx.beginPath();
961
+ if (eBL > 0 && bw === 0) {
962
+ ctx.moveTo(left + eBL, bottom);
963
+ ctx.arcTo(left, bottom, left, bottom - eBL, eBL);
964
+ } else if (eBL > 0) {
965
+ ctx.moveTo(left, bottom - eBL);
966
+ } else {
967
+ ctx.moveTo(left, y + height);
968
+ }
969
+ if (eTL > 0) {
970
+ ctx.lineTo(left, top + eTL);
971
+ ctx.arcTo(left, top, left + eTL, top, eTL);
972
+ } else {
973
+ ctx.lineTo(left, y);
974
+ }
975
+ ctx.stroke();
976
+ }
977
+ } else {
978
+ if (tw > 0) {
979
+ ctx.strokeStyle = tc;
980
+ ctx.lineWidth = tw;
981
+ ctx.beginPath();
982
+ ctx.moveTo(x, y + tw / 2);
983
+ ctx.lineTo(x + width, y + tw / 2);
984
+ ctx.stroke();
985
+ }
986
+ if (rw > 0) {
987
+ ctx.strokeStyle = rc;
988
+ ctx.lineWidth = rw;
989
+ ctx.beginPath();
990
+ ctx.moveTo(x + width - rw / 2, y);
991
+ ctx.lineTo(x + width - rw / 2, y + height);
992
+ ctx.stroke();
993
+ }
994
+ if (bw > 0) {
995
+ ctx.strokeStyle = bc;
996
+ ctx.lineWidth = bw;
997
+ ctx.beginPath();
998
+ ctx.moveTo(x, y + height - bw / 2);
999
+ ctx.lineTo(x + width, y + height - bw / 2);
1000
+ ctx.stroke();
1001
+ }
1002
+ if (lw > 0) {
1003
+ ctx.strokeStyle = lc;
1004
+ ctx.lineWidth = lw;
1005
+ ctx.beginPath();
1006
+ ctx.moveTo(x + lw / 2, y);
1007
+ ctx.lineTo(x + lw / 2, y + height);
1008
+ ctx.stroke();
1009
+ }
914
1010
  }
915
1011
  }
916
1012
  function drawBoxShadow(ctx, x, y, width, height, boxShadow, borderRadius) {
@@ -958,18 +1054,24 @@ function collectDefs(children) {
958
1054
  const clips = /* @__PURE__ */ new Map();
959
1055
  const gradients = /* @__PURE__ */ new Map();
960
1056
  const masks = /* @__PURE__ */ new Map();
1057
+ const filters = /* @__PURE__ */ new Map();
1058
+ function insertDef(def) {
1059
+ const id = def.props.id;
1060
+ if (!id) return;
1061
+ if (def.type === "clipPath") clips.set(id, normalizeChildren(def));
1062
+ else if (def.type === "mask") masks.set(id, normalizeChildren(def));
1063
+ else if (def.type === "filter") filters.set(id, def);
1064
+ else if (def.type === "radialGradient" || def.type === "linearGradient")
1065
+ gradients.set(id, def);
1066
+ }
961
1067
  for (const child of children) {
962
- if (child.type !== "defs") continue;
963
- for (const def of normalizeChildren(child)) {
964
- const id = def.props.id;
965
- if (!id) continue;
966
- if (def.type === "clipPath") clips.set(id, normalizeChildren(def));
967
- else if (def.type === "mask") masks.set(id, normalizeChildren(def));
968
- else if (def.type === "radialGradient" || def.type === "linearGradient")
969
- gradients.set(id, def);
1068
+ if (child.type === "defs") {
1069
+ for (const def of normalizeChildren(child)) insertDef(def);
1070
+ } else {
1071
+ insertDef(child);
970
1072
  }
971
1073
  }
972
- return { clips, gradients, masks };
1074
+ return { clips, gradients, masks, filters };
973
1075
  }
974
1076
  function parseUrlRef(value) {
975
1077
  if (typeof value !== "string") return void 0;
@@ -1353,21 +1455,177 @@ function drawSvgContainer(ctx, node, x, y, width, height) {
1353
1455
  var EMPTY_DEFS = {
1354
1456
  clips: /* @__PURE__ */ new Map(),
1355
1457
  gradients: /* @__PURE__ */ new Map(),
1356
- masks: /* @__PURE__ */ new Map()
1458
+ masks: /* @__PURE__ */ new Map(),
1459
+ filters: /* @__PURE__ */ new Map()
1357
1460
  };
1461
+ function applyFeOffset(input, dx, dy, w, h) {
1462
+ const [canvas, ctx] = acquireOffscreen(w, h);
1463
+ ctx.drawImage(input, dx, dy);
1464
+ return canvas;
1465
+ }
1466
+ function applyFeGaussianBlur(input, stdDeviation, w, h) {
1467
+ const [canvas, ctx] = acquireOffscreen(w, h);
1468
+ ctx.filter = `blur(${stdDeviation}px)`;
1469
+ ctx.drawImage(input, 0, 0);
1470
+ ctx.filter = "none";
1471
+ return canvas;
1472
+ }
1473
+ function applyFeColorMatrix(input, type, values, w, h) {
1474
+ const [canvas, ctx] = acquireOffscreen(w, h);
1475
+ ctx.drawImage(input, 0, 0);
1476
+ if (type === "matrix" && values) {
1477
+ const m = values.trim().split(/[\s,]+/).map(Number);
1478
+ if (m.length >= 20) {
1479
+ const imageData = ctx.getImageData(0, 0, w, h);
1480
+ const d = imageData.data;
1481
+ for (let i = 0; i < d.length; i += 4) {
1482
+ const r = d[i];
1483
+ const g = d[i + 1];
1484
+ const b = d[i + 2];
1485
+ const a = d[i + 3];
1486
+ d[i] = Math.min(
1487
+ 255,
1488
+ Math.max(
1489
+ 0,
1490
+ m[0] * r + m[1] * g + m[2] * b + m[3] * a + m[4] * 255
1491
+ )
1492
+ );
1493
+ d[i + 1] = Math.min(
1494
+ 255,
1495
+ Math.max(
1496
+ 0,
1497
+ m[5] * r + m[6] * g + m[7] * b + m[8] * a + m[9] * 255
1498
+ )
1499
+ );
1500
+ d[i + 2] = Math.min(
1501
+ 255,
1502
+ Math.max(
1503
+ 0,
1504
+ m[10] * r + m[11] * g + m[12] * b + m[13] * a + m[14] * 255
1505
+ )
1506
+ );
1507
+ d[i + 3] = Math.min(
1508
+ 255,
1509
+ Math.max(
1510
+ 0,
1511
+ m[15] * r + m[16] * g + m[17] * b + m[18] * a + m[19] * 255
1512
+ )
1513
+ );
1514
+ }
1515
+ ctx.putImageData(imageData, 0, 0);
1516
+ }
1517
+ }
1518
+ return canvas;
1519
+ }
1520
+ function applyFeBlend(in1, in2, mode, w, h) {
1521
+ const modeMap = {
1522
+ normal: "source-over",
1523
+ multiply: "multiply",
1524
+ screen: "screen",
1525
+ darken: "darken",
1526
+ lighten: "lighten",
1527
+ overlay: "overlay"
1528
+ };
1529
+ const [canvas, ctx] = acquireOffscreen(w, h);
1530
+ ctx.drawImage(in2, 0, 0);
1531
+ ctx.globalCompositeOperation = modeMap[mode] ?? "source-over";
1532
+ ctx.drawImage(in1, 0, 0);
1533
+ ctx.globalCompositeOperation = "source-over";
1534
+ return canvas;
1535
+ }
1536
+ function extractSourceAlpha(input, w, h) {
1537
+ const [canvas, ctx] = acquireOffscreen(w, h);
1538
+ ctx.fillStyle = "black";
1539
+ ctx.fillRect(0, 0, w, h);
1540
+ ctx.globalCompositeOperation = "destination-in";
1541
+ ctx.drawImage(input, 0, 0);
1542
+ ctx.globalCompositeOperation = "source-over";
1543
+ return canvas;
1544
+ }
1545
+ function applyFilter(filterDef, sourceGraphic, w, h) {
1546
+ const buffers = /* @__PURE__ */ new Map();
1547
+ buffers.set("SourceGraphic", sourceGraphic);
1548
+ let sourceAlpha;
1549
+ const getSourceAlpha = () => {
1550
+ if (!sourceAlpha) {
1551
+ sourceAlpha = extractSourceAlpha(sourceGraphic, w, h);
1552
+ buffers.set("SourceAlpha", sourceAlpha);
1553
+ }
1554
+ return sourceAlpha;
1555
+ };
1556
+ const children = normalizeChildren(filterDef);
1557
+ let lastResult = sourceGraphic;
1558
+ for (const prim of children) {
1559
+ const p = prim.props;
1560
+ const inName = p.in ?? "";
1561
+ const resolve = (name) => {
1562
+ if (name === "SourceAlpha") return getSourceAlpha();
1563
+ return buffers.get(name) ?? lastResult;
1564
+ };
1565
+ const input = inName ? resolve(inName) : lastResult;
1566
+ let output;
1567
+ switch (prim.type) {
1568
+ case "feOffset":
1569
+ output = applyFeOffset(
1570
+ input,
1571
+ Number(p.dx ?? 0),
1572
+ Number(p.dy ?? 0),
1573
+ w,
1574
+ h
1575
+ );
1576
+ break;
1577
+ case "feGaussianBlur": {
1578
+ const std = Number(p.stdDeviation ?? 0);
1579
+ output = std > 0 ? applyFeGaussianBlur(input, std, w, h) : input;
1580
+ break;
1581
+ }
1582
+ case "feColorMatrix":
1583
+ output = applyFeColorMatrix(
1584
+ input,
1585
+ p.type ?? "matrix",
1586
+ p.values,
1587
+ w,
1588
+ h
1589
+ );
1590
+ break;
1591
+ case "feBlend": {
1592
+ const in2Name = p.in2 ?? "";
1593
+ const in2 = in2Name ? resolve(in2Name) : lastResult;
1594
+ output = applyFeBlend(input, in2, p.mode ?? "normal", w, h);
1595
+ break;
1596
+ }
1597
+ default:
1598
+ output = input;
1599
+ break;
1600
+ }
1601
+ const resultName = p.result;
1602
+ if (resultName) buffers.set(resultName, output);
1603
+ lastResult = output;
1604
+ }
1605
+ return lastResult;
1606
+ }
1358
1607
  function drawSvgChild(ctx, child, inheritedFill, color, defs = EMPTY_DEFS, vbW = 0, vbH = 0) {
1359
1608
  const { type } = child;
1360
1609
  const props = mergeStyleIntoProps(child.props);
1361
- if (type === "defs" || type === "clipPath" || type === "mask") return;
1610
+ if (type === "defs" || type === "clipPath" || type === "mask" || type === "filter")
1611
+ return;
1612
+ const transform = type !== "g" ? props.transform : void 0;
1613
+ if (transform) {
1614
+ ctx.save();
1615
+ applySvgTransform(ctx, transform);
1616
+ }
1362
1617
  const clipRef = parseUrlRef(props.clipPath ?? props["clip-path"]);
1363
1618
  const clipShapes = clipRef ? defs.clips.get(clipRef) : void 0;
1364
1619
  const clipPath = clipShapes ? buildClipPath(clipShapes, vbW, vbH) : void 0;
1365
1620
  const maskRef = parseUrlRef(props.mask);
1366
1621
  const maskShapes = maskRef ? defs.masks.get(maskRef) : void 0;
1622
+ const filterRef = parseUrlRef(props.filter);
1623
+ const filterDef = filterRef ? defs.filters.get(filterRef) : void 0;
1367
1624
  if (clipPath) ctx.save();
1368
1625
  if (clipPath) ctx.clip(clipPath);
1626
+ const needsOffscreen = maskShapes || filterDef;
1369
1627
  let elemCanvas;
1370
- const targetCtx = maskShapes ? (() => {
1628
+ const targetCtx = needsOffscreen ? (() => {
1371
1629
  const [c, cCtx] = acquireOffscreen(Math.ceil(vbW), Math.ceil(vbH));
1372
1630
  elemCanvas = c;
1373
1631
  return cCtx;
@@ -1398,22 +1656,36 @@ function drawSvgChild(ctx, child, inheritedFill, color, defs = EMPTY_DEFS, vbW =
1398
1656
  drawGroup(targetCtx, child, inheritedFill, color, defs, vbW, vbH);
1399
1657
  break;
1400
1658
  }
1401
- if (maskShapes && elemCanvas) {
1402
- const [maskCanvas, maskCtx] = acquireOffscreen(
1403
- Math.ceil(vbW),
1404
- Math.ceil(vbH)
1405
- );
1406
- for (const shape of maskShapes) {
1407
- drawSvgChild(maskCtx, shape, "white", "white", defs, vbW, vbH);
1408
- }
1409
- targetCtx.globalCompositeOperation = "destination-in";
1410
- targetCtx.drawImage(maskCanvas, 0, 0);
1411
- targetCtx.globalCompositeOperation = "source-over";
1412
- ctx.drawImage(elemCanvas, 0, 0);
1413
- releaseOffscreen(maskCanvas);
1659
+ if (needsOffscreen && elemCanvas) {
1660
+ if (maskShapes) {
1661
+ const [maskCanvas, maskCtx] = acquireOffscreen(
1662
+ Math.ceil(vbW),
1663
+ Math.ceil(vbH)
1664
+ );
1665
+ for (const shape of maskShapes) {
1666
+ drawSvgChild(maskCtx, shape, "white", "white", defs, vbW, vbH);
1667
+ }
1668
+ targetCtx.globalCompositeOperation = "destination-in";
1669
+ targetCtx.drawImage(maskCanvas, 0, 0);
1670
+ targetCtx.globalCompositeOperation = "source-over";
1671
+ releaseOffscreen(maskCanvas);
1672
+ }
1673
+ if (filterDef) {
1674
+ const filteredCanvas = applyFilter(
1675
+ filterDef,
1676
+ elemCanvas,
1677
+ Math.ceil(vbW),
1678
+ Math.ceil(vbH)
1679
+ );
1680
+ ctx.drawImage(filteredCanvas, 0, 0);
1681
+ if (filteredCanvas !== elemCanvas) releaseOffscreen(filteredCanvas);
1682
+ } else {
1683
+ ctx.drawImage(elemCanvas, 0, 0);
1684
+ }
1414
1685
  releaseOffscreen(elemCanvas);
1415
1686
  }
1416
1687
  if (clipPath) ctx.restore();
1688
+ if (transform) ctx.restore();
1417
1689
  }
1418
1690
  function drawPath(ctx, props, inheritedFill, color, defs) {
1419
1691
  const d = props.d;
@@ -1600,14 +1872,34 @@ function parsePoints(value) {
1600
1872
  function applyFillAndStroke(ctx, props, path, inheritedFill, color, defs, bbox) {
1601
1873
  const fill = resolveCurrentColor(props.fill, color) ?? inheritedFill;
1602
1874
  const fillRule = props.fillRule ?? props["fill-rule"];
1875
+ const fillOpacity = Number(props.fillOpacity ?? props["fill-opacity"] ?? 1);
1603
1876
  const fillRef = parseUrlRef(fill);
1604
1877
  if (fillRef) {
1605
1878
  const gradientDef = defs.gradients.get(fillRef);
1606
1879
  if (gradientDef) {
1607
- fillWithSvgGradient(ctx, gradientDef, bbox, path, fillRule ?? "nonzero");
1880
+ if (fillOpacity < 1) {
1881
+ ctx.save();
1882
+ ctx.globalAlpha *= fillOpacity;
1883
+ fillWithSvgGradient(
1884
+ ctx,
1885
+ gradientDef,
1886
+ bbox,
1887
+ path,
1888
+ fillRule ?? "nonzero"
1889
+ );
1890
+ ctx.restore();
1891
+ } else {
1892
+ fillWithSvgGradient(
1893
+ ctx,
1894
+ gradientDef,
1895
+ bbox,
1896
+ path,
1897
+ fillRule ?? "nonzero"
1898
+ );
1899
+ }
1608
1900
  }
1609
1901
  } else if (fill !== "none") {
1610
- ctx.fillStyle = fill;
1902
+ ctx.fillStyle = applyOpacity(fill, fillOpacity);
1611
1903
  ctx.fill(path, fillRule ?? "nonzero");
1612
1904
  }
1613
1905
  applyStroke(ctx, props, path, color, defs, bbox);
@@ -1615,6 +1907,9 @@ function applyFillAndStroke(ctx, props, path, inheritedFill, color, defs, bbox)
1615
1907
  function applyStroke(ctx, props, path, color, defs, bbox) {
1616
1908
  const stroke = resolveCurrentColor(props.stroke, color);
1617
1909
  if (!stroke || stroke === "none") return;
1910
+ const strokeOpacity = Number(
1911
+ props.strokeOpacity ?? props["stroke-opacity"] ?? 1
1912
+ );
1618
1913
  ctx.lineWidth = Number(props.strokeWidth ?? props["stroke-width"] ?? 1);
1619
1914
  ctx.lineCap = props.strokeLinecap ?? props["stroke-linecap"] ?? "butt";
1620
1915
  ctx.lineJoin = props.strokeLinejoin ?? props["stroke-linejoin"] ?? "miter";
@@ -1622,11 +1917,18 @@ function applyStroke(ctx, props, path, color, defs, bbox) {
1622
1917
  if (strokeRef) {
1623
1918
  const gradientDef = defs.gradients.get(strokeRef);
1624
1919
  if (gradientDef) {
1625
- strokeWithSvgGradient(ctx, gradientDef, bbox, path);
1920
+ if (strokeOpacity < 1) {
1921
+ ctx.save();
1922
+ ctx.globalAlpha *= strokeOpacity;
1923
+ strokeWithSvgGradient(ctx, gradientDef, bbox, path);
1924
+ ctx.restore();
1925
+ } else {
1926
+ strokeWithSvgGradient(ctx, gradientDef, bbox, path);
1927
+ }
1626
1928
  return;
1627
1929
  }
1628
1930
  }
1629
- ctx.strokeStyle = stroke;
1931
+ ctx.strokeStyle = applyOpacity(stroke, strokeOpacity);
1630
1932
  ctx.stroke(path);
1631
1933
  }
1632
1934
 
@@ -2081,10 +2383,14 @@ async function drawNodeCore(ctx, node, parentX, parentY, offsetX, offsetY, debug
2081
2383
  const paddingLeft = resolveBoxValue(style.paddingLeft, width);
2082
2384
  const paddingRight = resolveBoxValue(style.paddingRight, width);
2083
2385
  const paddingBottom = resolveBoxValue(style.paddingBottom, width);
2084
- const imgX = x + paddingLeft;
2085
- const imgY = y + paddingTop;
2086
- const imgW = width - paddingLeft - paddingRight;
2087
- const imgH = height - paddingTop - paddingBottom;
2386
+ const borderTopW = resolveBoxValue(style.borderTopWidth, width);
2387
+ const borderLeftW = resolveBoxValue(style.borderLeftWidth, width);
2388
+ const borderRightW = resolveBoxValue(style.borderRightWidth, width);
2389
+ const borderBottomW = resolveBoxValue(style.borderBottomWidth, width);
2390
+ const imgX = x + paddingLeft + borderLeftW;
2391
+ const imgY = y + paddingTop + borderTopW;
2392
+ const imgW = width - paddingLeft - paddingRight - borderLeftW - borderRightW;
2393
+ const imgH = height - paddingTop - paddingBottom - borderTopW - borderBottomW;
2088
2394
  if (!isClipped) {
2089
2395
  const borderRadius = getBorderRadiusFromStyle(style, width, height);
2090
2396
  if (hasRadius(borderRadius)) {
@@ -2325,23 +2631,32 @@ function expandStyle(raw, fontFamilies) {
2325
2631
  }
2326
2632
  if (style.flex !== void 0) {
2327
2633
  const val = String(style.flex);
2328
- const parts = val.split(/\s+/);
2329
- if (parts.length === 1) {
2330
- const n = parseFloat(parts[0]);
2331
- if (!isNaN(n)) {
2332
- if (style.flexGrow === void 0) style.flexGrow = n;
2333
- if (style.flexShrink === void 0) style.flexShrink = 1;
2334
- if (style.flexBasis === void 0) style.flexBasis = 0;
2634
+ if (val === "none") {
2635
+ if (style.flexGrow === void 0) style.flexGrow = 0;
2636
+ if (style.flexShrink === void 0) style.flexShrink = 0;
2637
+ if (style.flexBasis === void 0) style.flexBasis = "auto";
2638
+ } else {
2639
+ const parts = val.split(/\s+/);
2640
+ if (parts.length === 1) {
2641
+ const n = parseFloat(parts[0]);
2642
+ if (!isNaN(n)) {
2643
+ if (style.flexGrow === void 0) style.flexGrow = n;
2644
+ if (style.flexShrink === void 0) style.flexShrink = 1;
2645
+ if (style.flexBasis === void 0) style.flexBasis = 0;
2646
+ }
2647
+ } else if (parts.length === 2) {
2648
+ if (style.flexGrow === void 0)
2649
+ style.flexGrow = parseFloat(parts[0]);
2650
+ if (style.flexShrink === void 0)
2651
+ style.flexShrink = parseFloat(parts[1]);
2652
+ } else if (parts.length >= 3) {
2653
+ if (style.flexGrow === void 0)
2654
+ style.flexGrow = parseFloat(parts[0]);
2655
+ if (style.flexShrink === void 0)
2656
+ style.flexShrink = parseFloat(parts[1]);
2657
+ if (style.flexBasis === void 0)
2658
+ style.flexBasis = parseValue(parts[2]);
2335
2659
  }
2336
- } else if (parts.length === 2) {
2337
- if (style.flexGrow === void 0) style.flexGrow = parseFloat(parts[0]);
2338
- if (style.flexShrink === void 0)
2339
- style.flexShrink = parseFloat(parts[1]);
2340
- } else if (parts.length >= 3) {
2341
- if (style.flexGrow === void 0) style.flexGrow = parseFloat(parts[0]);
2342
- if (style.flexShrink === void 0)
2343
- style.flexShrink = parseFloat(parts[1]);
2344
- if (style.flexBasis === void 0) style.flexBasis = parseValue(parts[2]);
2345
2660
  }
2346
2661
  delete style.flex;
2347
2662
  }
@@ -2853,36 +3168,6 @@ async function buildNode(element, parentStyle, yogaNode, viewportWidth, viewport
2853
3168
  yogaNode
2854
3169
  };
2855
3170
  }
2856
- if (Array.isArray(element)) {
2857
- const style2 = resolveStyle(void 0, parentStyle);
2858
- const children2 = [];
2859
- for (let i = 0; i < element.length; i++) {
2860
- const child = element[i];
2861
- if (child === null || child === void 0 || typeof child === "boolean")
2862
- continue;
2863
- const childYogaNode = createYogaNode();
2864
- yogaNode.insertChild(childYogaNode, children2.length);
2865
- children2.push(
2866
- await buildNode(
2867
- child,
2868
- style2,
2869
- childYogaNode,
2870
- viewportWidth,
2871
- viewportHeight,
2872
- ctx,
2873
- emojiEnabled,
2874
- fontFamilies
2875
- )
2876
- );
2877
- }
2878
- return {
2879
- type: "div",
2880
- style: style2,
2881
- children: children2,
2882
- props: {},
2883
- yogaNode
2884
- };
2885
- }
2886
3171
  const el = element;
2887
3172
  const type = el.type;
2888
3173
  if (typeof type === "function") {
@@ -2983,9 +3268,15 @@ async function buildNode(element, parentStyle, yogaNode, viewportWidth, viewport
2983
3268
  emojiEnabled
2984
3269
  );
2985
3270
  childYogaNode.setMeasureFunc(measureFunc);
2986
- childYogaNode.setFlexGrow(1);
3271
+ const jc = style.justifyContent;
3272
+ if (!jc || jc === "flex-start") {
3273
+ childYogaNode.setFlexGrow(1);
3274
+ }
2987
3275
  childYogaNode.setFlexShrink(1);
2988
3276
  yogaNode.insertChild(childYogaNode, 0);
3277
+ if (style.flexShrink === void 0) {
3278
+ yogaNode.setFlexShrink(1);
3279
+ }
2989
3280
  return {
2990
3281
  type: tagName,
2991
3282
  style,
@@ -3006,7 +3297,7 @@ async function buildNode(element, parentStyle, yogaNode, viewportWidth, viewport
3006
3297
  const children = [];
3007
3298
  const rawChildren = props.children;
3008
3299
  if (rawChildren !== void 0 && rawChildren !== null) {
3009
- const childArray = Array.isArray(rawChildren) ? rawChildren : [rawChildren];
3300
+ const childArray = Array.isArray(rawChildren) ? rawChildren.flat(Infinity) : [rawChildren];
3010
3301
  for (const child of childArray) {
3011
3302
  if (child === null || child === void 0 || typeof child === "boolean")
3012
3303
  continue;