@pipelex/mthds-ui 0.12.0 → 0.14.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.
@@ -749,16 +749,22 @@ svg.react-flow__connectionline {
749
749
  var(--shadow-lg) !important;
750
750
  z-index: 1000 !important;
751
751
  }
752
- /* Pipe cards handle their own selection styling — suppress the wrapper outline */
752
+ /* Pipe cards handle their own selection styling — suppress the wrapper outline.
753
+ The outline reset excludes .node-validation-flash: the flash animates the
754
+ wrapper outline, and an !important reset would override the animation. */
753
755
  .react-flow__node-pipeCard {
754
756
  background: transparent !important;
755
757
  border: none !important;
756
758
  box-shadow: none !important;
757
- outline: none !important;
758
759
  padding: 0 !important;
759
760
  }
761
+ .react-flow__node-pipeCard:not(.node-validation-flash) {
762
+ outline: none !important;
763
+ }
760
764
  .react-flow__node-pipeCard.selected {
761
765
  box-shadow: none !important;
766
+ }
767
+ .react-flow__node-pipeCard.selected:not(.node-validation-flash) {
762
768
  outline: none !important;
763
769
  }
764
770
  .react-flow__node-pipeCard.selected .pipe-card {
@@ -1007,6 +1013,40 @@ svg.react-flow__connectionline {
1007
1013
  .pipe-card--controller {
1008
1014
  --pipe-card-accent: var(--text-muted);
1009
1015
  }
1016
+ .pipe-card--static {
1017
+ background: var(--surface-sunken);
1018
+ border-left-style: solid;
1019
+ }
1020
+ .pipe-card-annotations {
1021
+ display: flex;
1022
+ flex-wrap: wrap;
1023
+ gap: 4px;
1024
+ min-width: 0;
1025
+ }
1026
+ .pipe-card-annotation {
1027
+ display: inline-flex;
1028
+ align-items: center;
1029
+ max-width: 100%;
1030
+ overflow: hidden;
1031
+ text-overflow: ellipsis;
1032
+ white-space: nowrap;
1033
+ border-radius: 4px;
1034
+ border: 1px solid var(--border-subtle);
1035
+ background: var(--surface-pill);
1036
+ color: var(--text-muted);
1037
+ font-family: var(--font-mono);
1038
+ font-size: 10px;
1039
+ line-height: 1.4;
1040
+ padding: 1px 6px;
1041
+ }
1042
+ .pipe-card-annotation--outcome {
1043
+ color: var(--color-warning);
1044
+ border-color: var(--ctrl-condition-border);
1045
+ }
1046
+ .pipe-card-annotation--batch {
1047
+ color: var(--ctrl-batch-text);
1048
+ border-color: var(--ctrl-batch-border);
1049
+ }
1010
1050
 
1011
1051
  /* Signature (unimplemented stub) — dashed + muted so it reads as "declared,
1012
1052
  not built yet", distinct from operator (solid accent) and controller (tinted). */
@@ -1176,6 +1216,69 @@ svg.react-flow__connectionline {
1176
1216
  max-width: 100px;
1177
1217
  }
1178
1218
 
1219
+ /* ─── Validation decorations (severity ring + count badge) ─────────────────
1220
+ Stamped by GraphViewer from targeted ValidationIssues. The ring is an
1221
+ outline so node geometry (and therefore layout) never changes; the badge
1222
+ lives in the header flow, which is size-locked by the ELK dimensions. */
1223
+
1224
+ .node-validation-ring--error {
1225
+ outline: 2px solid var(--color-error);
1226
+ outline-offset: 1px;
1227
+ }
1228
+ .node-validation-ring--warning {
1229
+ outline: 1.5px solid var(--color-warning);
1230
+ outline-offset: 1px;
1231
+ }
1232
+
1233
+ .node-validation-badge {
1234
+ flex-shrink: 0;
1235
+ min-width: 16px;
1236
+ height: 16px;
1237
+ padding: 0 4px;
1238
+ border: none;
1239
+ border-radius: 999px;
1240
+ font-family: var(--font-sans);
1241
+ font-size: 10px;
1242
+ font-weight: 700;
1243
+ line-height: 16px;
1244
+ text-align: center;
1245
+ box-sizing: border-box;
1246
+ }
1247
+ .node-validation-badge--error {
1248
+ background: var(--color-error);
1249
+ color: #fff;
1250
+ }
1251
+ .node-validation-badge--warning {
1252
+ background: var(--color-warning);
1253
+ color: rgba(0, 0, 0, 0.85);
1254
+ }
1255
+ button.node-validation-badge {
1256
+ cursor: pointer;
1257
+ }
1258
+ /* The controller header disables pointer events (it overlays children); the
1259
+ badge re-enables them for its tooltip and click-through to the panel. */
1260
+ .controller-group-header .node-validation-badge {
1261
+ pointer-events: auto;
1262
+ }
1263
+
1264
+ /* Transient highlight when a validation-panel row navigates to its node.
1265
+ Applied to the ReactFlow node wrapper; the animation fades the halo out and
1266
+ the class is cleared (or dropped by the next rebuild) once it has played. */
1267
+ .react-flow__node.node-validation-flash {
1268
+ animation: node-validation-flash 1.6s ease-out;
1269
+ }
1270
+ @keyframes node-validation-flash {
1271
+ 0%,
1272
+ 50% {
1273
+ outline: 3px solid var(--color-accent-strong);
1274
+ outline-offset: 5px;
1275
+ }
1276
+ 100% {
1277
+ outline: 3px solid transparent;
1278
+ outline-offset: 5px;
1279
+ }
1280
+ }
1281
+
1179
1282
  /* ─── StuffViewer component styles ────────────────────────────────────────── */
1180
1283
  /* StuffViewer is also exported standalone (used outside GraphViewer — e.g.
1181
1284
  * docs pages, embedded previews). The theme tokens are normally applied to
@@ -2197,6 +2300,207 @@ button.stuff-viewer-local-file--button:focus-visible {
2197
2300
  margin: 0 2px;
2198
2301
  }
2199
2302
 
2303
+ /* ─── Validation widget ─────────────────────────────────────────────────── */
2304
+ /* Lives in GraphToolbar.css on purpose: the VS Code extension copies exactly
2305
+ this stylesheet into its webview, so a separate file would need host build
2306
+ changes for no benefit. */
2307
+
2308
+ .graph-toolbar-validation {
2309
+ position: relative;
2310
+ display: inline-flex;
2311
+ }
2312
+
2313
+ .graph-toolbar-validation-btn {
2314
+ position: relative;
2315
+ }
2316
+
2317
+ .graph-toolbar-validation-btn--valid,
2318
+ .graph-toolbar-validation-btn--valid:hover {
2319
+ color: var(--color-success);
2320
+ }
2321
+
2322
+ .graph-toolbar-validation-btn--invalid,
2323
+ .graph-toolbar-validation-btn--invalid:hover {
2324
+ color: var(--color-error);
2325
+ }
2326
+
2327
+ .graph-toolbar-validation-btn--error,
2328
+ .graph-toolbar-validation-btn--error:hover {
2329
+ color: var(--color-warning);
2330
+ }
2331
+
2332
+ .graph-toolbar-validation-spin {
2333
+ animation: graph-toolbar-validation-rotate 1s linear infinite;
2334
+ }
2335
+
2336
+ @keyframes graph-toolbar-validation-rotate {
2337
+ to {
2338
+ transform: rotate(360deg);
2339
+ }
2340
+ }
2341
+
2342
+ .graph-toolbar-validation-badge {
2343
+ position: absolute;
2344
+ top: -5px;
2345
+ right: -5px;
2346
+ min-width: 14px;
2347
+ height: 14px;
2348
+ padding: 0 3px;
2349
+ box-sizing: border-box;
2350
+ border-radius: 7px;
2351
+ background: var(--color-error);
2352
+ color: var(--text-on-accent);
2353
+ font-family: var(--font-sans);
2354
+ font-size: 9px;
2355
+ line-height: 14px;
2356
+ font-weight: 600;
2357
+ text-align: center;
2358
+ pointer-events: none;
2359
+ }
2360
+
2361
+ .graph-toolbar-validation-btn--valid .graph-toolbar-validation-badge,
2362
+ .graph-toolbar-validation-btn--error .graph-toolbar-validation-badge {
2363
+ background: var(--color-warning);
2364
+ }
2365
+
2366
+ /* ─── Validation dropdown panel ─────────────────────────────────────────── */
2367
+
2368
+ .graph-validation-panel {
2369
+ position: absolute;
2370
+ z-index: 12;
2371
+ /* Viewport clamp: narrow webviews (VS Code panels) can be under 260px wide. */
2372
+ min-width: min(260px, calc(100vw - 24px));
2373
+ max-width: min(360px, calc(100vw - 24px));
2374
+ max-height: 320px;
2375
+ overflow-y: auto;
2376
+ padding: 6px;
2377
+ border-radius: 8px;
2378
+ background: var(--surface-overlay);
2379
+ border: 1px solid var(--border-default);
2380
+ box-shadow: var(--shadow-md);
2381
+ backdrop-filter: blur(6px);
2382
+ pointer-events: auto;
2383
+ font-family: var(--font-sans);
2384
+ cursor: default;
2385
+ }
2386
+
2387
+ /* Placement relative to the widget button — always unfolds toward the graph. */
2388
+ .graph-validation-panel--down-start {
2389
+ top: calc(100% + 6px);
2390
+ left: 0;
2391
+ }
2392
+ .graph-validation-panel--down-end {
2393
+ top: calc(100% + 6px);
2394
+ right: 0;
2395
+ }
2396
+ .graph-validation-panel--up-start {
2397
+ bottom: calc(100% + 6px);
2398
+ left: 0;
2399
+ }
2400
+ .graph-validation-panel--up-end {
2401
+ bottom: calc(100% + 6px);
2402
+ right: 0;
2403
+ }
2404
+ .graph-validation-panel--side-end {
2405
+ left: calc(100% + 6px);
2406
+ top: 0;
2407
+ }
2408
+ .graph-validation-panel--side-start {
2409
+ right: calc(100% + 6px);
2410
+ top: 0;
2411
+ }
2412
+
2413
+ .graph-validation-panel-header {
2414
+ padding: 4px 6px 6px;
2415
+ font-size: 11px;
2416
+ font-weight: 600;
2417
+ color: var(--text-secondary);
2418
+ }
2419
+
2420
+ .graph-validation-empty {
2421
+ padding: 2px 6px 6px;
2422
+ font-size: 12px;
2423
+ color: var(--text-secondary);
2424
+ }
2425
+
2426
+ .graph-validation-issues {
2427
+ list-style: none;
2428
+ margin: 0;
2429
+ padding: 0;
2430
+ display: flex;
2431
+ flex-direction: column;
2432
+ gap: 4px;
2433
+ }
2434
+
2435
+ .graph-validation-issue {
2436
+ padding: 6px 8px;
2437
+ border-radius: 6px;
2438
+ border-left: 3px solid var(--color-error);
2439
+ background: var(--color-error-bg);
2440
+ font-size: 12px;
2441
+ color: var(--text-primary);
2442
+ }
2443
+
2444
+ /* The focusable/clickable element inside each <li> (keeps listitem semantics). */
2445
+ .graph-validation-issue-body {
2446
+ display: flex;
2447
+ flex-direction: column;
2448
+ gap: 2px;
2449
+ }
2450
+
2451
+ .graph-validation-issue--warning {
2452
+ border-left-color: var(--color-warning);
2453
+ background: var(--surface-sunken);
2454
+ }
2455
+
2456
+ .graph-validation-issue--clickable {
2457
+ cursor: pointer;
2458
+ }
2459
+
2460
+ .graph-validation-issue--clickable:hover {
2461
+ filter: brightness(1.1);
2462
+ }
2463
+
2464
+ .graph-validation-issue-body:focus-visible {
2465
+ outline: 2px solid var(--focus-ring);
2466
+ outline-offset: 1px;
2467
+ border-radius: 4px;
2468
+ }
2469
+
2470
+ .graph-validation-issue-meta {
2471
+ display: flex;
2472
+ align-items: baseline;
2473
+ gap: 6px;
2474
+ flex-wrap: wrap;
2475
+ }
2476
+
2477
+ .graph-validation-issue-context {
2478
+ font-family: var(--font-mono);
2479
+ font-size: 11px;
2480
+ font-weight: 600;
2481
+ color: var(--text-secondary);
2482
+ }
2483
+
2484
+ .graph-validation-issue-file {
2485
+ font-size: 10px;
2486
+ color: var(--text-dim);
2487
+ }
2488
+
2489
+ .graph-validation-issue-message {
2490
+ white-space: pre-wrap;
2491
+ overflow-wrap: anywhere;
2492
+ }
2493
+
2494
+ .graph-validation-issue-fix {
2495
+ font-size: 11px;
2496
+ color: var(--text-secondary);
2497
+ }
2498
+
2499
+ .graph-validation-issue-fix::before {
2500
+ content: "Fix: ";
2501
+ font-weight: 600;
2502
+ }
2503
+
2200
2504
  /* ─── Standalone GraphViewer chrome (toolbar, theme, layout) ─────────── */
2201
2505
 
2202
2506
  * {