@fastspace/schema-form 0.0.1

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.
@@ -0,0 +1,539 @@
1
+ import { ControllerRenderProps } from 'react-hook-form';
2
+ import { default as default_2 } from 'react';
3
+ import { FieldValues } from 'react-hook-form';
4
+ import { GridSize } from '@mui/material/Grid';
5
+ import { JSX } from 'react/jsx-runtime';
6
+ import { Path } from 'react-hook-form';
7
+ import { ReactNode } from 'react';
8
+ import { UseFormReturn } from 'react-hook-form';
9
+ import * as v from 'valibot';
10
+
11
+ /** 自动完成(支持多选、远程搜索、分页) */
12
+ declare const AutocompleteWidget: WidgetComponent;
13
+ export { AutocompleteWidget }
14
+ export { AutocompleteWidget as SelectWidget }
15
+
16
+ /**
17
+ * 根据 ParsedSchema 和当前值动态构建完整的 Valibot schema
18
+ */
19
+ export declare function buildValibotSchema<T extends Record<string, unknown>>(parsed: ParsedSchema<T>, values: Record<string, unknown>): v.ObjectSchema<Record<string, v.BaseSchema<unknown, unknown, v.BaseIssue<unknown>>>, undefined>;
20
+
21
+ /** 复选框 */
22
+ export declare const CheckboxWidget: WidgetComponent;
23
+
24
+ /** 紧凑型表单字段样式 */
25
+ export declare const compactFieldStyles: {
26
+ "& .MuiInputBase-input": {
27
+ fontSize: number;
28
+ padding: string;
29
+ };
30
+ "& .MuiInputLabel-root": {
31
+ fontSize: number;
32
+ transform: string;
33
+ "&.MuiInputLabel-shrink": {
34
+ transform: string;
35
+ };
36
+ };
37
+ "& .MuiOutlinedInput-root": {
38
+ minHeight: string;
39
+ };
40
+ "& .MuiFormHelperText-root": {
41
+ marginTop: string;
42
+ fontSize: number;
43
+ };
44
+ "& .MuiInputLabel-asterisk": {
45
+ display: string;
46
+ };
47
+ };
48
+
49
+ /** 支持的组件类型 */
50
+ export declare type ComponentType = 'Text' | 'Number' | 'Password' | 'Textarea' | 'Select' | 'Autocomplete' | 'Checkbox' | 'Switch' | 'Radio' | 'Slider' | 'Rating' | 'Date' | 'Time' | 'DateTime' | 'Upload' | 'Hidden' | 'Custom' | 'Group' | 'FormList';
51
+
52
+ /** 复合条件:支持逻辑运算 */
53
+ export declare type CompoundCondition = {
54
+ and: ConditionExpression[];
55
+ } | {
56
+ or: ConditionExpression[];
57
+ } | {
58
+ not: ConditionExpression;
59
+ };
60
+
61
+ /**
62
+ * 计算所有字段的状态
63
+ */
64
+ export declare function computeAllFieldStates<T extends Record<string, unknown>>(parsed: ParsedSchema<T>, values: Record<string, unknown>, globalDisabled?: boolean, globalReadOnly?: boolean): FieldStatesMap;
65
+
66
+ /** 计算配置 */
67
+ export declare type ComputeConfig = {
68
+ /** 表达式字符串,如 "price * quantity" */
69
+ expr: string;
70
+ /** 依赖字段(可选,自动从 expr 解析) */
71
+ dependencies?: string[];
72
+ /** 小数精度(可选,默认为不处理) */
73
+ precision?: number;
74
+ /** 舍入模式(可选,默认为 'round' 四舍五入) */
75
+ roundMode?: 'round' | 'ceil' | 'floor';
76
+ };
77
+
78
+ /**
79
+ * 计算单个字段的状态
80
+ */
81
+ export declare function computeFieldState(field: FieldSchema, values: Record<string, unknown>, globalDisabled?: boolean, globalReadOnly?: boolean): FieldState;
82
+
83
+ /** 条件表达式:简单或复合或函数 */
84
+ export declare type ConditionExpression = SimpleCondition | CompoundCondition | ((values: Record<string, unknown>) => boolean);
85
+
86
+ /**
87
+ * 创建动态 resolver(用于 react-hook-form)
88
+ */
89
+ export declare function createDynamicResolver<T extends Record<string, unknown>>(parsed: ParsedSchema<T>): (values: Record<string, unknown>, _context: unknown, _options: unknown) => Promise<{
90
+ values: {
91
+ [x: string]: unknown;
92
+ };
93
+ errors: {};
94
+ } | {
95
+ values: {};
96
+ errors: Record<string, {
97
+ type: string;
98
+ message: string;
99
+ }>;
100
+ }>;
101
+
102
+ /** 自定义组件 */
103
+ export declare const CustomWidget: WidgetComponent;
104
+
105
+ /** 日期格式 */
106
+ export declare const DATE_FORMAT = "YYYY-MM-DD";
107
+
108
+ export declare const DATETIME_FORMAT = "YYYY-MM-DD HH:mm";
109
+
110
+ /** 日期时间选择 */
111
+ export declare const DateTimeWidget: WidgetComponent;
112
+
113
+ /** 日期选择 */
114
+ export declare const DateWidget: WidgetComponent;
115
+
116
+ /**
117
+ * 默认 Widget 映射表
118
+ */
119
+ export declare const defaultWidgets: Record<string, WidgetComponent>;
120
+
121
+ /**
122
+ * 求值条件表达式
123
+ * @param condition 条件表达式
124
+ * @param values 当前表单值
125
+ * @returns 条件是否满足
126
+ */
127
+ export declare function evaluateCondition(condition: ConditionExpression, values: Record<string, unknown>): boolean;
128
+
129
+ /**
130
+ * 从条件表达式中提取依赖字段
131
+ * @param condition 条件表达式
132
+ * @returns 依赖字段名数组
133
+ */
134
+ export declare function extractDependencies(condition: ConditionExpression): string[];
135
+
136
+ export declare const FieldRenderer: typeof FieldRendererInner;
137
+
138
+ /**
139
+ * 字段渲染器组件
140
+ * 负责根据 Schema 渲染单个表单字段
141
+ */
142
+ declare function FieldRendererInner<T extends FieldValues = FieldValues>({ field, index, values, form, disabled, readOnly, widgets, optionsMap, useGrid, }: FieldRendererProps<T>): JSX.Element | null;
143
+
144
+ export declare interface FieldRendererProps<T extends FieldValues = FieldValues> {
145
+ /** 字段 Schema */
146
+ field: FieldSchema<T>;
147
+ /** 字段索引 */
148
+ index: number;
149
+ /** 当前表单值 */
150
+ values: Record<string, unknown>;
151
+ /** 表单方法 */
152
+ form: UseFormReturn<T>;
153
+ /** 全局禁用 */
154
+ disabled?: boolean;
155
+ /** 全局只读 */
156
+ readOnly?: boolean;
157
+ /** Widget 映射 */
158
+ widgets: Record<string, WidgetComponent>;
159
+ /** 选项映射 */
160
+ optionsMap: Record<string, OptionItem[]>;
161
+ /** 是否使用 Grid 包装 */
162
+ useGrid?: boolean;
163
+ }
164
+
165
+ /** 字段 Schema 定义 */
166
+ export declare type FieldSchema<T extends FieldValues = FieldValues> = {
167
+ /** 字段名(对应表单数据的 key) */
168
+ name: Path<T>;
169
+ /** 组件类型 */
170
+ component: ComponentType | string;
171
+ /** 默认值 */
172
+ defaultValue?: unknown;
173
+ ui?: {
174
+ /** 标签 */
175
+ label?: string;
176
+ /** 占位符 */
177
+ placeholder?: string;
178
+ /** 帮助文本 */
179
+ helperText?: string;
180
+ /** 提示信息 */
181
+ tooltip?: string;
182
+ /** 选项(用于 Select/Radio 等) */
183
+ options?: OptionItem[];
184
+ /** 异步获取选项 */
185
+ optionRequest?: (values: T) => Promise<OptionItem[]>;
186
+ /** 远程搜索/分页配置 (Autocomplete 专用) */
187
+ remoteConfig?: RemoteConfig;
188
+ /** 组件透传属性 */
189
+ props?: Record<string, unknown>;
190
+ };
191
+ /** 列跨度(基于 MUI Grid),支持响应式 */
192
+ colSpan?: GridSize | {
193
+ xs?: GridSize;
194
+ sm?: GridSize;
195
+ md?: GridSize;
196
+ lg?: GridSize;
197
+ xl?: GridSize;
198
+ };
199
+ /** 强制从新行开始 */
200
+ newLine?: boolean;
201
+ /** 子字段定义 */
202
+ columns?: FieldSchema<T>[];
203
+ /** 最小行数 */
204
+ minItems?: number;
205
+ /** 最大行数 */
206
+ maxItems?: number;
207
+ /** 添加按钮文案 */
208
+ addText?: string;
209
+ /** 是否可拖拽排序 */
210
+ sortable?: boolean;
211
+ /** 是否可复制 */
212
+ copyable?: boolean;
213
+ /** 验证规则数组 */
214
+ rules?: ValidationRule[];
215
+ /** 条件显示 */
216
+ visibleWhen?: ConditionExpression;
217
+ /** 条件禁用 */
218
+ disabledWhen?: ConditionExpression;
219
+ /** 条件必填 */
220
+ requiredWhen?: ConditionExpression;
221
+ /** 只读 */
222
+ readonly?: boolean;
223
+ /** 禁用 */
224
+ disabled?: boolean;
225
+ /** 隐藏(不渲染) */
226
+ hidden?: boolean;
227
+ /** 自动计算配置 */
228
+ compute?: ComputeConfig;
229
+ /** 提交前转换 */
230
+ transform?: (value: unknown, values: T) => unknown;
231
+ /** 不参与提交 */
232
+ noSubmit?: boolean;
233
+ /** 依赖字段(用于触发重新计算/校验) */
234
+ dependencies?: string[];
235
+ };
236
+
237
+ /**
238
+ * 字段状态计算引擎
239
+ *
240
+ * 计算每个字段的运行时状态:
241
+ * - visible: 是否显示
242
+ * - disabled: 是否禁用
243
+ * - required: 是否必填
244
+ * - readonly: 是否只读
245
+ */
246
+ /** 单个字段的运行时状态 */
247
+ export declare type FieldState = {
248
+ /** 是否可见 */
249
+ visible: boolean;
250
+ /** 是否禁用 */
251
+ disabled: boolean;
252
+ /** 是否必填 */
253
+ required: boolean;
254
+ /** 是否只读 */
255
+ readonly: boolean;
256
+ };
257
+
258
+ /** 所有字段的状态映射 */
259
+ export declare type FieldStatesMap = Map<string, FieldState>;
260
+
261
+ /**
262
+ * FormList 动态列表组件
263
+ * 支持动态添加/删除/复制行
264
+ */
265
+ export declare const FormListWidget: WidgetComponent;
266
+
267
+ /**
268
+ * 获取字段的所有下游依赖(递归)
269
+ * 用于判断哪些字段需要重新计算
270
+ */
271
+ export declare function getDownstreamFields(fieldName: string, dependencyGraph: Map<string, Set<string>>): Set<string>;
272
+
273
+ /**
274
+ * 获取需要监听的依赖字段
275
+ * 用于构建 useWatch 的 name 数组
276
+ */
277
+ export declare function getWatchFields<T extends Record<string, unknown>>(parsed: ParsedSchema<T>): string[];
278
+
279
+ /**
280
+ * Grid 布局组件
281
+ * 使用 MUI Grid 实现响应式网格布局
282
+ */
283
+ export declare const GridLayout: ({ spacing, children }: GridLayoutProps) => JSX.Element;
284
+
285
+ export declare interface GridLayoutProps {
286
+ /** 间距 */
287
+ spacing?: number;
288
+ /** 子元素 */
289
+ children: ReactNode;
290
+ }
291
+
292
+ /**
293
+ * Group 分组组件
294
+ * 将多个字段组合在一行内显示
295
+ */
296
+ export declare const GroupWidget: WidgetComponent;
297
+
298
+ /** 隐藏字段 */
299
+ export declare const HiddenWidget: WidgetComponent;
300
+
301
+ export declare type LayoutConfig = {
302
+ /** 布局类型 */
303
+ type: 'grid' | 'stack';
304
+ /** 列数(仅 grid) */
305
+ columns?: number;
306
+ /** 区域定义(CSS Grid Area 风格) */
307
+ areas?: string[][];
308
+ /** 间距 */
309
+ spacing?: number;
310
+ };
311
+
312
+ /**
313
+ * 合并默认值与外部传入值
314
+ */
315
+ export declare function mergeDefaultValues<T extends Record<string, unknown>>(parsed: ParsedSchema<T>, externalValues?: Partial<T>): Partial<T>;
316
+
317
+ /** 数字输入 */
318
+ export declare const NumberWidget: WidgetComponent;
319
+
320
+ export declare type OptionItem = {
321
+ label: string;
322
+ value: string | number | boolean | null;
323
+ disabled?: boolean;
324
+ [key: string]: unknown;
325
+ };
326
+
327
+ export declare type ParsedSchema<T extends FieldValues = FieldValues> = {
328
+ /** 原始输入 */
329
+ input: SchemaInput<T>;
330
+ /** 字段索引(name -> FieldSchema) */
331
+ fieldMap: Map<string, FieldSchema<T>>;
332
+ /** 依赖图(field -> dependents) */
333
+ dependencyGraph: Map<string, Set<string>>;
334
+ /** 默认值 */
335
+ defaultValues: Partial<T>;
336
+ /** 扁平化的所有字段列表 (包含嵌套字段) */
337
+ allFields: FieldSchema<T>[];
338
+ };
339
+
340
+ /**
341
+ * 解析 Schema,生成预处理后的结构
342
+ */
343
+ export declare function parseSchema<T extends Record<string, unknown>>(input: SchemaInput<T>): ParsedSchema<T> & {
344
+ allFields: FieldSchema<T>[];
345
+ };
346
+
347
+ /** 密码输入 */
348
+ export declare const PasswordWidget: WidgetComponent;
349
+
350
+ /** 单选组 */
351
+ export declare const RadioWidget: WidgetComponent;
352
+
353
+ /** 评分 */
354
+ export declare const RatingWidget: WidgetComponent;
355
+
356
+ /** 远程加载配置 (分页/搜索) */
357
+ declare type RemoteConfig = {
358
+ /** 获取数据的函数 */
359
+ fetchOptions: (keyword: string, page: number, pageSize: number) => Promise<{
360
+ data: OptionItem[];
361
+ total: number;
362
+ hasMore: boolean;
363
+ }>;
364
+ /** 每页条数 */
365
+ pageSize?: number;
366
+ /** 搜索防抖时间 (ms) */
367
+ debounceTimeout?: number;
368
+ /** 最小搜索字符数 */
369
+ minSearchLength?: number;
370
+ /** 加载状态回调 */
371
+ onLoadingChange?: (loading: boolean) => void;
372
+ /** 根据 ID 获取选项 (用于回显) */
373
+ fetchById?: (value: string | number) => Promise<OptionItem | null>;
374
+ };
375
+
376
+ /** 导出 SchemaForm 组件 */
377
+ export declare const SchemaForm: <T extends FieldValues>(props: SchemaFormProps<T> & {
378
+ ref?: default_2.Ref<SchemaFormInstance<T>>;
379
+ }) => default_2.ReactElement;
380
+
381
+ export declare type SchemaFormInstance<T extends FieldValues = FieldValues> = UseFormReturn<T> & {
382
+ /** 提交表单 */
383
+ submit: () => Promise<void> | boolean;
384
+ /** 获取表单值(排除 noSubmit 字段) */
385
+ getFormValues: () => Partial<T>;
386
+ /** 批量设置值 */
387
+ setValues: (values: Partial<T>) => void;
388
+ };
389
+
390
+ declare type SchemaFormProps<T extends FieldValues = FieldValues> = {
391
+ /** Schema 定义 */
392
+ schema: SchemaInput<T>;
393
+ /** 默认值 */
394
+ defaultValues?: Partial<T>;
395
+ /** 提交回调 */
396
+ onSubmit?: (values: T) => void | Promise<void | boolean>;
397
+ /** 值变化回调 */
398
+ onValuesChange?: (values: T) => void;
399
+ /** 是否使用 Grid 布局 */
400
+ grid?: boolean;
401
+ /** 全局只读 */
402
+ readOnly?: boolean;
403
+ /** 全局禁用 */
404
+ disabled?: boolean;
405
+ /** 自定义控件 */
406
+ widgets?: Record<string, WidgetComponent<T>>;
407
+ /** 子元素 */
408
+ children?: React.ReactNode;
409
+ /** 间距 */
410
+ spacing?: number;
411
+ };
412
+
413
+ export declare type SchemaInput<T extends FieldValues = FieldValues> = {
414
+ /** 字段定义 */
415
+ fields: FieldSchema<T>[];
416
+ /** 布局配置(可选,默认使用 colSpan 响应式布局) */
417
+ layout?: LayoutConfig;
418
+ };
419
+
420
+ /** 简单条件:单字段比较 */
421
+ export declare type SimpleCondition = {
422
+ field: string;
423
+ eq?: unknown;
424
+ ne?: unknown;
425
+ gt?: number;
426
+ gte?: number;
427
+ lt?: number;
428
+ lte?: number;
429
+ in?: unknown[];
430
+ notIn?: unknown[];
431
+ empty?: boolean;
432
+ notEmpty?: boolean;
433
+ };
434
+
435
+ /** 滑块 */
436
+ export declare const SliderWidget: WidgetComponent;
437
+
438
+ /**
439
+ * Stack 布局组件
440
+ * 使用 MUI Stack 实现垂直堆叠布局
441
+ */
442
+ export declare const StackLayout: ({ spacing, children }: StackLayoutProps) => JSX.Element;
443
+
444
+ export declare interface StackLayoutProps {
445
+ /** 间距 */
446
+ spacing?: number;
447
+ /** 子元素 */
448
+ children: ReactNode;
449
+ }
450
+
451
+ /** 开关 */
452
+ export declare const SwitchWidget: WidgetComponent;
453
+
454
+ /** 多行文本 */
455
+ export declare const TextareaWidget: WidgetComponent;
456
+
457
+ /** 文本输入 */
458
+ export declare const TextWidget: WidgetComponent;
459
+
460
+ /** 时间选择 */
461
+ export declare const TimeWidget: WidgetComponent;
462
+
463
+ /** 基础验证规则 */
464
+ export declare type ValidationRule = {
465
+ type: 'required';
466
+ message?: string;
467
+ } | {
468
+ type: 'minLength';
469
+ value: number;
470
+ message?: string;
471
+ } | {
472
+ type: 'maxLength';
473
+ value: number;
474
+ message?: string;
475
+ } | {
476
+ type: 'min';
477
+ value: number;
478
+ message?: string;
479
+ } | {
480
+ type: 'max';
481
+ value: number;
482
+ message?: string;
483
+ } | {
484
+ type: 'pattern';
485
+ value: string | RegExp;
486
+ message?: string;
487
+ } | {
488
+ type: 'email';
489
+ message?: string;
490
+ } | {
491
+ type: 'url';
492
+ message?: string;
493
+ } | {
494
+ type: 'custom';
495
+ validate: (value: unknown, values: unknown) => boolean | string;
496
+ } | {
497
+ type: 'array';
498
+ minItems?: number;
499
+ maxItems?: number;
500
+ message?: string;
501
+ };
502
+
503
+ /** Widget 组件类型 */
504
+ export declare type WidgetComponent<T extends FieldValues = FieldValues> = React.ComponentType<WidgetProps<T>>;
505
+
506
+ export declare type WidgetProps<T extends FieldValues = FieldValues> = {
507
+ /** React Hook Form 字段对象 */
508
+ field: ControllerRenderProps<T>;
509
+ /** 标签 */
510
+ label?: string;
511
+ /** 是否有错误 */
512
+ error?: boolean;
513
+ /** 帮助/错误文本 */
514
+ helperText?: React.ReactNode;
515
+ /** 选项(用于 Select 等) */
516
+ options?: OptionItem[];
517
+ /** 透传属性 */
518
+ fieldProps?: Record<string, unknown> & {
519
+ disabled?: boolean;
520
+ required?: boolean;
521
+ readOnly?: boolean;
522
+ };
523
+ /** 表单实例 */
524
+ form?: UseFormReturn<T>;
525
+ /** 字段 Schema(用于 Group/FormList) */
526
+ schema?: FieldSchema<T>;
527
+ /** Widget 映射(用于嵌套渲染) */
528
+ widgets?: Record<string, WidgetComponent<T>>;
529
+ /** 选项映射(用于嵌套渲染) */
530
+ optionsMap?: Record<string, OptionItem[]>;
531
+ /** 全局禁用 */
532
+ globalDisabled?: boolean;
533
+ /** 全局只读 */
534
+ globalReadOnly?: boolean;
535
+ /** 当前表单值 (优化) */
536
+ values?: Record<string, unknown>;
537
+ };
538
+
539
+ export { }