weifuwu 0.67.3 → 0.69.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.
@@ -42,6 +42,8 @@
42
42
  --wf-dark-slate-300: #475569; --wf-dark-slate-200: #334155; --wf-dark-slate-100: #1e293b;
43
43
  --wf-dark-slate-50: #0f172a; --wf-dark-bg: #0f172a;
44
44
  --wf-dark-overlay: rgba(0, 0, 0, 0.6); /* 暗色遮罩(比亮色更深,压住暗底内容) */
45
+ --wf-dark-fill: var(--wf-dark-slate-200); /* 暗色填充(比底色亮一级) */
46
+ --wf-dark-bg-hover: rgba(255, 255, 255, 0.06); /* 暗色 hover 反白 */
45
47
  --wf-dark-surface-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
46
48
  --wf-dark-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.2);
47
49
  --wf-dark-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
@@ -94,8 +96,14 @@
94
96
  --wf-z-tour: 2000;
95
97
  --wf-tour-min-width: 240px;
96
98
  --wf-kanban-col-min-width: 200px;
99
+ /* Layout 布局外壳(batch-8) */
100
+ --wf-layout-sider-width: 240px;
101
+ --wf-layout-sider-collapsed-width: 64px;
102
+ --wf-layout-header-height: 56px;
97
103
  --wf-kanban-col-max-width: 300px;
98
104
  --wf-treeselect-min-width: 200px;
105
+ --wf-navmenu-min-width: 160px;
106
+ --wf-select-menu-min-width: 200px;
99
107
  --wf-treeselect-max-width: 320px;
100
108
  --wf-treeselect-dropdown-max-height: 260px;
101
109
  --wf-z-popover: 120; /* dropdown/select/datepicker 面板与 popover 同层 */
@@ -168,8 +176,9 @@
168
176
  /* ── 边框宽度 ── */
169
177
  --wf-border-width: 1px;
170
178
 
171
- /* ── 聚焦环(引用 primary-bg,暗色自动跟随) ── */
172
- --wf-focus-ring: 0 0 0 2px var(--wf-color-primary-bg);
179
+ /* ── 聚焦环(双层:淡环 bg + 1px primary 线——C5:系统暗色偏好下 primary-bg
180
+ 变暗不可见,primary 是亮蓝——明暗主题聚焦均可见) ── */
181
+ --wf-focus-ring: 0 0 0 2px var(--wf-color-primary-bg), 0 0 0 1px var(--wf-color-primary);
173
182
 
174
183
  /* ── 动效 ── */
175
184
  --wf-transition-duration: 150ms;
@@ -185,6 +194,8 @@
185
194
  --wf-ease-in: cubic-bezier(0.4, 0, 1, 1); /* 退场:渐入加速 */
186
195
  --wf-ease-in-out: cubic-bezier(0.4, 0, 0.2, 1); /* 往返/闪烁动画 */
187
196
  --wf-ease-snap: cubic-bezier(0.34, 1.56, 0.64, 1); /* 选中/弹跳 */
197
+ --wf-ease-standard: ease; /* 通用缓动(组件假 token 收敛) */
198
+ --wf-dur-md: var(--wf-dur-base); /* 中档时长(= base 别名) */
188
199
 
189
200
  --wf-motion-sm: 4px;
190
201
  --wf-motion-md: 8px;
@@ -201,6 +212,11 @@
201
212
  --wf-color-error-text: var(--wf-red-700);
202
213
  --wf-color-info-text: var(--wf-sky-700);
203
214
 
215
+ /* ── 色彩 — 通用填充/悬停底色(暗色经 _dark.css 映射) ── */
216
+ --wf-color-fill: var(--wf-slate-100); /* 通用填充色(禁裸灰——组件假 token 收敛) */
217
+ --wf-color-bg-subtle: var(--wf-color-fill); /* 极淡底(别名) */
218
+ --wf-color-bg-hover: rgba(0, 0, 0, 0.04); /* hover 底色(暗色反白) */
219
+
204
220
  /* ── 色彩 — 实心填充上的文字/图标(primary/success 等实心底色) ── */
205
221
  --wf-color-on-brand: #fff;
206
222
 
@@ -214,6 +230,9 @@
214
230
  /* 控件尺寸:垂直内边距 + 目标高度(移动端在 _base.css 提升到 44px) */
215
231
  --wf-control-pad-y: 10px;
216
232
  --wf-control-height: 36px;
233
+ /* 字段统一尺寸(组件假 token 收敛——Input/Select/Textarea 引用) */
234
+ --wf-field-height: var(--wf-control-height);
235
+ --wf-field-radius: var(--wf-radius);
217
236
 
218
237
  /* ── 断点 ── */
219
238
  --wf-bp-sm: 640px;
@@ -274,6 +293,9 @@
274
293
  --wf-color-bg: var(--wf-dark-bg);
275
294
  --wf-color-bg-secondary: var(--wf-dark-slate-100);
276
295
  --wf-color-bg-tertiary: var(--wf-dark-slate-200);
296
+ --wf-color-fill: var(--wf-dark-fill);
297
+ --wf-color-bg-subtle: var(--wf-dark-fill);
298
+ --wf-color-bg-hover: var(--wf-dark-bg-hover);
277
299
 
278
300
  --wf-color-border: var(--wf-dark-slate-200);
279
301
  --wf-color-border-light: var(--wf-dark-slate-100);
@@ -321,6 +343,9 @@
321
343
  --wf-color-bg: var(--wf-dark-bg);
322
344
  --wf-color-bg-secondary: var(--wf-dark-slate-100);
323
345
  --wf-color-bg-tertiary: var(--wf-dark-slate-200);
346
+ --wf-color-fill: var(--wf-dark-fill);
347
+ --wf-color-bg-subtle: var(--wf-dark-fill);
348
+ --wf-color-bg-hover: var(--wf-dark-bg-hover);
324
349
 
325
350
  --wf-color-border: var(--wf-dark-slate-200);
326
351
  --wf-color-border-light: var(--wf-dark-slate-100);
@@ -1639,9 +1664,82 @@ body.wf-dragging {
1639
1664
  opacity: 1;
1640
1665
  }
1641
1666
 
1667
+ /* weifuwu/components — AlertGroup 通知合并组 */
1668
+
1669
+ .wf-alertgroup {
1670
+ display: flex;
1671
+ flex-direction: column;
1672
+ gap: 6px;
1673
+ font-family: var(--wf-font-sans);
1674
+ font-size: var(--wf-font-size-sm, 13px);
1675
+ }
1676
+
1677
+ .wf-alertgroup-summary {
1678
+ display: flex;
1679
+ align-items: center;
1680
+ justify-content: center;
1681
+ padding: 10px 16px;
1682
+ border: var(--wf-border-width, 1px) solid var(--wf-color-border);
1683
+ border-radius: var(--wf-surface-radius, 8px);
1684
+ background: var(--wf-color-bg-secondary, #fff);
1685
+ color: var(--wf-color-primary, #1668dc);
1686
+ cursor: pointer;
1687
+ font-family: var(--wf-font-sans);
1688
+ transition: background var(--wf-dur-fast, 0.15s) var(--wf-ease-standard, ease);
1689
+ }
1690
+
1691
+ .wf-alertgroup-summary:hover {
1692
+ background: var(--wf-color-bg-hover, rgba(0, 0, 0, 0.04));
1693
+ }
1694
+
1695
+ .wf-alertgroup-item {
1696
+ display: flex;
1697
+ align-items: center;
1698
+ gap: 10px;
1699
+ padding: 10px 16px;
1700
+ border-radius: var(--wf-surface-radius, 8px);
1701
+ background: var(--wf-color-bg-secondary, #fff);
1702
+ border-left: 3px solid var(--wf-color-info);
1703
+ }
1704
+
1705
+ .wf-alertgroup-item--success { border-left-color: var(--wf-color-success); }
1706
+ .wf-alertgroup-item--warning { border-left-color: var(--wf-color-warning); }
1707
+ .wf-alertgroup-item--error { border-left-color: var(--wf-color-error); }
1708
+
1709
+ .wf-alertgroup-message {
1710
+ flex: 1;
1711
+ color: var(--wf-color-text);
1712
+ }
1713
+
1714
+ .wf-alertgroup-time {
1715
+ color: var(--wf-color-text-tertiary, #999);
1716
+ font-size: 12px;
1717
+ }
1718
+
1719
+ .wf-alertgroup-close {
1720
+ display: flex;
1721
+ align-items: center;
1722
+ justify-content: center;
1723
+ width: 24px;
1724
+ height: 24px;
1725
+ min-width: 24px;
1726
+ min-height: 24px;
1727
+ padding: 0;
1728
+ border: none;
1729
+ background: transparent;
1730
+ color: var(--wf-color-text-tertiary, #999);
1731
+ cursor: pointer;
1732
+ border-radius: 4px;
1733
+ }
1734
+
1735
+ .wf-alertgroup-close:hover {
1736
+ background: var(--wf-color-bg-hover, rgba(0, 0, 0, 0.04));
1737
+ color: var(--wf-color-text);
1738
+ }
1739
+
1642
1740
  /* weifuwu/components — Anchor(锚点导航) */
1643
1741
 
1644
- .wf-anchor {
1742
+ .wf-anchor-nav-nav {
1645
1743
  display: flex;
1646
1744
  flex-direction: column;
1647
1745
  gap: 2px;
@@ -1649,7 +1747,7 @@ body.wf-dragging {
1649
1747
  font-size: var(--wf-font-size-sm);
1650
1748
  }
1651
1749
 
1652
- .wf-anchor-link {
1750
+ .wf-anchor-nav-nav-link {
1653
1751
  display: block;
1654
1752
  padding: var(--wf-space-xs) var(--wf-space-sm);
1655
1753
  border-left: 2px solid transparent;
@@ -1662,19 +1760,19 @@ body.wf-dragging {
1662
1760
  border-color var(--wf-dur-fast) var(--wf-ease-out);
1663
1761
  }
1664
1762
 
1665
- .wf-anchor-link:hover {
1763
+ .wf-anchor-nav-nav-link:hover {
1666
1764
  background: var(--wf-color-bg-secondary);
1667
1765
  color: var(--wf-color-text);
1668
1766
  }
1669
1767
 
1670
- .wf-anchor-link--active {
1768
+ .wf-anchor-nav-nav-link--active {
1671
1769
  color: var(--wf-color-primary-text);
1672
1770
  border-left-color: var(--wf-color-primary);
1673
1771
  font-weight: var(--wf-font-weight-semibold);
1674
1772
  background: var(--wf-color-primary-bg);
1675
1773
  }
1676
1774
 
1677
- .wf-anchor-link:focus-visible {
1775
+ .wf-anchor-nav-nav-link:focus-visible {
1678
1776
  outline: none;
1679
1777
  box-shadow: var(--wf-focus-ring);
1680
1778
  }
@@ -1772,6 +1870,50 @@ body.wf-dragging {
1772
1870
  height: 100%;
1773
1871
  }
1774
1872
 
1873
+ /* weifuwu/components — AutoComplete 输入联想 */
1874
+
1875
+ .wf-autocomplete-wrap {
1876
+ position: relative;
1877
+ display: inline-block;
1878
+ width: 100%;
1879
+ }
1880
+
1881
+ .wf-autocomplete-input {
1882
+ width: 100%;
1883
+ }
1884
+
1885
+ .wf-autocomplete-dropdown {
1886
+ position: fixed;
1887
+ z-index: var(--wf-z-popover, 120);
1888
+ max-height: 280px;
1889
+ overflow-y: auto;
1890
+ border-radius: var(--wf-surface-radius, 8px);
1891
+ background: var(--wf-surface-bg, #fff);
1892
+ box-shadow: var(--wf-surface-shadow, 0 4px 16px rgba(0, 0, 0, 0.12));
1893
+ border: var(--wf-border-width, 1px) solid var(--wf-color-border-light);
1894
+ font-family: var(--wf-font-sans);
1895
+ font-size: var(--wf-font-size-sm, 13px);
1896
+ }
1897
+
1898
+ .wf-autocomplete-option {
1899
+ padding: 8px 12px;
1900
+ cursor: pointer;
1901
+ color: var(--wf-color-text);
1902
+ white-space: nowrap;
1903
+ overflow: hidden;
1904
+ text-overflow: ellipsis;
1905
+ transition: background var(--wf-dur-fast, 0.15s) var(--wf-ease-standard, ease);
1906
+ }
1907
+
1908
+ .wf-autocomplete-option:hover,
1909
+ .wf-autocomplete-option--active {
1910
+ background: var(--wf-color-bg-hover, rgba(0, 0, 0, 0.04));
1911
+ }
1912
+
1913
+ .wf-autocomplete-option--active {
1914
+ color: var(--wf-color-primary, #1668dc);
1915
+ }
1916
+
1775
1917
  /* weifuwu/components — Avatar */
1776
1918
 
1777
1919
  .wf-avatar {
@@ -2115,7 +2257,7 @@ body.wf-dragging {
2115
2257
  margin-top: 2px;
2116
2258
  font-size: var(--wf-font-size-xs);
2117
2259
  color: var(--wf-color-text);
2118
- background: var(--wf-event-color, var(--wf-color-primary-bg));
2260
+ background: var(--wf-color-primary-bg, var(--wf-color-primary-bg));
2119
2261
  color: var(--wf-color-primary-text);
2120
2262
  border-radius: var(--wf-radius-sm);
2121
2263
  padding: 1px 4px;
@@ -3455,7 +3597,7 @@ body.wf-dragging {
3455
3597
  flex-shrink: 0;
3456
3598
  }
3457
3599
  .wf-diffview-title--old {
3458
- color: var(--wf-color-danger-text);
3600
+ color: var(--wf-color-error-text);
3459
3601
  }
3460
3602
  .wf-diffview-title--new {
3461
3603
  color: var(--wf-color-success-text);
@@ -3495,10 +3637,10 @@ body.wf-dragging {
3495
3637
  color: var(--wf-color-success-text);
3496
3638
  }
3497
3639
  .wf-diffview-row--remove {
3498
- background: var(--wf-color-danger-bg, rgba(255, 0, 0, 0.06));
3640
+ background: var(--wf-color-error-bg, rgba(255, 0, 0, 0.06));
3499
3641
  }
3500
3642
  .wf-diffview-row--remove .wf-diffview-sign {
3501
- color: var(--wf-color-danger-text);
3643
+ color: var(--wf-color-error-text);
3502
3644
  }
3503
3645
 
3504
3646
  /* ── 折叠块 ── */
@@ -3734,6 +3876,8 @@ body.wf-dragging {
3734
3876
  box-shadow: var(--wf-shadow-md);
3735
3877
  z-index: var(--wf-z-dropdown);
3736
3878
  padding: var(--wf-space-xs) 0;
3879
+
3880
+ transform: translateX(-50%);
3737
3881
  }
3738
3882
 
3739
3883
  .wf-dropdown--open {
@@ -3767,11 +3911,16 @@ body.wf-dragging {
3767
3911
  color: var(--wf-color-error-text);
3768
3912
  }
3769
3913
 
3770
- /* ── 入场动画:面板族统一 wf-panel-in(scale+fade,Token 驱动) ── */
3914
+ /* ── 入场动画:fade-only(wf-panel-in 含 transform——覆盖定位 translateX(-50%)
3915
+ 动画期间右偏,结束归位 = 跳一下——真实 bug,对齐 Popconfirm 修复) ── */
3771
3916
  .wf-dropdown-menu {
3772
- animation: wf-panel-in var(--wf-dur-fast) var(--wf-ease-out);
3917
+ animation: wf-dropdown-in var(--wf-dur-fast) var(--wf-ease-out);
3773
3918
  transform-origin: top center;
3774
3919
  }
3920
+ @keyframes wf-dropdown-in {
3921
+ from { opacity: 0; }
3922
+ to { opacity: 1; }
3923
+ }
3775
3924
 
3776
3925
  /* weifuwu/components — Editor */
3777
3926
 
@@ -3836,7 +3985,7 @@ body.wf-dragging {
3836
3985
  }
3837
3986
 
3838
3987
  .wf-editor-tb-btn--active:hover {
3839
- background: var(--wf-color-primary-lighter, #bae6fd);
3988
+ background: var(--wf-color-primary-bg, #bae6fd);
3840
3989
  }
3841
3990
 
3842
3991
  .wf-editor-tb-btn--link {
@@ -4072,7 +4221,7 @@ body.wf-dragging {
4072
4221
 
4073
4222
  .wf-editor-table-grid-cell:hover,
4074
4223
  .wf-editor-table-grid-cell--active {
4075
- background: var(--wf-color-primary-light, #e0f2fe);
4224
+ background: var(--wf-color-primary-bg, #e0f2fe);
4076
4225
  border-color: var(--wf-color-primary);
4077
4226
  }
4078
4227
 
@@ -4138,23 +4287,35 @@ body.wf-dragging {
4138
4287
  gap: var(--wf-gap-xs);
4139
4288
  }
4140
4289
 
4141
- .wf-field-label {
4290
+ .wf-field-label,
4291
+ .wf-input-label,
4292
+ .wf-select-label,
4293
+ .wf-textarea-label,
4294
+ .wf-slider-label {
4142
4295
  font-size: var(--wf-font-size-sm);
4143
4296
  font-weight: var(--wf-font-weight-medium);
4144
4297
  color: var(--wf-color-text);
4145
4298
  }
4146
4299
 
4147
- .wf-field-req {
4300
+ .wf-field-req,
4301
+ .wf-input-req,
4302
+ .wf-select-req,
4303
+ .wf-textarea-req {
4148
4304
  color: var(--wf-color-error-text);
4149
4305
  margin-left: 2px;
4150
4306
  }
4151
4307
 
4152
- .wf-field-err {
4308
+ .wf-field-err,
4309
+ .wf-input-err,
4310
+ .wf-select-err,
4311
+ .wf-textarea-err {
4153
4312
  font-size: var(--wf-font-size-xs);
4154
4313
  color: var(--wf-color-error-text);
4155
4314
  }
4156
4315
 
4157
- .wf-field-hint {
4316
+ .wf-field-hint,
4317
+ .wf-input-hint,
4318
+ .wf-textarea-hint {
4158
4319
  font-size: var(--wf-font-size-xs);
4159
4320
  color: var(--wf-color-text-tertiary);
4160
4321
  }
@@ -4330,6 +4491,126 @@ body.wf-dragging {
4330
4491
  transition: width var(--wf-dur-fast) var(--wf-ease-out);
4331
4492
  }
4332
4493
 
4494
+ /* weifuwu/components — FloatButton 悬浮操作按钮 */
4495
+
4496
+ .wf-float-btn {
4497
+ display: flex;
4498
+ align-items: center;
4499
+ justify-content: center;
4500
+ gap: 6px;
4501
+ width: 44px;
4502
+ height: 44px;
4503
+ min-width: 44px;
4504
+ min-height: 44px;
4505
+ padding: 0;
4506
+ border: none;
4507
+ border-radius: 50%;
4508
+ background: var(--wf-color-primary);
4509
+ color: var(--wf-color-on-brand, #fff);
4510
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
4511
+ cursor: pointer;
4512
+ z-index: var(--wf-z-sticky, 40);
4513
+ font-family: var(--wf-font-sans);
4514
+ font-size: 16px;
4515
+ transition: transform var(--wf-dur-fast, 0.15s) var(--wf-ease-standard, ease),
4516
+ background var(--wf-dur-fast, 0.15s) var(--wf-ease-standard, ease);
4517
+ }
4518
+
4519
+ .wf-float-btn:hover {
4520
+ transform: scale(1.05);
4521
+ background: var(--wf-color-primary, #1668dc);
4522
+ }
4523
+
4524
+ .wf-float-btn--disabled {
4525
+ background: var(--wf-color-text-disabled, #bfbfbf);
4526
+ cursor: not-allowed;
4527
+ opacity: 0.7;
4528
+ }
4529
+
4530
+ .wf-float-btn--top-left { top: 24px; left: 24px; }
4531
+ .wf-float-btn--top-right { top: 24px; right: 24px; }
4532
+ .wf-float-btn--bottom-left { bottom: 24px; left: 24px; }
4533
+ .wf-float-btn--bottom-right { bottom: 24px; right: 24px; }
4534
+
4535
+ .wf-float-btn-badge {
4536
+ position: absolute;
4537
+ top: -4px;
4538
+ right: -4px;
4539
+ min-width: 18px;
4540
+ height: 18px;
4541
+ padding: 0 5px;
4542
+ border-radius: 50%;
4543
+ background: var(--wf-color-error);
4544
+ color: var(--wf-color-on-brand, #fff);
4545
+ font-size: 11px;
4546
+ line-height: 18px;
4547
+ text-align: center;
4548
+ }
4549
+
4550
+ /* ── 组模式 ── */
4551
+ .wf-float-group {
4552
+ position: fixed;
4553
+ z-index: var(--wf-z-sticky, 40);
4554
+ display: flex;
4555
+ flex-direction: column;
4556
+ align-items: center;
4557
+ gap: 12px;
4558
+ }
4559
+
4560
+ .wf-float-group--bottom-right { bottom: 24px; right: 24px; }
4561
+ .wf-float-group--bottom-left { bottom: 24px; left: 24px; }
4562
+ .wf-float-group--top-right { top: 24px; right: 24px; }
4563
+ .wf-float-group--top-left { top: 24px; left: 24px; }
4564
+
4565
+ .wf-float-group-items {
4566
+ display: flex;
4567
+ flex-direction: column;
4568
+ gap: 10px;
4569
+ }
4570
+
4571
+ .wf-float-group-item {
4572
+ animation: wf-float-item-in var(--wf-dur-md, 0.2s) var(--wf-ease-standard, ease);
4573
+ }
4574
+
4575
+ @keyframes wf-float-item-in {
4576
+ from { opacity: 0; transform: translateY(8px); }
4577
+ to { opacity: 1; transform: translateY(0); }
4578
+ }
4579
+
4580
+ .wf-float-group-main {
4581
+ display: flex;
4582
+ align-items: center;
4583
+ justify-content: center;
4584
+ width: 44px;
4585
+ height: 44px;
4586
+ min-width: 44px;
4587
+ min-height: 44px;
4588
+ padding: 0;
4589
+ border: none;
4590
+ border-radius: 50%;
4591
+ background: var(--wf-color-primary);
4592
+ color: var(--wf-color-on-brand, #fff);
4593
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
4594
+ cursor: pointer;
4595
+ font-size: var(--wf-font-size-xl, 20px);
4596
+ font-family: var(--wf-font-sans);
4597
+ }
4598
+
4599
+ .wf-float-group-icon {
4600
+ display: inline-block;
4601
+ transition: transform var(--wf-dur-md, 0.2s) var(--wf-ease-standard, ease);
4602
+ }
4603
+
4604
+ .wf-float-group-icon.is-open {
4605
+ transform: rotate(45deg);
4606
+ }
4607
+
4608
+ /* 组内子项:不 fixed(由 group 容器排列) */
4609
+ .wf-float-btn--static {
4610
+ position: static;
4611
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
4612
+ }
4613
+
4333
4614
  /* weifuwu/components — Form */
4334
4615
 
4335
4616
  .wf-form {
@@ -4338,6 +4619,29 @@ body.wf-dragging {
4338
4619
  gap: var(--wf-gap-md);
4339
4620
  }
4340
4621
 
4622
+ /* weifuwu/components — Grid 栅格 + Flex 容器 */
4623
+
4624
+ .wf-grid-comp {
4625
+ display: flex;
4626
+ flex-wrap: wrap;
4627
+ width: 100%;
4628
+ box-sizing: border-box;
4629
+ }
4630
+
4631
+ .wf-grid-comp--column {
4632
+ flex-direction: column;
4633
+ }
4634
+
4635
+ .wf-grid-comp--flex {
4636
+ display: flex;
4637
+ flex-wrap: wrap;
4638
+ }
4639
+
4640
+ .wf-col {
4641
+ box-sizing: border-box;
4642
+ min-width: 0;
4643
+ }
4644
+
4341
4645
  /* weifuwu/components — Highlight */
4342
4646
 
4343
4647
  .wf-highlight-mark {
@@ -4489,17 +4793,6 @@ body.wf-dragging {
4489
4793
  gap: var(--wf-gap-xs);
4490
4794
  }
4491
4795
 
4492
- .wf-input-label {
4493
- font-size: var(--wf-font-size-sm);
4494
- font-weight: var(--wf-font-weight-medium);
4495
- color: var(--wf-color-text);
4496
- }
4497
-
4498
- .wf-input-req {
4499
- color: var(--wf-color-error-text);
4500
- margin-left: 2px;
4501
- }
4502
-
4503
4796
  .wf-input {
4504
4797
  font-family: var(--wf-font-sans);
4505
4798
  font-size: var(--wf-font-size-sm);
@@ -4547,16 +4840,6 @@ body.wf-dragging {
4547
4840
  color: var(--wf-color-text-tertiary);
4548
4841
  }
4549
4842
 
4550
- .wf-input-err {
4551
- font-size: var(--wf-font-size-xs);
4552
- color: var(--wf-color-error-text);
4553
- }
4554
-
4555
- .wf-input-hint {
4556
- font-size: var(--wf-font-size-xs);
4557
- color: var(--wf-color-text-tertiary);
4558
- }
4559
-
4560
4843
  .wf-input--err .wf-input {
4561
4844
  border-color: var(--wf-color-error);
4562
4845
  }
@@ -4957,6 +5240,162 @@ body.wf-dragging {
4957
5240
  color: var(--wf-color-error-text);
4958
5241
  }
4959
5242
 
5243
+ /* weifuwu/components — Layout 布局外壳
5244
+ * 三库等价:antd Layout / EP Container / shadcn Sidebar
5245
+ */
5246
+
5247
+ .wf-layout {
5248
+ display: flex;
5249
+ width: 100%;
5250
+ min-height: 100%;
5251
+ background: var(--wf-color-bg, #f5f5f5);
5252
+ color: var(--wf-color-text);
5253
+ font-family: var(--wf-font-sans);
5254
+ }
5255
+
5256
+ .wf-layout--column {
5257
+ flex-direction: column;
5258
+ }
5259
+
5260
+ .wf-layout--row {
5261
+ flex-direction: row;
5262
+ }
5263
+
5264
+ /* ── 侧边栏 ── */
5265
+ .wf-layout-sider {
5266
+ display: flex;
5267
+ flex-direction: column;
5268
+ flex-shrink: 0;
5269
+ height: 100vh;
5270
+ overflow: hidden;
5271
+ background: var(--wf-color-bg-secondary, #fff);
5272
+ border-right: var(--wf-border-width, 1px) solid var(--wf-color-border);
5273
+ transition: width var(--wf-dur-fast, 0.15s) var(--wf-ease-standard, ease);
5274
+ }
5275
+
5276
+ .wf-layout-sider--collapsed {
5277
+ border-right: var(--wf-border-width, 1px) solid var(--wf-color-border-light);
5278
+ }
5279
+
5280
+ .wf-layout-sider-body {
5281
+ flex: 1;
5282
+ overflow-y: auto;
5283
+ min-height: 0;
5284
+ }
5285
+
5286
+ /* 折叠触发器(底部) */
5287
+ .wf-layout-sider-trigger {
5288
+ display: flex;
5289
+ align-items: center;
5290
+ justify-content: center;
5291
+ width: 100%;
5292
+ height: 40px;
5293
+ flex-shrink: 0;
5294
+ border: none;
5295
+ border-top: var(--wf-border-width, 1px) solid var(--wf-color-border-light);
5296
+ background: transparent;
5297
+ color: var(--wf-color-text-secondary);
5298
+ cursor: pointer;
5299
+ font-size: 12px;
5300
+ transition: background var(--wf-dur-fast, 0.15s) var(--wf-ease-standard, ease);
5301
+ }
5302
+
5303
+ .wf-layout-sider-trigger:hover {
5304
+ background: var(--wf-color-bg-hover, rgba(0, 0, 0, 0.04));
5305
+ }
5306
+
5307
+ .wf-layout-sider-trigger-icon {
5308
+ display: inline-block;
5309
+ transition: transform var(--wf-dur-fast, 0.15s) var(--wf-ease-standard, ease);
5310
+ }
5311
+
5312
+ .wf-layout-sider-trigger-icon.is-collapsed {
5313
+ transform: rotate(180deg);
5314
+ }
5315
+
5316
+ /* ── 顶部栏 ── */
5317
+ .wf-layout-header {
5318
+ display: flex;
5319
+ align-items: center;
5320
+ gap: var(--wf-gap-md, 16px);
5321
+ height: var(--wf-layout-header-height, 56px);
5322
+ padding: 0 var(--wf-space-md, 16px);
5323
+ flex-shrink: 0;
5324
+ background: var(--wf-color-bg-secondary, #fff);
5325
+ border-bottom: var(--wf-border-width, 1px) solid var(--wf-color-border-light);
5326
+ }
5327
+
5328
+ /* ── 主内容区 ── */
5329
+ .wf-layout-content {
5330
+ flex: 1;
5331
+ min-height: 0;
5332
+ overflow: auto;
5333
+ padding: var(--wf-space-md, 16px);
5334
+ }
5335
+
5336
+ /* ── 底部栏 ── */
5337
+ .wf-layout-footer {
5338
+ padding: var(--wf-space-md, 16px);
5339
+ flex-shrink: 0;
5340
+ text-align: center;
5341
+ color: var(--wf-color-text-secondary);
5342
+ font-size: var(--wf-font-size-sm, 13px);
5343
+ background: var(--wf-color-bg-secondary, #fff);
5344
+ border-top: var(--wf-border-width, 1px) solid var(--wf-color-border-light);
5345
+ }
5346
+
5347
+ /* weifuwu/components — Link 文字链接 */
5348
+
5349
+ .wf-link {
5350
+ display: inline-flex;
5351
+ align-items: center;
5352
+ gap: 4px;
5353
+ text-decoration: underline;
5354
+ text-underline-offset: 3px;
5355
+ color: var(--wf-color-primary, #1668dc);
5356
+ cursor: pointer;
5357
+ font-family: var(--wf-font-sans);
5358
+ font-size: var(--wf-font-size-sm, 13px);
5359
+ transition: color var(--wf-dur-fast, 0.15s) var(--wf-ease-standard, ease);
5360
+ }
5361
+
5362
+ .wf-link:hover {
5363
+ color: var(--wf-color-primary, #1668dc);
5364
+ }
5365
+
5366
+ .wf-link--default {
5367
+ color: var(--wf-color-text-secondary);
5368
+ }
5369
+ .wf-link--default:hover {
5370
+ color: var(--wf-color-text);
5371
+ }
5372
+
5373
+ .wf-link--danger {
5374
+ color: var(--wf-color-error-text, #cf1322);
5375
+ }
5376
+ .wf-link--danger:hover {
5377
+ color: var(--wf-color-error-text, #a8071a);
5378
+ }
5379
+
5380
+ .wf-link--muted {
5381
+ color: var(--wf-color-text-tertiary, #999);
5382
+ text-decoration: none;
5383
+ }
5384
+ .wf-link--muted:hover {
5385
+ color: var(--wf-color-text-secondary);
5386
+ }
5387
+
5388
+ .wf-link--no-underline {
5389
+ text-decoration: none;
5390
+ }
5391
+
5392
+ .wf-link--disabled {
5393
+ color: var(--wf-color-text-disabled, #bfbfbf);
5394
+ cursor: not-allowed;
5395
+ text-decoration: none;
5396
+ pointer-events: none;
5397
+ }
5398
+
4960
5399
  /* weifuwu/components — List */
4961
5400
 
4962
5401
  .wf-list {
@@ -5653,6 +6092,112 @@ body.wf-dragging {
5653
6092
  }
5654
6093
  }
5655
6094
 
6095
+ /* weifuwu/components — NavMenu 顶部导航(shadcn NavigationMenu 对齐) */
6096
+
6097
+ .wf-navmenu {
6098
+ display: flex;
6099
+ align-items: center;
6100
+ gap: 2px;
6101
+ padding: 0 var(--wf-space-md, 16px);
6102
+ background: var(--wf-color-bg-secondary, #fff);
6103
+ border-bottom: var(--wf-border-width, 1px) solid var(--wf-color-border-light);
6104
+ font-family: var(--wf-font-sans);
6105
+ font-size: var(--wf-font-size-sm, 13px);
6106
+ min-height: 48px;
6107
+ }
6108
+
6109
+ .wf-navmenu-item {
6110
+ position: relative;
6111
+ display: inline-flex;
6112
+ align-items: center;
6113
+ gap: 6px;
6114
+ padding: 8px 14px;
6115
+ border-radius: var(--wf-surface-radius, 8px);
6116
+ color: var(--wf-color-text-secondary);
6117
+ cursor: pointer;
6118
+ transition: background var(--wf-dur-fast, 0.15s) var(--wf-ease-standard, ease),
6119
+ color var(--wf-dur-fast, 0.15s) var(--wf-ease-standard, ease);
6120
+ }
6121
+
6122
+ .wf-navmenu-item:hover {
6123
+ background: var(--wf-color-bg-hover, rgba(0, 0, 0, 0.04));
6124
+ color: var(--wf-color-text);
6125
+ }
6126
+
6127
+ .wf-navmenu-item--active {
6128
+ color: var(--wf-color-primary, #1668dc);
6129
+ font-weight: 600;
6130
+ }
6131
+
6132
+ .wf-navmenu-item--disabled {
6133
+ color: var(--wf-color-text-disabled, #bfbfbf);
6134
+ cursor: not-allowed;
6135
+ }
6136
+
6137
+ .wf-navmenu-arrow {
6138
+ font-size: 10px;
6139
+ opacity: 0.6;
6140
+ }
6141
+
6142
+ /* ── 子菜单弹出 ── */
6143
+ .wf-navmenu-sub {
6144
+ position: absolute;
6145
+ top: calc(100% + 6px);
6146
+ left: 0;
6147
+ min-width: var(--wf-navmenu-min-width, 160px);
6148
+ padding: 6px;
6149
+ border-radius: var(--wf-surface-radius, 8px);
6150
+ background: var(--wf-surface-bg, #fff);
6151
+ box-shadow: var(--wf-surface-shadow, 0 4px 16px rgba(0, 0, 0, 0.12));
6152
+ border: var(--wf-border-width, 1px) solid var(--wf-color-border-light);
6153
+ z-index: var(--wf-z-dropdown, 120);
6154
+ animation: wf-navmenu-in var(--wf-dur-fast, 0.15s) var(--wf-ease-standard, ease);
6155
+ }
6156
+
6157
+ @keyframes wf-navmenu-in {
6158
+ from { opacity: 0; transform: translateY(-4px); }
6159
+ to { opacity: 1; transform: translateY(0); }
6160
+ }
6161
+
6162
+ .wf-navmenu-sub-item {
6163
+ position: relative;
6164
+ display: flex;
6165
+ align-items: center;
6166
+ justify-content: space-between;
6167
+ gap: 12px;
6168
+ padding: 8px 12px;
6169
+ border-radius: var(--wf-radius, 6px);
6170
+ color: var(--wf-color-text);
6171
+ cursor: pointer;
6172
+ white-space: nowrap;
6173
+ transition: background var(--wf-dur-fast, 0.15s) var(--wf-ease-standard, ease);
6174
+ }
6175
+
6176
+ .wf-navmenu-sub-item:hover {
6177
+ background: var(--wf-color-bg-hover, rgba(0, 0, 0, 0.04));
6178
+ }
6179
+
6180
+ .wf-navmenu-sub-item--disabled {
6181
+ color: var(--wf-color-text-disabled, #bfbfbf);
6182
+ cursor: not-allowed;
6183
+ }
6184
+
6185
+ .wf-navmenu-sub-arrow {
6186
+ color: var(--wf-color-text-tertiary, #999);
6187
+ }
6188
+
6189
+ .wf-navmenu-sub-nested {
6190
+ position: absolute;
6191
+ top: -6px;
6192
+ left: calc(100% + 4px);
6193
+ min-width: var(--wf-navmenu-min-width, 160px);
6194
+ padding: 6px;
6195
+ border-radius: var(--wf-surface-radius, 8px);
6196
+ background: var(--wf-surface-bg, #fff);
6197
+ box-shadow: var(--wf-surface-shadow, 0 4px 16px rgba(0, 0, 0, 0.12));
6198
+ border: var(--wf-border-width, 1px) solid var(--wf-color-border-light);
6199
+ }
6200
+
5656
6201
  /* weifuwu/components — Notification */
5657
6202
 
5658
6203
  .wf-notification-container {
@@ -5982,9 +6527,9 @@ body.wf-dragging {
5982
6527
  background: var(--wf-color-primary-bg, rgba(79, 110, 247, 0.08));
5983
6528
  }
5984
6529
  .wf-pipeline-node--error {
5985
- border-color: var(--wf-color-danger-text);
5986
- color: var(--wf-color-danger-text);
5987
- background: var(--wf-color-danger-bg, rgba(255, 0, 0, 0.06));
6530
+ border-color: var(--wf-color-error-text);
6531
+ color: var(--wf-color-error-text);
6532
+ background: var(--wf-color-error-bg, rgba(255, 0, 0, 0.06));
5988
6533
  }
5989
6534
  .wf-pipeline-node--pending {
5990
6535
  border-color: var(--wf-color-border);
@@ -6000,6 +6545,76 @@ body.wf-dragging {
6000
6545
  color: var(--wf-color-warning-text);
6001
6546
  }
6002
6547
 
6548
+ /* weifuwu/components — Popconfirm 气泡确认
6549
+ * 复用 usePopup 基座:定位/portal/Escape 继承 Popover 同款
6550
+ */
6551
+
6552
+ .wf-popconfirm-wrap {
6553
+ display: inline-block;
6554
+ }
6555
+
6556
+ .wf-popconfirm {
6557
+ position: fixed;
6558
+ z-index: var(--wf-z-popover, 120);
6559
+ min-width: var(--wf-popconfirm-min-width, 180px);
6560
+ padding: var(--wf-space-sm, 12px);
6561
+ border-radius: var(--wf-surface-radius, 8px);
6562
+ background: var(--wf-surface-bg, #fff);
6563
+ box-shadow: var(--wf-surface-shadow, 0 4px 16px rgba(0, 0, 0, 0.12));
6564
+ border: var(--wf-border-width, 1px) solid var(--wf-color-border-light);
6565
+ font-family: var(--wf-font-sans);
6566
+ font-size: var(--wf-font-size-sm, 13px);
6567
+ }
6568
+
6569
+ .wf-popconfirm--bottom { transform: translateX(-50%); }
6570
+ .wf-popconfirm--top { transform: translateX(-50%) translateY(-100%); }
6571
+ .wf-popconfirm--left { transform: translateY(-50%) translateX(-100%); }
6572
+ .wf-popconfirm--right { transform: translateY(-50%); }
6573
+
6574
+ .wf-popconfirm--enter {
6575
+ animation: wf-popconfirm-in var(--wf-dur-md, 0.2s) var(--wf-ease-standard, ease);
6576
+ }
6577
+
6578
+ .wf-popconfirm--exit {
6579
+ animation: wf-popconfirm-out var(--wf-dur-md, 0.2s) var(--wf-ease-standard, ease) forwards;
6580
+ }
6581
+
6582
+ /* 入场/退场只 fade(opacity)——transform 由定位类独占:
6583
+ 动画含 transform 会覆盖 .wf-popconfirm--top 的 translateX(-50%)
6584
+ translateY(-100%)——动画期间弹层右偏/跳位,结束才归位(真实 bug) */
6585
+ @keyframes wf-popconfirm-in {
6586
+ from { opacity: 0; }
6587
+ to { opacity: 1; }
6588
+ }
6589
+
6590
+ @keyframes wf-popconfirm-out {
6591
+ from { opacity: 1; }
6592
+ to { opacity: 0; }
6593
+ }
6594
+
6595
+ .wf-popconfirm-title {
6596
+ display: flex;
6597
+ align-items: flex-start;
6598
+ gap: var(--wf-gap-xs, 8px);
6599
+ margin-bottom: var(--wf-space-xs, 8px);
6600
+ color: var(--wf-color-text);
6601
+ line-height: 1.5;
6602
+ }
6603
+
6604
+ .wf-popconfirm-icon {
6605
+ display: inline-flex;
6606
+ flex-shrink: 0;
6607
+ margin-top: 2px;
6608
+ color: var(--wf-color-warning-text, #ad6800);
6609
+ }
6610
+
6611
+ .wf-popconfirm-actions {
6612
+ display: flex;
6613
+ justify-content: flex-end;
6614
+ gap: var(--wf-gap-xs, 8px);
6615
+ margin-top: var(--wf-space-xs, 8px);
6616
+ }
6617
+
6003
6618
  /* weifuwu/components — Popover */
6004
6619
 
6005
6620
  .wf-popover-wrap {
@@ -6329,6 +6944,32 @@ body.wf-dragging {
6329
6944
  justify-content: center;
6330
6945
  }
6331
6946
 
6947
+ /* weifuwu/components — Scrollbar 自定义滚动容器 */
6948
+
6949
+ .wf-scrollbar {
6950
+ overflow: auto;
6951
+ scrollbar-width: thin;
6952
+ scrollbar-color: var(--wf-color-border) transparent;
6953
+ }
6954
+
6955
+ .wf-scrollbar::-webkit-scrollbar {
6956
+ width: 8px;
6957
+ height: 8px;
6958
+ }
6959
+
6960
+ .wf-scrollbar::-webkit-scrollbar-track {
6961
+ background: transparent;
6962
+ }
6963
+
6964
+ .wf-scrollbar::-webkit-scrollbar-thumb {
6965
+ background: var(--wf-color-border);
6966
+ border-radius: 4px;
6967
+ }
6968
+
6969
+ .wf-scrollbar::-webkit-scrollbar-thumb:hover {
6970
+ background: var(--wf-color-text-tertiary, #999);
6971
+ }
6972
+
6332
6973
  /* weifuwu/components — SearchInput */
6333
6974
 
6334
6975
  .wf-search {
@@ -6469,17 +7110,6 @@ body.wf-dragging {
6469
7110
  position: relative;
6470
7111
  }
6471
7112
 
6472
- .wf-select-label {
6473
- font-size: var(--wf-font-size-sm);
6474
- font-weight: var(--wf-font-weight-medium);
6475
- color: var(--wf-color-text);
6476
- }
6477
-
6478
- .wf-select-req {
6479
- color: var(--wf-color-error-text);
6480
- margin-left: 2px;
6481
- }
6482
-
6483
7113
  /* ── 原生 select ── */
6484
7114
 
6485
7115
  .wf-select {
@@ -6508,11 +7138,6 @@ body.wf-dragging {
6508
7138
  cursor: not-allowed;
6509
7139
  }
6510
7140
 
6511
- .wf-select-err {
6512
- font-size: var(--wf-font-size-xs);
6513
- color: var(--wf-color-error-text);
6514
- }
6515
-
6516
7141
  .wf-select--err .wf-select {
6517
7142
  border-color: var(--wf-color-error);
6518
7143
  }
@@ -6532,7 +7157,13 @@ body.wf-dragging {
6532
7157
  }
6533
7158
  .wf-select-search-trigger:focus-within {
6534
7159
  border-color: var(--wf-color-primary);
6535
- box-shadow: var(--wf-focus-ring);
7160
+ }
7161
+
7162
+ .wf-select-search-input:focus {
7163
+ /* 蓝框在 input 自身(不依赖 trigger box-shadow——trigger 底边蓝框会被
7164
+ menu 面板紧贴遮挡,用户反馈'被挡住了')。明暗主题均可见(不用
7165
+ focus-ring:系统暗色偏好下 primary-bg 变暗不可见)。 */
7166
+ box-shadow: 0 0 0 1px var(--wf-color-primary);
6536
7167
  }
6537
7168
  .wf-select-search--disabled {
6538
7169
  opacity: var(--wf-opacity-disabled);
@@ -6560,11 +7191,8 @@ body.wf-dragging {
6560
7191
  }
6561
7192
 
6562
7193
  .wf-select-search-menu {
6563
- position: absolute;
6564
- top: 100%;
6565
- left: 0;
6566
- right: 0;
6567
- margin-top: 2px;
7194
+ /* portal 定位(usePopup 接管)——absolute 会被父容器 overflow 裁剪 */
7195
+ min-width: var(--wf-select-menu-min-width, 200px);
6568
7196
  background: var(--wf-color-bg);
6569
7197
  border: var(--wf-border-width) solid var(--wf-color-border);
6570
7198
  border-radius: var(--wf-field-radius, var(--wf-radius));
@@ -6739,12 +7367,6 @@ body.wf-dragging {
6739
7367
  gap: var(--wf-gap-xs);
6740
7368
  }
6741
7369
 
6742
- .wf-slider-label {
6743
- font-size: var(--wf-font-size-sm);
6744
- font-weight: var(--wf-font-weight-medium);
6745
- color: var(--wf-color-text);
6746
- }
6747
-
6748
7370
  .wf-slider {
6749
7371
  display: flex;
6750
7372
  align-items: center;
@@ -6801,6 +7423,22 @@ body.wf-dragging {
6801
7423
  text-align: center;
6802
7424
  }
6803
7425
 
7426
+ /* weifuwu/components — Space 间距容器 */
7427
+
7428
+ .wf-space {
7429
+ display: flex;
7430
+ align-items: center;
7431
+ }
7432
+
7433
+ .wf-space--vertical {
7434
+ flex-direction: column;
7435
+ align-items: stretch;
7436
+ }
7437
+
7438
+ .wf-space-split {
7439
+ color: var(--wf-color-text-tertiary, #999);
7440
+ }
7441
+
6804
7442
  .wf-sparkline {
6805
7443
  display: inline-block;
6806
7444
  vertical-align: middle;
@@ -7247,17 +7885,6 @@ body.wf-dragging {
7247
7885
  gap: var(--wf-gap-xs);
7248
7886
  }
7249
7887
 
7250
- .wf-textarea-label {
7251
- font-size: var(--wf-font-size-sm);
7252
- font-weight: var(--wf-font-weight-medium);
7253
- color: var(--wf-color-text);
7254
- }
7255
-
7256
- .wf-textarea-req {
7257
- color: var(--wf-color-error-text);
7258
- margin-left: 2px;
7259
- }
7260
-
7261
7888
  .wf-textarea {
7262
7889
  font-family: var(--wf-font-sans);
7263
7890
  font-size: var(--wf-font-size-sm);
@@ -7288,16 +7915,6 @@ body.wf-dragging {
7288
7915
  color: var(--wf-color-text-tertiary);
7289
7916
  }
7290
7917
 
7291
- .wf-textarea-err {
7292
- font-size: var(--wf-font-size-xs);
7293
- color: var(--wf-color-error-text);
7294
- }
7295
-
7296
- .wf-textarea-hint {
7297
- font-size: var(--wf-font-size-xs);
7298
- color: var(--wf-color-text-tertiary);
7299
- }
7300
-
7301
7918
  /* 字数统计 */
7302
7919
  .wf-textarea-count {
7303
7920
  font-size: var(--wf-font-size-xs);