@zhang_jifan/fanui 2.1.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 (127) hide show
  1. package/ACCESSIBILITY.md +61 -0
  2. package/CHANGELOG.md +112 -0
  3. package/COMMERCIAL-LICENSE.md +71 -0
  4. package/DESIGN-SYSTEM.md +294 -0
  5. package/LICENSE +661 -0
  6. package/README.md +348 -0
  7. package/USAGE.md +1926 -0
  8. package/_index.scss +20 -0
  9. package/dist/fanui.cjs +15 -0
  10. package/dist/fanui.css +28209 -0
  11. package/dist/fanui.d.ts +353 -0
  12. package/dist/fanui.esm.js +71 -0
  13. package/dist/fanui.js +4782 -0
  14. package/dist/fanui.min.css +1 -0
  15. package/dist/fanui.mjs +71 -0
  16. package/dist/modules/fanui-advanced.css +830 -0
  17. package/dist/modules/fanui-advanced.min.css +129 -0
  18. package/dist/modules/fanui-alert.css +575 -0
  19. package/dist/modules/fanui-alert.min.css +122 -0
  20. package/dist/modules/fanui-badge.css +426 -0
  21. package/dist/modules/fanui-badge.min.css +77 -0
  22. package/dist/modules/fanui-base.css +1394 -0
  23. package/dist/modules/fanui-base.min.css +236 -0
  24. package/dist/modules/fanui-blog.css +762 -0
  25. package/dist/modules/fanui-blog.min.css +108 -0
  26. package/dist/modules/fanui-button.css +526 -0
  27. package/dist/modules/fanui-button.min.css +56 -0
  28. package/dist/modules/fanui-card.css +291 -0
  29. package/dist/modules/fanui-card.min.css +52 -0
  30. package/dist/modules/fanui-choice.css +539 -0
  31. package/dist/modules/fanui-choice.min.css +83 -0
  32. package/dist/modules/fanui-dashboard.css +1057 -0
  33. package/dist/modules/fanui-dashboard.min.css +160 -0
  34. package/dist/modules/fanui-data.css +687 -0
  35. package/dist/modules/fanui-data.min.css +125 -0
  36. package/dist/modules/fanui-feedback.css +432 -0
  37. package/dist/modules/fanui-feedback.min.css +79 -0
  38. package/dist/modules/fanui-form.css +779 -0
  39. package/dist/modules/fanui-form.min.css +123 -0
  40. package/dist/modules/fanui-glass.css +497 -0
  41. package/dist/modules/fanui-glass.min.css +46 -0
  42. package/dist/modules/fanui-input-plus.css +799 -0
  43. package/dist/modules/fanui-input-plus.min.css +124 -0
  44. package/dist/modules/fanui-interactive.css +960 -0
  45. package/dist/modules/fanui-interactive.min.css +138 -0
  46. package/dist/modules/fanui-layout.css +4399 -0
  47. package/dist/modules/fanui-layout.min.css +1172 -0
  48. package/dist/modules/fanui-marketing.css +1125 -0
  49. package/dist/modules/fanui-marketing.min.css +144 -0
  50. package/dist/modules/fanui-nav.css +458 -0
  51. package/dist/modules/fanui-nav.min.css +76 -0
  52. package/dist/modules/fanui-overlay.css +547 -0
  53. package/dist/modules/fanui-overlay.min.css +91 -0
  54. package/dist/modules/fanui-table.css +290 -0
  55. package/dist/modules/fanui-table.min.css +62 -0
  56. package/dist/modules/fanui-tabs.css +333 -0
  57. package/dist/modules/fanui-tabs.min.css +58 -0
  58. package/dist/modules/fanui-themes.css +2728 -0
  59. package/dist/modules/fanui-themes.min.css +40 -0
  60. package/dist/modules/fanui-tokens.css +587 -0
  61. package/dist/modules/fanui-tokens.min.css +3 -0
  62. package/dist/modules/fanui-utilities.css +6557 -0
  63. package/dist/modules/fanui-utilities.min.css +1762 -0
  64. package/dist/modules/sizes.json +103 -0
  65. package/docs/MIGRATION-v2.md +179 -0
  66. package/examples/01-script-tag.html +149 -0
  67. package/examples/02-react/README.md +39 -0
  68. package/examples/02-react/index.html +12 -0
  69. package/examples/02-react/package.json +20 -0
  70. package/examples/02-react/src/App.jsx +108 -0
  71. package/examples/02-react/src/main.jsx +13 -0
  72. package/examples/02-react/src/useFanUI.js +87 -0
  73. package/examples/02-react/vite.config.js +6 -0
  74. package/examples/03-vue3/README.md +67 -0
  75. package/examples/03-vue3/index.html +12 -0
  76. package/examples/03-vue3/package.json +19 -0
  77. package/examples/03-vue3/src/App.vue +93 -0
  78. package/examples/03-vue3/src/main.js +8 -0
  79. package/examples/03-vue3/src/useFanUI.js +85 -0
  80. package/examples/03-vue3/vite.config.js +6 -0
  81. package/examples/04-vue2-cdn.html +93 -0
  82. package/examples/README.md +34 -0
  83. package/package.json +127 -0
  84. package/src/_functions.scss +319 -0
  85. package/src/_mixins.scss +1202 -0
  86. package/src/_tokens.scss +180 -0
  87. package/src/_variables.scss +491 -0
  88. package/src/base/_animations.scss +210 -0
  89. package/src/base/_reset.scss +359 -0
  90. package/src/base/_rtl.scss +133 -0
  91. package/src/base/_typography.scss +353 -0
  92. package/src/components/_advanced.scss +763 -0
  93. package/src/components/_alert.scss +322 -0
  94. package/src/components/_badge.scss +279 -0
  95. package/src/components/_blog.scss +693 -0
  96. package/src/components/_button.scss +351 -0
  97. package/src/components/_capabilities.scss +463 -0
  98. package/src/components/_card.scss +281 -0
  99. package/src/components/_choice.scss +444 -0
  100. package/src/components/_dashboard.scss +950 -0
  101. package/src/components/_data.scss +618 -0
  102. package/src/components/_feedback.scss +403 -0
  103. package/src/components/_form.scss +408 -0
  104. package/src/components/_glass.scss +374 -0
  105. package/src/components/_input-plus.scss +730 -0
  106. package/src/components/_interactive.scss +885 -0
  107. package/src/components/_marketing.scss +982 -0
  108. package/src/components/_nav.scss +480 -0
  109. package/src/components/_overlay.scss +517 -0
  110. package/src/components/_table.scss +276 -0
  111. package/src/components/_tabs.scss +338 -0
  112. package/src/fanui.d.ts +353 -0
  113. package/src/fanui.js +4782 -0
  114. package/src/fanui.scss +79 -0
  115. package/src/glass/_switches.scss +36 -0
  116. package/src/glass/_tokens.scss +259 -0
  117. package/src/layout/_container.scss +111 -0
  118. package/src/layout/_flex.scss +164 -0
  119. package/src/layout/_grid.scss +180 -0
  120. package/src/themes/_accents.scss +201 -0
  121. package/src/themes/_palettes.scss +180 -0
  122. package/src/utilities/_borders.scss +104 -0
  123. package/src/utilities/_display.scss +145 -0
  124. package/src/utilities/_effects.scss +210 -0
  125. package/src/utilities/_sizing.scss +123 -0
  126. package/src/utilities/_spacing.scss +118 -0
  127. package/src/utilities/_texture.scss +323 -0
package/src/fanui.d.ts ADDED
@@ -0,0 +1,353 @@
1
+ /* =============================================================================
2
+ * fanUI v2.1.0 · TypeScript 类型声明
3
+ * -----------------------------------------------------------------------------
4
+ * tsconfig 中配置 "types": ["@zhang_jifan/fanui"] 或在代码里:
5
+ * import FanUI from "@zhang_jifan/fanui";
6
+ * FanUI.theme.setAccent("violet");
7
+ * ========================================================================== */
8
+
9
+ /** 12 套内置主题色名,或任意自定义主题名(createAccent 生成) */
10
+ export type AccentName =
11
+ | "cyan" | "sky" | "blue" | "indigo" | "violet" | "purple"
12
+ | "pink" | "rose" | "red" | "orange" | "emerald" | "teal" | (string & {});
13
+
14
+ /** 明暗模式:light / dark / 跟随系统 */
15
+ export type ThemeMode = "light" | "dark" | "auto";
16
+
17
+ /** 液态玻璃厚度预设 */
18
+ export type GlassPreset = "thin" | "regular" | "thick" | "ultra" | "lens";
19
+
20
+ /** 主题快照(持久化到 localStorage 的完整状态) */
21
+ export interface ThemeSnapshot {
22
+ accent: AccentName;
23
+ mode: ThemeMode;
24
+ /** mode 为 auto 时解析出的实际模式 */
25
+ effectiveMode: "light" | "dark";
26
+ glass: boolean;
27
+ glassPreset: GlassPreset;
28
+ glassIntensity: number;
29
+ }
30
+
31
+ /**
32
+ * 每套主题色在指定模式下解析出的关键令牌。
33
+ * 数据源是 CSS 自定义属性 —— `available` 为 false 表示样式表尚未加载,
34
+ * 此时各字段为空串(并在控制台给出一次性告警)。
35
+ */
36
+ export interface AccentColors {
37
+ primary: string;
38
+ primaryFg: string;
39
+ vivid: string;
40
+ vivid2: string;
41
+ accent: string;
42
+ accentVivid: string;
43
+ available: boolean;
44
+ }
45
+
46
+ export interface CreateAccentOptions {
47
+ /** 主题名,缺省自动命名为 "custom-<hex>" */
48
+ name?: string;
49
+ }
50
+
51
+ export interface GlassOptions {
52
+ preset?: GlassPreset;
53
+ /** 强度 0–2,最终 = preset.intensity × 该值 */
54
+ intensity?: number;
55
+ }
56
+
57
+ export interface ThemeAPI {
58
+ /** 当前主题色名 */
59
+ getAccent(): AccentName;
60
+ /** 运行时切换主题色(全站即时生效并持久化) */
61
+ setAccent(name: AccentName): void;
62
+ /** 循环切换到下一套内置主题色 */
63
+ nextAccent(): void;
64
+ /** 12 套内置主题色元数据 */
65
+ readonly accents: ReadonlyArray<{ key: AccentName; label: string; en: string; vibe: string }>;
66
+ /** 读取某主题色在某模式下的角色令牌 */
67
+ readAccentColors(accent: AccentName, mode?: ThemeMode): AccentColors;
68
+ /** 明暗模式 */
69
+ getMode(): ThemeMode;
70
+ setMode(mode: ThemeMode): void;
71
+ /** 实际生效的模式(auto 已解析) */
72
+ getEffectiveMode(): "light" | "dark";
73
+ cycleMode(): void;
74
+ toggleMode(): void;
75
+ /** 液态玻璃 */
76
+ getGlass(): boolean;
77
+ setGlass(on: boolean, options?: GlassOptions): void;
78
+ toggleGlass(): void;
79
+ setGlassPreset(preset: GlassPreset): void;
80
+ setGlassIntensity(intensity: number): void;
81
+ getGlassPreset(): GlassPreset;
82
+ getGlassIntensity(): number;
83
+ /** 任意品牌色 → 合规主题(对比度自动择优,白字恒 ≥ 4.5:1);返回主题名 */
84
+ createAccent(hex: string, options?: CreateAccentOptions): AccentName;
85
+ /** 完整状态快照 / 恢复 */
86
+ snapshot(): ThemeSnapshot;
87
+ /**
88
+ * 恢复主题状态。
89
+ * @param snapshot 传入 `snapshot()` 的返回值即可往返还原(保存用户预设 / 撤销 / SSR 注水);
90
+ * 不传则读取 localStorage 持久化偏好。
91
+ * @returns 生效后的完整状态
92
+ */
93
+ restore(snapshot?: Partial<ThemeSnapshot>): ThemeSnapshot;
94
+ }
95
+
96
+ export interface ToastAPI {
97
+ show(message: string, options?: { type?: "info" | "success" | "warning" | "error"; duration?: number; title?: string }): void;
98
+ info(message: string): void;
99
+ success(message: string): void;
100
+ warning(message: string): void;
101
+ error(message: string): void;
102
+ }
103
+
104
+ export interface OverlayInstance {
105
+ open(): OverlayInstance;
106
+ close(): OverlayInstance;
107
+ toggle(): OverlayInstance;
108
+ isOpen(): boolean;
109
+ destroy(): void;
110
+ readonly el: HTMLElement;
111
+ }
112
+
113
+ export interface OverlayOptions {
114
+ onClose?: () => void;
115
+ onOpen?: () => void;
116
+ }
117
+
118
+ export interface CommandItem {
119
+ group?: string;
120
+ id: string;
121
+ icon?: string;
122
+ title: string;
123
+ desc?: string;
124
+ keywords?: string;
125
+ hint?: string;
126
+ disabled?: boolean;
127
+ }
128
+
129
+ export interface CommandInstance extends OverlayInstance {
130
+ setItems(items: CommandItem[]): void;
131
+ getItems(): CommandItem[];
132
+ }
133
+
134
+ export interface LoadingBarAPI {
135
+ start(): LoadingBarAPI;
136
+ /** 设置确定进度 0–100 */
137
+ set(progress: number): LoadingBarAPI;
138
+ /** 不确定态(进度未知,如路由跳转) */
139
+ indeterminate(): LoadingBarAPI;
140
+ done(): LoadingBarAPI;
141
+ isLoading(): boolean;
142
+ }
143
+
144
+ export interface DatePickerInstance {
145
+ readonly el: HTMLInputElement;
146
+ open(): void;
147
+ close(): void;
148
+ value(): string;
149
+ setValue(value: string | Date | null): void;
150
+ destroy(): void;
151
+ }
152
+
153
+ export interface TimePickerInstance {
154
+ readonly el: HTMLInputElement;
155
+ open(): void;
156
+ close(): void;
157
+ value(): string;
158
+ setValue(value: string): void;
159
+ }
160
+
161
+ export interface ColorPickerInstance {
162
+ readonly el: HTMLInputElement;
163
+ open(): void;
164
+ close(): void;
165
+ value(): string;
166
+ setValue(hex: string): void;
167
+ }
168
+
169
+ export interface CascaderNode {
170
+ label: string;
171
+ value?: string;
172
+ children?: CascaderNode[];
173
+ disabled?: boolean;
174
+ }
175
+
176
+ export interface CascaderInstance {
177
+ readonly el: HTMLElement;
178
+ open(): void;
179
+ close(): void;
180
+ value(): Array<string | undefined>;
181
+ labels(): string[];
182
+ setValue(values: string[]): void;
183
+ }
184
+
185
+ export interface TreeNode {
186
+ label: string;
187
+ value?: string;
188
+ icon?: string;
189
+ badge?: string;
190
+ children?: TreeNode[];
191
+ }
192
+
193
+ export interface TreeInstance {
194
+ readonly el: HTMLElement;
195
+ getChecked(): string[];
196
+ checkAll(checked: boolean): void;
197
+ expandAll(expanded: boolean): void;
198
+ }
199
+
200
+ export interface TransferItem {
201
+ label: string;
202
+ value?: string;
203
+ tag?: string;
204
+ disabled?: boolean;
205
+ }
206
+
207
+ export interface TransferInstance {
208
+ readonly el: HTMLElement;
209
+ value(): string[];
210
+ set(values: string[]): void;
211
+ }
212
+
213
+ export interface I18NAPI {
214
+ readonly locale: string;
215
+ /** 取词:t("today")、t("selectedCount", { n: 3 }) */
216
+ t(key: string, vars?: Record<string, string | number>): string;
217
+ setLocale(locale: string): I18NAPI;
218
+ register(locale: string, dict: Record<string, unknown>): I18NAPI;
219
+ }
220
+
221
+ export interface FormatAPI {
222
+ date(value: string | number | Date, opts?: Intl.DateTimeFormatOptions): string;
223
+ time(value: string | number | Date, opts?: Intl.DateTimeFormatOptions): string;
224
+ number(value: number, opts?: Intl.NumberFormatOptions): string;
225
+ currency(value: number, currency?: string): string;
226
+ }
227
+
228
+ export interface StudioAPI {
229
+ open(): void;
230
+ close(): void;
231
+ toggle(): void;
232
+ isOpen(): boolean;
233
+ refresh(): void;
234
+ destroy(): void;
235
+ }
236
+
237
+ export interface A11yFocusableOptions {
238
+ /** 默认 "pre, .fanui-scroll-area, [data-fanui-scrollable]" */
239
+ selector?: string;
240
+ /** 补充的可访问名,默认 "可滚动区域,使用方向键滚动" */
241
+ label?: string;
242
+ }
243
+
244
+ export interface A11yAPI {
245
+ /**
246
+ * 给「确实可滚动、但内部没有可聚焦内容」的容器补 tabindex + region 角色 + 可访问名,
247
+ * 解决 axe 的 scrollable-region-focusable。幂等,重复调用不会重复标记。
248
+ * @returns 本次处理的元素个数
249
+ */
250
+ focusableScrollables(scope?: Element | Document, opts?: A11yFocusableOptions): number;
251
+ init(scope?: Element | Document): void;
252
+ }
253
+
254
+ export interface InitResult {
255
+ destroyed: boolean;
256
+ }
257
+
258
+ declare const FanUI: {
259
+ readonly version: string;
260
+ /** CSS 类名前缀(恒为 "fanui") */
261
+ readonly prefix: string;
262
+
263
+ /** 主题引擎:12 色 × 明暗 × 玻璃,三条正交运行时轴 */
264
+ theme: ThemeAPI;
265
+ /** 主题工作台(右下角悬浮调参面板) */
266
+ studio: { mount(options?: { defaultOpen?: boolean }): StudioAPI; api(): StudioAPI | null };
267
+ /** 顶部全局加载条 */
268
+ loadingBar: LoadingBarAPI;
269
+
270
+ modal: Record<string, unknown>;
271
+ /** 浮层工厂:模态框 / 抽屉 / Sheet 通用 */
272
+ overlay(target: string | HTMLElement, options?: OverlayOptions): OverlayInstance;
273
+ toast: ToastAPI;
274
+
275
+ tabs(target: string | HTMLElement): InitResult;
276
+ dropdown(target: string | HTMLElement): InitResult;
277
+ collapse(target: string | HTMLElement): InitResult;
278
+ form(target: string | HTMLElement): InitResult;
279
+ /** 注意:switch 是 JS 保留字,ESM 具名导入请用 `switchModule` */
280
+ switch(target: string | HTMLElement): InitResult;
281
+ command(target: string | HTMLElement, options?: { items?: CommandItem[] }): CommandInstance;
282
+ carousel(target: string | HTMLElement): InitResult;
283
+ rate(target: string | HTMLElement): InitResult;
284
+ tags(target: string | HTMLElement): InitResult;
285
+ stepper(target: string | HTMLElement): InitResult;
286
+ pin(target: string | HTMLElement): InitResult;
287
+ swatch(target: string | HTMLElement): InitResult;
288
+ upload(target: string | HTMLElement): InitResult;
289
+ combobox(target: string | HTMLElement): InitResult;
290
+ kanban(target: string | HTMLElement): InitResult;
291
+ notify(target: string | HTMLElement): InitResult;
292
+ filterBar(target: string | HTMLElement): InitResult;
293
+
294
+ /** 进阶数据录入组件(data-fanui-* 可声明式自动初始化) */
295
+ datePicker(target: string | HTMLElement, options?: { range?: boolean }): DatePickerInstance;
296
+ timePicker(target: string | HTMLElement, options?: { step?: number }): TimePickerInstance;
297
+ colorPicker(target: string | HTMLElement, options?: { asTheme?: boolean }): ColorPickerInstance;
298
+ cascader(target: string | HTMLElement, options?: { items?: CascaderNode[]; searchable?: boolean }): CascaderInstance;
299
+ tree(target: string | HTMLElement, options?: { items?: TreeNode[]; checkable?: boolean }): TreeInstance;
300
+ transfer(target: string | HTMLElement, options?: { items?: TransferItem[]; value?: string[] }): TransferInstance;
301
+
302
+ /** i18n 词表与 Intl 格式化层 */
303
+ i18n: I18NAPI;
304
+ format: FormatAPI;
305
+
306
+ /** 无障碍增强(随 init 自动执行,也可手动调用) */
307
+ a11y: A11yAPI;
308
+
309
+ scroll: Record<string, unknown>;
310
+ counter(target: string | HTMLElement): InitResult;
311
+ ripple(host: HTMLElement, event?: MouseEvent): void;
312
+ copy(target: string | HTMLElement): InitResult;
313
+ track: Record<string, unknown>;
314
+
315
+ lockScroll(): void;
316
+ unlockScroll(): void;
317
+ /** 手动初始化(默认 DOMContentLoaded 自动执行;data-fanui-auto="false" 可关闭) */
318
+ init(scope?: ParentNode): void;
319
+ $(selector: string, scope?: ParentNode): HTMLElement | null;
320
+ $$(selector: string, scope?: ParentNode): HTMLElement[];
321
+ };
322
+
323
+ export default FanUI;
324
+ export { FanUI };
325
+
326
+ /** 模块级自定义事件(bubbles: true) */
327
+ export interface FanUIEventMap {
328
+ "fanui:accentchange": CustomEvent<{ accent: AccentName }>;
329
+ "fanui:themechange": CustomEvent<{ mode: ThemeMode }>;
330
+ "fanui:glasschange": CustomEvent<{ glass: boolean }>;
331
+ "fanui:localechange": CustomEvent<{ locale: string }>;
332
+ "fanui:command": CustomEvent<{ id: string }>;
333
+ "fanui:datechange": CustomEvent<{ value: string; start: Date | null; end: Date | null }>;
334
+ "fanui:timechange": CustomEvent<{ value: string }>;
335
+ "fanui:colorchange": CustomEvent<{ value: string }>;
336
+ "fanui:cascaderchange": CustomEvent<{ labels: string[]; value: Array<string | undefined> }>;
337
+ "fanui:treechange": CustomEvent<string[]>;
338
+ "fanui:treeselect": CustomEvent<{ value: string; label: string }>;
339
+ "fanui:transferchange": CustomEvent<{ value: string[] }>;
340
+ }
341
+
342
+ declare global {
343
+ interface Document {
344
+ addEventListener<K extends keyof FanUIEventMap>(
345
+ type: K,
346
+ listener: (ev: FanUIEventMap[K]) => void,
347
+ options?: boolean | AddEventListenerOptions
348
+ ): void;
349
+ }
350
+ interface Window {
351
+ FanUI: typeof FanUI;
352
+ }
353
+ }