weifuwu 0.69.0 → 0.71.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.
- package/README.md +8 -8
- package/dist/client/diff.d.ts +7 -6
- package/dist/client/index.js +5 -5
- package/dist/client/registry.d.ts +17 -2
- package/dist/client/render.d.ts +12 -5
- package/dist/client/router.d.ts +3 -2
- package/dist/client/types.d.ts +41 -18
- package/dist/client/ui.d.ts +7 -1
- package/dist/client/vnode.d.ts +12 -5
- package/dist/components/ApprovalCard/ApprovalCard.d.ts +2 -0
- package/dist/components/Badge/Badge.d.ts +6 -0
- package/dist/components/Card/Card.d.ts +2 -0
- package/dist/components/Cascader/Cascader.d.ts +6 -2
- package/dist/components/CodeBlock/CodeBlock.d.ts +2 -2
- package/dist/components/CodeBlock/highlight.d.ts +15 -0
- package/dist/components/Drawer/Drawer.d.ts +2 -0
- package/dist/components/EmptyState/EmptyState.d.ts +3 -2
- package/dist/components/Icon/Icon.d.ts +1 -1
- package/dist/components/InputNumber/InputNumber.d.ts +2 -2
- package/dist/components/Layout/Layout.d.ts +2 -0
- package/dist/components/Markdown/parser.d.ts +11 -5
- package/dist/components/Menu/Menu.d.ts +1 -1
- package/dist/components/ProgressBar/ProgressBar.d.ts +5 -0
- package/dist/components/Rate/Rate.d.ts +2 -0
- package/dist/components/Sparkline/Sparkline.d.ts +2 -0
- package/dist/components/StatCard/StatCard.d.ts +5 -3
- package/dist/components/Timeline/Timeline.d.ts +5 -4
- package/dist/components/Transfer/Transfer.d.ts +6 -2
- package/dist/components/Tree/Tree.d.ts +3 -1
- package/dist/components/VirtualTable/VirtualTable.d.ts +9 -1
- package/dist/components/index.d.ts +1 -1
- package/dist/components/index.js +14 -14
- package/dist/components/style.css +874 -331
- package/dist/index.js +8 -1
- package/dist/layout/weifuwu-layout.css +193 -25
- package/docs/components.md +2 -2
- package/docs/layout.md +37 -9
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4787,11 +4787,18 @@ function extractParams(path, match) {
|
|
|
4787
4787
|
const m = path.match(match.re);
|
|
4788
4788
|
if (m) {
|
|
4789
4789
|
for (let i = 0; i < match.keys.length; i++) {
|
|
4790
|
-
params[match.keys[i]] =
|
|
4790
|
+
params[match.keys[i]] = safeDecode(m[i + 1]);
|
|
4791
4791
|
}
|
|
4792
4792
|
}
|
|
4793
4793
|
return params;
|
|
4794
4794
|
}
|
|
4795
|
+
function safeDecode(s) {
|
|
4796
|
+
try {
|
|
4797
|
+
return decodeURIComponent(s);
|
|
4798
|
+
} catch {
|
|
4799
|
+
return s;
|
|
4800
|
+
}
|
|
4801
|
+
}
|
|
4795
4802
|
|
|
4796
4803
|
// src/ui/ssr-page.ts
|
|
4797
4804
|
var DEFAULT_TEMPLATE = (p) => `<!DOCTYPE html>
|
|
@@ -46,6 +46,7 @@
|
|
|
46
46
|
--wf-dark-bg-hover: rgba(255, 255, 255, 0.06); /* 暗色 hover 反白 */
|
|
47
47
|
--wf-dark-surface-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
|
|
48
48
|
--wf-dark-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.2);
|
|
49
|
+
--wf-dark-shadow-inset: inset 0 1px 2px rgba(0, 0, 0, 0.3);
|
|
49
50
|
--wf-dark-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
|
|
50
51
|
--wf-dark-shadow-md: 0 4px 12px rgba(0, 0, 0, 0.4);
|
|
51
52
|
--wf-dark-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.4);
|
|
@@ -82,6 +83,7 @@
|
|
|
82
83
|
|
|
83
84
|
/* ── 阴影 ── */
|
|
84
85
|
--wf-shadow-sm: 0 1px 2px rgba(0,0,0,0.05);
|
|
86
|
+
--wf-shadow-inset: inset 0 1px 2px rgba(0,0,0,0.04); /* 内阴影:凹槽/轨道深度(Switch/ThemeSwitch) */
|
|
85
87
|
--wf-shadow: 0 1px 3px rgba(0,0,0,0.08);
|
|
86
88
|
--wf-shadow-md: 0 4px 12px rgba(0,0,0,0.1);
|
|
87
89
|
--wf-shadow-lg: 0 10px 15px -3px rgba(0,0,0,0.1);
|
|
@@ -222,6 +224,7 @@
|
|
|
222
224
|
|
|
223
225
|
/* ── 浮层遮罩(Modal/Drawer overlay,暗色经 --wf-dark-overlay 映射) ── */
|
|
224
226
|
--wf-overlay: rgba(0, 0, 0, 0.4);
|
|
227
|
+
--wf-overlay-blur: 4px; /* 遮罩毛玻璃(弹层现代质感,不支持 backdrop-filter 的环境自动降级为纯色) */
|
|
225
228
|
|
|
226
229
|
/* ── 表单控件 ── */
|
|
227
230
|
--wf-accent-color: var(--wf-color-primary);
|
|
@@ -307,6 +310,7 @@
|
|
|
307
310
|
--wf-shadow: var(--wf-dark-shadow);
|
|
308
311
|
--wf-shadow-md: var(--wf-dark-shadow-md);
|
|
309
312
|
--wf-shadow-lg: var(--wf-dark-shadow-lg);
|
|
313
|
+
--wf-shadow-inset: var(--wf-dark-shadow-inset);
|
|
310
314
|
|
|
311
315
|
--wf-color-primary-text: var(--wf-dark-brand-500);
|
|
312
316
|
--wf-color-success-text: var(--wf-dark-green-500);
|
|
@@ -357,6 +361,7 @@
|
|
|
357
361
|
--wf-shadow: var(--wf-dark-shadow);
|
|
358
362
|
--wf-shadow-md: var(--wf-dark-shadow-md);
|
|
359
363
|
--wf-shadow-lg: var(--wf-dark-shadow-lg);
|
|
364
|
+
--wf-shadow-inset: var(--wf-dark-shadow-inset);
|
|
360
365
|
|
|
361
366
|
--wf-color-primary-text: var(--wf-dark-brand-500);
|
|
362
367
|
--wf-color-success-text: var(--wf-dark-green-500);
|
|
@@ -377,6 +382,36 @@
|
|
|
377
382
|
box-sizing: border-box;
|
|
378
383
|
}
|
|
379
384
|
|
|
385
|
+
/* 选区色:primary 调(文字反白,与品牌一致) */
|
|
386
|
+
::selection {
|
|
387
|
+
background: var(--wf-color-primary-bg);
|
|
388
|
+
color: var(--wf-color-primary-text);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
/* 主题滚动条(全局——所有滚动区一致;Firefox thin + WebKit 样式) */
|
|
392
|
+
* {
|
|
393
|
+
scrollbar-width: thin;
|
|
394
|
+
scrollbar-color: var(--wf-color-border-dark) transparent;
|
|
395
|
+
}
|
|
396
|
+
::-webkit-scrollbar {
|
|
397
|
+
width: 8px;
|
|
398
|
+
height: 8px;
|
|
399
|
+
}
|
|
400
|
+
::-webkit-scrollbar-track {
|
|
401
|
+
background: transparent;
|
|
402
|
+
}
|
|
403
|
+
::-webkit-scrollbar-thumb {
|
|
404
|
+
background: var(--wf-color-border-dark);
|
|
405
|
+
border-radius: var(--wf-radius-sm);
|
|
406
|
+
border: 2px solid transparent;
|
|
407
|
+
background-clip: padding-box;
|
|
408
|
+
}
|
|
409
|
+
::-webkit-scrollbar-thumb:hover {
|
|
410
|
+
background: var(--wf-color-text-secondary);
|
|
411
|
+
background-clip: padding-box;
|
|
412
|
+
border: 2px solid transparent;
|
|
413
|
+
}
|
|
414
|
+
|
|
380
415
|
:root {
|
|
381
416
|
/* 原生控件/滚动条跟随主题;暗色激活时在 _dark.css 中切为 dark */
|
|
382
417
|
color-scheme: light;
|
|
@@ -447,11 +482,20 @@ button {
|
|
|
447
482
|
padding: var(--wf-control-pad-y) var(--wf-space-md);
|
|
448
483
|
min-height: var(--wf-control-height);
|
|
449
484
|
cursor: pointer;
|
|
485
|
+
transition: border-color var(--wf-dur-fast) var(--wf-ease-out),
|
|
486
|
+
color var(--wf-dur-fast) var(--wf-ease-out),
|
|
487
|
+
box-shadow var(--wf-dur-fast) var(--wf-ease-out),
|
|
488
|
+
background-color var(--wf-dur-fast) var(--wf-ease-out),
|
|
489
|
+
filter var(--wf-dur-fast) var(--wf-ease-out);
|
|
450
490
|
}
|
|
451
491
|
button:hover {
|
|
452
492
|
border-color: var(--wf-color-primary);
|
|
453
493
|
color: var(--wf-color-primary-text);
|
|
454
494
|
}
|
|
495
|
+
button:active:not(:disabled),
|
|
496
|
+
[role="button"]:active {
|
|
497
|
+
filter: brightness(0.95); /* 按压反馈:不偏移布局,适用任意宽度(block/inline) */
|
|
498
|
+
}
|
|
455
499
|
|
|
456
500
|
/* 键盘焦点:button 与 [tabindex] 统一 focus ring(仅键盘触发,鼠标点击不闪) */
|
|
457
501
|
button:focus-visible,
|
|
@@ -460,6 +504,15 @@ button:focus-visible,
|
|
|
460
504
|
box-shadow: var(--wf-focus-ring);
|
|
461
505
|
}
|
|
462
506
|
|
|
507
|
+
[role="button"] {
|
|
508
|
+
cursor: pointer;
|
|
509
|
+
transition: background-color var(--wf-dur-fast) var(--wf-ease-out),
|
|
510
|
+
border-color var(--wf-dur-fast) var(--wf-ease-out),
|
|
511
|
+
box-shadow var(--wf-dur-fast) var(--wf-ease-out),
|
|
512
|
+
color var(--wf-dur-fast) var(--wf-ease-out),
|
|
513
|
+
filter var(--wf-dur-fast) var(--wf-ease-out);
|
|
514
|
+
}
|
|
515
|
+
|
|
463
516
|
/* 触屏设备(coarse pointer):交互目标提升到 44px(Apple HIG / WCAG 2.5.8) */
|
|
464
517
|
@media (pointer: coarse) {
|
|
465
518
|
button,
|
|
@@ -571,10 +624,13 @@ body.wf-dragging {
|
|
|
571
624
|
}
|
|
572
625
|
|
|
573
626
|
@layer layout {
|
|
574
|
-
/* stack —
|
|
627
|
+
/* stack — 纵向堆叠(L3:gap 默认值 :where() 零优先级——wf-gap-* 等覆盖工具
|
|
628
|
+
靠优先级获胜,不再依赖 import 顺序) */
|
|
575
629
|
.wf-stack {
|
|
576
630
|
display: flex;
|
|
577
631
|
flex-direction: column;
|
|
632
|
+
}
|
|
633
|
+
:where(.wf-stack) {
|
|
578
634
|
gap: var(--wf-gap, var(--wf-gap-md));
|
|
579
635
|
}
|
|
580
636
|
@media (min-width: 640px) { .wf-stack\@sm { flex-direction: row; align-items: var(--wf-align, center); } }
|
|
@@ -585,6 +641,8 @@ body.wf-dragging {
|
|
|
585
641
|
.wf-stack-reverse {
|
|
586
642
|
display: flex;
|
|
587
643
|
flex-direction: column-reverse;
|
|
644
|
+
}
|
|
645
|
+
:where(.wf-stack-reverse) {
|
|
588
646
|
gap: var(--wf-gap, var(--wf-gap-md));
|
|
589
647
|
}
|
|
590
648
|
@media (min-width: 640px) { .wf-stack-reverse\@sm { flex-direction: row-reverse; align-items: var(--wf-align, center); } }
|
|
@@ -593,10 +651,13 @@ body.wf-dragging {
|
|
|
593
651
|
}
|
|
594
652
|
|
|
595
653
|
@layer layout {
|
|
596
|
-
/* row —
|
|
654
|
+
/* row — 横向排列(L3:gap/align 默认值 :where() 零优先级——wf-gap-*、wf-top 等
|
|
655
|
+
覆盖工具靠优先级获胜,不再依赖 import 顺序) */
|
|
597
656
|
.wf-row {
|
|
598
657
|
display: flex;
|
|
599
658
|
flex-wrap: wrap;
|
|
659
|
+
}
|
|
660
|
+
:where(.wf-row) {
|
|
600
661
|
gap: var(--wf-gap, var(--wf-gap-md));
|
|
601
662
|
align-items: var(--wf-align, center);
|
|
602
663
|
}
|
|
@@ -609,6 +670,8 @@ body.wf-dragging {
|
|
|
609
670
|
display: flex;
|
|
610
671
|
flex-direction: row-reverse;
|
|
611
672
|
flex-wrap: wrap;
|
|
673
|
+
}
|
|
674
|
+
:where(.wf-row-reverse) {
|
|
612
675
|
gap: var(--wf-gap, var(--wf-gap-md));
|
|
613
676
|
align-items: var(--wf-align, center);
|
|
614
677
|
}
|
|
@@ -618,10 +681,12 @@ body.wf-dragging {
|
|
|
618
681
|
}
|
|
619
682
|
|
|
620
683
|
@layer layout {
|
|
621
|
-
/* split —
|
|
684
|
+
/* split — 两端展开(L3:align/gap 默认值 :where() 零优先级) */
|
|
622
685
|
.wf-split {
|
|
623
686
|
display: flex;
|
|
624
687
|
justify-content: space-between;
|
|
688
|
+
}
|
|
689
|
+
:where(.wf-split) {
|
|
625
690
|
align-items: var(--wf-align, center);
|
|
626
691
|
gap: var(--wf-gap, var(--wf-gap-md));
|
|
627
692
|
}
|
|
@@ -641,57 +706,84 @@ body.wf-dragging {
|
|
|
641
706
|
}
|
|
642
707
|
|
|
643
708
|
@layer layout {
|
|
644
|
-
/*
|
|
709
|
+
/* between — 两端对齐(行内垂直居中;L3:align/gap 默认值 :where() 零优先级) */
|
|
710
|
+
.wf-between {
|
|
711
|
+
display: flex;
|
|
712
|
+
justify-content: space-between;
|
|
713
|
+
}
|
|
714
|
+
:where(.wf-between) {
|
|
715
|
+
align-items: var(--wf-align, center);
|
|
716
|
+
gap: var(--wf-gap, var(--wf-gap-md));
|
|
717
|
+
}
|
|
718
|
+
@media (min-width: 640px) { .wf-between\@sm { display: flex; justify-content: space-between; align-items: var(--wf-align, center); gap: var(--wf-gap, var(--wf-gap-md)); } }
|
|
719
|
+
@media (min-width: 768px) { .wf-between\@md { display: flex; justify-content: space-between; align-items: var(--wf-align, center); gap: var(--wf-gap, var(--wf-gap-md)); } }
|
|
720
|
+
@media (min-width: 1024px) { .wf-between\@lg { display: flex; justify-content: space-between; align-items: var(--wf-align, center); gap: var(--wf-gap, var(--wf-gap-md)); } }
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
@layer layout {
|
|
724
|
+
/* right — 靠右对齐(L3:align/gap 默认值 :where() 零优先级) */
|
|
645
725
|
.wf-right {
|
|
646
726
|
display: flex;
|
|
647
727
|
justify-content: flex-end;
|
|
728
|
+
}
|
|
729
|
+
:where(.wf-right) {
|
|
648
730
|
align-items: var(--wf-align, center);
|
|
649
731
|
gap: var(--wf-gap, var(--wf-gap-md));
|
|
650
732
|
}
|
|
651
733
|
}
|
|
652
734
|
|
|
653
735
|
@layer layout {
|
|
654
|
-
/* top —
|
|
736
|
+
/* top — 顶部对齐(L3:gap 默认值 :where() 零优先级;align-items 是身份属性) */
|
|
655
737
|
.wf-top {
|
|
656
738
|
display: flex;
|
|
657
739
|
align-items: flex-start;
|
|
740
|
+
}
|
|
741
|
+
:where(.wf-top) {
|
|
658
742
|
gap: var(--wf-gap, var(--wf-gap-md));
|
|
659
743
|
}
|
|
660
744
|
}
|
|
661
745
|
|
|
662
746
|
@layer layout {
|
|
663
|
-
/* bottom —
|
|
747
|
+
/* bottom — 底部对齐(L3:gap 默认值 :where() 零优先级;align-items 是身份属性) */
|
|
664
748
|
.wf-bottom {
|
|
665
749
|
display: flex;
|
|
666
750
|
align-items: flex-end;
|
|
751
|
+
}
|
|
752
|
+
:where(.wf-bottom) {
|
|
667
753
|
gap: var(--wf-gap, var(--wf-gap-md));
|
|
668
754
|
}
|
|
669
755
|
}
|
|
670
756
|
|
|
671
757
|
@layer layout {
|
|
672
|
-
/* stretch —
|
|
758
|
+
/* stretch — 拉伸对齐(L3:gap 默认值 :where() 零优先级;align-items 是身份属性) */
|
|
673
759
|
.wf-stretch {
|
|
674
760
|
display: flex;
|
|
675
761
|
align-items: stretch;
|
|
762
|
+
}
|
|
763
|
+
:where(.wf-stretch) {
|
|
676
764
|
gap: var(--wf-gap, var(--wf-gap-md));
|
|
677
765
|
}
|
|
678
766
|
}
|
|
679
767
|
|
|
680
768
|
@layer layout {
|
|
681
|
-
/* around —
|
|
769
|
+
/* around — 均匀环绕分布(L3:align/gap 默认值 :where() 零优先级) */
|
|
682
770
|
.wf-around {
|
|
683
771
|
display: flex;
|
|
684
772
|
justify-content: space-around;
|
|
773
|
+
}
|
|
774
|
+
:where(.wf-around) {
|
|
685
775
|
align-items: var(--wf-align, center);
|
|
686
776
|
gap: var(--wf-gap, var(--wf-gap-md));
|
|
687
777
|
}
|
|
688
778
|
}
|
|
689
779
|
|
|
690
780
|
@layer layout {
|
|
691
|
-
/* evenly —
|
|
781
|
+
/* evenly — 均匀分布(L3:align/gap 默认值 :where() 零优先级) */
|
|
692
782
|
.wf-evenly {
|
|
693
783
|
display: flex;
|
|
694
784
|
justify-content: space-evenly;
|
|
785
|
+
}
|
|
786
|
+
:where(.wf-evenly) {
|
|
695
787
|
align-items: var(--wf-align, center);
|
|
696
788
|
gap: var(--wf-gap, var(--wf-gap-md));
|
|
697
789
|
}
|
|
@@ -707,10 +799,18 @@ body.wf-dragging {
|
|
|
707
799
|
}
|
|
708
800
|
|
|
709
801
|
@layer layout {
|
|
710
|
-
/*
|
|
802
|
+
/* flex-none — 固定不伸缩(推荐名;wf-fixed 为兼容别名——易与 position:fixed 混淆,
|
|
803
|
+
position:fixed 请用 wf-pin) */
|
|
804
|
+
.wf-flex-none,
|
|
711
805
|
.wf-fixed {
|
|
712
806
|
flex: none;
|
|
713
807
|
}
|
|
808
|
+
|
|
809
|
+
/* pin — 固定定位(角标/浮层锚点——position: fixed,坐标由 inline 参数控制) */
|
|
810
|
+
.wf-pin {
|
|
811
|
+
position: fixed;
|
|
812
|
+
z-index: var(--wf-z, var(--wf-cover-z));
|
|
813
|
+
}
|
|
714
814
|
}
|
|
715
815
|
|
|
716
816
|
@layer layout {
|
|
@@ -862,19 +962,24 @@ body.wf-dragging {
|
|
|
862
962
|
}
|
|
863
963
|
|
|
864
964
|
@layer layout {
|
|
865
|
-
/* grid —
|
|
965
|
+
/* grid — 二维网格(L3:gap 默认值 :where() 零优先级) */
|
|
866
966
|
.wf-grid {
|
|
867
967
|
display: grid;
|
|
868
968
|
grid-template-columns: var(--wf-cols, repeat(auto-fill, minmax(280px, 1fr)));
|
|
969
|
+
}
|
|
970
|
+
:where(.wf-grid) {
|
|
869
971
|
gap: var(--wf-gap, var(--wf-gap-lg));
|
|
870
972
|
}
|
|
871
973
|
}
|
|
872
974
|
|
|
873
975
|
@layer layout {
|
|
874
|
-
/* cluster —
|
|
976
|
+
/* cluster — 换行簇(L3:justify/align/gap 默认值 :where() 零优先级——
|
|
977
|
+
wf-right 等分布工具叠加时靠优先级获胜) */
|
|
875
978
|
.wf-cluster {
|
|
876
979
|
display: flex;
|
|
877
980
|
flex-wrap: wrap;
|
|
981
|
+
}
|
|
982
|
+
:where(.wf-cluster) {
|
|
878
983
|
gap: var(--wf-gap, var(--wf-gap-sm));
|
|
879
984
|
justify-content: var(--wf-justify, center);
|
|
880
985
|
align-items: var(--wf-align, center);
|
|
@@ -882,7 +987,7 @@ body.wf-dragging {
|
|
|
882
987
|
}
|
|
883
988
|
|
|
884
989
|
@layer layout {
|
|
885
|
-
/* scroll —
|
|
990
|
+
/* scroll — 可滚动容器(全局滚动条样式见 _base.css;此类仅标记语义 + overflow) */
|
|
886
991
|
.wf-scroll {
|
|
887
992
|
overflow: auto;
|
|
888
993
|
}
|
|
@@ -920,7 +1025,7 @@ body.wf-dragging {
|
|
|
920
1025
|
}
|
|
921
1026
|
}
|
|
922
1027
|
|
|
923
|
-
@layer
|
|
1028
|
+
@layer utilities {
|
|
924
1029
|
/* block — 块级显示 */
|
|
925
1030
|
.wf-block {
|
|
926
1031
|
display: block;
|
|
@@ -944,9 +1049,25 @@ body.wf-dragging {
|
|
|
944
1049
|
}
|
|
945
1050
|
}
|
|
946
1051
|
|
|
1052
|
+
@layer utilities {
|
|
1053
|
+
/* flex — 弹性盒 display 工具(补全 display 族:block/inline/inline-block/contents/hidden/flex)
|
|
1054
|
+
* 核心场景:响应式显隐的 flex 容器——`wf-hidden wf-flex@lg`(窄隐宽显且保持 flex 布局)。
|
|
1055
|
+
* 不可用 wf-block@lg 替代:block 会覆盖 wf-stack 的 display:flex,
|
|
1056
|
+
* 致 flex-direction/gap/mt-auto 全部静默失效(layouts-demo 侧栏 mt-auto 实测踩坑)。 */
|
|
1057
|
+
.wf-flex {
|
|
1058
|
+
display: flex;
|
|
1059
|
+
}
|
|
1060
|
+
@media (min-width: 640px) { .wf-flex\@sm { display: flex; } }
|
|
1061
|
+
@media (min-width: 768px) { .wf-flex\@md { display: flex; } }
|
|
1062
|
+
@media (min-width: 1024px) { .wf-flex\@lg { display: flex; } }
|
|
1063
|
+
}
|
|
1064
|
+
|
|
947
1065
|
@layer layout {
|
|
948
1066
|
/* container — 内容宽度约束居中 */
|
|
1067
|
+
/* width: 100% 必须:margin: 0 auto 在 flex 父中阻止 stretch(宽度=内容)
|
|
1068
|
+
——landing 特性区 404px 而非撑满 1100 容器的根因 */
|
|
949
1069
|
.wf-container {
|
|
1070
|
+
width: 100%;
|
|
950
1071
|
max-width: var(--wf-max, 1200px);
|
|
951
1072
|
margin: 0 auto;
|
|
952
1073
|
padding: 0 var(--wf-gap, var(--wf-gap-lg));
|
|
@@ -969,12 +1090,15 @@ body.wf-dragging {
|
|
|
969
1090
|
}
|
|
970
1091
|
|
|
971
1092
|
@layer layout {
|
|
972
|
-
/* nowrap —
|
|
1093
|
+
/* nowrap — 不换行(只管 flex-wrap——不定义 align-items,避免与
|
|
1094
|
+
wf-stretch 等对齐工具叠加冲突:双份 CSS 下 nowrap 后置曾覆盖 stretch;
|
|
1095
|
+
L3:gap 默认值 :where() 零优先级) */
|
|
973
1096
|
.wf-nowrap {
|
|
974
1097
|
display: flex;
|
|
975
1098
|
flex-wrap: nowrap;
|
|
1099
|
+
}
|
|
1100
|
+
:where(.wf-nowrap) {
|
|
976
1101
|
gap: var(--wf-gap, var(--wf-gap-md));
|
|
977
|
-
align-items: var(--wf-align, center);
|
|
978
1102
|
}
|
|
979
1103
|
}
|
|
980
1104
|
|
|
@@ -1016,6 +1140,20 @@ body.wf-dragging {
|
|
|
1016
1140
|
.wf-py-xl { padding-top: var(--wf-space-xl); padding-bottom: var(--wf-space-xl); }
|
|
1017
1141
|
.wf-py-2xl { padding-top: var(--wf-space-2xl); padding-bottom: var(--wf-space-2xl); }
|
|
1018
1142
|
|
|
1143
|
+
/* ── padding: 单侧顶/底(幽灵类防线抓出 wf-pt-md/wf-pb-md 误用——补全家族) ── */
|
|
1144
|
+
.wf-pt-xs { padding-top: var(--wf-space-xs); }
|
|
1145
|
+
.wf-pt-sm { padding-top: var(--wf-space-sm); }
|
|
1146
|
+
.wf-pt-md { padding-top: var(--wf-space-md); }
|
|
1147
|
+
.wf-pt-lg { padding-top: var(--wf-space-lg); }
|
|
1148
|
+
.wf-pt-xl { padding-top: var(--wf-space-xl); }
|
|
1149
|
+
.wf-pt-2xl { padding-top: var(--wf-space-2xl); }
|
|
1150
|
+
.wf-pb-xs { padding-bottom: var(--wf-space-xs); }
|
|
1151
|
+
.wf-pb-sm { padding-bottom: var(--wf-space-sm); }
|
|
1152
|
+
.wf-pb-md { padding-bottom: var(--wf-space-md); }
|
|
1153
|
+
.wf-pb-lg { padding-bottom: var(--wf-space-lg); }
|
|
1154
|
+
.wf-pb-xl { padding-bottom: var(--wf-space-xl); }
|
|
1155
|
+
.wf-pb-2xl { padding-bottom: var(--wf-space-2xl); }
|
|
1156
|
+
|
|
1019
1157
|
/* ── margin:重置 ── */
|
|
1020
1158
|
.wf-m-0 { margin: 0; }
|
|
1021
1159
|
.wf-p-0 { padding: 0; }
|
|
@@ -1045,20 +1183,33 @@ body.wf-dragging {
|
|
|
1045
1183
|
/* ── margin: auto(居中) ── */
|
|
1046
1184
|
.wf-mx-auto { margin-left: auto; margin-right: auto; }
|
|
1047
1185
|
.wf-my-auto { margin-top: auto; margin-bottom: auto; }
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
.wf-gap-
|
|
1054
|
-
.wf-gap-
|
|
1055
|
-
.wf-gap-
|
|
1056
|
-
.wf-gap-
|
|
1186
|
+
.wf-mt-auto { margin-top: auto; } /* flex 列推底(侧栏 footer——曾写不存在类静默失效) */
|
|
1187
|
+
.wf-mb-auto { margin-bottom: auto; }
|
|
1188
|
+
|
|
1189
|
+
/* ── gap:直接设置 gap 属性(不设 --wf-gap 变量——变量会继承污染子孙:
|
|
1190
|
+
壳 root wf-gap-none 曾让 KPI grid 的 gap: var(--wf-gap) = 0 卡无间距) ── */
|
|
1191
|
+
.wf-gap-none { gap: 0; }
|
|
1192
|
+
.wf-gap-xs { gap: var(--wf-gap-xs); }
|
|
1193
|
+
.wf-gap-sm { gap: var(--wf-gap-sm); }
|
|
1194
|
+
.wf-gap-md { gap: var(--wf-gap-md); }
|
|
1195
|
+
.wf-gap-lg { gap: var(--wf-gap-lg); }
|
|
1196
|
+
.wf-gap-xl { gap: var(--wf-gap-xl); }
|
|
1197
|
+
.wf-gap-2xl { gap: var(--wf-gap-2xl); }
|
|
1057
1198
|
|
|
1058
1199
|
/* ── 尺寸 ── */
|
|
1059
1200
|
.wf-w-full { width: 100%; }
|
|
1060
1201
|
.wf-h-full { height: 100%; }
|
|
1061
1202
|
.wf-w-auto { width: auto; }
|
|
1203
|
+
|
|
1204
|
+
/* ── 固定宽度阶梯(对齐 token 阶梯——卡片/面板/容器宽不再内联) ── */
|
|
1205
|
+
.wf-w-xs { width: var(--wf-w-xs, 320px); }
|
|
1206
|
+
.wf-w-sm { width: var(--wf-w-sm, 480px); }
|
|
1207
|
+
.wf-w-md { width: var(--wf-w-md, 640px); }
|
|
1208
|
+
.wf-w-lg { width: var(--wf-w-lg, 768px); }
|
|
1209
|
+
.wf-w-xl { width: var(--wf-w-xl, 1024px); }
|
|
1210
|
+
.wf-w-max { max-width: 100%; }
|
|
1211
|
+
.wf-w-md-auto { width: 100%; }
|
|
1212
|
+
@media (min-width: 768px) { .wf-w-md-auto { width: var(--wf-w-md, 640px); } }
|
|
1062
1213
|
}
|
|
1063
1214
|
|
|
1064
1215
|
@layer layout {
|
|
@@ -1177,6 +1328,23 @@ body.wf-dragging {
|
|
|
1177
1328
|
display: inline-flex;
|
|
1178
1329
|
}
|
|
1179
1330
|
|
|
1331
|
+
/* ── 折叠态:图标-only 导航(配合 --wf-sidebar-width 收窄侧栏) ── */
|
|
1332
|
+
.wf-nav--collapsed .wf-nav-item {
|
|
1333
|
+
justify-content: center;
|
|
1334
|
+
gap: 0;
|
|
1335
|
+
padding: var(--wf-space-sm);
|
|
1336
|
+
}
|
|
1337
|
+
.wf-nav--collapsed .wf-nav-label {
|
|
1338
|
+
display: none;
|
|
1339
|
+
}
|
|
1340
|
+
.wf-nav--collapsed .wf-nav-group {
|
|
1341
|
+
text-align: center;
|
|
1342
|
+
padding-left: 0;
|
|
1343
|
+
padding-right: 0;
|
|
1344
|
+
overflow: hidden;
|
|
1345
|
+
white-space: nowrap;
|
|
1346
|
+
}
|
|
1347
|
+
|
|
1180
1348
|
/* ── 主内容区 ── */
|
|
1181
1349
|
.wf-main {
|
|
1182
1350
|
padding: var(--wf-space-lg);
|
package/docs/components.md
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
> 本页为 weifuwu 官方文档拆分页 · [返回 README](../README.md)
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
109 个 HTML 原语组件。每个是 `(_init, ctx) => (props) => VNode`(两阶段组件,与前端框架同一模型),引用 `--wf-*` CSS 变量做主题。另含 `confirm()` / `toast()` 命令式中间件。
|
|
6
6
|
|
|
7
7
|
> **组件速查(weifuwu 组件 ↔ antd / Element Plus / shadcn-ui 对应 + 迁移示例)**:见 [`docs/components-map.md`](components-map.md)——从其他组件库迁来的开发者按功能直接找对应组件。
|
|
8
8
|
> **自定义组件开发**:见 [docs/custom-components.md](custom-components.md)——usePopup/useControlled/对话框/AI 组件/类型纪律逐步指南。
|
|
9
9
|
|
|
10
10
|
```ts
|
|
11
11
|
import { Button, Input, Table, Modal, Toast } from 'weifuwu/components'
|
|
12
|
-
import 'weifuwu/components/style.css' // 包含 Token +
|
|
12
|
+
import 'weifuwu/components/style.css' // 包含 Token + 57 布局原语 + 136 工具类 + 组件样式,一次性引入
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
### 使用示例
|
package/docs/layout.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> 本页为 weifuwu 官方文档拆分页 · [返回 README](../README.md)
|
|
4
4
|
|
|
5
|
-
纯 CSS
|
|
5
|
+
纯 CSS 57 个布局原语 + 136 个工具类 + 167 个主题 Token。不绑定任何 JS 框架。
|
|
6
6
|
|
|
7
7
|
> **学习路径与命名规范**:见 [`design/style-guide.md`](../design/style-guide.md)——统一语法 `wf-<域>-<名>`、三档学习(组件 → 10 核心原语 → 完整速查)、场景速查、变量定制。
|
|
8
8
|
|
|
@@ -25,7 +25,7 @@ app.get('/layout.css', (req, ctx) => ctx.ui.css('weifuwu/layout'))
|
|
|
25
25
|
|
|
26
26
|
也支持相对路径:`ctx.ui.css('./src/style.css')`。
|
|
27
27
|
|
|
28
|
-
##
|
|
28
|
+
## 57 个布局原语
|
|
29
29
|
|
|
30
30
|
| 类别 | 原语 | 效果 |
|
|
31
31
|
|------|------|------|
|
|
@@ -44,11 +44,12 @@ app.get('/layout.css', (req, ctx) => ctx.ui.css('weifuwu/layout'))
|
|
|
44
44
|
| | `wf-bottom` | align-items: flex-end |
|
|
45
45
|
| | `wf-stretch` | align-items: stretch |
|
|
46
46
|
| **弹性** | `wf-fill` | flex: 1 + min-width: 0 |
|
|
47
|
-
| | `wf-
|
|
47
|
+
| | `wf-flex-none` | flex: none(`wf-fixed` 为兼容别名——易与 position:fixed 混淆,推荐新名) |
|
|
48
48
|
| | `wf-auto` | flex: auto |
|
|
49
49
|
| | `wf-shrink` | min-width/height: 0 |
|
|
50
50
|
| **Z轴** | `wf-cover` | position: fixed + inset: 0 |
|
|
51
|
-
| | `wf-
|
|
51
|
+
| | `wf-pin` | position: fixed(角标/浮层锚点,坐标由 inline 控制——相对视口) |
|
|
52
|
+
| | `wf-pop` | position: absolute(容器内角标:配合 `wf-layer`/`wf-anchor` 父级) |
|
|
52
53
|
| | `wf-anchor` | position: relative |
|
|
53
54
|
| | `wf-layer` | position: relative + z-index |
|
|
54
55
|
| | `wf-sticky` | position: sticky |
|
|
@@ -60,17 +61,24 @@ app.get('/layout.css', (req, ctx) => ctx.ui.css('weifuwu/layout'))
|
|
|
60
61
|
| | `wf-scroll` | overflow: auto |
|
|
61
62
|
| | `wf-clip` | overflow: hidden |
|
|
62
63
|
| **显隐** | `wf-hidden` `wf-hidden@sm/md/lg` | display: none |
|
|
64
|
+
| | `wf-flex` `wf-flex@sm/md/lg` | display: flex(响应式显隐的 flex 容器恢复用——见「组合规则」) |
|
|
63
65
|
| | `wf-block` `wf-block@sm/md/lg` | display: block |
|
|
64
66
|
| | `wf-inline` | display: inline |
|
|
65
67
|
| | `wf-inline-block` | display: inline-block |
|
|
66
68
|
| | `wf-contents` | display: contents |
|
|
67
|
-
|
|
|
69
|
+
| | `wf-dim` | opacity 0.7(运行中/历史态淡化) |
|
|
70
|
+
| **间距** | `wf-p-*` / `wf-px-*` / `wf-py-*`(xs~2xl,另有 `wf-p-0`) | padding:全/水平/垂直,引用 `--wf-space-*` |
|
|
71
|
+
| | `wf-m-0` | margin: 0 |
|
|
68
72
|
| | `wf-mt-*` / `wf-mb-*` / `wf-my-*`(xs~2xl) | margin:top/bottom/垂直 |
|
|
69
|
-
| | `wf-
|
|
73
|
+
| | `wf-pt-*` / `wf-pb-*`(xs~2xl) | padding:单侧顶/底(分隔条场景) |
|
|
74
|
+
| | `wf-mx-auto` / `wf-my-auto` / `wf-mt-auto` / `wf-mb-auto` | margin: auto 居中 / flex 列推底 |
|
|
70
75
|
| | `wf-gap-*`(xs~2xl) | 为 flex/grid 原语设置 `--wf-gap` |
|
|
71
76
|
| **尺寸** | `wf-w-full` / `wf-h-full` / `wf-w-auto` | 宽/高 100%、auto |
|
|
77
|
+
| | `wf-w-xs…xl` / `wf-w-max` / `wf-w-md-auto` | 固定宽阶(`--wf-space-*` 派生)/ max-content / md 起 auto |
|
|
72
78
|
| **边框** | `wf-border` / `wf-border-t/b/l/r` | 1px 边框(`--wf-border-width` + `--wf-color-border`) |
|
|
73
|
-
| **面工具** | `wf-bg-secondary/tertiary/brand/success/warning/error/info` | 语义背景色(`--wf-color-*-bg`) |
|
|
79
|
+
| **面工具** | `wf-bg-secondary/tertiary/brand/success/warning/error/info`(`wf-bg-primary` 为 brand 别名) | 语义背景色(`--wf-color-*-bg`) |
|
|
80
|
+
| | `wf-elevate` | 抬升阴影(`--wf-shadow-*`) |
|
|
81
|
+
| | `wf-panel-in` | 内凹面板(次级背景 + 内边距) |
|
|
74
82
|
| | `wf-pill` | 胶囊圆角(999px,状态徽章/标签/色块) |
|
|
75
83
|
| | `wf-rounded-sm` `wf-rounded` `wf-rounded-md` `wf-rounded-lg` | 圆角工具(`--wf-radius-*`) |
|
|
76
84
|
| **气泡** | `wf-bubble` / `wf-bubble--own` / `wf-bubble--ai` | 聊天气泡(pre-wrap + 折行内建) |
|
|
@@ -84,13 +92,33 @@ app.get('/layout.css', (req, ctx) => ctx.ui.css('weifuwu/layout'))
|
|
|
84
92
|
| | `wf-main` | 主内容区(padding + min-width: 0) |
|
|
85
93
|
| | `wf-text-*` 排版工具 | 见下文「排版工具」 |
|
|
86
94
|
|
|
95
|
+
### 组合规则(冲突防线)
|
|
96
|
+
|
|
97
|
+
原语分两类:**布局身份类**(display/position/flex-direction——stack/row/grid/nav/center/cover/pop…)
|
|
98
|
+
与**叠加工具类**(gap/对齐/显隐——叠加在身份类上)。规则:
|
|
99
|
+
|
|
100
|
+
1. **同一元素只带一个布局身份类**——两个身份类设置同一属性不同值时 import 顺序定胜负,
|
|
101
|
+
静默失效(事故例:`wf-nav wf-row` → nav 的 column 胜,横向失效;`wf-grid wf-stack` → stack 胜,网格失效)。
|
|
102
|
+
`style-audit` 静态扫描 class 组合,命中即红。
|
|
103
|
+
2. **对齐工具可叠加**:`wf-top/right/bottom/stretch/between/around/evenly` 专门用于覆盖
|
|
104
|
+
`wf-row` 等的默认对齐(后导入获胜,组合合法)。`wf-nowrap` 专门关 `wf-row` 的 wrap。
|
|
105
|
+
3. **`wf-center` 是 column 双轴居中**(不是 justify-center)——要“行内水平居中”用 `wf-cluster`,
|
|
106
|
+
不要 `wf-row wf-center`(center 的 column 方向会静默覆盖 row)。
|
|
107
|
+
4. **响应式显隐用 `wf-flex@bp` 恢复**:`wf-hidden wf-flex@lg` = 窄隐宽显(flex 容器)。
|
|
108
|
+
不可用 `wf-block@lg`——block 会覆盖 `wf-stack` 的 display:flex,gap/mt-auto 静默失效。
|
|
109
|
+
5. **容器内角标用 `wf-pop`**(父级 `wf-layer`/`wf-anchor`);`wf-pin` 是相对视口的 fixed,
|
|
110
|
+
嵌进带壳页面会覆盖壳。
|
|
111
|
+
|
|
112
|
+
完整冲突矩阵由 `node scripts/layout-inventory.mjs --json` 生成(属性指纹自动推导)。
|
|
113
|
+
|
|
87
114
|
### 排版工具(`wf-text-*`)
|
|
88
115
|
|
|
89
116
|
| 工具 | 效果 |
|
|
90
117
|
|------|------|
|
|
91
118
|
| `wf-text-left/center/right` | text-align |
|
|
92
119
|
| `wf-text-xs…5xl` | 字号(`--wf-font-size-*`) |
|
|
93
|
-
| `wf-text-secondary/tertiary/disabled/brand` | 中性色阶 |
|
|
120
|
+
| `wf-text-secondary/tertiary/disabled/brand`(`wf-text-primary` 为 brand 别名) | 中性色阶 |
|
|
121
|
+
| `wf-nums` | tabular-nums(数值防宽度抖动) |
|
|
94
122
|
| `wf-text-success/warning/error/info` | 语义色文本(`--wf-color-*`) |
|
|
95
123
|
| `wf-text-medium/semibold/bold` | 字重 |
|
|
96
124
|
| `wf-tracking-normal/wide/wider` | letter-spacing |
|
|
@@ -101,7 +129,7 @@ app.get('/layout.css', (req, ctx) => ctx.ui.css('weifuwu/layout'))
|
|
|
101
129
|
| `wf-truncate` | 单行省略(ellipsis) |
|
|
102
130
|
| `wf-line-clamp-2/3` | 多行截断 |
|
|
103
131
|
|
|
104
|
-
##
|
|
132
|
+
## 167 个主题 Token
|
|
105
133
|
|
|
106
134
|
**双层结构**:原始层(Primitive,色值只定义一次,品牌/暗色调校改这里)+ 语义层(Semantic,组件消费)。
|
|
107
135
|
|