@tianyr/schema-antd 0.0.0-stage → 0.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.
- package/LICENSE +21 -0
- package/README.md +158 -2
- package/dist/SchemaField.d.ts +15 -0
- package/dist/SchemaField.d.ts.map +1 -0
- package/dist/SchemaField.js +107 -0
- package/dist/SchemaField.js.map +1 -0
- package/dist/SchemaForm.d.ts +22 -0
- package/dist/SchemaForm.d.ts.map +1 -0
- package/dist/SchemaForm.js +19 -0
- package/dist/SchemaForm.js.map +1 -0
- package/dist/TableFooter.d.ts +38 -0
- package/dist/TableFooter.d.ts.map +1 -0
- package/dist/TableFooter.js +16 -0
- package/dist/TableFooter.js.map +1 -0
- package/dist/app-select/AppSelect.d.ts +3 -0
- package/dist/app-select/AppSelect.d.ts.map +1 -0
- package/dist/app-select/AppSelect.js +56 -0
- package/dist/app-select/AppSelect.js.map +1 -0
- package/dist/app-select/AppSelectDisplay.d.ts +3 -0
- package/dist/app-select/AppSelectDisplay.d.ts.map +1 -0
- package/dist/app-select/AppSelectDisplay.js +39 -0
- package/dist/app-select/AppSelectDisplay.js.map +1 -0
- package/dist/app-select/cache.d.ts +26 -0
- package/dist/app-select/cache.d.ts.map +1 -0
- package/dist/app-select/cache.js +82 -0
- package/dist/app-select/cache.js.map +1 -0
- package/dist/app-select/hooks.d.ts +56 -0
- package/dist/app-select/hooks.d.ts.map +1 -0
- package/dist/app-select/hooks.js +322 -0
- package/dist/app-select/hooks.js.map +1 -0
- package/dist/app-select/index.d.ts +7 -0
- package/dist/app-select/index.d.ts.map +1 -0
- package/dist/app-select/index.js +6 -0
- package/dist/app-select/index.js.map +1 -0
- package/dist/app-select/register.d.ts +2 -0
- package/dist/app-select/register.d.ts.map +1 -0
- package/dist/app-select/register.js +10 -0
- package/dist/app-select/register.js.map +1 -0
- package/dist/app-select/sources.d.ts +20 -0
- package/dist/app-select/sources.d.ts.map +1 -0
- package/dist/app-select/sources.js +59 -0
- package/dist/app-select/sources.js.map +1 -0
- package/dist/app-select/types.d.ts +68 -0
- package/dist/app-select/types.d.ts.map +1 -0
- package/dist/app-select/types.js +2 -0
- package/dist/app-select/types.js.map +1 -0
- package/dist/app-select/utils.d.ts +30 -0
- package/dist/app-select/utils.d.ts.map +1 -0
- package/dist/app-select/utils.js +76 -0
- package/dist/app-select/utils.js.map +1 -0
- package/dist/editable-table/EditableTable.d.ts +3 -0
- package/dist/editable-table/EditableTable.d.ts.map +1 -0
- package/dist/editable-table/EditableTable.js +499 -0
- package/dist/editable-table/EditableTable.js.map +1 -0
- package/dist/editable-table/dirty.d.ts +17 -0
- package/dist/editable-table/dirty.d.ts.map +1 -0
- package/dist/editable-table/dirty.js +72 -0
- package/dist/editable-table/dirty.js.map +1 -0
- package/dist/editable-table/index.d.ts +4 -0
- package/dist/editable-table/index.d.ts.map +1 -0
- package/dist/editable-table/index.js +3 -0
- package/dist/editable-table/index.js.map +1 -0
- package/dist/editable-table/types.d.ts +109 -0
- package/dist/editable-table/types.d.ts.map +1 -0
- package/dist/editable-table/types.js +2 -0
- package/dist/editable-table/types.js.map +1 -0
- package/dist/env.d.ts +3 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/env.js +11 -0
- package/dist/env.js.map +1 -0
- package/dist/form/FormRuntimeHost.d.ts +39 -0
- package/dist/form/FormRuntimeHost.d.ts.map +1 -0
- package/dist/form/FormRuntimeHost.js +184 -0
- package/dist/form/FormRuntimeHost.js.map +1 -0
- package/dist/form/SchemaFormField.d.ts +15 -0
- package/dist/form/SchemaFormField.d.ts.map +1 -0
- package/dist/form/SchemaFormField.js +142 -0
- package/dist/form/SchemaFormField.js.map +1 -0
- package/dist/form/derive.d.ts +33 -0
- package/dist/form/derive.d.ts.map +1 -0
- package/dist/form/derive.js +59 -0
- package/dist/form/derive.js.map +1 -0
- package/dist/form/namePath.d.ts +12 -0
- package/dist/form/namePath.d.ts.map +1 -0
- package/dist/form/namePath.js +33 -0
- package/dist/form/namePath.js.map +1 -0
- package/dist/full-editable-table/EditableCell.d.ts +12 -0
- package/dist/full-editable-table/EditableCell.d.ts.map +1 -0
- package/dist/full-editable-table/EditableCell.js +8 -0
- package/dist/full-editable-table/EditableCell.js.map +1 -0
- package/dist/full-editable-table/EditableRow.d.ts +8 -0
- package/dist/full-editable-table/EditableRow.d.ts.map +1 -0
- package/dist/full-editable-table/EditableRow.js +23 -0
- package/dist/full-editable-table/EditableRow.js.map +1 -0
- package/dist/full-editable-table/FullEditableTable.d.ts +3 -0
- package/dist/full-editable-table/FullEditableTable.d.ts.map +1 -0
- package/dist/full-editable-table/FullEditableTable.js +384 -0
- package/dist/full-editable-table/FullEditableTable.js.map +1 -0
- package/dist/full-editable-table/context.d.ts +4 -0
- package/dist/full-editable-table/context.d.ts.map +1 -0
- package/dist/full-editable-table/context.js +6 -0
- package/dist/full-editable-table/context.js.map +1 -0
- package/dist/full-editable-table/index.d.ts +3 -0
- package/dist/full-editable-table/index.d.ts.map +1 -0
- package/dist/full-editable-table/index.js +2 -0
- package/dist/full-editable-table/index.js.map +1 -0
- package/dist/full-editable-table/types.d.ts +95 -0
- package/dist/full-editable-table/types.d.ts.map +1 -0
- package/dist/full-editable-table/types.js +2 -0
- package/dist/full-editable-table/types.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/read.d.ts +14 -0
- package/dist/read.d.ts.map +1 -0
- package/dist/read.js +151 -0
- package/dist/read.js.map +1 -0
- package/dist/registry.d.ts +24 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +49 -0
- package/dist/registry.js.map +1 -0
- package/dist/rowMerge.d.ts +2 -0
- package/dist/rowMerge.d.ts.map +1 -0
- package/dist/rowMerge.js +32 -0
- package/dist/rowMerge.js.map +1 -0
- package/dist/tableScroll.d.ts +10 -0
- package/dist/tableScroll.d.ts.map +1 -0
- package/dist/tableScroll.js +14 -0
- package/dist/tableScroll.js.map +1 -0
- package/dist/types.d.ts +128 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +60 -4
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import type { Key, ReactElement, ReactNode, Ref } from 'react';
|
|
2
|
+
import type { TableProps } from 'antd';
|
|
3
|
+
import type { TableFooterContext } from '../TableFooter.js';
|
|
4
|
+
import type { EditableColumn, ToolbarPlacement } from '../types.js';
|
|
5
|
+
/** onSave 返回 T 表示“本次确认版本”,返回 void 表示由上层刷新 dataSource */
|
|
6
|
+
export type SaveResult<T> = T | void;
|
|
7
|
+
export type EditingState = {
|
|
8
|
+
status: 'idle';
|
|
9
|
+
} | {
|
|
10
|
+
status: 'editing';
|
|
11
|
+
rowKey: Key;
|
|
12
|
+
} | {
|
|
13
|
+
status: 'validating';
|
|
14
|
+
rowKey: Key;
|
|
15
|
+
} | {
|
|
16
|
+
status: 'saving';
|
|
17
|
+
rowKey: Key;
|
|
18
|
+
};
|
|
19
|
+
export interface DiscardConfirmContext<T> {
|
|
20
|
+
/** switch:切换编辑行;cancel:取消/覆盖草稿 */
|
|
21
|
+
reason: 'switch' | 'cancel';
|
|
22
|
+
currentRow: T;
|
|
23
|
+
nextRow: T | null;
|
|
24
|
+
}
|
|
25
|
+
export interface EditableRowActionContext<T> {
|
|
26
|
+
row: T;
|
|
27
|
+
/** 该行是否为当前活动行 */
|
|
28
|
+
active: boolean;
|
|
29
|
+
/** 校验或保存进行中,冲突操作应禁用 */
|
|
30
|
+
busy: boolean;
|
|
31
|
+
edit(): void;
|
|
32
|
+
save(): void;
|
|
33
|
+
cancel(): void;
|
|
34
|
+
remove(): void;
|
|
35
|
+
}
|
|
36
|
+
export interface EditableTableProps<T extends object> extends Omit<TableProps<T>, 'columns' | 'rowKey'> {
|
|
37
|
+
rowKey: keyof T | ((row: T) => Key);
|
|
38
|
+
columns: EditableColumn<T>[];
|
|
39
|
+
/** 仅在活动行校验通过后调用;抛错视为保存失败,草稿保留 */
|
|
40
|
+
onSave(nextRow: T, originalRow: T): Promise<SaveResult<T>> | SaveResult<T>;
|
|
41
|
+
onDelete?(row: T): Promise<void> | void;
|
|
42
|
+
/** 有脏差异需要切换时优先使用它;返回 false 表示不切换 */
|
|
43
|
+
onBeforeEditSwitch?(currentRow: T, nextRow: T): boolean | Promise<boolean>;
|
|
44
|
+
/** 覆盖内置“放弃修改”确认框 */
|
|
45
|
+
confirmDiscard?(ctx: DiscardConfirmContext<T>): boolean | Promise<boolean>;
|
|
46
|
+
/** 保存抛错时的出口;未提供则内置提示一次 */
|
|
47
|
+
onSaveError?(error: unknown): void;
|
|
48
|
+
/** dataSource 受控时,ref.setData() 通过它向上层发出替换请求 */
|
|
49
|
+
onSetData?(rows: T[]): void | Promise<void>;
|
|
50
|
+
/** 默认 true:追加行尾操作列 */
|
|
51
|
+
showActions?: boolean;
|
|
52
|
+
actionsColumnProps?: Partial<EditableColumn<T>>;
|
|
53
|
+
renderActions?(ctx: EditableRowActionContext<T>): ReactNode;
|
|
54
|
+
/** 整表只读:不进入编辑、不渲染操作列 */
|
|
55
|
+
disabled?: boolean;
|
|
56
|
+
/** 表体最大高度(scroll.y 的便捷入口):超过后表体自身滚动;不传则整表撑开 */
|
|
57
|
+
maxHeight?: number;
|
|
58
|
+
/**
|
|
59
|
+
* 新增按钮(追加到末尾),默认开启。
|
|
60
|
+
* dataSource 受控,组件自己加不了行:只有同时提供 createRow 与 onSetData 时才默认显示,
|
|
61
|
+
* 显式传值优先(想关掉就传 false)。
|
|
62
|
+
*/
|
|
63
|
+
showAddButton?: boolean;
|
|
64
|
+
/** 新增按钮文案,默认「新增」 */
|
|
65
|
+
addButtonText?: string;
|
|
66
|
+
/** 新增行默认值;必须能产出唯一 rowKey,否则新增被拒绝 */
|
|
67
|
+
createRow?: () => Partial<T>;
|
|
68
|
+
/** 底部新增按钮右侧插槽;不传则只渲染新增按钮 */
|
|
69
|
+
renderFooterExtra?: (ctx: TableFooterContext<T>) => ReactNode;
|
|
70
|
+
/** 行多选(勾选框),默认关闭;调用方自己传 rowSelection 时以调用方为准 */
|
|
71
|
+
showRowSelection?: boolean;
|
|
72
|
+
/**
|
|
73
|
+
* 底部批量删除按钮,默认关闭;只删勾选行。
|
|
74
|
+
* dataSource 受控,删除同样经由 onSetData 落地。
|
|
75
|
+
*/
|
|
76
|
+
showBatchDelete?: boolean;
|
|
77
|
+
/** 批量删除文案,默认「批量删除」 */
|
|
78
|
+
batchDeleteText?: string;
|
|
79
|
+
/** 内置工具条(新增 / 插槽 / 批量删除)位置,默认顶部(与老家族 BatchEdit 一致) */
|
|
80
|
+
toolbarPlacement?: ToolbarPlacement;
|
|
81
|
+
/** 内置按钮是否带图标(新增 / 批量删除),默认不带 */
|
|
82
|
+
showButtonIcon?: boolean;
|
|
83
|
+
}
|
|
84
|
+
export interface EditableTableRef<T extends object> {
|
|
85
|
+
/** 仅返回已确认的 dataSource 快照,不含正在编辑的草稿 */
|
|
86
|
+
getDataSync(): T[];
|
|
87
|
+
/** 活动行草稿(原始行 + 表单值合并);无活动行返回 null */
|
|
88
|
+
getEditingDraftSync(): T | null;
|
|
89
|
+
getEditingRowKey(): Key | null;
|
|
90
|
+
isEditing(): boolean;
|
|
91
|
+
/** 当前活动行是否有未保存差异 */
|
|
92
|
+
isDirty(): boolean;
|
|
93
|
+
/** 结束编辑并丢弃草稿;脏数据需确认,返回是否已退出 */
|
|
94
|
+
cancelEdit(): Promise<boolean>;
|
|
95
|
+
/**
|
|
96
|
+
* 请求替换已确认数据,成功后才结束编辑;脏草稿需先确认。
|
|
97
|
+
*
|
|
98
|
+
* 返回值回答的是“这次请求是否已生效”,false 不是错误,调用方可以忽略:
|
|
99
|
+
* - resolve true:onSetData 已成功执行;
|
|
100
|
+
* - resolve false:未做任何改动——用户放弃覆盖,或被校验/保存占用(稍后重试);
|
|
101
|
+
* - reject:只有两种情况——未提供 onSetData(集成错误,须在丢草稿前暴露),
|
|
102
|
+
* 或 onSetData 自身失败(草稿保留,原样上抛)。
|
|
103
|
+
*/
|
|
104
|
+
setData(rows: T[]): Promise<boolean>;
|
|
105
|
+
}
|
|
106
|
+
export type EditableTableComponent = <T extends object>(props: EditableTableProps<T> & {
|
|
107
|
+
ref?: Ref<EditableTableRef<T>>;
|
|
108
|
+
}) => ReactElement;
|
|
109
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/editable-table/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/editable-table/types.ts"],"names":[],"mappings":""}
|
package/dist/env.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,eAAO,MAAM,MAAM,SAOf,CAAC"}
|
package/dist/env.js
ADDED
package/dist/env.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.js","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,GAAG,EAAE;IAC1B,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,CAAC,IAAgD,CAAC;QACrE,OAAO,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC,CAAC,EAAE,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import type { FormInstance } from 'antd';
|
|
3
|
+
import type { FormFieldSchema } from '../types.js';
|
|
4
|
+
export declare class FormRuntimeHost {
|
|
5
|
+
private readonly form;
|
|
6
|
+
private readonly fields;
|
|
7
|
+
/** 防止同一轮派发内被重入 */
|
|
8
|
+
private dispatching;
|
|
9
|
+
/** immediate 规则上次执行时的依赖值签名,键为 `${字段}#${规则序号}` */
|
|
10
|
+
private readonly immediateSignatures;
|
|
11
|
+
/** 依赖值未变却重复执行的次数,用于发现跨字段成环 */
|
|
12
|
+
private readonly immediateRepeats;
|
|
13
|
+
constructor(form: FormInstance);
|
|
14
|
+
/** 返回注销函数;同名字段以最后一次登记为准 */
|
|
15
|
+
registerField(schema: FormFieldSchema): () => void;
|
|
16
|
+
private createWriteContext;
|
|
17
|
+
private runRule;
|
|
18
|
+
/** 依赖值签名:两次执行签名相同说明这次不是被依赖变化驱动的 */
|
|
19
|
+
private dependencySignature;
|
|
20
|
+
/**
|
|
21
|
+
* 用户交互后的派发入口。
|
|
22
|
+
* 调用前必须保证新值已经写入 Form Store,否则 ctx.get() 会读到旧值。
|
|
23
|
+
* immediate 规则不在这里执行:它们由依赖值订阅统一驱动,避免同一变更跑两遍。
|
|
24
|
+
*/
|
|
25
|
+
dispatchUserChange(changed: FormFieldSchema, value: unknown, meta: unknown[]): void;
|
|
26
|
+
/**
|
|
27
|
+
* 执行某个字段声明的 immediate 规则。
|
|
28
|
+
* 由 SchemaFormField 在依赖值变化时调用(含初始值、回填、setData),
|
|
29
|
+
* 不区分变更来源。
|
|
30
|
+
*/
|
|
31
|
+
runImmediateRulesOf(schema: FormFieldSchema): void;
|
|
32
|
+
}
|
|
33
|
+
export declare function FormRuntimeHostProvider({ form, children, }: {
|
|
34
|
+
form: FormInstance;
|
|
35
|
+
children: ReactNode;
|
|
36
|
+
}): import("react").JSX.Element;
|
|
37
|
+
/** 不在 Host 内时返回 null:字段照常渲染,只是没有联动派发 */
|
|
38
|
+
export declare function useFormRuntimeHost(): FormRuntimeHost | null;
|
|
39
|
+
//# sourceMappingURL=FormRuntimeHost.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormRuntimeHost.d.ts","sourceRoot":"","sources":["../../src/form/FormRuntimeHost.tsx"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AACvC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,MAAM,CAAC;AAGzC,OAAO,KAAK,EAAqB,eAAe,EAAuC,MAAM,UAAU,CAAC;AAMxG,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAe;IAEpC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsC;IAE7D,kBAAkB;IAClB,OAAO,CAAC,WAAW,CAAS;IAE5B,iDAAiD;IACjD,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAA6B;IAEjE,8BAA8B;IAC9B,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA6B;gBAElD,IAAI,EAAE,YAAY;IAI9B,2BAA2B;IAC3B,aAAa,CAAC,MAAM,EAAE,eAAe,GAAG,MAAM,IAAI;IAUlD,OAAO,CAAC,kBAAkB;IAyC1B,OAAO,CAAC,OAAO;IAIf,mCAAmC;IACnC,OAAO,CAAC,mBAAmB;IAS3B;;;;OAIG;IACH,kBAAkB,CAAC,OAAO,EAAE,eAAe,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IA4BnF;;;;OAIG;IACH,mBAAmB,CAAC,MAAM,EAAE,eAAe,GAAG,IAAI;CA4CnD;AAID,wBAAgB,uBAAuB,CAAC,EACtC,IAAI,EACJ,QAAQ,GACT,EAAE;IACD,IAAI,EAAE,YAAY,CAAC;IACnB,QAAQ,EAAE,SAAS,CAAC;CACrB,+BAGA;AAED,wCAAwC;AACxC,wBAAgB,kBAAkB,IAAI,eAAe,GAAG,IAAI,CAE3D"}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* FormRuntimeHost:一个 FormInstance 一份的联动运行作用域。
|
|
4
|
+
*
|
|
5
|
+
* 职责边界(见统一运行契约 §2/§4):
|
|
6
|
+
* - 登记字段级 linkage / events 配置;
|
|
7
|
+
* - 用户交互后派发 events 与**非 immediate** 的 linkage;
|
|
8
|
+
* - 派发顺序固定:Form Store 写入 → events → linkage;
|
|
9
|
+
* - 写入不再隐式触发下一轮联动,避免循环。
|
|
10
|
+
*
|
|
11
|
+
* 变更来源:antd 的 `setFieldsValue` / `setFields` 走 `source: 'external'`,
|
|
12
|
+
* 不会触发 `onValuesChange`,因此**不能**靠它识别程序赋值(契约明确要求
|
|
13
|
+
* 用显式标记,不依赖该偶然行为)。这里的来源划分是:
|
|
14
|
+
* - 用户交互:SchemaField 的 onChange → dispatchUserChange,显式调用;
|
|
15
|
+
* - 任意变更(含初始化、回填、setData):immediate 规则由 SchemaFormField
|
|
16
|
+
* 订阅自身依赖值变化后调用 runImmediateRulesOf,与来源无关。
|
|
17
|
+
*/
|
|
18
|
+
import { createContext, useContext, useMemo } from 'react';
|
|
19
|
+
import { IS_DEV } from '../env.js';
|
|
20
|
+
import { namePathKey } from './namePath.js';
|
|
21
|
+
/** 依赖值没变却重复执行的容忍次数,超出视为规则成环 */
|
|
22
|
+
const MAX_IMMEDIATE_REPEATS = 3;
|
|
23
|
+
export class FormRuntimeHost {
|
|
24
|
+
constructor(form) {
|
|
25
|
+
this.fields = new Map();
|
|
26
|
+
/** 防止同一轮派发内被重入 */
|
|
27
|
+
this.dispatching = false;
|
|
28
|
+
/** immediate 规则上次执行时的依赖值签名,键为 `${字段}#${规则序号}` */
|
|
29
|
+
this.immediateSignatures = new Map();
|
|
30
|
+
/** 依赖值未变却重复执行的次数,用于发现跨字段成环 */
|
|
31
|
+
this.immediateRepeats = new Map();
|
|
32
|
+
this.form = form;
|
|
33
|
+
}
|
|
34
|
+
/** 返回注销函数;同名字段以最后一次登记为准 */
|
|
35
|
+
registerField(schema) {
|
|
36
|
+
const key = namePathKey(schema.name);
|
|
37
|
+
this.fields.set(key, schema);
|
|
38
|
+
return () => {
|
|
39
|
+
if (this.fields.get(key) === schema) {
|
|
40
|
+
this.fields.delete(key);
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
createWriteContext(written, touched, skipUnchanged = false) {
|
|
45
|
+
const form = this.form;
|
|
46
|
+
const track = (name, value) => {
|
|
47
|
+
const key = namePathKey(name);
|
|
48
|
+
if (written.has(key) && written.get(key) !== value && IS_DEV) {
|
|
49
|
+
console.warn(`[schema] 同一轮联动重复写入 "${key}",结果依赖规则执行顺序,请合并规则`);
|
|
50
|
+
}
|
|
51
|
+
written.set(key, value);
|
|
52
|
+
touched.add(key);
|
|
53
|
+
};
|
|
54
|
+
const set = (name, value) => {
|
|
55
|
+
track(name, value);
|
|
56
|
+
// 仅优化 immediate 的纯标量赋值;对象、显式清空和错误清理保持原行为。
|
|
57
|
+
if (skipUnchanged && value != null && typeof value !== 'object'
|
|
58
|
+
&& typeof value !== 'function' && Object.is(form.getFieldValue(name), value)
|
|
59
|
+
&& !form.isFieldValidating(name) && !form.getFieldError(name).length
|
|
60
|
+
&& !form.getFieldWarning(name).length)
|
|
61
|
+
return;
|
|
62
|
+
form.setFieldValue(name, value);
|
|
63
|
+
};
|
|
64
|
+
return {
|
|
65
|
+
form,
|
|
66
|
+
get: (name) => form.getFieldValue(name),
|
|
67
|
+
getValues: () => form.getFieldsValue(true),
|
|
68
|
+
set,
|
|
69
|
+
// 批量写入:记账口径与 set 一致(按顶层键),写入合并成一次 Store 更新
|
|
70
|
+
setValues: (values) => {
|
|
71
|
+
const entries = Object.entries(values);
|
|
72
|
+
for (const [key, value] of entries)
|
|
73
|
+
track(key, value);
|
|
74
|
+
if (!entries.length)
|
|
75
|
+
return;
|
|
76
|
+
form.setFieldsValue(values);
|
|
77
|
+
},
|
|
78
|
+
clear: (name) => set(name, undefined),
|
|
79
|
+
clearValues: (names) => names.forEach((name) => set(name, undefined)),
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
runRule(ctx, rule) {
|
|
83
|
+
rule.handler(ctx);
|
|
84
|
+
}
|
|
85
|
+
/** 依赖值签名:两次执行签名相同说明这次不是被依赖变化驱动的 */
|
|
86
|
+
dependencySignature(rule) {
|
|
87
|
+
try {
|
|
88
|
+
return JSON.stringify(rule.dependencies.map((dep) => this.form.getFieldValue(dep)));
|
|
89
|
+
}
|
|
90
|
+
catch {
|
|
91
|
+
// 存在循环引用时放弃判定,宁可不拦也不误伤
|
|
92
|
+
return undefined;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* 用户交互后的派发入口。
|
|
97
|
+
* 调用前必须保证新值已经写入 Form Store,否则 ctx.get() 会读到旧值。
|
|
98
|
+
* immediate 规则不在这里执行:它们由依赖值订阅统一驱动,避免同一变更跑两遍。
|
|
99
|
+
*/
|
|
100
|
+
dispatchUserChange(changed, value, meta) {
|
|
101
|
+
if (this.dispatching)
|
|
102
|
+
return;
|
|
103
|
+
this.dispatching = true;
|
|
104
|
+
try {
|
|
105
|
+
const written = new Map();
|
|
106
|
+
const ctx = this.createWriteContext(written, new Set());
|
|
107
|
+
// 1. 当前字段的交互副作用
|
|
108
|
+
if (changed.events?.onChange) {
|
|
109
|
+
const eventCtx = { ...ctx, option: meta[0], meta };
|
|
110
|
+
changed.events.onChange(value, eventCtx);
|
|
111
|
+
}
|
|
112
|
+
// 2. 依赖该字段的非 immediate linkage 规则
|
|
113
|
+
const changedKey = namePathKey(changed.name);
|
|
114
|
+
for (const field of this.fields.values()) {
|
|
115
|
+
for (const rule of field.linkage ?? []) {
|
|
116
|
+
if (rule.immediate)
|
|
117
|
+
continue;
|
|
118
|
+
if (rule.dependencies.some((dep) => namePathKey(dep) === changedKey)) {
|
|
119
|
+
this.runRule(ctx, rule);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
finally {
|
|
125
|
+
this.dispatching = false;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* 执行某个字段声明的 immediate 规则。
|
|
130
|
+
* 由 SchemaFormField 在依赖值变化时调用(含初始值、回填、setData),
|
|
131
|
+
* 不区分变更来源。
|
|
132
|
+
*/
|
|
133
|
+
runImmediateRulesOf(schema) {
|
|
134
|
+
if (this.dispatching)
|
|
135
|
+
return;
|
|
136
|
+
const rules = (schema.linkage ?? []).filter((rule) => rule.immediate);
|
|
137
|
+
if (!rules.length)
|
|
138
|
+
return;
|
|
139
|
+
this.dispatching = true;
|
|
140
|
+
try {
|
|
141
|
+
for (const rule of rules) {
|
|
142
|
+
const ruleKey = `${namePathKey(schema.name)}#${schema.linkage?.indexOf(rule)}`;
|
|
143
|
+
// 依赖值没变还在跑,说明是别的规则写回了依赖,继续跑下去就是成环
|
|
144
|
+
const signature = this.dependencySignature(rule);
|
|
145
|
+
const repeated = signature !== undefined && signature === this.immediateSignatures.get(ruleKey);
|
|
146
|
+
const repeats = repeated ? (this.immediateRepeats.get(ruleKey) ?? 0) + 1 : 0;
|
|
147
|
+
if (signature !== undefined)
|
|
148
|
+
this.immediateSignatures.set(ruleKey, signature);
|
|
149
|
+
this.immediateRepeats.set(ruleKey, repeats);
|
|
150
|
+
if (repeats > MAX_IMMEDIATE_REPEATS) {
|
|
151
|
+
if (IS_DEV) {
|
|
152
|
+
console.error(`[schema] "${ruleKey}" 依赖值未变却重复执行 ${repeats} 次,判定为成环,已跳过`);
|
|
153
|
+
}
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
const written = new Map();
|
|
157
|
+
const touched = new Set();
|
|
158
|
+
this.runRule(this.createWriteContext(written, touched, true), rule);
|
|
159
|
+
// immediate 写回自己的依赖会形成渲染死循环,开发态直接指出来
|
|
160
|
+
if (IS_DEV) {
|
|
161
|
+
const depKeys = new Set(rule.dependencies.map((dep) => namePathKey(dep)));
|
|
162
|
+
for (const key of touched) {
|
|
163
|
+
if (depKeys.has(key)) {
|
|
164
|
+
console.warn(`[schema] immediate 规则 "${ruleKey}" 写回了自己的依赖 "${key}"`);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
finally {
|
|
171
|
+
this.dispatching = false;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
const FormRuntimeHostContext = createContext(null);
|
|
176
|
+
export function FormRuntimeHostProvider({ form, children, }) {
|
|
177
|
+
const host = useMemo(() => new FormRuntimeHost(form), [form]);
|
|
178
|
+
return _jsx(FormRuntimeHostContext.Provider, { value: host, children: children });
|
|
179
|
+
}
|
|
180
|
+
/** 不在 Host 内时返回 null:字段照常渲染,只是没有联动派发 */
|
|
181
|
+
export function useFormRuntimeHost() {
|
|
182
|
+
return useContext(FormRuntimeHostContext);
|
|
183
|
+
}
|
|
184
|
+
//# sourceMappingURL=FormRuntimeHost.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FormRuntimeHost.js","sourceRoot":"","sources":["../../src/form/FormRuntimeHost.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { AnyFormFieldSchema, FieldMode } from '../types.js';
|
|
2
|
+
export interface SchemaFormFieldProps {
|
|
3
|
+
/** 普通字段或 type: 'Custom' 的局部自定义字段 */
|
|
4
|
+
schema: AnyFormFieldSchema;
|
|
5
|
+
/** 只调整布局与错误展示,不改变绑定/校验/联动语义 */
|
|
6
|
+
compact?: boolean;
|
|
7
|
+
/** 表单级只读,优先于字段自身 mode */
|
|
8
|
+
mode?: FieldMode;
|
|
9
|
+
/** 表单级禁用,永远优先于字段配置 */
|
|
10
|
+
disabled?: boolean;
|
|
11
|
+
}
|
|
12
|
+
declare function SchemaFormFieldInner(props: SchemaFormFieldProps): import("react").JSX.Element;
|
|
13
|
+
export declare const SchemaFormField: import("react").MemoExoticComponent<typeof SchemaFormFieldInner>;
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=SchemaFormField.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SchemaFormField.d.ts","sourceRoot":"","sources":["../../src/form/SchemaFormField.tsx"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,kBAAkB,EAAE,SAAS,EAAgC,MAAM,UAAU,CAAC;AAO5F,MAAM,WAAW,oBAAoB;IACnC,oCAAoC;IACpC,MAAM,EAAE,kBAAkB,CAAC;IAC3B,+BAA+B;IAC/B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,yBAAyB;IACzB,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,sBAAsB;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAkBD,iBAAS,oBAAoB,CAAC,KAAK,EAAE,oBAAoB,+BAQxD;AAED,eAAO,MAAM,eAAe,kEAA6B,CAAC"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* SchemaFormField:唯一可复用的字段绑定层。
|
|
4
|
+
*
|
|
5
|
+
* 普通 SchemaForm、EditableTable 活动行、FullEditableTable 每一行都复用它,
|
|
6
|
+
* 不另建第二套 Form.Item 绑定。它负责:具名 Form.Item、dynamic 派生、
|
|
7
|
+
* 隐藏时跳过校验、以及把用户交互交给 FormRuntimeHost 派发。
|
|
8
|
+
*/
|
|
9
|
+
import { memo, useEffect, useMemo, useRef } from 'react';
|
|
10
|
+
import { Form } from 'antd';
|
|
11
|
+
import { IS_DEV } from '../env.js';
|
|
12
|
+
import { SchemaField } from '../SchemaField.js';
|
|
13
|
+
import { useFormRuntimeHost } from './FormRuntimeHost.js';
|
|
14
|
+
import { deriveFieldState, withDerivedProps } from './derive.js';
|
|
15
|
+
import { dedupeNamePaths, getNestedValue, namePathKey } from './namePath.js';
|
|
16
|
+
const EMPTY_DEPS = [];
|
|
17
|
+
/** 漏写 dependencies 的字段已提醒过,按字段名去重,避免千格表格刷屏 */
|
|
18
|
+
const warnedMissingDeps = new Set();
|
|
19
|
+
/**
|
|
20
|
+
* `dynamic.dependencies` 在契约里是必填,但配置可能来自 JS 或后端下发。
|
|
21
|
+
* 缺了只会退化成静态字段(联动不生效),所以只在开发态提示一次,不抛错。
|
|
22
|
+
*/
|
|
23
|
+
function warnMissingDependencies(schema) {
|
|
24
|
+
const key = namePathKey(schema.name);
|
|
25
|
+
if (warnedMissingDeps.has(key))
|
|
26
|
+
return;
|
|
27
|
+
warnedMissingDeps.add(key);
|
|
28
|
+
console.warn(`[schema] 字段 "${key}" 配了 dynamic 却没有 dependencies,将按静态字段渲染`);
|
|
29
|
+
}
|
|
30
|
+
function SchemaFormFieldInner(props) {
|
|
31
|
+
const { schema } = props;
|
|
32
|
+
const dependencies = schema.dynamic?.dependencies;
|
|
33
|
+
if (IS_DEV && schema.dynamic && !dependencies)
|
|
34
|
+
warnMissingDependencies(schema);
|
|
35
|
+
const reactive = Boolean(dependencies?.length || schema.linkage?.some((rule) => rule.immediate));
|
|
36
|
+
return reactive ? _jsx(ReactiveField, { ...props }) : _jsx(FieldBody, { ...props });
|
|
37
|
+
}
|
|
38
|
+
export const SchemaFormField = memo(SchemaFormFieldInner);
|
|
39
|
+
function FieldBody({ schema, compact, mode, disabled }) {
|
|
40
|
+
const form = Form.useFormInstance();
|
|
41
|
+
const host = useFormRuntimeHost();
|
|
42
|
+
useEffect(() => host?.registerField(schema), [host, schema]);
|
|
43
|
+
const readCtx = useMemo(() => ({
|
|
44
|
+
get: (name) => form.getFieldValue(name),
|
|
45
|
+
getValues: () => form.getFieldsValue(true),
|
|
46
|
+
}), [form]);
|
|
47
|
+
const derived = deriveFieldState(schema, readCtx);
|
|
48
|
+
return _jsx(FieldContent, { schema: schema, compact: compact, mode: mode, disabled: disabled, derived: derived });
|
|
49
|
+
}
|
|
50
|
+
/** 静态字段不订阅;动态字段变化后仍复用相同的绑定与校验。 */
|
|
51
|
+
function ReactiveField(props) {
|
|
52
|
+
const { schema } = props;
|
|
53
|
+
const form = Form.useFormInstance();
|
|
54
|
+
const host = useFormRuntimeHost();
|
|
55
|
+
// immediate 规则的依赖:变更来源无关(初始化、回填、setData 都重算),
|
|
56
|
+
// 与非 immediate 的“只响应用户交互”区分开。
|
|
57
|
+
const immediateDeps = useMemo(() => (schema.linkage ?? [])
|
|
58
|
+
.filter((rule) => rule.immediate)
|
|
59
|
+
.flatMap((rule) => rule.dependencies), [schema]);
|
|
60
|
+
// 依赖订阅:用稳定 selector + ref 取最新依赖,
|
|
61
|
+
// 避免把一个 NamePath 数组误当成单条嵌套路径传给 useWatch。
|
|
62
|
+
const dependencies = schema.dynamic?.dependencies ?? EMPTY_DEPS;
|
|
63
|
+
const watchDependencies = useMemo(() => immediateDeps.length
|
|
64
|
+
? dedupeNamePaths([...dependencies, ...immediateDeps])
|
|
65
|
+
: dependencies, [dependencies, immediateDeps]);
|
|
66
|
+
const depsRef = useRef(watchDependencies);
|
|
67
|
+
depsRef.current = watchDependencies;
|
|
68
|
+
const selector = useMemo(() => (values) => depsRef.current.map((dep) => getNestedValue(values, dep)), []);
|
|
69
|
+
// useWatch 内部按 JSON 比较,值没变就返回同一个引用,可直接做 effect 依赖
|
|
70
|
+
const watchedDeps = Form.useWatch(selector, { form, preserve: true });
|
|
71
|
+
// schema 多为模块级常量,用 ref 兜住内联定义,避免每次渲染都重跑 immediate 规则
|
|
72
|
+
const schemaRef = useRef(schema);
|
|
73
|
+
schemaRef.current = schema;
|
|
74
|
+
useEffect(() => {
|
|
75
|
+
// undefined 是 useWatch 首帧占位,等它读到真实依赖值再跑,避免初始化跑两遍
|
|
76
|
+
if (!immediateDeps.length || watchedDeps === undefined)
|
|
77
|
+
return;
|
|
78
|
+
host?.runImmediateRulesOf(schemaRef.current);
|
|
79
|
+
}, [host, watchedDeps, immediateDeps.length]);
|
|
80
|
+
return _jsx(FieldBody, { ...props });
|
|
81
|
+
}
|
|
82
|
+
function FieldContent({ schema, compact, mode, disabled, derived }) {
|
|
83
|
+
const form = Form.useFormInstance();
|
|
84
|
+
const host = useFormRuntimeHost();
|
|
85
|
+
const visible = derived.visible;
|
|
86
|
+
// 隐藏期间跳过校验:清掉历史错误,重新显示后按当时的规则恢复
|
|
87
|
+
const nameKey = namePathKey(schema.name);
|
|
88
|
+
useEffect(() => {
|
|
89
|
+
if (!visible) {
|
|
90
|
+
form.setFields([{ name: schema.name, errors: [] }]);
|
|
91
|
+
}
|
|
92
|
+
// name 用 nameKey 表达,避免数组字面量每次渲染都触发
|
|
93
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
94
|
+
}, [visible, form, nameKey]);
|
|
95
|
+
const finalMode = mode ?? schema.mode ?? 'edit';
|
|
96
|
+
if (finalMode === 'read') {
|
|
97
|
+
// 只读态同样消费派生结果:props 里的 queryParams / options / format 必须透传
|
|
98
|
+
return _jsx(ReadableSchemaFormField, { schema: schema, state: derived, compact: compact });
|
|
99
|
+
}
|
|
100
|
+
// dynamic.disabled 覆盖字段级 props.disabled;表单级 disabled 永远优先
|
|
101
|
+
const finalDisabled = disabled ? true : derived.disabled;
|
|
102
|
+
const rules = derived.rules;
|
|
103
|
+
const field = withDerivedProps(schema, derived.props);
|
|
104
|
+
const itemProps = {
|
|
105
|
+
name: schema.name,
|
|
106
|
+
// 表格单元格由列头承担标题,compact 不重复渲染 label
|
|
107
|
+
label: compact ? undefined : schema.label,
|
|
108
|
+
rules,
|
|
109
|
+
dependencies: schema.dependencies,
|
|
110
|
+
hidden: !visible,
|
|
111
|
+
...(compact ? { style: { marginBottom: 0 } } : null),
|
|
112
|
+
...schema.formItemProps,
|
|
113
|
+
};
|
|
114
|
+
return (_jsx(Form.Item, { ...itemProps, children: _jsx(BoundField, { fieldSchema: schema, field: field, host: host, disabled: finalDisabled }) }));
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Form.Item 固定以 value/onChange 注入,控件各自的受控属性名由 SchemaField 的注册表处理。
|
|
118
|
+
* 事件顺序:先写 Form Store,再派发 events/linkage,保证 ctx.get() 读到新值。
|
|
119
|
+
*/
|
|
120
|
+
function BoundField({ value, onChange, id, fieldSchema, field, host, disabled }) {
|
|
121
|
+
const handleChange = (next, ...meta) => {
|
|
122
|
+
// Form.Item 的受控写入是同步的,先落 Store 再派发,保证 ctx.get() 读到新值
|
|
123
|
+
onChange?.(next);
|
|
124
|
+
host?.dispatchUserChange(fieldSchema, next, meta);
|
|
125
|
+
};
|
|
126
|
+
return (_jsx(SchemaField, { schema: field, value: value, onChange: handleChange, disabled: disabled, id: id }));
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* 只读字段:轻量展示,订阅 Store 但不注册具名 Form.Item、不参与校验。
|
|
130
|
+
*
|
|
131
|
+
* 不注册指的是不传 name;label 与外层布局仍要走 Form.Item,
|
|
132
|
+
* 否则整表只读后会只剩一列值、字段名全丢,和编辑态对不上。
|
|
133
|
+
*/
|
|
134
|
+
function ReadableSchemaFormField({ schema, state, compact, }) {
|
|
135
|
+
const form = Form.useFormInstance();
|
|
136
|
+
const value = Form.useWatch(schema.name, { form, preserve: true });
|
|
137
|
+
// dynamic.visible 同样作用于只读态;普通表单隐藏即不渲染(表格由列自己保留 <td>)
|
|
138
|
+
if (!state.visible)
|
|
139
|
+
return null;
|
|
140
|
+
return (_jsx(Form.Item, { label: compact ? undefined : schema.label, ...(compact ? { style: { marginBottom: 0 } } : null), ...schema.formItemProps, children: _jsx(SchemaField, { schema: withDerivedProps(schema, state.props), value: value, mode: "read" }) }));
|
|
141
|
+
}
|
|
142
|
+
//# sourceMappingURL=SchemaFormField.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SchemaFormField.js","sourceRoot":"","sources":["../../src/form/SchemaFormField.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 字段状态的统一派生(统一运行契约 §3)。
|
|
3
|
+
*
|
|
4
|
+
* `dynamic` 是字段的运行时派生配置,不是编辑态专属配置:
|
|
5
|
+
* 编辑态与只读态必须共用这一份求值逻辑,两种模式只在
|
|
6
|
+
* 属性下发、校验、事件与写入行为上不同,派生结果本身一致。
|
|
7
|
+
*/
|
|
8
|
+
import type { FieldSchema, FormFieldSchema, ReadContext, Rule } from '../types.js';
|
|
9
|
+
export interface DerivedFieldState {
|
|
10
|
+
/** 显示优先级:dynamic.visible > visible > !hidden > true */
|
|
11
|
+
visible: boolean;
|
|
12
|
+
/** 仅 dynamic.disabled 的结果;表单级 disabled 由调用方优先合并 */
|
|
13
|
+
disabled?: boolean;
|
|
14
|
+
/** 仅 dynamic.props 的覆盖项;静态 props 由调用方浅合并 */
|
|
15
|
+
props?: Record<string, unknown>;
|
|
16
|
+
/** 隐藏时规则为空:隐藏期间跳过校验 */
|
|
17
|
+
rules: Rule[];
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* 计算字段当前的有效状态。派生函数必须是纯函数,只依赖 dynamic.dependencies 声明的字段。
|
|
21
|
+
*/
|
|
22
|
+
export declare function deriveFieldState(schema: FormFieldSchema, ctx: ReadContext): DerivedFieldState;
|
|
23
|
+
/** 把 dynamic.props 浅合并到静态 props 上,用于编辑态与只读态共用同一份有效属性 */
|
|
24
|
+
export declare function withDerivedProps<T extends FieldSchema>(schema: T, props?: Record<string, unknown>): T;
|
|
25
|
+
/**
|
|
26
|
+
* 用行记录构造只读上下文。
|
|
27
|
+
*
|
|
28
|
+
* 单活动行表格的 Form Store 里只有活动行的草稿,普通行没有自己的 Form,
|
|
29
|
+
* 必须从 record 取数;用 Form 会读到活动行的值(错行)。
|
|
30
|
+
* `getValues()` 因此返回整条行记录,而不是整表值。
|
|
31
|
+
*/
|
|
32
|
+
export declare function createRecordReadContext(record: unknown): ReadContext;
|
|
33
|
+
//# sourceMappingURL=derive.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"derive.d.ts","sourceRoot":"","sources":["../../src/form/derive.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAW,WAAW,EAAE,eAAe,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAGzF,MAAM,WAAW,iBAAiB;IAChC,uDAAuD;IACvD,OAAO,EAAE,OAAO,CAAC;IACjB,mDAAmD;IACnD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,4CAA4C;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,uBAAuB;IACvB,KAAK,EAAE,IAAI,EAAE,CAAC;CACf;AAqBD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG,EAAE,WAAW,GAAG,iBAAiB,CAsB7F;AAED,wDAAwD;AACxD,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,WAAW,EACpD,MAAM,EAAE,CAAC,EACT,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B,CAAC,CAGH;AAED;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,OAAO,GAAG,WAAW,CAMpE"}
|