crud-page-react 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.
- package/README.md +200 -0
- package/dist/components/CrudPage.d.ts +9 -0
- package/dist/components/DynamicFilter.d.ts +8 -0
- package/dist/components/DynamicForm.d.ts +12 -0
- package/dist/components/DynamicTable.d.ts +18 -0
- package/dist/index.d.ts +270 -0
- package/dist/index.esm.js +2492 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/index.js +2526 -0
- package/dist/index.js.map +1 -0
- package/dist/types/schema.d.ts +191 -0
- package/dist/types/validationRules.d.ts +32 -0
- package/package.json +59 -0
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/** API 请求函数类型 */
|
|
2
|
+
export interface ApiRequest {
|
|
3
|
+
<T = unknown>(url: string, options?: RequestInit): Promise<T>;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* 数据类型:描述字段存储的值类型。
|
|
7
|
+
*
|
|
8
|
+
* 嵌套对象不再作为独立类型,而是通过 key 的点分路径(dot-path)表达,
|
|
9
|
+
* 例如 `emergencyContact.name`、`emergencyContact.phone`。
|
|
10
|
+
* 框架会自动将 Form 数据写入/读出对应的嵌套路径。
|
|
11
|
+
*/
|
|
12
|
+
export type DataType = 'string' | 'number' | 'boolean' | 'datetime' | 'date' | 'array' | 'objectArray';
|
|
13
|
+
/** UI 组件类型:描述字段渲染使用的组件 */
|
|
14
|
+
export type WidgetType = 'input' | 'textarea' | 'inputNumber' | 'select' | 'multiselect' | 'radio' | 'checkbox' | 'switch' | 'datePicker' | 'rangePicker' | 'timePicker' | 'editableTable' | 'jsonInput';
|
|
15
|
+
/** 兼容旧版 —— 不再推荐直接使用 */
|
|
16
|
+
export type FieldType = DataType;
|
|
17
|
+
export interface SelectOption {
|
|
18
|
+
label: string;
|
|
19
|
+
value: string | number | boolean;
|
|
20
|
+
color?: string;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* 筛选项配置 —— 仅放筛选独有配置。
|
|
24
|
+
* options / placeholder / dateFormat 统一在 FieldSchema.config 里配置。
|
|
25
|
+
*/
|
|
26
|
+
export interface FilterConfig {
|
|
27
|
+
/** 覆盖字段级 widget,指定筛选组件类型 */
|
|
28
|
+
widget?: WidgetType;
|
|
29
|
+
/** inputNumber 时可开启数字范围(min/max 两个输入框) */
|
|
30
|
+
range?: boolean;
|
|
31
|
+
defaultValue?: unknown;
|
|
32
|
+
}
|
|
33
|
+
/** 表格列配置 */
|
|
34
|
+
export interface TableColumnConfig {
|
|
35
|
+
width?: number;
|
|
36
|
+
fixed?: 'left' | 'right';
|
|
37
|
+
sortable?: boolean;
|
|
38
|
+
ellipsis?: boolean;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* 表单字段配置 —— 仅放表单独有配置。
|
|
42
|
+
* options / placeholder / dateFormat / rows 统一在 FieldSchema.config 里配置。
|
|
43
|
+
*/
|
|
44
|
+
export interface FormFieldConfig {
|
|
45
|
+
/** 覆盖字段级 widget,指定表单组件类型 */
|
|
46
|
+
widget?: WidgetType;
|
|
47
|
+
required?: boolean;
|
|
48
|
+
min?: number;
|
|
49
|
+
max?: number;
|
|
50
|
+
step?: number;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* 字段级共用组件配置。
|
|
54
|
+
* filter 和 form 均可读取,无需在两处重复填写。
|
|
55
|
+
*/
|
|
56
|
+
export interface FieldConfig {
|
|
57
|
+
/** 下拉/多选/单选等组件的选项列表 */
|
|
58
|
+
options?: SelectOption[];
|
|
59
|
+
/** 输入框、选择框等的占位提示文字 */
|
|
60
|
+
placeholder?: string;
|
|
61
|
+
/** 日期/时间组件的显示格式,如 'YYYY-MM-DD' */
|
|
62
|
+
dateFormat?: string;
|
|
63
|
+
/** textarea / jsonInput 的行数 */
|
|
64
|
+
rows?: number;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* 对象数组(objectArray)中每个 item 的字段定义。
|
|
68
|
+
* 故意保持简单:不支持嵌套 objectArray,不支持 dot-path key。
|
|
69
|
+
*/
|
|
70
|
+
export interface ArrayItemField {
|
|
71
|
+
/** item 对象的属性名,不使用点分路径 */
|
|
72
|
+
key: string;
|
|
73
|
+
label: string;
|
|
74
|
+
/** 不允许嵌套数组 */
|
|
75
|
+
type: Exclude<DataType, 'array' | 'objectArray'>;
|
|
76
|
+
/** 不允许嵌套 editableTable */
|
|
77
|
+
widget?: Exclude<WidgetType, 'editableTable'>;
|
|
78
|
+
config?: Pick<FieldConfig, 'options' | 'placeholder' | 'dateFormat'>;
|
|
79
|
+
required?: boolean;
|
|
80
|
+
/** 列宽(px) */
|
|
81
|
+
width?: number;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* 字段定义。
|
|
85
|
+
*
|
|
86
|
+
* ### 点分路径(dot-path)规则
|
|
87
|
+
* `key` 支持点分路径表达嵌套结构,例如:
|
|
88
|
+
* - `emergencyContact.name`
|
|
89
|
+
* - `emergencyContact.phone`
|
|
90
|
+
*
|
|
91
|
+
* Form 层会自动将值写入 / 读取对应的嵌套对象属性;
|
|
92
|
+
* 具有相同前缀的字段在表单中会被归为同一视觉分组,并显示分组标题。
|
|
93
|
+
*/
|
|
94
|
+
export interface FieldSchema {
|
|
95
|
+
key: string;
|
|
96
|
+
label: string;
|
|
97
|
+
/** 数据类型(值的类型) */
|
|
98
|
+
type: DataType;
|
|
99
|
+
/**
|
|
100
|
+
* 默认 UI 组件类型;可被 filter / form 级别的 widget 覆盖。
|
|
101
|
+
* 不填时由 defaultWidgetForType 推导。
|
|
102
|
+
*/
|
|
103
|
+
widget?: WidgetType;
|
|
104
|
+
filter?: boolean | FilterConfig;
|
|
105
|
+
table?: boolean | TableColumnConfig;
|
|
106
|
+
form?: boolean | FormFieldConfig;
|
|
107
|
+
/**
|
|
108
|
+
* 字段级共用组件配置(options、placeholder、dateFormat 等)。
|
|
109
|
+
* filter 和 form 均从这里读取,不再重复配置。
|
|
110
|
+
*/
|
|
111
|
+
config?: FieldConfig;
|
|
112
|
+
render?: string;
|
|
113
|
+
/**
|
|
114
|
+
* 对象数组子字段定义,仅 type='objectArray' 时生效。
|
|
115
|
+
* 配置后 widget 默认推导为 'editableTable'。
|
|
116
|
+
*/
|
|
117
|
+
itemFields?: ArrayItemField[];
|
|
118
|
+
/**
|
|
119
|
+
* 校验规则 key 数组,引用 validationRules.ts 中内置或自定义规则的 key。
|
|
120
|
+
* 例如 `rules: ['phone_cn', 'max_len_50']`
|
|
121
|
+
* 注意:required 规则通过 form.required 单独控制,无需在此重复。
|
|
122
|
+
*/
|
|
123
|
+
rules?: string[];
|
|
124
|
+
}
|
|
125
|
+
export type ActionType = 'edit' | 'delete' | 'view' | 'custom';
|
|
126
|
+
export interface ActionPermission {
|
|
127
|
+
role?: string[];
|
|
128
|
+
condition?: string;
|
|
129
|
+
}
|
|
130
|
+
export interface ActionSchema {
|
|
131
|
+
key: string;
|
|
132
|
+
label: string;
|
|
133
|
+
type: ActionType;
|
|
134
|
+
icon?: string;
|
|
135
|
+
danger?: boolean;
|
|
136
|
+
permission?: ActionPermission;
|
|
137
|
+
confirm?: {
|
|
138
|
+
title: string;
|
|
139
|
+
content?: string;
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
export interface PaginationConfig {
|
|
143
|
+
pageSize?: number;
|
|
144
|
+
pageSizeOptions?: number[];
|
|
145
|
+
showTotal?: boolean;
|
|
146
|
+
}
|
|
147
|
+
export interface CrudPageSchema {
|
|
148
|
+
id: string;
|
|
149
|
+
title: string;
|
|
150
|
+
api: {
|
|
151
|
+
list: string;
|
|
152
|
+
create?: string;
|
|
153
|
+
update?: string;
|
|
154
|
+
delete?: string;
|
|
155
|
+
detail?: string;
|
|
156
|
+
};
|
|
157
|
+
fields: FieldSchema[];
|
|
158
|
+
actions?: ActionSchema[];
|
|
159
|
+
pagination?: PaginationConfig;
|
|
160
|
+
rowKey?: string;
|
|
161
|
+
createButtonLabel?: string;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* 根据数据类型推导默认 UI 组件
|
|
165
|
+
*
|
|
166
|
+
* string → input
|
|
167
|
+
* number → inputNumber
|
|
168
|
+
* boolean → switch
|
|
169
|
+
* date → datePicker
|
|
170
|
+
* datetime → datePicker
|
|
171
|
+
* array → multiselect
|
|
172
|
+
* objectArray → editableTable
|
|
173
|
+
*/
|
|
174
|
+
export declare function defaultWidgetForType(type: DataType): WidgetType;
|
|
175
|
+
/** 获取实际生效的组件类型(context.widget > field.widget > type 推导) */
|
|
176
|
+
export declare function getEffectiveWidget(field: FieldSchema, config?: FilterConfig | FormFieldConfig): WidgetType;
|
|
177
|
+
/**
|
|
178
|
+
* 从嵌套对象按点分路径取值
|
|
179
|
+
*
|
|
180
|
+
* getNestedValue({ a: { b: 1 } }, 'a.b') → 1
|
|
181
|
+
* getNestedValue({ x: [1, 2] }, 'x') → [1, 2]
|
|
182
|
+
*/
|
|
183
|
+
export declare function getNestedValue(obj: Record<string, unknown>, path: string): unknown;
|
|
184
|
+
/**
|
|
185
|
+
* 从点分路径 key 中提取分组前缀(第一个 segment)。
|
|
186
|
+
* 无前缀的顶层字段返回 null。
|
|
187
|
+
*
|
|
188
|
+
* 'emergencyContact.name' → 'emergencyContact'
|
|
189
|
+
* 'name' → null
|
|
190
|
+
*/
|
|
191
|
+
export declare function getFieldGroupPrefix(key: string): string | null;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { Rule } from 'antd/es/form';
|
|
2
|
+
/** 校验规则配置(内置 + 自定义均使用此结构) */
|
|
3
|
+
export interface ValidationRuleConfig {
|
|
4
|
+
key: string;
|
|
5
|
+
label: string;
|
|
6
|
+
description?: string;
|
|
7
|
+
message: string;
|
|
8
|
+
/** 正则字符串(将转为 RegExp) */
|
|
9
|
+
pattern?: string;
|
|
10
|
+
/** 最小值(number)或最小长度(string) */
|
|
11
|
+
min?: number;
|
|
12
|
+
/** 最大值(number)或最大长度(string) */
|
|
13
|
+
max?: number;
|
|
14
|
+
/** antd 内置类型校验 */
|
|
15
|
+
type?: 'string' | 'number' | 'email' | 'url' | 'integer';
|
|
16
|
+
/** 是否不允许纯空白字符 */
|
|
17
|
+
whitespace?: boolean;
|
|
18
|
+
/** 是否内置(内置规则不可删除) */
|
|
19
|
+
builtin?: boolean;
|
|
20
|
+
}
|
|
21
|
+
/** 内置规则集 */
|
|
22
|
+
export declare const BUILTIN_RULES: ValidationRuleConfig[];
|
|
23
|
+
export declare function loadCustomRules(): ValidationRuleConfig[];
|
|
24
|
+
export declare function saveCustomRules(rules: ValidationRuleConfig[]): void;
|
|
25
|
+
/** 获取所有规则(内置 + 自定义) */
|
|
26
|
+
export declare function getAllRules(): ValidationRuleConfig[];
|
|
27
|
+
/** 根据 key 查找规则 */
|
|
28
|
+
export declare function getRuleByKey(key: string): ValidationRuleConfig | undefined;
|
|
29
|
+
/** 将规则配置转为 Ant Design Form Rule */
|
|
30
|
+
export declare function ruleConfigToAntdRule(config: ValidationRuleConfig): Rule;
|
|
31
|
+
/** 将一组规则 key 转为 Ant Design Form Rules 数组 */
|
|
32
|
+
export declare function keysToAntdRules(keys: string[]): Rule[];
|
package/package.json
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "crud-page-react",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "一个基于 React + Ant Design 的动态 CRUD 组件库,支持通过 JSON Schema 配置生成完整的增删改查界面",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.esm.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist",
|
|
10
|
+
"README.md"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "npx rollup -c",
|
|
14
|
+
"dev": "npx rollup -c -w",
|
|
15
|
+
"prepare": "npm run build",
|
|
16
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
17
|
+
},
|
|
18
|
+
"keywords": [
|
|
19
|
+
"react",
|
|
20
|
+
"crud",
|
|
21
|
+
"dynamic",
|
|
22
|
+
"form",
|
|
23
|
+
"table",
|
|
24
|
+
"antd",
|
|
25
|
+
"typescript",
|
|
26
|
+
"json-schema"
|
|
27
|
+
],
|
|
28
|
+
"author": "ffhopever5@gmail.com",
|
|
29
|
+
"license": "MIT",
|
|
30
|
+
"repository": {
|
|
31
|
+
"type": "git",
|
|
32
|
+
"url": "https://github.com/ffhope/crud-page-react.git"
|
|
33
|
+
},
|
|
34
|
+
"bugs": {
|
|
35
|
+
"url": "https://github.com/ffhope/crud-page-react/issues"
|
|
36
|
+
},
|
|
37
|
+
"homepage": "https://github.com/ffhope/crud-page-react#readme",
|
|
38
|
+
"peerDependencies": {
|
|
39
|
+
"antd": ">=5.0.0",
|
|
40
|
+
"dayjs": ">=1.11.0",
|
|
41
|
+
"react": ">=16.8.0",
|
|
42
|
+
"react-dom": ">=16.8.0"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@rollup/plugin-commonjs": "^25.0.7",
|
|
46
|
+
"@rollup/plugin-node-resolve": "^15.2.3",
|
|
47
|
+
"@rollup/plugin-typescript": "^11.1.6",
|
|
48
|
+
"@types/react": "^18.2.45",
|
|
49
|
+
"@types/react-dom": "^18.2.18",
|
|
50
|
+
"rollup": "^4.9.2",
|
|
51
|
+
"rollup-plugin-dts": "^6.1.0",
|
|
52
|
+
"rollup-plugin-peer-deps-external": "^2.2.4",
|
|
53
|
+
"tslib": "^2.8.1",
|
|
54
|
+
"typescript": "^5.3.3"
|
|
55
|
+
},
|
|
56
|
+
"dependencies": {
|
|
57
|
+
"@ant-design/icons": "^5.2.6"
|
|
58
|
+
}
|
|
59
|
+
}
|