@likec4/diagram 1.2.1 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/dist/LikeC4Diagram.d.ts +1 -1
  2. package/dist/LikeC4Diagram.props.d.ts +21 -3
  3. package/dist/index.mjs +1335 -1240
  4. package/dist/state/DiagramContext.d.ts +2263 -175
  5. package/dist/state/diagramStore.d.ts +2272 -180
  6. package/dist/state/useDiagramStore.d.ts +2409 -321
  7. package/dist/style.css +123 -92
  8. package/dist/theme.css.d.ts +0 -1
  9. package/dist/ui/OptionsPanel.d.ts +3 -1
  10. package/dist/xyflow/XYFlow.d.ts +2 -1
  11. package/dist/xyflow/XYFlowInner.d.ts +1 -1
  12. package/dist/xyflow/const.d.ts +1 -1
  13. package/dist/xyflow/diagram-to-xyflow.d.ts +1 -1
  14. package/dist/xyflow/edges/RelationshipEdge.d.ts +3 -4
  15. package/dist/xyflow/edges/utils.d.ts +4 -2
  16. package/dist/xyflow/nodes/compound/CompoundNode.css.d.ts +3 -1
  17. package/dist/xyflow/nodes/element/ElementNode.d.ts +1 -1
  18. package/dist/xyflow/nodes/element/index.d.ts +1 -1
  19. package/dist/xyflow/types.d.ts +2 -2
  20. package/dist/xyflow/utils.d.ts +3 -0
  21. package/package.json +15 -14
  22. package/src/LikeC4Diagram.css.ts +4 -4
  23. package/src/LikeC4Diagram.props.ts +23 -2
  24. package/src/LikeC4Diagram.tsx +79 -31
  25. package/src/globals.css.ts +0 -1
  26. package/src/mantine/theme.ts +1 -0
  27. package/src/state/DiagramContext.tsx +0 -1
  28. package/src/state/diagramStore.ts +177 -100
  29. package/src/theme.css.ts +0 -1
  30. package/src/ui/DiagramTitlePanel.tsx +3 -3
  31. package/src/ui/DynamicViewWalkthrough.css.ts +3 -2
  32. package/src/ui/DynamicViewWalkthrough.tsx +36 -17
  33. package/src/ui/OptionsPanel.tsx +12 -12
  34. package/src/ui/options/NodeOptions.tsx +16 -19
  35. package/src/xyflow/FitviewOnDiagramChange.tsx +15 -23
  36. package/src/xyflow/SelectEdgesOnNodeFocus.tsx +3 -6
  37. package/src/xyflow/SyncWithDiagram.tsx +21 -2
  38. package/src/xyflow/XYFlow.tsx +20 -23
  39. package/src/xyflow/XYFlowEvents.tsx +26 -8
  40. package/src/xyflow/XYFlowInner.tsx +5 -4
  41. package/src/xyflow/const.ts +1 -1
  42. package/src/xyflow/diagram-to-xyflow.ts +5 -31
  43. package/src/xyflow/edges/RelationshipEdge.tsx +158 -112
  44. package/src/xyflow/edges/edges.css.ts +32 -21
  45. package/src/xyflow/edges/utils.ts +5 -2
  46. package/src/xyflow/hooks/useLayoutConstraints.ts +17 -3
  47. package/src/xyflow/nodes/compound/CompoundNode.css.ts +40 -32
  48. package/src/xyflow/nodes/compound/CompoundNode.tsx +36 -26
  49. package/src/xyflow/nodes/element/ElementNode.tsx +20 -6
  50. package/src/xyflow/nodes/element/element.css.ts +15 -15
  51. package/src/xyflow/nodes/element/index.ts +1 -1
  52. package/src/xyflow/nodes/shared/NavigateToBtn.tsx +7 -3
  53. package/src/xyflow/types.ts +5 -2
  54. package/src/xyflow/utils.ts +48 -0
  55. package/dist/ui/index.d.ts +0 -2
  56. package/src/ui/index.ts +0 -3
package/dist/style.css CHANGED
@@ -605,7 +605,6 @@ svg.react-flow__connectionline {
605
605
  --likec4-font-family: var(--likec4-default-font-family,'ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji"');
606
606
  --likec4-background-color: var(--mantine-color-body);
607
607
  --likec4-background-pattern-color: var(--mantine-color-dimmed);
608
- --likec4-filter-dimmed: brightness(.6) grayscale(.8) opacity(.5) blur(1px);
609
608
  --likec4-compound-font-family: var(--likec4-font-family);
610
609
  --likec4-compound-title-color: var(--likec4-element-loContrast);
611
610
  --likec4-element-font-family: var(--likec4-font-family);
@@ -1268,9 +1267,6 @@ svg.react-flow__connectionline {
1268
1267
  --xy-background-color: var(--likec4-background-color);
1269
1268
  --xy-background-pattern-color: var(--likec4-background-pattern-color);
1270
1269
  }
1271
- .react-flow._2h8g8h1 .react-flow__viewport {
1272
- backface-visibility: hidden;
1273
- }
1274
1270
  .react-flow._2h8g8h1._2h8g8h3 {
1275
1271
  --likec4-background-color: transparent !important;
1276
1272
  --xy-background-color: transparent !important;
@@ -1294,10 +1290,6 @@ svg.react-flow__connectionline {
1294
1290
  --xy-edge-label-background-color: color-mix(in srgb, var(--likec4-relation-labelBg), transparent 35%);
1295
1291
  --xy-edge-stroke-width: 2.2px;
1296
1292
  }
1297
- svg:has(.bexn7q2) {
1298
- filter: var(--likec4-filter-dimmed);
1299
- transition: filter 800ms ease-out;
1300
- }
1301
1293
  :where([data-mantine-color-scheme="dark"]) .bexn7q1 {
1302
1294
  --bexn7q0: white;
1303
1295
  --xy-edge-label-color: var(--likec4-relation-labelColor);
@@ -1317,6 +1309,13 @@ svg:has(.bexn7q2) {
1317
1309
  .react-flow__edges > svg {
1318
1310
  mix-blend-mode: screen;
1319
1311
  }
1312
+ .react-flow__edges > svg:has(.bexn7q2) {
1313
+ opacity: 0.8;
1314
+ transition: opacity 600ms ease-in-out, filter 600ms ease-in-out;
1315
+ transition-delay: 200ms;
1316
+ filter: grayscale(0.85) blur(1px);
1317
+ will-change: opacity, filter;
1318
+ }
1320
1319
  .bexn7q3 {
1321
1320
  stroke-width: var(--xy-edge-stroke-width);
1322
1321
  stroke-opacity: 0.08;
@@ -1331,7 +1330,6 @@ svg:has(.bexn7q2) {
1331
1330
  .bexn7q4 {
1332
1331
  fill: var(--xy-edge-stroke);
1333
1332
  stroke: var(--xy-edge-stroke);
1334
- pointer-events: none;
1335
1333
  }
1336
1334
  .bexn7q5 {
1337
1335
  fill: var(--xy-edge-stroke);
@@ -1339,12 +1337,20 @@ svg:has(.bexn7q2) {
1339
1337
  fill-opacity: 0.75;
1340
1338
  stroke-width: 1;
1341
1339
  cursor: grab;
1342
- pointer-events: visible;
1340
+ pointer-events: auto;
1341
+ visibility: hidden;
1343
1342
  }
1344
- :where(.react-flow__edge.selected, [data-edge-active='true'], [data-edge-hovered='true']) .bexn7q5 {
1345
- transition: all 150ms ease-out;
1343
+ .bexn7q5:hover {
1344
+ stroke: var(--mantine-primary-color-filled-hover);
1345
+ stroke-width: 9;
1346
+ transition: stroke 100ms ease-out, stroke-width 100ms ease-out;
1347
+ }
1348
+ :where(.react-flow__edge.selected, [data-edge-hovered='true']) .bexn7q5 {
1349
+ visibility: visible;
1350
+ transition: fill-opacity 150ms ease-out, stroke 150ms ease-out, stroke-width 150ms ease-out;
1351
+ transition-delay: 50ms;
1346
1352
  fill-opacity: 1;
1347
- stroke-width: 3;
1353
+ stroke-width: 5;
1348
1354
  }
1349
1355
  .bexn7q7 {
1350
1356
  animation-duration: 800ms;
@@ -1354,18 +1360,18 @@ svg:has(.bexn7q2) {
1354
1360
  :where([data-edge-hovered='true']) .bexn7q7 {
1355
1361
  animation-name: bexn7q6;
1356
1362
  animation-delay: 350ms;
1357
- transition: all 130ms ease-out;
1363
+ transition: stroke,stroke-width 130ms ease-out;
1358
1364
  }
1359
1365
  :where(.react-flow__edge.selected, [data-edge-active='true']) .bexn7q7 {
1360
1366
  animation-name: bexn7q6;
1361
1367
  animation-delay: 0ms;
1362
- transition: all 130ms ease-out;
1368
+ transition: stroke,stroke-width 130ms ease-out;
1363
1369
  }
1364
1370
  :where([data-edge-dir='back']) .bexn7q7 {
1365
1371
  animation-direction: reverse;
1366
1372
  }
1367
1373
  .bexn7qb {
1368
- --bexn7qa: translate(var(--bexn7q8, 50%), var(--bexn7q9, 50%));
1374
+ --bexn7qa: translate(var(--bexn7q8, -50%), var(--bexn7q9, -50%));
1369
1375
  top: 0;
1370
1376
  left: 0;
1371
1377
  font-family: var(--likec4-font-family);
@@ -1384,8 +1390,11 @@ svg:has(.bexn7q2) {
1384
1390
  transform: var(--bexn7qa) scale(1.1);
1385
1391
  }
1386
1392
  .bexn7qb:is(.bexn7q2) {
1387
- transition: filter 800ms ease-out;
1388
- filter: var(--likec4-filter-dimmed);
1393
+ opacity: 0.8;
1394
+ transition: opacity 600ms ease-in-out, filter 600ms ease-in-out;
1395
+ transition-delay: 200ms;
1396
+ filter: grayscale(0.85) blur(2px);
1397
+ will-change: opacity, filter;
1389
1398
  }
1390
1399
  .bexn7qc {
1391
1400
  position: absolute;
@@ -1412,7 +1421,7 @@ svg:has(.bexn7q2) {
1412
1421
  text-align: left;
1413
1422
  font-size: calc(0.78125rem * var(--mantine-scale));
1414
1423
  line-height: 1.2;
1415
- }@keyframes lbtzdo8 {
1424
+ }@keyframes lbtzdo9 {
1416
1425
  from {
1417
1426
  opacity: 0.6;
1418
1427
  }
@@ -1427,46 +1436,62 @@ svg:has(.bexn7q2) {
1427
1436
  padding: 0;
1428
1437
  margin: 0;
1429
1438
  }
1430
- .lbtzdo1 {
1431
- filter: var(--likec4-filter-dimmed);
1432
- transition: filter 800ms ease-out;
1439
+ .react-flow__node-compound:has(.lbtzdo1) {
1440
+ opacity: 0.25;
1441
+ transition: opacity 600ms ease-in-out, filter 600ms ease-in-out;
1442
+ transition-delay: 200ms;
1443
+ filter: grayscale(0.85) blur(1px);
1444
+ will-change: opacity, filter;
1433
1445
  }
1434
- .lbtzdo3 {
1446
+ .lbtzdo4 {
1435
1447
  width: 100%;
1436
1448
  height: 100%;
1437
1449
  position: relative;
1438
1450
  border-radius: 6px;
1439
1451
  box-shadow: 0 4px 10px 0.5px rgba(0,0,0,0.1) , 0 2px 2px -1px rgba(0,0,0,0.4);
1440
1452
  padding: 8px;
1441
- background: var(--likec4-element-fill);
1442
1453
  transition: all 200ms ease-out;
1443
1454
  }
1444
- :where(.react-flow__node.selected) .lbtzdo3 {
1455
+ .lbtzdo4:before {
1456
+ content: " ";
1457
+ position: absolute;
1458
+ top: 0;
1459
+ left: 0;
1460
+ width: 100%;
1461
+ height: 100%;
1462
+ border-radius: 6px;
1463
+ pointer-events: none;
1464
+ transition: background 175ms ease-out, opacity 175ms ease-out;
1465
+ background: var(--likec4-element-fill);
1466
+ background-clip: padding-box;
1467
+ }
1468
+ :where(.react-flow__node.selected) .lbtzdo4 {
1445
1469
  box-shadow: none;
1446
1470
  }
1447
- :where(.react-flow__node:focus-visible) .lbtzdo3 {
1471
+ :where(.react-flow__node:focus-visible) .lbtzdo4 {
1448
1472
  transition-duration: 0ms;
1449
1473
  outline: 3px solid var(--mantine-primary-color-outline, var(--mantine-primary-color-filled, var(--likec4-element-stroke)));
1450
1474
  outline-offset: calc(0.09375rem * var(--mantine-scale));
1451
1475
  }
1452
1476
  .lbtzdo6 {
1453
- --lbtzdo4: calc(var(--lbtzdo2, 80%) - var(--lbtzdo5));
1454
- --lbtzdo5: 0%;
1477
+ --lbtzdo5: 0;
1455
1478
  --ai-bg: color-mix(in srgb , var(--likec4-element-fill), transparent 99%);
1456
1479
  border-style: dashed;
1457
1480
  border-width: 3px;
1458
1481
  padding: 6px;
1459
- border-color: color-mix(in srgb , var(--likec4-element-stroke), transparent min(var(--lbtzdo4), 30%));
1460
- background: color-mix(in srgb , var(--likec4-element-fill), transparent var(--lbtzdo4));
1482
+ box-shadow: none;
1483
+ border-color: color-mix(in srgb , var(--likec4-element-stroke), transparent var(--lbtzdo3, 10%));
1461
1484
  background-clip: padding-box;
1462
1485
  }
1486
+ .lbtzdo6:before {
1487
+ transition-delay: 200ms;
1488
+ opacity: calc(var(--lbtzdo2, 1) + var(--lbtzdo5));
1489
+ }
1463
1490
  :where(.react-flow__node.selected) .lbtzdo6 {
1464
- --lbtzdo5: 5%;
1465
- transition-delay: 50ms;
1491
+ --lbtzdo5: .05;
1466
1492
  }
1467
1493
  :where([data-hovered]) .lbtzdo6 {
1468
- --lbtzdo5: 15%;
1469
- transition-delay: 175ms;
1494
+ --lbtzdo5: .1;
1470
1495
  }
1471
1496
  .lbtzdo7 {
1472
1497
  font-family: var(--likec4-compound-font-family);
@@ -1483,7 +1508,7 @@ svg:has(.bexn7q2) {
1483
1508
  color: var(--_compound-title-color,var(--likec4-compound-title-color));
1484
1509
  padding-left: 12px;
1485
1510
  }
1486
- :where([data-likec4-navigable='true']) .lbtzdo7 {
1511
+ .lbtzdo8 {
1487
1512
  padding-left: 26px;
1488
1513
  }
1489
1514
  :where([data-mantine-color-scheme='light'] .likec4-compound-transparent) {
@@ -1492,9 +1517,9 @@ svg:has(.bexn7q2) {
1492
1517
  :where([data-mantine-color-scheme='light'] .likec4-compound-transparent) .lbtzdo7 {
1493
1518
  opacity: 1;
1494
1519
  }
1495
- .lbtzdob {
1496
- --lbtzdo9: var(--likec4-element-loContrast);
1497
- --lbtzdoa: 6;
1520
+ .lbtzdoc {
1521
+ --lbtzdoa: var(--likec4-element-loContrast);
1522
+ --lbtzdob: 6;
1498
1523
  position: absolute;
1499
1524
  top: 0;
1500
1525
  left: 0;
@@ -1504,33 +1529,33 @@ svg:has(.bexn7q2) {
1504
1529
  overflow: visible;
1505
1530
  visibility: hidden;
1506
1531
  }
1507
- :where(.react-flow__node.selected:not(:focus-visible)) .lbtzdob {
1532
+ :where(.react-flow__node.selected:not(:focus-visible)) .lbtzdoc {
1508
1533
  visibility: visible;
1509
1534
  }
1510
- :where(.react-flow__node:focus-within:not(.selected)) .lbtzdob {
1511
- --lbtzdo9: color-mix(in srgb, var(--likec4-element-stroke) 30%, var(--likec4-element-loContrast));
1512
- --lbtzdoa: 8;
1535
+ :where(.react-flow__node:focus-within:not(.selected)) .lbtzdoc {
1536
+ --lbtzdoa: color-mix(in srgb, var(--likec4-element-stroke) 30%, var(--likec4-element-loContrast));
1537
+ --lbtzdob: 8;
1513
1538
  }
1514
- :where([data-mantine-color-scheme='light']) .lbtzdob {
1515
- --lbtzdo9: color-mix(in srgb, var(--likec4-element-stroke) 80%, #000);
1539
+ :where([data-mantine-color-scheme='light']) .lbtzdoc {
1540
+ --lbtzdoa: color-mix(in srgb, var(--likec4-element-stroke) 80%, #000);
1516
1541
  }
1517
- .lbtzdob rect {
1518
- stroke: var(--lbtzdo9);
1542
+ .lbtzdoc rect {
1543
+ stroke: var(--lbtzdoa);
1519
1544
  transform-origin: center center;
1520
- stroke-width: var(--lbtzdoa);
1545
+ stroke-width: var(--lbtzdob);
1521
1546
  animation-duration: 800ms;
1522
- animation-name: lbtzdo8;
1547
+ animation-name: lbtzdo9;
1523
1548
  animation-iteration-count: infinite;
1524
1549
  animation-direction: alternate;
1525
1550
  fill: none;
1526
1551
  }
1527
1552
  .lbtzdo0 {
1528
- --lbtzdoc: var(--likec4-element-loContrast);
1553
+ --lbtzdod: var(--likec4-element-loContrast);
1529
1554
  }
1530
1555
  :where([data-mantine-color-scheme='light'] .likec4-compound-transparent) {
1531
- --lbtzdoc: var(--likec4-element-stroke);
1556
+ --lbtzdod: var(--likec4-element-stroke);
1532
1557
  }
1533
- .lbtzdod {
1558
+ .lbtzdoe {
1534
1559
  --ai-bg: color-mix(in srgb , var(--likec4-element-fill), transparent 99%);
1535
1560
  --ai-bg-hover: color-mix(in srgb , var(--likec4-element-fill) 65%, var(--likec4-element-stroke));
1536
1561
  --ai-hover: color-mix(in srgb , var(--likec4-element-fill) 50%, var(--likec4-element-stroke));
@@ -1539,37 +1564,37 @@ svg:has(.bexn7q2) {
1539
1564
  left: 3px;
1540
1565
  top: 7px;
1541
1566
  cursor: pointer;
1542
- color: var(--_compound-title-color,var(--lbtzdoc));
1567
+ color: var(--_compound-title-color,var(--lbtzdod));
1543
1568
  transform-origin: 90% 70%;
1544
1569
  opacity: 0.75;
1545
1570
  transition: all 150ms ease-out;
1546
1571
  transition-delay: 0ms;
1547
1572
  background-color: var(--ai-bg);
1548
1573
  }
1549
- .lbtzdod:hover {
1574
+ .lbtzdoe:hover {
1550
1575
  box-shadow: var(--mantine-shadow-lg);
1551
1576
  transform: scale(1.466);
1552
1577
  opacity: 1;
1553
1578
  transition-delay: 0;
1554
1579
  }
1555
- .lbtzdod:active {
1580
+ .lbtzdoe:active {
1556
1581
  transform: scale(1.1);
1557
1582
  opacity: 1;
1558
1583
  transition-delay: 0;
1559
1584
  }
1560
- :where([data-mantine-color-scheme='light'] .likec4-compound-transparent) .lbtzdod {
1585
+ :where([data-mantine-color-scheme='light'] .likec4-compound-transparent) .lbtzdoe {
1561
1586
  --ai-bg-hover: color-mix(in srgb , var(--likec4-element-fill), transparent 50%);
1562
1587
  --ai-hover: color-mix(in srgb , var(--likec4-element-fill), transparent 20%);
1563
1588
  opacity: 0.85;
1564
1589
  }
1565
- :where(.react-flow__node:not(.dragging) .lbtzdo0:hover) .lbtzdod:not(:hover) {
1590
+ :where(.react-flow__node:not(.dragging) .lbtzdo0:hover) .lbtzdoe:not(:hover) {
1566
1591
  --ai-bg: var(--ai-bg-hover);
1567
1592
  box-shadow: var(--mantine-shadow-lg);
1568
1593
  transform: scale(1.223);
1569
1594
  opacity: 1;
1570
1595
  transition-delay: 250ms;
1571
1596
  }
1572
- .lbtzdod svg.icon {
1597
+ .lbtzdoe svg.icon {
1573
1598
  width: 70%;
1574
1599
  height: 70%;
1575
1600
  stroke-width: 1.5;
@@ -1583,16 +1608,19 @@ svg:has(.bexn7q2) {
1583
1608
  }
1584
1609
  ._1b6tkn2 {
1585
1610
  --_1b6tkn0: color-mix(in srgb, var(--likec4-element-stroke) 90%, var(--likec4-element-fill));
1586
- position: relative;
1587
1611
  width: 100%;
1588
1612
  height: 100%;
1589
1613
  padding: 0;
1590
1614
  margin: 0;
1591
- backface-visibility: hidden;
1615
+ display: flex;
1616
+ align-items: stretch;
1592
1617
  }
1593
- .react-flow__node:has(._1b6tkn3) {
1594
- filter: var(--likec4-filter-dimmed);
1595
- transition: filter 800ms ease-out;
1618
+ .react-flow__node-element:has(._1b6tkn3) {
1619
+ opacity: 0.25;
1620
+ transition: opacity 600ms ease-in-out, filter 600ms ease-in-out;
1621
+ transition-delay: 200ms;
1622
+ filter: grayscale(0.85) blur(2px);
1623
+ will-change: opacity, filter;
1596
1624
  }
1597
1625
  ._1b6tkn5 {
1598
1626
  stroke: var(--likec4-element-loContrast);
@@ -1616,6 +1644,9 @@ svg:has(.bexn7q2) {
1616
1644
  :where([data-likec4-shape="queue"], [data-likec4-shape="cylinder"], [data-likec4-shape="storage"]) ._1b6tkn5 {
1617
1645
  stroke-width: 10;
1618
1646
  }
1647
+ ._1b6tkn3 ._1b6tkn5 {
1648
+ visibility: hidden;
1649
+ }
1619
1650
  ._1b6tkn6 {
1620
1651
  fill: var(--likec4-element-fill);
1621
1652
  }
@@ -1670,9 +1701,7 @@ svg:has(.bexn7q2) {
1670
1701
  }
1671
1702
  ._1b6tknc {
1672
1703
  --_1b6tkn1: calc(1.5rem * var(--mantine-scale));
1673
- position: relative;
1674
- width: 100%;
1675
- height: 100%;
1704
+ flex: 1;
1676
1705
  padding: var(--_1b6tkn1);
1677
1706
  display: flex;
1678
1707
  flex-direction: column;
@@ -1731,6 +1760,7 @@ svg:has(.bexn7q2) {
1731
1760
  filter: var(--_1b6tkng, var(--_1b6tknf));
1732
1761
  transition: filter 300ms ease-out;
1733
1762
  transition-delay: 0ms;
1763
+ z-index: -1;
1734
1764
  }
1735
1765
  :where(.react-flow__node.selected, .react-flow__node:focus-visible, ._1b6tkn2:focus-visible) ._1b6tknh {
1736
1766
  filter: none;
@@ -1829,6 +1859,31 @@ svg:has(.bexn7q2) {
1829
1859
  }
1830
1860
  ._4ysv0o2 {
1831
1861
  text-align: left;
1862
+ }.hbkbtj0 {
1863
+ bottom: 0;
1864
+ left: 0;
1865
+ padding: 8px;
1866
+ margin: 0;
1867
+ }
1868
+ .hbkbtj1 {
1869
+ cursor: default;
1870
+ min-width: 100px;
1871
+ max-width: calc(100vw - 16px);
1872
+ background-color: color-mix(in srgb, var(--mantine-color-body), transparent 20%);
1873
+ -webkit-backdrop-filter: blur(8px);
1874
+ backdrop-filter: blur(8px);
1875
+ }
1876
+ .hbkbtj3 {
1877
+ white-space-collapse: preserve-breaks;
1878
+ color: var(--mantine-color-gray-7);
1879
+ }
1880
+ :where([data-mantine-color-scheme="dark"]) .hbkbtj3 {
1881
+ color: var(--mantine-color-gray-5);
1882
+ }
1883
+ @media (min-width: 62em) {
1884
+ .hbkbtj1 {
1885
+ max-width: 45vw;
1886
+ }
1832
1887
  }._2jkb2y0 {
1833
1888
  position: absolute;
1834
1889
  bottom: 0.5rem;
@@ -1859,36 +1914,12 @@ svg:has(.bexn7q2) {
1859
1914
  [data-mantine-color-scheme="light"] ._2jkb2y3 {
1860
1915
  --_2jkb2y2: 15%;
1861
1916
  }
1862
- ._2jkb2y3 .tabler-icon {
1863
- width: 80%;
1917
+ :where(._2jkb2y1, ._2jkb2y3) .tabler-icon {
1918
+ width: 0.85em;
1919
+ height: 0.85em;
1864
1920
  }._1lmzt1h0 {
1865
1921
  top: var(--likec4-options-panel-top, 1rem);
1866
1922
  right: var(--likec4-options-panel-right, 1rem);
1867
1923
  margin: 0;
1868
1924
  box-shadow: var(--mantine-shadow-xl);
1869
- }.hbkbtj0 {
1870
- bottom: 0;
1871
- left: 0;
1872
- padding: 8px;
1873
- margin: 0;
1874
- }
1875
- .hbkbtj1 {
1876
- cursor: default;
1877
- min-width: 100px;
1878
- max-width: calc(100vw - 16px);
1879
- background-color: color-mix(in srgb, var(--mantine-color-body), transparent 20%);
1880
- -webkit-backdrop-filter: blur(8px);
1881
- backdrop-filter: blur(8px);
1882
- }
1883
- .hbkbtj3 {
1884
- white-space-collapse: preserve-breaks;
1885
- color: var(--mantine-color-gray-7);
1886
- }
1887
- :where([data-mantine-color-scheme="dark"]) .hbkbtj3 {
1888
- color: var(--mantine-color-gray-5);
1889
- }
1890
- @media (min-width: 62em) {
1891
- .hbkbtj1 {
1892
- max-width: 45vw;
1893
- }
1894
1925
  }
@@ -2,7 +2,6 @@ export declare const vars: {
2
2
  default: {
3
3
  font: `var(--${string})` | `var(--${string}, ${string})` | `var(--${string}, ${number})`;
4
4
  };
5
- filterDimmed: `var(--${string})` | `var(--${string}, ${string})` | `var(--${string}, ${number})`;
6
5
  likec4: {
7
6
  font: `var(--${string})` | `var(--${string}, ${string})` | `var(--${string}, ${number})`;
8
7
  background: {
@@ -1 +1,3 @@
1
- export default function OptionsPanel(): import("react/jsx-runtime").JSX.Element;
1
+ /// <reference types="react" />
2
+ declare const OptionsPanelMemo: import('react').NamedExoticComponent<object>;
3
+ export default OptionsPanelMemo;
@@ -2,10 +2,11 @@ import { CSSProperties, PropsWithChildren } from 'react';
2
2
  import { XYFlowEdge, XYFlowNode } from './types';
3
3
 
4
4
  type XYFlowWrapperProps = PropsWithChildren<{
5
+ colorMode?: 'system' | 'light' | 'dark';
5
6
  className?: string | undefined;
6
7
  defaultNodes: XYFlowNode[];
7
8
  defaultEdges: XYFlowEdge[];
8
9
  style?: CSSProperties | undefined;
9
10
  }>;
10
- export declare function XYFlow({ className, children, defaultNodes, defaultEdges, style }: XYFlowWrapperProps): import("react/jsx-runtime").JSX.Element;
11
+ export declare function XYFlow({ colorMode, className, children, defaultNodes, defaultEdges, style }: XYFlowWrapperProps): import("react/jsx-runtime").JSX.Element;
11
12
  export {};
@@ -7,5 +7,5 @@ type XYFlowInnerProps = PropsWithChildren<{
7
7
  showDiagramTitle: boolean;
8
8
  enableDynamicViewWalkthrough: boolean;
9
9
  }>;
10
- export declare function XYFlowInner({ children, background, controls, showDiagramTitle, enableDynamicViewWalkthrough }: XYFlowInnerProps): import("react/jsx-runtime").JSX.Element;
10
+ export declare const XYFlowInner: import('react').NamedExoticComponent<XYFlowInnerProps>;
11
11
  export {};
@@ -3,4 +3,4 @@ export declare const ZIndexes: {
3
3
  readonly Edge: 2;
4
4
  readonly Element: 3;
5
5
  };
6
- export declare const MinZoom = 0.05;
6
+ export declare const MinZoom = 0.1;
@@ -1,7 +1,7 @@
1
1
  import { DiagramView } from '@likec4/core';
2
2
  import { XYFlowData } from '../xyflow/types';
3
3
 
4
- export declare function diagramViewToXYFlowData(view: Pick<DiagramView, 'nodes' | 'edges' | '__'>, opts: {
4
+ export declare function diagramViewToXYFlowData(view: Pick<DiagramView, 'id' | 'nodes' | 'edges' | '__' | 'manualLayout'>, opts: {
5
5
  draggable: boolean;
6
6
  selectable: boolean;
7
7
  }): XYFlowData;
@@ -1,5 +1,4 @@
1
1
  import { EdgeProps } from '@xyflow/react';
2
- import { CSSProperties } from 'react';
3
2
 
4
3
  export declare const RelationshipEdge: import('react').NamedExoticComponent<EdgeProps<{
5
4
  source: string;
@@ -17,12 +16,12 @@ export declare const RelationshipEdge: import('react').NamedExoticComponent<Edge
17
16
  ariaLabel?: string;
18
17
  interactionWidth?: number;
19
18
  label?: import('react').ReactNode;
20
- labelStyle?: CSSProperties;
19
+ labelStyle?: import('react').CSSProperties;
21
20
  labelShowBg?: boolean;
22
- labelBgStyle?: CSSProperties;
21
+ labelBgStyle?: import('react').CSSProperties;
23
22
  labelBgPadding?: [number, number];
24
23
  labelBgBorderRadius?: number;
25
- style?: CSSProperties;
24
+ style?: import('react').CSSProperties;
26
25
  className?: string;
27
26
  updatable?: import('@xyflow/react').EdgeUpdatable;
28
27
  focusable?: boolean;
@@ -1,8 +1,10 @@
1
- import { Point } from '@likec4/core';
2
1
  import { Position, XYPosition } from '@xyflow/react';
3
2
  import { InternalXYFlowNode } from '../types';
4
3
 
5
- export declare function getNodeIntersectionFromCenterToPoint(intersectionNode: InternalXYFlowNode, [x1, y1]: Point): readonly [number, number];
4
+ export declare function getNodeIntersectionFromCenterToPoint(intersectionNode: InternalXYFlowNode, { x: x1, y: y1 }: XYPosition): {
5
+ x: number;
6
+ y: number;
7
+ };
6
8
  export declare function getPointPosition(node: InternalXYFlowNode, intersectionPoint: XYPosition): readonly [number, number, Position];
7
9
  export declare function getEdgeParams(source: InternalXYFlowNode, target: InternalXYFlowNode): {
8
10
  sx: number;
@@ -1,8 +1,10 @@
1
1
  export declare const container: string;
2
2
  export declare const dimmed: string;
3
- export declare const varTransparency: `var(--${string})` | `var(--${string}, ${string})` | `var(--${string}, ${number})`;
3
+ export declare const varOpacity: `var(--${string})` | `var(--${string}, ${string})` | `var(--${string}, ${number})`;
4
+ export declare const varBorderTransparency: `var(--${string})` | `var(--${string}, ${string})` | `var(--${string}, ${number})`;
4
5
  export declare const compoundBody: string;
5
6
  export declare const transparent: string;
6
7
  export declare const title: string;
8
+ export declare const titleWithNavigation: string;
7
9
  export declare const indicator: string;
8
10
  export declare const navigateBtn: string;
@@ -2,5 +2,5 @@ import { NodeProps } from '@xyflow/react';
2
2
  import { ElementXYFlowNode } from '../../types';
3
3
 
4
4
  type ElementNodeProps = NodeProps<ElementXYFlowNode>;
5
- export declare function ElementNode({ id, data: { element }, dragging, selected, width, height }: ElementNodeProps): import("react/jsx-runtime").JSX.Element;
5
+ export declare const ElementNodeMemo: import('react').NamedExoticComponent<ElementNodeProps>;
6
6
  export {};
@@ -1 +1 @@
1
- export { ElementNode } from './ElementNode';
1
+ export { ElementNodeMemo as ElementNode } from './ElementNode';
@@ -1,4 +1,4 @@
1
- import { BBox, DiagramEdge, DiagramNode, Fqn, Point } from '@likec4/core';
1
+ import { BBox, DiagramEdge, DiagramNode, Fqn, Point, XYPosition } from '@likec4/core';
2
2
  import { Edge, EdgeMouseHandler, InternalNode, Node, NodeMouseHandler, OnMoveEnd, OnMoveStart, ReactFlowInstance, ReactFlowState } from '@xyflow/react';
3
3
  import { MouseEvent as ReactMouseEvent } from 'react';
4
4
  import { SetReadonly, SetRequired } from 'type-fest';
@@ -25,7 +25,7 @@ export declare namespace XYFlowNode {
25
25
  }
26
26
  export type RelationshipData = {
27
27
  edge: DiagramEdge;
28
- controlPoints: Point[];
28
+ controlPoints: XYPosition[] | null;
29
29
  headPoint: Point | null;
30
30
  tailPoint: Point | null;
31
31
  type: 'bezier' | 'poly';
@@ -1,4 +1,7 @@
1
+ import { DiagramEdge, Point } from '@likec4/core/types';
1
2
  import { XYPosition } from '@xyflow/react';
2
3
 
3
4
  export declare function toDomPrecision(v: number | null): number;
4
5
  export declare function distance(a: XYPosition, b: XYPosition): number;
6
+ export declare function bezierControlPoints(diagramEdge: DiagramEdge): XYPosition[];
7
+ export declare function isSamePoint(a: XYPosition | Point, b: XYPosition | Point): boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@likec4/diagram",
3
- "version": "1.2.1",
3
+ "version": "1.3.0",
4
4
  "license": "MIT",
5
5
  "bugs": "https://github.com/likec4/likec4/issues",
6
6
  "homepage": "https://likec4.dev",
@@ -48,9 +48,12 @@
48
48
  "clean": "run -T rimraf -v -g 'dist/*' .tsbuildinfo"
49
49
  },
50
50
  "dependencies": {
51
- "@likec4/core": "1.2.1",
51
+ "@likec4/core": "1.3.0",
52
52
  "@react-hookz/web": "^24.0.4",
53
53
  "@tabler/icons-react": "^3.0.0",
54
+ "@vanilla-extract/css": "^1.15.3",
55
+ "@vanilla-extract/css-utils": "^0.1.4",
56
+ "@vanilla-extract/dynamic": "^2.1.1",
54
57
  "d3-shape": "^3.2.0",
55
58
  "esm-env": "^1.0.0",
56
59
  "fast-equals": "^5.0.1",
@@ -59,27 +62,26 @@
59
62
  "zustand": "^4.5.2"
60
63
  },
61
64
  "peerDependencies": {
62
- "@mantine/core": "^7.10.1",
63
- "@mantine/hooks": "^7.10.1",
65
+ "@mantine/core": "7.10.2",
66
+ "@mantine/hooks": "7.10.2",
64
67
  "react": "^18.3.1",
65
68
  "react-dom": "^18.3.1"
66
69
  },
67
70
  "devDependencies": {
68
- "@likec4/tsconfig": "1.2.1",
71
+ "@likec4/tsconfig": "1.3.0",
69
72
  "@lume/kiwi": "^0.4.3",
70
- "@mantine/core": "^7.10.1",
71
- "@mantine/hooks": "^7.10.1",
72
- "@mantine/vanilla-extract": "^7.10.1",
73
+ "@mantine/core": "7.10.2",
74
+ "@mantine/hooks": "7.10.2",
75
+ "@mantine/vanilla-extract": "7.10.2",
73
76
  "@total-typescript/ts-reset": "^0.5.1",
74
77
  "@types/bezier-js": "^4.1.3",
75
78
  "@types/d3-shape": "^3",
76
79
  "@types/react": "^18.3.3",
77
80
  "@types/react-dom": "^18.3.0",
78
- "@vanilla-extract/css": "^1.15.2",
79
- "@vanilla-extract/dynamic": "^2.1.1",
80
- "@vanilla-extract/esbuild-plugin": "^2.3.6",
81
+ "@vanilla-extract/esbuild-plugin": "^2.3.7",
81
82
  "@vitejs/plugin-react": "^4.3.1",
82
- "@xyflow/react": "^12.0.0-next",
83
+ "@xyflow/react": "12.0.0-next.21",
84
+ "@xyflow/system": "0.0.29",
83
85
  "bezier-js": "^6.1.4",
84
86
  "clsx": "^2.1.1",
85
87
  "execa": "^9.1.0",
@@ -89,8 +91,7 @@
89
91
  "tilg": "^0.1.1",
90
92
  "type-fest": "^4.18.2",
91
93
  "typescript": "^5.4.5",
92
- "unbuild": "^2.0.0",
93
- "vite": "5.3.0",
94
+ "vite": "5.3.1",
94
95
  "vite-plugin-dts": "^3.9.1"
95
96
  }
96
97
  }
@@ -17,10 +17,10 @@ globalStyle(`.react-flow${cssReactFlow}`, {
17
17
  [xyvars.background.pattern.color]: vars.likec4.background.pattern.color
18
18
  }
19
19
  })
20
- globalStyle(`.react-flow${cssReactFlow} .react-flow__viewport`, {
21
- // willChange: 'transform'
22
- backfaceVisibility: 'hidden'
23
- })
20
+
21
+ // globalStyle(`.react-flow${cssReactFlow} .react-flow__node`, {
22
+ // willChange: 'transform'
23
+ // })
24
24
 
25
25
  export const cssDisablePan = style({})
26
26