@truedat/dd 8.12.10 → 8.12.12

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.
@@ -2481,8 +2481,8 @@
2481
2481
  var(--td-lineage-inspector-toolbar-offset) +
2482
2482
  var(--td-lineage-context-control-size) - 1px
2483
2483
  );
2484
- --td-lineage-inspector-motion-duration: 180ms;
2485
- --td-lineage-inspector-motion-easing: cubic-bezier(0.16, 1, 0.3, 1);
2484
+ --td-lineage-inspector-motion-duration: 220ms;
2485
+ --td-lineage-inspector-motion-easing: cubic-bezier(0.22, 0.68, 0, 1);
2486
2486
 
2487
2487
  position: relative;
2488
2488
  display: flex;
@@ -2540,12 +2540,16 @@
2540
2540
  content: "";
2541
2541
  pointer-events: none;
2542
2542
  }
2543
+ .lineage-graph__dock-context--pinned .lineage-graph__dock-context-bar {
2544
+ background: var(--td-graph-accent, #ed5c17);
2545
+ }
2543
2546
  .lineage-graph__dock-context--pinned
2544
2547
  .lineage-graph__dock-context-bar:not(
2545
2548
  .lineage-graph__dock-context-bar--expanded
2546
2549
  ) {
2547
2550
  background: var(--td-graph-accent, #ed5c17);
2548
- box-shadow: 0 5px 12px rgba(237, 92, 23, 0.28);
2551
+ box-shadow: 0 5px 12px
2552
+ color-mix(in srgb, var(--td-graph-accent, #ed5c17) 28%, transparent);
2549
2553
  }
2550
2554
  .lineage-graph__dock-context-bar--edge {
2551
2555
  background: var(--td-graph-edge-metadata, #7c3aed);
@@ -2564,6 +2568,11 @@
2564
2568
  cursor: pointer;
2565
2569
  }
2566
2570
  .lineage-graph__dock-context-reopen {
2571
+ padding: 0;
2572
+ border: 0;
2573
+ background: transparent;
2574
+ color: inherit;
2575
+ font: inherit;
2567
2576
  position: static;
2568
2577
  display: flex;
2569
2578
  height: 100%;
@@ -2572,28 +2581,30 @@
2572
2581
  align-items: center;
2573
2582
  text-align: left;
2574
2583
  }
2584
+ button.lineage-graph__dock-context-reopen {
2585
+ cursor: pointer;
2586
+ }
2575
2587
  .lineage-graph__dock-context-clear,
2576
2588
  .lineage-graph__dock-context-unpin {
2577
2589
  width: var(--td-lineage-context-control-size);
2578
2590
  min-width: var(--td-lineage-context-control-size);
2579
2591
  }
2592
+ @keyframes td-lineage-context-copy-in {
2593
+ from {
2594
+ opacity: 0;
2595
+ }
2596
+ to {
2597
+ opacity: 1;
2598
+ }
2599
+ }
2580
2600
  .lineage-graph__dock-context-clear {
2581
2601
  border-left: 1px solid rgba(255, 255, 255, 0.34);
2582
2602
  }
2583
2603
  .lineage-graph__dock-context-bar--expanded .lineage-graph__dock-context-clear {
2584
2604
  border-left: 0;
2585
2605
  }
2586
- .lineage-graph__dock-context-bar--expanded .lineage-graph__dock-context-unpin {
2587
- height: 100%;
2588
- border-right: 1px solid rgba(255, 255, 255, 0.34);
2589
- }
2590
- .lineage-graph__dock-context--pinned
2591
- .lineage-graph__dock-context-bar--expanded
2592
- .lineage-graph__dock-context-unpin {
2593
- background: var(--td-graph-accent, #ed5c17);
2594
- color: #ffffff;
2595
- }
2596
2606
  .lineage-graph__dock-context-summary {
2607
+ animation: td-lineage-context-copy-in 140ms ease-out;
2597
2608
  display: flex;
2598
2609
  width: 100%;
2599
2610
  height: 100%;
@@ -2614,12 +2625,6 @@
2614
2625
  border: 1px solid transparent;
2615
2626
  border-radius: 6px;
2616
2627
  transition:
2617
- width var(--td-lineage-inspector-motion-duration)
2618
- var(--td-lineage-inspector-motion-easing),
2619
- min-width var(--td-lineage-inspector-motion-duration)
2620
- var(--td-lineage-inspector-motion-easing),
2621
- height var(--td-lineage-inspector-motion-duration)
2622
- var(--td-lineage-inspector-motion-easing),
2623
2628
  border-color var(--td-lineage-inspector-motion-duration)
2624
2629
  var(--td-lineage-inspector-motion-easing),
2625
2630
  background-color var(--td-lineage-inspector-motion-duration)
@@ -2635,7 +2640,7 @@
2635
2640
  flex: 1 1 auto;
2636
2641
  flex-direction: column;
2637
2642
  justify-content: center;
2638
- gap: 3px;
2643
+ gap: 0;
2639
2644
  }
2640
2645
  .lineage-graph__dock-context-label,
2641
2646
  .lineage-graph__dock-context-type {
@@ -2649,8 +2654,6 @@
2649
2654
  .lineage-graph__dock-context-label {
2650
2655
  font-size: 11px;
2651
2656
  font-weight: 700;
2652
- transition: font-size var(--td-lineage-inspector-motion-duration)
2653
- var(--td-lineage-inspector-motion-easing);
2654
2657
  }
2655
2658
  .lineage-graph__dock-context-type {
2656
2659
  max-height: 0;
@@ -2662,8 +2665,6 @@
2662
2665
  text-transform: uppercase;
2663
2666
  transform: translateY(-3px);
2664
2667
  transition:
2665
- max-height var(--td-lineage-inspector-motion-duration)
2666
- var(--td-lineage-inspector-motion-easing),
2667
2668
  opacity var(--td-lineage-inspector-motion-duration)
2668
2669
  var(--td-lineage-inspector-motion-easing),
2669
2670
  transform var(--td-lineage-inspector-motion-duration)
@@ -2678,6 +2679,9 @@
2678
2679
  border-radius: 8px;
2679
2680
  background: rgba(255, 255, 255, 0.1);
2680
2681
  }
2682
+ .lineage-graph__dock-context-bar--expanded .lineage-graph__dock-context-copy {
2683
+ gap: 3px;
2684
+ }
2681
2685
  .lineage-graph__dock-context-bar--expanded .lineage-graph__dock-context-label {
2682
2686
  font-size: 16px;
2683
2687
  font-weight: 800;
@@ -3607,6 +3611,7 @@
3607
3611
  @media (prefers-reduced-motion: reduce) {
3608
3612
  .lineage-graph__tool-panel,
3609
3613
  .lineage-inspector,
3614
+ .lineage-graph__dock-context-summary,
3610
3615
  .lineage-graph__dock-context-clear .icon {
3611
3616
  animation: none;
3612
3617
  }
@@ -3642,28 +3647,96 @@
3642
3647
  box-shadow: 0 12px 28px rgba(15, 23, 42, 0.13);
3643
3648
  backdrop-filter: blur(10px);
3644
3649
  -webkit-backdrop-filter: blur(10px);
3645
- transition: width 200ms ease;
3646
- }
3647
-
3648
- .td-graph-minimap-shell--collapsed {
3649
- width: 200px;
3650
+ box-sizing: content-box;
3651
+ transition: width 220ms cubic-bezier(0.22, 1, 0.36, 1);
3650
3652
  }
3651
3653
 
3652
3654
  .td-graph-minimap-shell--expanded {
3653
- width: auto;
3654
- min-width: 288px;
3655
+ width: 288px;
3655
3656
  }
3656
3657
 
3657
3658
  .td-graph-minimap-body {
3658
3659
  position: relative;
3659
3660
  width: 100%;
3661
+ height: 150px;
3662
+ overflow: hidden;
3663
+ opacity: 1;
3664
+ transition:
3665
+ height 220ms cubic-bezier(0.22, 1, 0.36, 1),
3666
+ opacity 160ms ease;
3667
+ }
3668
+
3669
+ .td-graph-minimap-shell--expanded .td-graph-minimap-body {
3670
+ height: 200px;
3671
+ }
3672
+
3673
+ .td-graph-minimap-shell--collapsed {
3674
+ width: 200px;
3675
+
3676
+ .td-graph-minimap-body {
3677
+ height: 0;
3678
+ opacity: 0;
3679
+ pointer-events: none;
3680
+ }
3681
+ }
3682
+
3683
+ .td-graph-minimap {
3684
+ transition:
3685
+ width 220ms cubic-bezier(0.22, 1, 0.36, 1),
3686
+ height 220ms cubic-bezier(0.22, 1, 0.36, 1);
3687
+
3688
+ svg {
3689
+ display: block;
3690
+ width: 100%;
3691
+ height: 100%;
3692
+ }
3693
+ }
3694
+
3695
+ @media (prefers-reduced-motion: reduce) {
3696
+ .td-graph-minimap-shell,
3697
+ .td-graph-minimap-body,
3698
+ .td-graph-minimap {
3699
+ transition: none;
3700
+ }
3660
3701
  }
3661
3702
 
3662
3703
  .td-graph-minimap-expand {
3663
- display: none;
3704
+ position: absolute;
3705
+ bottom: 6px;
3706
+ left: 6px;
3707
+ z-index: 2;
3708
+ display: inline-flex;
3709
+ width: 22px;
3710
+ height: 22px;
3711
+ align-items: center;
3712
+ justify-content: center;
3713
+ padding: 0;
3714
+ border: 1px solid rgba(15, 23, 42, 0.12);
3715
+ border-radius: 5px;
3716
+ background: rgba(255, 255, 255, 0.88);
3717
+ color: #64748b;
3718
+ cursor: pointer;
3719
+ backdrop-filter: blur(6px);
3720
+ -webkit-backdrop-filter: blur(6px);
3721
+ transition:
3722
+ background-color 120ms ease,
3723
+ color 120ms ease,
3724
+ border-color 120ms ease;
3725
+ }
3726
+
3727
+ .td-graph-minimap-expand:hover {
3728
+ background: rgba(255, 255, 255, 0.98);
3729
+ border-color: #002057;
3730
+ color: #002057;
3731
+ }
3732
+
3733
+ .td-graph-minimap-expand:focus-visible {
3734
+ outline: 2px solid #ed5c17;
3735
+ outline-offset: 2px;
3664
3736
  }
3665
3737
 
3666
3738
  .td-graph-minimap-header {
3739
+ position: relative;
3667
3740
  display: flex;
3668
3741
  height: 32px;
3669
3742
  align-items: center;
@@ -3673,6 +3746,13 @@
3673
3746
  color: #334155;
3674
3747
  }
3675
3748
 
3749
+ .td-graph-minimap-toggle::before {
3750
+ content: "";
3751
+ position: absolute;
3752
+ inset: 0;
3753
+ cursor: pointer;
3754
+ }
3755
+
3676
3756
  .td-graph-minimap-title {
3677
3757
  display: inline-flex;
3678
3758
  min-width: 0;
@@ -4044,3 +4124,55 @@
4044
4124
  .lineage-graph__legend-section {
4045
4125
  flex-shrink: 0;
4046
4126
  }
4127
+
4128
+ .lineage-graph__stage-surface
4129
+ .react-flow__node.lineage-node--pinned
4130
+ > :is(.td-lineage-resource-node, .td-lineage-group-node) {
4131
+ box-shadow: inset 0 0 0 2px var(--td-graph-accent, #ed5c17);
4132
+ opacity: 1;
4133
+
4134
+ > :is(
4135
+ .td-lineage-resource-node__header,
4136
+ .td-lineage-group-node__header,
4137
+ .td-lineage-group-node__absolute-header
4138
+ ) {
4139
+ background: var(--td-lineage-interaction-bg, #fff7ed);
4140
+ box-shadow: none;
4141
+ color: color-mix(in srgb, var(--td-graph-accent, #ed5c17) 70%, #000000);
4142
+
4143
+ :is(
4144
+ .td-lineage-resource-node__label,
4145
+ .td-lineage-resource-node__kind,
4146
+ .td-lineage-group-node__label,
4147
+ .td-lineage-group-node__absolute-label,
4148
+ .td-lineage-group-node__toggle,
4149
+ .td-lineage-group-node__type-icon.icon
4150
+ ) {
4151
+ color: color-mix(in srgb, var(--td-graph-accent, #ed5c17) 70%, #000000);
4152
+ }
4153
+ }
4154
+ }
4155
+
4156
+ .lineage-graph__stage-surface .lineage-graph__node-unpin {
4157
+ position: absolute;
4158
+ top: -10px;
4159
+ left: -10px;
4160
+ z-index: 5;
4161
+ display: inline-flex;
4162
+ width: 24px;
4163
+ height: 24px;
4164
+ align-items: center;
4165
+ justify-content: center;
4166
+ padding: 0;
4167
+ border: 1px solid var(--td-graph-accent, #ed5c17);
4168
+ border-radius: 50%;
4169
+ background: var(--td-graph-accent, #ed5c17);
4170
+ color: #ffffff;
4171
+ cursor: pointer;
4172
+ pointer-events: auto;
4173
+
4174
+ &:focus-visible {
4175
+ outline: 2px solid #0284c7;
4176
+ outline-offset: 2px;
4177
+ }
4178
+ }
@@ -233,6 +233,74 @@ describe("compound root columns", () => {
233
233
  });
234
234
  });
235
235
 
236
+ describe("relations within one lineage group", () => {
237
+ const group = { ...node("group"), data: { label: "group", topology: true } };
238
+ const child = (id) => ({ ...node(id), parentId: "group" });
239
+
240
+ it("places related siblings from left to right and keeps an unrelated sibling separate", () => {
241
+ const nodes = [group, child("source"), child("target"), child("unrelated")];
242
+ const edges = [{ source: "source", target: "target" }];
243
+ const positions = geometry(freshLayout()({ nodes, edges }));
244
+
245
+ expect(positions.source.x + positions.source.w).toBeLessThan(
246
+ positions.target.x,
247
+ );
248
+ expect(positions.unrelated.x).toBe(positions.source.x);
249
+ expect(positions.unrelated.y).toBeGreaterThan(positions.source.y);
250
+ expect(positions.target.x + positions.target.w).toBeLessThanOrEqual(
251
+ positions.group.x + positions.group.w,
252
+ );
253
+ });
254
+
255
+ it("projects relations between nested nodes onto their sibling groups", () => {
256
+ const nodes = [
257
+ group,
258
+ child("left"),
259
+ child("right"),
260
+ { ...node("left/leaf"), parentId: "left" },
261
+ { ...node("right/leaf"), parentId: "right" },
262
+ ];
263
+ const edges = [{ source: "left/leaf", target: "right/leaf" }];
264
+ const positions = geometry(freshLayout()({ nodes, edges }));
265
+
266
+ expect(positions.left.x + positions.left.w).toBeLessThan(positions.right.x);
267
+ expect(positions["left/leaf"].x).toBeGreaterThanOrEqual(positions.left.x);
268
+ expect(positions["right/leaf"].x).toBeGreaterThanOrEqual(positions.right.x);
269
+ });
270
+
271
+ it("reflows the whole graph when an internal dependency widens a group", () => {
272
+ const nodes = [group, child("source"), child("target"), node("other")];
273
+ const layout = freshLayout();
274
+ const before = geometry(layout({ nodes, edges: [] }));
275
+ const after = geometry(
276
+ layout({
277
+ nodes,
278
+ edges: [{ source: "source", target: "target" }],
279
+ }),
280
+ );
281
+
282
+ expect(after.group.w).toBeGreaterThan(before.group.w);
283
+ expect(after.group.h).toBeLessThan(before.group.h);
284
+ expect(after.other.y).toBeLessThan(before.other.y);
285
+ });
286
+
287
+ it("keeps cyclic siblings in one column without overlapping", () => {
288
+ const nodes = [group, child("a"), child("b")];
289
+ const positions = geometry(
290
+ freshLayout()({
291
+ nodes,
292
+ edges: [
293
+ { source: "a", target: "b" },
294
+ { source: "b", target: "a" },
295
+ ],
296
+ }),
297
+ );
298
+
299
+ expect(positions.a.x).toBe(positions.b.x);
300
+ expect(positions.b.y).toBeGreaterThanOrEqual(positions.a.y + positions.a.h);
301
+ });
302
+ });
303
+
236
304
  it.each([undefined, "lineage-field"])(
237
305
  "leaves only bottom padding after the last child (%s)",
238
306
  (variant) => {
@@ -3108,8 +3108,8 @@ export const planLineageEdgeRoutes = (edges = [], nodes = []) => {
3108
3108
  data: {
3109
3109
  ...edge.data,
3110
3110
  ...routePortPositions[index],
3111
- edgeOffset: routeGuides[index]?.edgeOffset ?? edge.data?.edgeOffset,
3112
- routeGuide: routeGuides[index] || edge.data?.routeGuide,
3111
+ edgeOffset: routeGuides[index]?.edgeOffset,
3112
+ routeGuide: routeGuides[index],
3113
3113
  },
3114
3114
  }));
3115
3115
  };
@@ -3139,6 +3139,7 @@ export const focusLineageNodes = (
3139
3139
  focusedNodeIds,
3140
3140
  focusActive,
3141
3141
  selectedNodeId,
3142
+ pinnedNodeId,
3142
3143
  ) =>
3143
3144
  focusActive
3144
3145
  ? nodes.map((node) => {
@@ -3147,7 +3148,8 @@ export const focusLineageNodes = (
3147
3148
  node.data?.lineageNode?.lineageKind === "group";
3148
3149
  const selected = node.id === selectedNodeId;
3149
3150
  const direct = !selected && focusedNodeIds.has(node.id);
3150
- const dimmed = !selected && !focusedNodeIds.has(node.id);
3151
+ const dimmed =
3152
+ !selected && node.id !== pinnedNodeId && !focusedNodeIds.has(node.id);
3151
3153
 
3152
3154
  return {
3153
3155
  ...node,