weifuwu 0.55.1 → 0.55.3

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.
@@ -35,8 +35,20 @@
35
35
  --wf-shadow-lg: 0 10px 15px -3px rgba(0,0,0,0.1);
36
36
 
37
37
  /* ── 层级 ── */
38
- --wf-pop-z: 50;
39
- --wf-cover-z: 100;
38
+ /* 浮层全部 createPortal 到 body,全局参与堆叠。
39
+ 顺序:sticky < overlay < modal/drawer < 弹出面板族 < toast < tooltip。
40
+ modal 与 drawer 互斥出现;面板族同级(dropdown/select/datepicker/popover)用 DOM 顺序裁决。 */
41
+ --wf-z-sticky: 40;
42
+ --wf-z-overlay: 80;
43
+ --wf-z-modal: 100;
44
+ --wf-z-popover: 120; /* dropdown/select/datepicker 面板与 popover 同层 */
45
+ --wf-z-toast: 140;
46
+ --wf-z-tooltip: 160;
47
+ --wf-z-dropdown: var(--wf-z-popover); /* 语义别名:下拉菜单属弹出面板族 */
48
+
49
+ /* ── 兼容别名(旧 token 名,语义近似映射) ── */
50
+ --wf-pop-z: var(--wf-z-popover);
51
+ --wf-cover-z: var(--wf-z-modal);
40
52
 
41
53
  /* ── 色彩 — 品牌 ── */
42
54
  --wf-color-primary: #4f6ef7;
@@ -71,15 +83,15 @@
71
83
  --wf-font-sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
72
84
  --wf-font-mono: 'SF Mono', 'Fira Code', 'JetBrains Mono', monospace;
73
85
 
74
- --wf-font-size-xs: 11px;
75
- --wf-font-size-sm: 12px;
76
- --wf-font-size-base: 13px;
77
- --wf-font-size-lg: 14px;
78
- --wf-font-size-xl: 15px;
79
- --wf-font-size-2xl: 20px;
86
+ --wf-font-size-xs: 12px;
87
+ --wf-font-size-sm: 13px;
88
+ --wf-font-size-base: 14px;
89
+ --wf-font-size-lg: 15px;
90
+ --wf-font-size-xl: 16px;
91
+ --wf-font-size-2xl: 21px;
80
92
  --wf-font-size-3xl: 24px;
81
- --wf-font-size-4xl: 28px;
82
- --wf-font-size-5xl: 32px;
93
+ --wf-font-size-4xl: 30px;
94
+ --wf-font-size-5xl: 36px;
83
95
 
84
96
  --wf-font-weight-normal: 400;
85
97
  --wf-font-weight-medium: 500;
@@ -110,6 +122,10 @@
110
122
  --wf-accent-color: var(--wf-color-primary);
111
123
  --wf-caret-color: var(--wf-color-primary);
112
124
 
125
+ /* 控件尺寸:垂直内边距 + 目标高度(移动端在 _base.css 提升到 44px) */
126
+ --wf-control-pad-y: 10px;
127
+ --wf-control-height: 36px;
128
+
113
129
  /* ── 断点 ── */
114
130
  --wf-bp-sm: 640px;
115
131
  --wf-bp-md: 768px;
@@ -126,8 +142,21 @@
126
142
  --wf-letter-spacing-wider: 1px;
127
143
  }
128
144
 
129
- /* weifuwu/theme — 暗色模式 */
130
- [data-theme="dark"] {
145
+ /* weifuwu/theme — 暗色模式
146
+ *
147
+ * 两种激活方式(优先级:显式 data-theme > 系统偏好):
148
+ * 1. 手动:<html data-theme="dark">(或 data-theme="light" 强制亮色)
149
+ * 2. 自动:系统偏好 prefers-color-scheme: dark,无显式覆盖时生效
150
+ *
151
+ * ⚠️ 两段暗色覆盖值必须保持一致(静态 CSS 无法共享选择器列表,改动需同步)。
152
+ * 每段末尾都设置 color-scheme: dark,让原生控件/滚动条跟随。
153
+ */
154
+
155
+ /* ── 激活方式一:手动 data-theme="dark" ── */
156
+ /* color-scheme 用 :root[data-theme] 提升优先级,压过 _base.css 的 :root 定义(导入顺序在后者) */
157
+ :root[data-theme="dark"] {
158
+ color-scheme: dark;
159
+
131
160
  --wf-color-primary: #6b8aff;
132
161
  --wf-color-primary-hover: #8ba3ff;
133
162
  --wf-color-primary-bg: #1e293b;
@@ -166,6 +195,50 @@
166
195
  --wf-surface-bg: var(--wf-color-bg);
167
196
  }
168
197
 
198
+ /* ── 激活方式二:系统暗色偏好(data-theme="light" 可强制亮色) ── */
199
+ @media (prefers-color-scheme: dark) {
200
+ :root:not([data-theme="light"]) {
201
+ color-scheme: dark;
202
+
203
+ --wf-color-primary: #6b8aff;
204
+ --wf-color-primary-hover: #8ba3ff;
205
+ --wf-color-primary-bg: #1e293b;
206
+
207
+ --wf-color-success: #4ade80;
208
+ --wf-color-success-bg: #14532d;
209
+ --wf-color-warning: #fbbf24;
210
+ --wf-color-warning-bg: #451a03;
211
+ --wf-color-error: #f87171;
212
+ --wf-color-error-bg: #451a1a;
213
+
214
+ --wf-color-info: #60a5fa;
215
+ --wf-color-info-bg: #172554;
216
+
217
+ --wf-color-text: #f1f5f9;
218
+ --wf-color-text-secondary: #94a3b8;
219
+ --wf-color-text-tertiary: #64748b;
220
+ --wf-color-text-disabled: #475569;
221
+
222
+ --wf-color-bg: #0f172a;
223
+ --wf-color-bg-secondary: #1e293b;
224
+ --wf-color-bg-tertiary: #334155;
225
+
226
+ --wf-color-border: #334155;
227
+ --wf-color-border-light: #1e293b;
228
+ --wf-color-border-dark: #475569;
229
+
230
+ --wf-surface-shadow: 0 1px 3px rgba(0,0,0,0.3);
231
+ --wf-shadow-sm: 0 1px 2px rgba(0,0,0,0.2);
232
+ --wf-shadow: 0 1px 3px rgba(0,0,0,0.3);
233
+ --wf-shadow-md: 0 4px 12px rgba(0,0,0,0.4);
234
+ --wf-shadow-lg: 0 10px 15px -3px rgba(0,0,0,0.4);
235
+
236
+ --wf-focus-ring: 0 0 0 2px var(--wf-color-primary-bg);
237
+
238
+ --wf-surface-bg: var(--wf-color-bg);
239
+ }
240
+ }
241
+
169
242
  /* weifuwu/theme — 基础元素默认样式 */
170
243
  *,
171
244
  *::before,
@@ -173,6 +246,11 @@
173
246
  box-sizing: border-box;
174
247
  }
175
248
 
249
+ :root {
250
+ /* 原生控件/滚动条跟随主题;暗色激活时在 _dark.css 中切为 dark */
251
+ color-scheme: light;
252
+ }
253
+
176
254
  body {
177
255
  margin: 0;
178
256
  background: var(--wf-color-bg);
@@ -210,7 +288,7 @@ select {
210
288
  color: var(--wf-color-text);
211
289
  border: var(--wf-border-width) solid var(--wf-color-border);
212
290
  border-radius: var(--wf-radius);
213
- padding: var(--wf-space-sm) var(--wf-space);
291
+ padding: var(--wf-control-pad-y) var(--wf-space);
214
292
  }
215
293
 
216
294
  input:focus,
@@ -235,7 +313,8 @@ button {
235
313
  color: var(--wf-color-text);
236
314
  border: var(--wf-border-width) solid var(--wf-color-border);
237
315
  border-radius: var(--wf-radius);
238
- padding: var(--wf-space-sm) var(--wf-space-md);
316
+ padding: var(--wf-control-pad-y) var(--wf-space-md);
317
+ min-height: var(--wf-control-height);
239
318
  cursor: pointer;
240
319
  }
241
320
  button:hover {
@@ -243,6 +322,31 @@ button:hover {
243
322
  color: var(--wf-color-primary);
244
323
  }
245
324
 
325
+ /* 键盘焦点:button 与 [tabindex] 统一 focus ring(仅键盘触发,鼠标点击不闪) */
326
+ button:focus-visible,
327
+ [tabindex]:focus-visible {
328
+ outline: none;
329
+ box-shadow: var(--wf-focus-ring);
330
+ }
331
+
332
+ /* 触屏设备(coarse pointer):交互目标提升到 44px(Apple HIG / WCAG 2.5.8) */
333
+ @media (pointer: coarse) {
334
+ button,
335
+ [role="button"],
336
+ input,
337
+ textarea,
338
+ select,
339
+ .wf-card--clickable,
340
+ .wf-table-th--sortable,
341
+ .wf-accordion-summary,
342
+ .wf-tag-close,
343
+ .wf-checkbox,
344
+ .wf-switch,
345
+ .wf-radio {
346
+ min-height: 44px;
347
+ }
348
+ }
349
+
246
350
  h1, h2, h3, h4, h5, h6 {
247
351
  font-weight: var(--wf-font-weight-semibold);
248
352
  line-height: var(--wf-line-height-tight);
@@ -314,6 +418,18 @@ code {
314
418
  border-radius: var(--wf-radius-sm);
315
419
  }
316
420
 
421
+ /* ── 无障碍:尊重系统减弱动效偏好 ── */
422
+ @media (prefers-reduced-motion: reduce) {
423
+ *,
424
+ *::before,
425
+ *::after {
426
+ animation-duration: 0.01ms !important;
427
+ animation-iteration-count: 1 !important;
428
+ transition-duration: 0.01ms !important;
429
+ scroll-behavior: auto !important;
430
+ }
431
+ }
432
+
317
433
  /* stack — 纵向堆叠 */
318
434
  .wf-stack {
319
435
  display: flex;
@@ -558,7 +674,9 @@ code {
558
674
  min-height: 0;
559
675
  }
560
676
 
561
- /* text-align 对齐原语 */
677
+ /* 排版工具类 — 字号 / 色阶 / 字重 / 截断(零 CSS 用户自排版) */
678
+
679
+ /* ── text-align ── */
562
680
 
563
681
  .wf-text-left {
564
682
  text-align: left;
@@ -571,3 +689,50 @@ code {
571
689
  .wf-text-right {
572
690
  text-align: right;
573
691
  }
692
+
693
+ /* ── 字号 ── */
694
+
695
+ .wf-text-xs { font-size: var(--wf-font-size-xs); }
696
+ .wf-text-sm { font-size: var(--wf-font-size-sm); }
697
+ .wf-text-base { font-size: var(--wf-font-size-base); }
698
+ .wf-text-lg { font-size: var(--wf-font-size-lg); }
699
+ .wf-text-xl { font-size: var(--wf-font-size-xl); }
700
+ .wf-text-2xl { font-size: var(--wf-font-size-2xl); }
701
+ .wf-text-3xl { font-size: var(--wf-font-size-3xl); }
702
+ .wf-text-4xl { font-size: var(--wf-font-size-4xl); }
703
+ .wf-text-5xl { font-size: var(--wf-font-size-5xl); }
704
+
705
+ /* ── 色阶 ── */
706
+
707
+ .wf-text-secondary { color: var(--wf-color-text-secondary); }
708
+ .wf-text-tertiary { color: var(--wf-color-text-tertiary); }
709
+ .wf-text-disabled { color: var(--wf-color-text-disabled); }
710
+ .wf-text-brand { color: var(--wf-color-primary); }
711
+
712
+ /* ── 字重 ── */
713
+
714
+ .wf-text-medium { font-weight: var(--wf-font-weight-medium); }
715
+ .wf-text-semibold { font-weight: var(--wf-font-weight-semibold); }
716
+ .wf-text-bold { font-weight: var(--wf-font-weight-bold); }
717
+
718
+ /* ── 截断 ── */
719
+
720
+ .wf-truncate {
721
+ overflow: hidden;
722
+ text-overflow: ellipsis;
723
+ white-space: nowrap;
724
+ }
725
+
726
+ .wf-line-clamp-2 {
727
+ display: -webkit-box;
728
+ -webkit-line-clamp: 2;
729
+ -webkit-box-orient: vertical;
730
+ overflow: hidden;
731
+ }
732
+
733
+ .wf-line-clamp-3 {
734
+ display: -webkit-box;
735
+ -webkit-line-clamp: 3;
736
+ -webkit-box-orient: vertical;
737
+ overflow: hidden;
738
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "weifuwu",
3
3
  "type": "module",
4
- "version": "0.55.1",
4
+ "version": "0.55.3",
5
5
  "description": "AI SaaS framework — (req, ctx) => Response",
6
6
  "exports": {
7
7
  ".": {
@@ -38,6 +38,7 @@
38
38
  "release:dry": "node scripts/release.mjs --dry-run"
39
39
  },
40
40
  "dependencies": {
41
+ "esbuild": "^0.28.1",
41
42
  "graphql": "^16",
42
43
  "ws": "^8"
43
44
  },
@@ -62,7 +63,6 @@
62
63
  "@tailwindcss/postcss": "^4.3.3",
63
64
  "@types/node": "^25",
64
65
  "@types/ws": "^8",
65
- "esbuild": "^0.28.1",
66
66
  "ioredis": "^5.11.1",
67
67
  "jsdom": "^29.1.1",
68
68
  "postcss": "^8.5.19",