weifuwu 0.65.1 → 0.67.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 (32) hide show
  1. package/README.md +12 -12
  2. package/dist/client/browser.d.ts +10 -0
  3. package/dist/client/index.js +4 -4
  4. package/dist/client/types.d.ts +51 -0
  5. package/dist/client/ui.d.ts +8 -0
  6. package/dist/components/Anchor/Anchor.d.ts +27 -0
  7. package/dist/components/DiffView/DiffView.d.ts +24 -0
  8. package/dist/components/DiffView/diff-utils.d.ts +19 -0
  9. package/dist/components/Editor/Editor.d.ts +1 -1
  10. package/dist/components/Editor/tools/format.d.ts +1 -1
  11. package/dist/components/FileUpload/FileUpload.d.ts +4 -0
  12. package/dist/components/JSONViewer/JSONViewer.d.ts +21 -0
  13. package/dist/components/Kanban/Kanban.d.ts +28 -0
  14. package/dist/components/LogViewer/LogViewer.d.ts +29 -0
  15. package/dist/components/Menu/Menu.d.ts +11 -2
  16. package/dist/components/Pipeline/Pipeline.d.ts +27 -0
  17. package/dist/components/Pipeline/dag-utils.d.ts +36 -0
  18. package/dist/components/Sparkline/Sparkline.d.ts +21 -0
  19. package/dist/components/Sparkline/sparkline-utils.d.ts +16 -0
  20. package/dist/components/Tour/Tour.d.ts +34 -0
  21. package/dist/components/Tree/Tree.d.ts +2 -0
  22. package/dist/components/TreeSelect/TreeSelect.d.ts +24 -0
  23. package/dist/components/VirtualTable/VirtualTable.d.ts +32 -0
  24. package/dist/components/index.d.ts +16 -0
  25. package/dist/components/index.js +15 -11
  26. package/dist/components/style.css +1048 -101
  27. package/dist/index.js +28 -1
  28. package/dist/layout/weifuwu-layout.css +7 -0
  29. package/docs/components-map.md +28 -7
  30. package/docs/custom-components.md +29 -0
  31. package/docs/frontend.md +28 -0
  32. package/package.json +1 -1
@@ -91,6 +91,13 @@
91
91
  --wf-z-sticky: 40;
92
92
  --wf-z-overlay: 80;
93
93
  --wf-z-modal: 100;
94
+ --wf-z-tour: 2000;
95
+ --wf-tour-min-width: 240px;
96
+ --wf-kanban-col-min-width: 200px;
97
+ --wf-kanban-col-max-width: 300px;
98
+ --wf-treeselect-min-width: 200px;
99
+ --wf-treeselect-max-width: 320px;
100
+ --wf-treeselect-dropdown-max-height: 260px;
94
101
  --wf-z-popover: 120; /* dropdown/select/datepicker 面板与 popover 同层 */
95
102
  --wf-z-toast: 140;
96
103
  --wf-z-tooltip: 160;
@@ -1626,6 +1633,46 @@ code {
1626
1633
  opacity: 1;
1627
1634
  }
1628
1635
 
1636
+ /* weifuwu/components — Anchor(锚点导航) */
1637
+
1638
+ .wf-anchor {
1639
+ display: flex;
1640
+ flex-direction: column;
1641
+ gap: 2px;
1642
+ font-family: var(--wf-font-sans);
1643
+ font-size: var(--wf-font-size-sm);
1644
+ }
1645
+
1646
+ .wf-anchor-link {
1647
+ display: block;
1648
+ padding: var(--wf-space-xs) var(--wf-space-sm);
1649
+ border-left: 2px solid transparent;
1650
+ border-radius: 0 var(--wf-radius-sm) var(--wf-radius-sm) 0;
1651
+ color: var(--wf-color-text-secondary);
1652
+ text-decoration: none;
1653
+ cursor: pointer;
1654
+ transition: color var(--wf-dur-fast) var(--wf-ease-out),
1655
+ background var(--wf-dur-fast) var(--wf-ease-out),
1656
+ border-color var(--wf-dur-fast) var(--wf-ease-out);
1657
+ }
1658
+
1659
+ .wf-anchor-link:hover {
1660
+ background: var(--wf-color-bg-secondary);
1661
+ color: var(--wf-color-text);
1662
+ }
1663
+
1664
+ .wf-anchor-link--active {
1665
+ color: var(--wf-color-primary-text);
1666
+ border-left-color: var(--wf-color-primary);
1667
+ font-weight: var(--wf-font-weight-semibold);
1668
+ background: var(--wf-color-primary-bg);
1669
+ }
1670
+
1671
+ .wf-anchor-link:focus-visible {
1672
+ outline: none;
1673
+ box-shadow: var(--wf-focus-ring);
1674
+ }
1675
+
1629
1676
  /* weifuwu/components — ApprovalCard */
1630
1677
 
1631
1678
  .wf-approval {
@@ -3377,6 +3424,104 @@ code {
3377
3424
  .wf-descriptions--sm .wf-descriptions-value { font-size: var(--wf-font-size-xs); }
3378
3425
  .wf-descriptions--lg .wf-descriptions-value { font-size: var(--wf-font-size-base); }
3379
3426
 
3427
+ .wf-diffview {
3428
+ display: flex;
3429
+ flex-direction: column;
3430
+ border: 1px solid var(--wf-color-border);
3431
+ border-radius: var(--wf-radius-md);
3432
+ overflow: hidden;
3433
+ background: var(--wf-color-bg);
3434
+ font-family: var(--wf-font-mono, 'SFMono-Regular', Consolas, monospace);
3435
+ font-size: 13px;
3436
+ line-height: 1.6;
3437
+ min-width: 0;
3438
+ }
3439
+
3440
+ /* ── header ── */
3441
+ .wf-diffview-header {
3442
+ display: flex;
3443
+ align-items: center;
3444
+ gap: 8px;
3445
+ padding: 8px 12px;
3446
+ background: var(--wf-color-fill);
3447
+ border-bottom: 1px solid var(--wf-color-border);
3448
+ font-size: 12px;
3449
+ flex-shrink: 0;
3450
+ }
3451
+ .wf-diffview-title--old {
3452
+ color: var(--wf-color-danger-text);
3453
+ }
3454
+ .wf-diffview-title--new {
3455
+ color: var(--wf-color-success-text);
3456
+ }
3457
+ .wf-diffview-arrow {
3458
+ color: var(--wf-color-text-tertiary);
3459
+ }
3460
+
3461
+ /* ── body ── */
3462
+ .wf-diffview-body {
3463
+ overflow: auto;
3464
+ max-height: 480px;
3465
+ padding: 8px 0;
3466
+ }
3467
+
3468
+ .wf-diffview-row {
3469
+ display: flex;
3470
+ gap: 8px;
3471
+ padding: 0 12px;
3472
+ white-space: pre;
3473
+ }
3474
+ .wf-diffview-sign {
3475
+ width: 14px;
3476
+ flex-shrink: 0;
3477
+ user-select: none;
3478
+ color: var(--wf-color-text-tertiary);
3479
+ }
3480
+ .wf-diffview-line {
3481
+ min-width: 0;
3482
+ overflow: visible;
3483
+ }
3484
+
3485
+ .wf-diffview-row--add {
3486
+ background: var(--wf-color-success-bg, rgba(0, 128, 0, 0.08));
3487
+ }
3488
+ .wf-diffview-row--add .wf-diffview-sign {
3489
+ color: var(--wf-color-success-text);
3490
+ }
3491
+ .wf-diffview-row--remove {
3492
+ background: var(--wf-color-danger-bg, rgba(255, 0, 0, 0.06));
3493
+ }
3494
+ .wf-diffview-row--remove .wf-diffview-sign {
3495
+ color: var(--wf-color-danger-text);
3496
+ }
3497
+
3498
+ /* ── 折叠块 ── */
3499
+ .wf-diffview-fold {
3500
+ display: flex;
3501
+ align-items: center;
3502
+ justify-content: center;
3503
+ margin: 2px 12px;
3504
+ padding: 4px 8px;
3505
+ border: 1px dashed var(--wf-color-border);
3506
+ border-radius: var(--wf-radius-sm);
3507
+ color: var(--wf-color-text-secondary);
3508
+ font-size: 12px;
3509
+ cursor: pointer;
3510
+ background: var(--wf-color-bg-subtle, var(--wf-color-fill));
3511
+ user-select: none;
3512
+ min-height: 28px;
3513
+ }
3514
+ .wf-diffview-fold:hover {
3515
+ background: var(--wf-color-fill);
3516
+ }
3517
+
3518
+ .wf-diffview-overflow {
3519
+ padding: 8px 12px;
3520
+ color: var(--wf-color-text-tertiary);
3521
+ font-size: 12px;
3522
+ text-align: center;
3523
+ }
3524
+
3380
3525
  /* weifuwu/components — Divider */
3381
3526
 
3382
3527
  .wf-divider {
@@ -4116,27 +4261,67 @@ code {
4116
4261
  flex-shrink: 0;
4117
4262
  }
4118
4263
 
4264
+ .wf-upload-err {
4265
+ font-family: var(--wf-font-sans);
4266
+ font-size: var(--wf-font-size-xs);
4267
+ color: var(--wf-color-error-text);
4268
+ }
4269
+
4270
+ /* ── 第六批增强:缩略图 / 进度条 ────────────────────────── */
4271
+
4272
+ .wf-upload-item {
4273
+ display: flex;
4274
+ align-items: center;
4275
+ gap: var(--wf-gap-sm);
4276
+ padding: var(--wf-space-sm);
4277
+ border-radius: var(--wf-radius-sm);
4278
+ background: var(--wf-color-bg-secondary);
4279
+ }
4280
+
4281
+ .wf-upload-thumb {
4282
+ width: 36px;
4283
+ height: 36px;
4284
+ object-fit: cover;
4285
+ border-radius: var(--wf-radius-sm);
4286
+ border: var(--wf-border-width) solid var(--wf-color-border);
4287
+ flex-shrink: 0;
4288
+ background: var(--wf-color-bg);
4289
+ }
4290
+
4119
4291
  .wf-upload-item-remove {
4292
+ margin-left: auto;
4293
+ width: 24px; height: 24px;
4294
+ min-width: 24px; max-width: 24px;
4295
+ min-height: 24px; max-height: 24px;
4296
+ display: inline-flex;
4297
+ align-items: center;
4298
+ justify-content: center;
4120
4299
  border: none;
4121
- background: transparent;
4300
+ background: none;
4301
+ border-radius: var(--wf-radius-sm);
4122
4302
  color: var(--wf-color-text-tertiary);
4123
4303
  cursor: pointer;
4124
- padding: 2px 4px;
4125
- font-size: 12px;
4126
- line-height: 1;
4127
- border-radius: var(--wf-radius-sm);
4128
- flex-shrink: 0;
4304
+ line-height: 0; padding: 0; flex-shrink: 0;
4129
4305
  }
4130
4306
 
4131
4307
  .wf-upload-item-remove:hover {
4132
- color: var(--wf-color-error-text);
4133
4308
  background: var(--wf-color-error-bg);
4309
+ color: var(--wf-color-error-text);
4134
4310
  }
4135
4311
 
4136
- .wf-upload-err {
4137
- font-family: var(--wf-font-sans);
4138
- font-size: var(--wf-font-size-xs);
4139
- color: var(--wf-color-error-text);
4312
+ .wf-upload-progress {
4313
+ height: 4px;
4314
+ border-radius: 2px;
4315
+ background: var(--wf-color-bg-tertiary);
4316
+ overflow: hidden;
4317
+ margin-top: var(--wf-space-sm);
4318
+ }
4319
+
4320
+ .wf-upload-progress-fill {
4321
+ height: 100%;
4322
+ background: var(--wf-color-primary);
4323
+ border-radius: 2px;
4324
+ transition: width var(--wf-dur-fast) var(--wf-ease-out);
4140
4325
  }
4141
4326
 
4142
4327
  /* weifuwu/components — Form */
@@ -4516,111 +4701,444 @@ code {
4516
4701
  .wf-inputnumber-err { font-size: var(--wf-font-size-xs); color: var(--wf-color-error-text); }
4517
4702
  .wf-inputnumber-hint { font-size: var(--wf-font-size-xs); color: var(--wf-color-text-tertiary); }
4518
4703
 
4519
- /* weifuwu/components — Label(与 Input/Field 的 label 样式同源) */
4704
+ /* weifuwu/components — JSONViewer(结构化 JSON 浏览) */
4520
4705
 
4521
- .wf-label {
4522
- display: inline-flex;
4523
- align-items: center;
4524
- gap: var(--wf-gap-xs);
4525
- font-family: var(--wf-font-sans);
4526
- font-size: var(--wf-font-size-sm);
4527
- font-weight: var(--wf-font-weight-medium);
4706
+ .wf-json-viewer {
4707
+ font-family: var(--wf-font-mono);
4708
+ font-size: var(--wf-font-size-xs);
4528
4709
  color: var(--wf-color-text);
4529
- margin-bottom: var(--wf-space-xs);
4710
+ background: var(--wf-color-bg-secondary);
4711
+ border-radius: var(--wf-radius-sm);
4712
+ padding: var(--wf-space-sm);
4713
+ overflow-x: auto;
4714
+ line-height: 1.6;
4530
4715
  }
4531
4716
 
4532
- .wf-label-req {
4533
- color: var(--wf-color-error-text);
4717
+ /* 对象/数组节点不额外缩进——同层键(标量/对象/数组)对齐;
4718
+ 子层缩进由 .wf-json-children 容器承担(padding + border-left) */
4719
+ .wf-json-node {
4720
+ padding-left: 0;
4534
4721
  }
4535
4722
 
4536
- /* weifuwu/components — List */
4723
+ .wf-json-row {
4724
+ display: flex;
4725
+ align-items: center;
4726
+ gap: var(--wf-gap-xs);
4727
+ white-space: nowrap;
4728
+ border-radius: var(--wf-radius-sm);
4729
+ }
4537
4730
 
4538
- .wf-list {
4539
- font-family: var(--wf-font-sans);
4731
+ .wf-json-row:hover {
4732
+ background: var(--wf-color-bg-tertiary);
4540
4733
  }
4541
4734
 
4542
- .wf-list-header {
4543
- font-weight: var(--wf-font-weight-semibold);
4544
- font-size: var(--wf-font-size-sm);
4545
- color: var(--wf-color-text);
4546
- padding: var(--wf-space-sm) 0;
4735
+ .wf-json-children {
4736
+ padding-left: var(--wf-space-sm);
4737
+ border-left: 1px solid var(--wf-color-border);
4738
+ margin-left: var(--wf-space-xs);
4547
4739
  }
4548
4740
 
4549
- .wf-list-body {
4550
- margin: 0;
4551
- padding: 0;
4552
- list-style: none;
4741
+ .wf-json-key {
4742
+ color: var(--wf-color-text-secondary);
4553
4743
  }
4554
4744
 
4555
- .wf-list-item {
4556
- padding: var(--wf-space-sm) 0;
4745
+ /* 标量行 toggle 占位(与对象/数组行 chevron 同宽 16px)——同层 key 文本对齐 */
4746
+ .wf-json-toggle-placeholder {
4747
+ width: 16px;
4748
+ flex-shrink: 0;
4749
+ display: inline-flex;
4557
4750
  }
4558
4751
 
4559
- .wf-list--divided .wf-list-item {
4560
- border-bottom: 1px solid var(--wf-color-border);
4752
+ .wf-json-toggle {
4753
+ width: 16px; height: 16px;
4754
+ min-width: 16px; max-width: 16px;
4755
+ min-height: 16px; max-height: 16px;
4756
+ display: inline-flex;
4757
+ align-items: center;
4758
+ justify-content: center;
4759
+ border: none;
4760
+ background: none;
4761
+ color: var(--wf-color-text-tertiary);
4762
+ cursor: pointer;
4763
+ line-height: 0; padding: 0; flex-shrink: 0;
4561
4764
  }
4562
- .wf-list--divided .wf-list-item:last-child {
4563
- border-bottom: none;
4765
+
4766
+ .wf-json-toggle:hover {
4767
+ color: var(--wf-color-text);
4564
4768
  }
4565
4769
 
4566
- .wf-list-footer {
4567
- padding: var(--wf-space-sm) 0;
4568
- font-size: var(--wf-font-size-sm);
4569
- color: var(--wf-color-text-tertiary);
4770
+ .wf-json-toggle:focus-visible {
4771
+ outline: none;
4772
+ box-shadow: var(--wf-focus-ring);
4570
4773
  }
4571
4774
 
4572
- .wf-list-empty {
4573
- display: flex;
4574
- flex-direction: column;
4575
- align-items: center;
4576
- gap: var(--wf-gap-sm);
4577
- padding: var(--wf-space-lg) 0;
4775
+ .wf-json-summary,
4776
+ .wf-json-node-summary {
4578
4777
  color: var(--wf-color-text-tertiary);
4579
- font-size: var(--wf-font-size-sm);
4580
4778
  }
4581
4779
 
4582
- /* weifuwu/components — Loading */
4780
+ .wf-json-more {
4781
+ padding-left: var(--wf-space-lg);
4782
+ color: var(--wf-color-warning-text);
4783
+ font-size: var(--wf-font-size-xs);
4784
+ }
4583
4785
 
4584
- .wf-loading {
4585
- display: flex;
4586
- flex-direction: column;
4786
+ .wf-json-copy {
4787
+ width: 16px; height: 16px;
4788
+ min-width: 16px; max-width: 16px;
4789
+ min-height: 16px; max-height: 16px;
4790
+ display: inline-flex;
4587
4791
  align-items: center;
4588
4792
  justify-content: center;
4589
- gap: var(--wf-gap-sm);
4590
- padding: var(--wf-space-2xl);
4591
- color: var(--wf-color-text-secondary);
4793
+ border: none;
4794
+ background: none;
4795
+ color: var(--wf-color-text-tertiary);
4796
+ cursor: pointer;
4797
+ line-height: 0; padding: 0; flex-shrink: 0;
4798
+ opacity: 0;
4592
4799
  }
4593
4800
 
4594
- .wf-loading-spinner {
4595
- width: 24px;
4596
- height: 24px;
4597
- border: 3px solid var(--wf-color-border);
4598
- border-top-color: var(--wf-color-primary);
4599
- border-radius: 50%;
4600
- animation: wf-spin 0.6s linear infinite;
4801
+ .wf-json-row:hover .wf-json-copy {
4802
+ opacity: 1;
4601
4803
  }
4602
4804
 
4603
- @keyframes wf-spin {
4604
- to { transform: rotate(360deg); }
4805
+ .wf-json-copy:hover {
4806
+ color: var(--wf-color-primary-text);
4605
4807
  }
4606
4808
 
4607
- .wf-loading-text {
4608
- font-family: var(--wf-font-sans);
4609
- font-size: var(--wf-font-size-sm);
4809
+ .wf-json-copy:focus-visible {
4810
+ outline: none;
4811
+ box-shadow: var(--wf-focus-ring);
4812
+ opacity: 1;
4610
4813
  }
4611
4814
 
4612
- /* weifuwu/components — Markdown 排版 */
4815
+ /* ── 类型色(语义 Token) ── */
4816
+ .wf-json-string { color: var(--wf-color-success-text); }
4817
+ .wf-json-number { color: var(--wf-color-primary-text); }
4818
+ .wf-json-boolean { color: var(--wf-color-warning-text); }
4819
+ .wf-json-null { color: var(--wf-color-text-tertiary); font-style: italic; }
4613
4820
 
4614
- .wf-md {
4615
- font-family: var(--wf-font-sans);
4616
- font-size: var(--wf-font-size-sm);
4617
- line-height: var(--wf-line-height);
4618
- color: var(--wf-color-text);
4619
- word-break: break-word;
4620
- }
4821
+ /* ── 整行折叠交互(大命中区)+ 触屏适配 ── */
4621
4822
 
4622
- .wf-md > :first-child { margin-top: 0; }
4623
- .wf-md > :last-child { margin-bottom: 0; }
4823
+ .wf-json-collapse,
4824
+ .wf-json-row--header {
4825
+ cursor: pointer;
4826
+ }
4827
+
4828
+ .wf-json-collapse:hover,
4829
+ .wf-json-row--header:hover {
4830
+ background: var(--wf-color-bg-tertiary);
4831
+ }
4832
+
4833
+ .wf-json-collapse:focus-visible,
4834
+ .wf-json-row--header:focus-visible {
4835
+ outline: none;
4836
+ box-shadow: var(--wf-focus-ring);
4837
+ }
4838
+
4839
+ /* 触屏(coarse):toggle/复制按钮 44px 命中区(padding 扩展) */
4840
+ @media (pointer: coarse) {
4841
+ .wf-json-toggle,
4842
+ .wf-json-copy {
4843
+ width: 24px; height: 24px;
4844
+ min-width: 24px; max-width: 24px;
4845
+ min-height: 24px; max-height: 24px;
4846
+ padding: 4px;
4847
+ }
4848
+ }
4849
+
4850
+ .wf-kanban {
4851
+ display: flex;
4852
+ gap: 12px;
4853
+ align-items: flex-start;
4854
+ overflow-x: auto;
4855
+ padding: 4px;
4856
+ }
4857
+
4858
+ .wf-kanban-col {
4859
+ flex: 1 1 220px;
4860
+ min-width: var(--wf-kanban-col-min-width);
4861
+ max-width: var(--wf-kanban-col-max-width);
4862
+ background: var(--wf-color-bg-subtle, var(--wf-color-fill));
4863
+ border-radius: var(--wf-radius-md);
4864
+ border: 1px solid var(--wf-color-border);
4865
+ display: flex;
4866
+ flex-direction: column;
4867
+ transition: border-color var(--wf-dur-fast) var(--wf-ease-out);
4868
+ }
4869
+ .wf-kanban-col:hover {
4870
+ border-color: var(--wf-color-primary);
4871
+ border-style: dashed;
4872
+ }
4873
+
4874
+ .wf-kanban-col-header {
4875
+ display: flex;
4876
+ align-items: center;
4877
+ justify-content: space-between;
4878
+ padding: 10px 12px;
4879
+ font-weight: 600;
4880
+ font-size: 13px;
4881
+ }
4882
+ .wf-kanban-col-count {
4883
+ font-size: 12px;
4884
+ color: var(--wf-color-text-tertiary);
4885
+ background: var(--wf-color-fill);
4886
+ border-radius: 50%;
4887
+ padding: 1px 8px;
4888
+ }
4889
+
4890
+ .wf-kanban-col-body {
4891
+ padding: 0 8px 8px;
4892
+ display: flex;
4893
+ flex-direction: column;
4894
+ gap: 8px;
4895
+ min-height: 40px;
4896
+ }
4897
+
4898
+ .wf-kanban-card {
4899
+ background: var(--wf-color-bg);
4900
+ border: 1px solid var(--wf-color-border);
4901
+ border-radius: var(--wf-radius-sm);
4902
+ padding: 10px 12px;
4903
+ cursor: grab;
4904
+ display: flex;
4905
+ align-items: center;
4906
+ gap: 8px;
4907
+ transition: border-color var(--wf-dur-fast) var(--wf-ease-out), transform var(--wf-dur-fast) var(--wf-ease-out);
4908
+ }
4909
+ .wf-kanban-card:hover {
4910
+ border-color: var(--wf-color-primary);
4911
+ }
4912
+ .wf-kanban-card:active {
4913
+ cursor: grabbing;
4914
+ }
4915
+ .wf-kanban-card:hover {
4916
+ border-color: var(--wf-color-primary);
4917
+ }
4918
+ .wf-kanban-card[aria-grabbed='true'] {
4919
+ opacity: 0.4;
4920
+ }
4921
+
4922
+ .wf-kanban-card-title {
4923
+ font-size: 13px;
4924
+ line-height: 1.5;
4925
+ min-width: 0;
4926
+ }
4927
+
4928
+ .wf-kanban-tag {
4929
+ font-size: 11px;
4930
+ color: var(--wf-color-primary-text);
4931
+ background: var(--wf-color-primary-bg, rgba(79, 110, 247, 0.12));
4932
+ border-radius: var(--wf-radius-xs);
4933
+ padding: 1px 6px;
4934
+ flex-shrink: 0;
4935
+ }
4936
+
4937
+ /* weifuwu/components — Label(与 Input/Field 的 label 样式同源) */
4938
+
4939
+ .wf-label {
4940
+ display: inline-flex;
4941
+ align-items: center;
4942
+ gap: var(--wf-gap-xs);
4943
+ font-family: var(--wf-font-sans);
4944
+ font-size: var(--wf-font-size-sm);
4945
+ font-weight: var(--wf-font-weight-medium);
4946
+ color: var(--wf-color-text);
4947
+ margin-bottom: var(--wf-space-xs);
4948
+ }
4949
+
4950
+ .wf-label-req {
4951
+ color: var(--wf-color-error-text);
4952
+ }
4953
+
4954
+ /* weifuwu/components — List */
4955
+
4956
+ .wf-list {
4957
+ font-family: var(--wf-font-sans);
4958
+ }
4959
+
4960
+ .wf-list-header {
4961
+ font-weight: var(--wf-font-weight-semibold);
4962
+ font-size: var(--wf-font-size-sm);
4963
+ color: var(--wf-color-text);
4964
+ padding: var(--wf-space-sm) 0;
4965
+ }
4966
+
4967
+ .wf-list-body {
4968
+ margin: 0;
4969
+ padding: 0;
4970
+ list-style: none;
4971
+ }
4972
+
4973
+ .wf-list-item {
4974
+ padding: var(--wf-space-sm) 0;
4975
+ }
4976
+
4977
+ .wf-list--divided .wf-list-item {
4978
+ border-bottom: 1px solid var(--wf-color-border);
4979
+ }
4980
+ .wf-list--divided .wf-list-item:last-child {
4981
+ border-bottom: none;
4982
+ }
4983
+
4984
+ .wf-list-footer {
4985
+ padding: var(--wf-space-sm) 0;
4986
+ font-size: var(--wf-font-size-sm);
4987
+ color: var(--wf-color-text-tertiary);
4988
+ }
4989
+
4990
+ .wf-list-empty {
4991
+ display: flex;
4992
+ flex-direction: column;
4993
+ align-items: center;
4994
+ gap: var(--wf-gap-sm);
4995
+ padding: var(--wf-space-lg) 0;
4996
+ color: var(--wf-color-text-tertiary);
4997
+ font-size: var(--wf-font-size-sm);
4998
+ }
4999
+
5000
+ /* weifuwu/components — Loading */
5001
+
5002
+ .wf-loading {
5003
+ display: flex;
5004
+ flex-direction: column;
5005
+ align-items: center;
5006
+ justify-content: center;
5007
+ gap: var(--wf-gap-sm);
5008
+ padding: var(--wf-space-2xl);
5009
+ color: var(--wf-color-text-secondary);
5010
+ }
5011
+
5012
+ .wf-loading-spinner {
5013
+ width: 24px;
5014
+ height: 24px;
5015
+ border: 3px solid var(--wf-color-border);
5016
+ border-top-color: var(--wf-color-primary);
5017
+ border-radius: 50%;
5018
+ animation: wf-spin 0.6s linear infinite;
5019
+ }
5020
+
5021
+ @keyframes wf-spin {
5022
+ to { transform: rotate(360deg); }
5023
+ }
5024
+
5025
+ .wf-loading-text {
5026
+ font-family: var(--wf-font-sans);
5027
+ font-size: var(--wf-font-size-sm);
5028
+ }
5029
+
5030
+ /* weifuwu/components — LogViewer(日志流:ANSI 着色 + 虚拟滚动) */
5031
+
5032
+ .wf-log-viewer {
5033
+ font-family: var(--wf-font-mono);
5034
+ font-size: var(--wf-font-size-xs);
5035
+ color: var(--wf-color-text);
5036
+ position: relative;
5037
+ border: var(--wf-border-width) solid var(--wf-color-border);
5038
+ border-radius: var(--wf-radius);
5039
+ background: var(--wf-color-bg-secondary);
5040
+ overflow: hidden;
5041
+ }
5042
+
5043
+ .wf-log-copy {
5044
+ position: absolute;
5045
+ top: var(--wf-space-sm);
5046
+ right: var(--wf-space-sm);
5047
+ z-index: 1;
5048
+ width: 24px; height: 24px;
5049
+ min-width: 24px; max-width: 24px;
5050
+ min-height: 24px; max-height: 24px;
5051
+ display: inline-flex;
5052
+ align-items: center;
5053
+ justify-content: center;
5054
+ border: none;
5055
+ background: var(--wf-color-bg-tertiary);
5056
+ border-radius: var(--wf-radius-sm);
5057
+ color: var(--wf-color-text-secondary);
5058
+ cursor: pointer;
5059
+ line-height: 0; padding: 0; flex-shrink: 0;
5060
+ }
5061
+
5062
+ .wf-log-copy:hover {
5063
+ background: var(--wf-color-bg);
5064
+ color: var(--wf-color-text);
5065
+ }
5066
+
5067
+ .wf-log-body {
5068
+ position: relative;
5069
+ overflow-y: auto;
5070
+ }
5071
+
5072
+ .wf-log-spacer {
5073
+ pointer-events: none;
5074
+ }
5075
+
5076
+ .wf-log-row {
5077
+ display: flex;
5078
+ align-items: center;
5079
+ box-sizing: border-box;
5080
+ padding-right: var(--wf-space-md);
5081
+ white-space: pre;
5082
+ }
5083
+
5084
+ .wf-log-row:hover {
5085
+ background: var(--wf-color-bg-tertiary);
5086
+ }
5087
+
5088
+ .wf-log-line-no {
5089
+ display: inline-flex;
5090
+ align-items: center;
5091
+ justify-content: flex-end;
5092
+ min-width: 48px;
5093
+ padding: 0 var(--wf-space-sm);
5094
+ margin-right: var(--wf-space-sm);
5095
+ color: var(--wf-color-text-tertiary);
5096
+ user-select: none;
5097
+ flex-shrink: 0;
5098
+ }
5099
+
5100
+ .wf-log-line-content {
5101
+ overflow: hidden;
5102
+ }
5103
+
5104
+ /* ── ANSI 前景色(16 色映射到语义 Token) ── */
5105
+ .wf-log-ansi--bold { font-weight: var(--wf-font-weight-bold); }
5106
+ .wf-log-ansi--30 { color: var(--wf-color-text-secondary); }
5107
+ .wf-log-ansi--31 { color: var(--wf-color-error-text); }
5108
+ .wf-log-ansi--32 { color: var(--wf-color-success-text); }
5109
+ .wf-log-ansi--33 { color: var(--wf-color-warning-text); }
5110
+ .wf-log-ansi--34 { color: var(--wf-color-primary-text); }
5111
+ .wf-log-ansi--35 { color: var(--wf-color-primary-text); }
5112
+ .wf-log-ansi--36 { color: var(--wf-color-info-text); }
5113
+ .wf-log-ansi--37 { color: var(--wf-color-text); }
5114
+
5115
+ /* ── ANSI 背景色(8 色 → 50 级语义底) ── */
5116
+ .wf-log-ansi--bg41 { background: var(--wf-color-error-bg); }
5117
+ .wf-log-ansi--bg42 { background: var(--wf-color-success-bg); }
5118
+ .wf-log-ansi--bg43 { background: var(--wf-color-warning-bg); }
5119
+ .wf-log-ansi--bg44 { background: var(--wf-color-primary-bg); }
5120
+ .wf-log-ansi--bg47 { background: var(--wf-color-bg-tertiary); }
5121
+
5122
+ .wf-log-empty {
5123
+ display: flex;
5124
+ align-items: center;
5125
+ justify-content: center;
5126
+ padding: var(--wf-space-lg);
5127
+ color: var(--wf-color-text-tertiary);
5128
+ }
5129
+
5130
+ /* weifuwu/components — Markdown 排版 */
5131
+
5132
+ .wf-md {
5133
+ font-family: var(--wf-font-sans);
5134
+ font-size: var(--wf-font-size-sm);
5135
+ line-height: var(--wf-line-height);
5136
+ color: var(--wf-color-text);
5137
+ word-break: break-word;
5138
+ }
5139
+
5140
+ .wf-md > :first-child { margin-top: 0; }
5141
+ .wf-md > :last-child { margin-bottom: 0; }
4624
5142
 
4625
5143
  .wf-md-h { margin: var(--wf-space-md) 0 var(--wf-space-sm); font-weight: var(--wf-font-weight-bold); line-height: 1.25; }
4626
5144
  .wf-md-h1 { font-size: var(--wf-font-size-xl); }
@@ -4767,37 +5285,133 @@ code {
4767
5285
  font-size: var(--wf-font-size-sm);
4768
5286
  color: var(--wf-color-text-secondary);
4769
5287
  cursor: pointer;
4770
- user-select: none;
4771
- transition: background var(--wf-dur-fast) var(--wf-ease-out), color var(--wf-dur-fast) var(--wf-ease-out);
5288
+ user-select: none;
5289
+ transition: background var(--wf-dur-fast) var(--wf-ease-out), color var(--wf-dur-fast) var(--wf-ease-out);
5290
+ }
5291
+
5292
+ .wf-menu-item:hover {
5293
+ background: var(--wf-color-bg-secondary);
5294
+ color: var(--wf-color-text);
5295
+ }
5296
+
5297
+ .wf-menu-item--active {
5298
+ background: var(--wf-color-primary-bg);
5299
+ color: var(--wf-color-primary-text);
5300
+ font-weight: var(--wf-font-weight-semibold);
5301
+ }
5302
+
5303
+ .wf-menu-item--danger { color: var(--wf-color-error-text); }
5304
+ .wf-menu-item--danger:hover { background: var(--wf-color-error-bg); color: var(--wf-color-error-text); }
5305
+
5306
+ .wf-menu-item:focus-visible {
5307
+ outline: 2px solid var(--wf-color-primary);
5308
+ outline-offset: -2px;
5309
+ }
5310
+
5311
+ .wf-menu-icon {
5312
+ display: inline-flex;
5313
+ font-size: var(--wf-font-size-base);
5314
+ width: 18px;
5315
+ justify-content: center;
5316
+ flex-shrink: 0;
5317
+ }
5318
+
5319
+ /* ── 子菜单(第六批) ────────────────────────────── */
5320
+
5321
+ .wf-menu-submenu {
5322
+ display: flex;
5323
+ flex-direction: column;
5324
+ gap: 2px;
5325
+ }
5326
+
5327
+ .wf-menu-submenu-title {
5328
+ display: flex;
5329
+ align-items: center;
5330
+ gap: var(--wf-gap-sm);
5331
+ padding: var(--wf-space-sm) var(--wf-space-md);
5332
+ border-radius: var(--wf-radius-sm);
5333
+ font-size: var(--wf-font-size-sm);
5334
+ color: var(--wf-color-text-secondary);
5335
+ cursor: pointer;
5336
+ user-select: none;
5337
+ transition: background var(--wf-dur-fast) var(--wf-ease-out), color var(--wf-dur-fast) var(--wf-ease-out);
5338
+ }
5339
+
5340
+ .wf-menu-submenu-title:hover {
5341
+ background: var(--wf-color-bg-secondary);
5342
+ color: var(--wf-color-text);
5343
+ }
5344
+
5345
+ .wf-menu-submenu-title:focus-visible {
5346
+ outline: 2px solid var(--wf-color-primary);
5347
+ outline-offset: -2px;
5348
+ }
5349
+
5350
+ .wf-menu-arrow {
5351
+ margin-left: auto;
5352
+ display: inline-flex;
5353
+ color: var(--wf-color-text-tertiary);
5354
+ transition: transform var(--wf-dur-fast) var(--wf-ease-out);
5355
+ }
5356
+
5357
+ .wf-menu-submenu--open .wf-menu-arrow {
5358
+ transform: rotate(90deg);
5359
+ }
5360
+
5361
+ .wf-menu-submenu-content {
5362
+ display: none;
5363
+ flex-direction: column;
5364
+ gap: 2px;
5365
+ }
5366
+
5367
+ .wf-menu-submenu--open .wf-menu-submenu-content {
5368
+ display: flex;
5369
+ }
5370
+
5371
+ .wf-menu-item--child {
5372
+ padding-left: var(--wf-space-xl);
5373
+ font-size: var(--wf-font-size-sm);
5374
+ }
5375
+
5376
+ /* ── 折叠(第六批) ────────────────────────────── */
5377
+
5378
+ .wf-menu--collapsed {
5379
+ width: 56px;
5380
+ }
5381
+
5382
+ .wf-menu--collapsed .wf-menu-group {
5383
+ display: none;
5384
+ }
5385
+
5386
+ .wf-menu--collapsed .wf-menu-item,
5387
+ .wf-menu--collapsed .wf-menu-submenu-title {
5388
+ justify-content: center;
5389
+ padding: var(--wf-space-sm);
5390
+ gap: 0;
5391
+ }
5392
+
5393
+ .wf-menu-collapse-btn {
5394
+ display: flex;
5395
+ align-items: center;
5396
+ justify-content: center;
5397
+ margin-top: auto;
5398
+ padding: var(--wf-space-sm);
5399
+ border-radius: var(--wf-radius-sm);
5400
+ color: var(--wf-color-text-tertiary);
5401
+ cursor: pointer;
5402
+ min-height: 36px;
4772
5403
  }
4773
5404
 
4774
- .wf-menu-item:hover {
5405
+ .wf-menu-collapse-btn:hover {
4775
5406
  background: var(--wf-color-bg-secondary);
4776
5407
  color: var(--wf-color-text);
4777
5408
  }
4778
5409
 
4779
- .wf-menu-item--active {
4780
- background: var(--wf-color-primary-bg);
4781
- color: var(--wf-color-primary-text);
4782
- font-weight: var(--wf-font-weight-semibold);
4783
- }
4784
-
4785
- .wf-menu-item--danger { color: var(--wf-color-error-text); }
4786
- .wf-menu-item--danger:hover { background: var(--wf-color-error-bg); color: var(--wf-color-error-text); }
4787
-
4788
- .wf-menu-item:focus-visible {
5410
+ .wf-menu-collapse-btn:focus-visible {
4789
5411
  outline: 2px solid var(--wf-color-primary);
4790
5412
  outline-offset: -2px;
4791
5413
  }
4792
5414
 
4793
- .wf-menu-icon {
4794
- display: inline-flex;
4795
- font-size: var(--wf-font-size-base);
4796
- width: 18px;
4797
- justify-content: center;
4798
- flex-shrink: 0;
4799
- }
4800
-
4801
5415
  /* weifuwu/components — Menubar */
4802
5416
 
4803
5417
  .wf-menubar {
@@ -5309,6 +5923,77 @@ code {
5309
5923
  .wf-pin-input--sm .wf-pin-input-cell { font-size: var(--wf-font-size-base); width: 2.4em; height: 2.4em; }
5310
5924
  .wf-pin-input--lg .wf-pin-input-cell { font-size: var(--wf-font-size-2xl); width: 2.8em; height: 2.8em; }
5311
5925
 
5926
+ .wf-pipeline {
5927
+ position: relative;
5928
+ display: inline-block;
5929
+ max-width: 100%;
5930
+ }
5931
+
5932
+ .wf-pipeline-svg {
5933
+ display: block;
5934
+ overflow: visible;
5935
+ }
5936
+
5937
+ .wf-pipeline-edge {
5938
+ fill: none;
5939
+ stroke: var(--wf-color-border);
5940
+ stroke-width: 1.5;
5941
+ }
5942
+
5943
+ .wf-pipeline-nodes {
5944
+ position: absolute;
5945
+ inset: 0;
5946
+ pointer-events: none;
5947
+ }
5948
+
5949
+ .wf-pipeline-node {
5950
+ position: absolute;
5951
+ transform: translate(-50%, -50%);
5952
+ padding: 8px 14px;
5953
+ min-width: 72px;
5954
+ max-width: 120px;
5955
+ text-align: center;
5956
+ background: var(--wf-color-bg);
5957
+ border: 1px solid var(--wf-color-border);
5958
+ border-radius: var(--wf-radius-md);
5959
+ font-size: 13px;
5960
+ font-weight: 500;
5961
+ pointer-events: auto;
5962
+ white-space: nowrap;
5963
+ overflow: hidden;
5964
+ text-overflow: ellipsis;
5965
+ box-shadow: var(--wf-shadow-sm, 0 1px 3px rgba(0, 0, 0, 0.08));
5966
+ }
5967
+
5968
+ .wf-pipeline-node--success {
5969
+ border-color: var(--wf-color-success-text);
5970
+ color: var(--wf-color-success-text);
5971
+ background: var(--wf-color-success-bg, rgba(20, 83, 45, 0.06));
5972
+ }
5973
+ .wf-pipeline-node--running {
5974
+ border-color: var(--wf-color-primary);
5975
+ color: var(--wf-color-primary-text);
5976
+ background: var(--wf-color-primary-bg, rgba(79, 110, 247, 0.08));
5977
+ }
5978
+ .wf-pipeline-node--error {
5979
+ border-color: var(--wf-color-danger-text);
5980
+ color: var(--wf-color-danger-text);
5981
+ background: var(--wf-color-danger-bg, rgba(255, 0, 0, 0.06));
5982
+ }
5983
+ .wf-pipeline-node--pending {
5984
+ border-color: var(--wf-color-border);
5985
+ color: var(--wf-color-text-tertiary);
5986
+ background: var(--wf-color-fill);
5987
+ }
5988
+
5989
+ .wf-pipeline-warn {
5990
+ position: absolute;
5991
+ bottom: -24px;
5992
+ left: 0;
5993
+ font-size: 12px;
5994
+ color: var(--wf-color-warning-text);
5995
+ }
5996
+
5312
5997
  /* weifuwu/components — Popover */
5313
5998
 
5314
5999
  .wf-popover-wrap {
@@ -6110,6 +6795,12 @@ code {
6110
6795
  text-align: center;
6111
6796
  }
6112
6797
 
6798
+ .wf-sparkline {
6799
+ display: inline-block;
6800
+ vertical-align: middle;
6801
+ flex-shrink: 0;
6802
+ }
6803
+
6113
6804
  /* weifuwu/components — StatCard */
6114
6805
 
6115
6806
  .wf-stat {
@@ -7100,6 +7791,99 @@ code {
7100
7791
  to { opacity: 1; }
7101
7792
  }
7102
7793
 
7794
+ .wf-tour-overlay {
7795
+ position: fixed;
7796
+ inset: 0;
7797
+ z-index: var(--wf-z-tour);
7798
+ outline: none;
7799
+ }
7800
+
7801
+ .wf-tour-mask {
7802
+ position: absolute;
7803
+ inset: 0;
7804
+ background: var(--wf-overlay);
7805
+ }
7806
+
7807
+ .wf-tour-highlight {
7808
+ position: fixed;
7809
+ border-radius: var(--wf-radius-sm);
7810
+ box-shadow: 0 0 0 9999px var(--wf-overlay), 0 0 0 2px var(--wf-color-primary);
7811
+ z-index: 1;
7812
+ pointer-events: none;
7813
+ transition: all var(--wf-dur-fast) var(--wf-ease-out);
7814
+ }
7815
+
7816
+ .wf-tour-bubble {
7817
+ position: fixed;
7818
+ z-index: 1; /* 同层 DOM 顺序裁决(bubble 在 highlight 后 = 最上) */
7819
+ min-width: var(--wf-tour-min-width);
7820
+ max-width: 360px;
7821
+ background: var(--wf-color-bg);
7822
+ border: 1px solid var(--wf-color-border);
7823
+ border-radius: var(--wf-radius-md);
7824
+ box-shadow: var(--wf-shadow-lg, 0 12px 32px rgba(0, 0, 0, 0.12));
7825
+ padding: 16px;
7826
+ display: flex;
7827
+ flex-direction: column;
7828
+ gap: 8px;
7829
+ }
7830
+
7831
+ .wf-tour-bubble-header {
7832
+ display: flex;
7833
+ align-items: center;
7834
+ justify-content: space-between;
7835
+ gap: 8px;
7836
+ }
7837
+ .wf-tour-title {
7838
+ font-weight: 600;
7839
+ font-size: 14px;
7840
+ }
7841
+ .wf-tour-step {
7842
+ font-size: 12px;
7843
+ color: var(--wf-color-text-tertiary);
7844
+ flex-shrink: 0;
7845
+ }
7846
+
7847
+ .wf-tour-content {
7848
+ font-size: 13px;
7849
+ color: var(--wf-color-text-secondary);
7850
+ line-height: 1.6;
7851
+ }
7852
+
7853
+ .wf-tour-actions {
7854
+ display: flex;
7855
+ justify-content: flex-end;
7856
+ gap: 8px;
7857
+ margin-top: 4px;
7858
+ }
7859
+
7860
+ .wf-tour-btn {
7861
+ min-height: 32px;
7862
+ padding: 0 14px;
7863
+ border-radius: var(--wf-radius-sm);
7864
+ border: 1px solid var(--wf-color-border);
7865
+ background: var(--wf-color-bg);
7866
+ color: var(--wf-color-text);
7867
+ font-size: 13px;
7868
+ cursor: pointer;
7869
+ display: inline-flex;
7870
+ align-items: center;
7871
+ justify-content: center;
7872
+ }
7873
+ .wf-tour-btn--primary {
7874
+ background: var(--wf-color-primary);
7875
+ border-color: var(--wf-color-primary);
7876
+ color: var(--wf-color-on-brand);
7877
+ }
7878
+ .wf-tour-btn--ghost {
7879
+ background: transparent;
7880
+ border-color: transparent;
7881
+ color: var(--wf-color-text-secondary);
7882
+ }
7883
+ .wf-tour-btn:hover {
7884
+ filter: brightness(0.95);
7885
+ }
7886
+
7103
7887
  /* weifuwu/components — Transfer */
7104
7888
 
7105
7889
  .wf-transfer {
@@ -7381,6 +8165,71 @@ code {
7381
8165
  white-space: nowrap;
7382
8166
  }
7383
8167
 
8168
+ .wf-treeselect {
8169
+ position: relative;
8170
+ display: inline-block;
8171
+ min-width: var(--wf-treeselect-min-width);
8172
+ max-width: var(--wf-treeselect-max-width);
8173
+ }
8174
+
8175
+ .wf-treeselect-trigger {
8176
+ display: flex;
8177
+ align-items: center;
8178
+ justify-content: space-between;
8179
+ gap: 8px;
8180
+ padding: 7px 12px;
8181
+ border: 1px solid var(--wf-color-border);
8182
+ border-radius: var(--wf-radius-sm);
8183
+ background: var(--wf-color-bg);
8184
+ cursor: pointer;
8185
+ min-height: 36px;
8186
+ user-select: none;
8187
+ }
8188
+ .wf-treeselect-trigger:hover {
8189
+ border-color: var(--wf-color-primary);
8190
+ }
8191
+ .wf-treeselect-trigger--open {
8192
+ border-color: var(--wf-color-primary);
8193
+ box-shadow: 0 0 0 2px var(--wf-color-primary-bg, rgba(79, 110, 247, 0.15));
8194
+ }
8195
+
8196
+ .wf-treeselect-placeholder {
8197
+ color: var(--wf-color-text-tertiary);
8198
+ font-size: 13px;
8199
+ }
8200
+ .wf-treeselect-label {
8201
+ font-size: 13px;
8202
+ min-width: 0;
8203
+ overflow: hidden;
8204
+ text-overflow: ellipsis;
8205
+ white-space: nowrap;
8206
+ }
8207
+
8208
+ .wf-treeselect-arrow {
8209
+ width: 0;
8210
+ height: 0;
8211
+ border-left: 4px solid transparent;
8212
+ border-right: 4px solid transparent;
8213
+ border-top: 5px solid var(--wf-color-text-tertiary);
8214
+ transition: transform var(--wf-dur-fast) var(--wf-ease-out);
8215
+ flex-shrink: 0;
8216
+ }
8217
+ .wf-treeselect-arrow--open {
8218
+ transform: rotate(180deg);
8219
+ }
8220
+
8221
+ .wf-treeselect-dropdown {
8222
+ /* position: fixed + top/left/width 由 JS(usePopupPosition)提供 */
8223
+ z-index: var(--wf-z-popover);
8224
+ background: var(--wf-color-bg);
8225
+ border: 1px solid var(--wf-color-border);
8226
+ border-radius: var(--wf-radius-md);
8227
+ box-shadow: var(--wf-shadow-md, 0 4px 16px rgba(0, 0, 0, 0.1));
8228
+ padding: 4px;
8229
+ max-height: var(--wf-treeselect-dropdown-max-height);
8230
+ overflow: auto;
8231
+ }
8232
+
7384
8233
  /* weifuwu/components — Typography */
7385
8234
 
7386
8235
  .wf-title {
@@ -7473,6 +8322,104 @@ code {
7473
8322
  box-sizing: border-box;
7474
8323
  }
7475
8324
 
8325
+ /* weifuwu/components — VirtualTable(固定表头 + 虚拟滚动表体) */
8326
+
8327
+ .wf-virtual-table {
8328
+ font-family: var(--wf-font-sans);
8329
+ font-size: var(--wf-font-size-sm);
8330
+ color: var(--wf-color-text);
8331
+ border: var(--wf-border-width) solid var(--wf-color-border);
8332
+ border-radius: var(--wf-radius);
8333
+ overflow: hidden;
8334
+ }
8335
+
8336
+ .wf-virtual-table-thead {
8337
+ display: flex;
8338
+ border-bottom: var(--wf-border-width) solid var(--wf-color-border);
8339
+ background: var(--wf-color-bg-secondary);
8340
+ }
8341
+
8342
+ .wf-virtual-table-th {
8343
+ display: flex;
8344
+ align-items: center;
8345
+ gap: var(--wf-gap-xs);
8346
+ padding: var(--wf-space-sm) var(--wf-space-md);
8347
+ font-size: var(--wf-font-size-xs);
8348
+ font-weight: var(--wf-font-weight-semibold);
8349
+ color: var(--wf-color-text-secondary);
8350
+ flex-shrink: 0;
8351
+ box-sizing: border-box;
8352
+ }
8353
+
8354
+ .wf-virtual-table-th--sortable {
8355
+ cursor: pointer;
8356
+ user-select: none;
8357
+ }
8358
+
8359
+ .wf-virtual-table-th--sortable:hover {
8360
+ color: var(--wf-color-text);
8361
+ }
8362
+
8363
+ .wf-virtual-table-th--sortable:focus-visible {
8364
+ outline: none;
8365
+ box-shadow: var(--wf-focus-ring);
8366
+ }
8367
+
8368
+ .wf-virtual-table-th--sorted {
8369
+ color: var(--wf-color-primary-text);
8370
+ }
8371
+
8372
+ .wf-virtual-table-sort-icon {
8373
+ display: inline-flex;
8374
+ color: var(--wf-color-text-tertiary);
8375
+ }
8376
+
8377
+ .wf-virtual-table-sort-icon--active {
8378
+ color: var(--wf-color-primary-text);
8379
+ }
8380
+
8381
+ .wf-virtual-table-body {
8382
+ position: relative;
8383
+ overflow-y: auto;
8384
+ }
8385
+
8386
+ .wf-virtual-table-spacer {
8387
+ pointer-events: none;
8388
+ }
8389
+
8390
+ .wf-virtual-table-row {
8391
+ display: flex;
8392
+ align-items: center;
8393
+ box-sizing: border-box;
8394
+ border-bottom: var(--wf-border-width) solid var(--wf-color-border);
8395
+ cursor: default;
8396
+ }
8397
+
8398
+ .wf-virtual-table-row:hover {
8399
+ background: var(--wf-color-bg-tertiary);
8400
+ }
8401
+
8402
+ .wf-virtual-table-td {
8403
+ display: flex;
8404
+ align-items: center;
8405
+ padding: 0 var(--wf-space-md);
8406
+ flex-shrink: 0;
8407
+ box-sizing: border-box;
8408
+ overflow: hidden;
8409
+ white-space: nowrap;
8410
+ text-overflow: ellipsis;
8411
+ color: var(--wf-color-text);
8412
+ }
8413
+
8414
+ .wf-virtual-table-empty {
8415
+ display: flex;
8416
+ align-items: center;
8417
+ justify-content: center;
8418
+ padding: var(--wf-space-lg);
8419
+ color: var(--wf-color-text-tertiary);
8420
+ font-size: var(--wf-font-size-sm);
8421
+ }
8422
+
7476
8423
  /* weifuwu/components — Watermark */
7477
8424
 
7478
8425
  .wf-watermark {