@react-typed-forms/schemas 14.2.0 → 14.3.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/lib/controlDefinition.d.ts +11 -0
- package/lib/index.cjs +3392 -1
- package/lib/index.cjs.map +1 -1
- package/lib/index.js +2869 -1
- package/lib/index.js.map +1 -1
- package/lib/renderers.d.ts +2 -2
- package/lib/util.d.ts +7 -2
- package/package.json +3 -2
- package/src/controlBuilder.ts +268 -0
- package/src/controlDefinition.ts +792 -0
- package/src/controlRender.tsx +1252 -0
- package/src/createFormRenderer.tsx +218 -0
- package/src/defaultSchemaInterface.ts +191 -0
- package/src/dynamicHooks.ts +98 -0
- package/src/entityExpression.ts +38 -0
- package/src/hooks.tsx +459 -0
- package/src/index.ts +14 -0
- package/src/renderers.tsx +205 -0
- package/src/schemaBuilder.ts +318 -0
- package/src/schemaField.ts +552 -0
- package/src/schemaValidator.ts +32 -0
- package/src/util.ts +1039 -0
- package/src/validators.ts +217 -0
package/lib/renderers.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ReactElement, ReactNode } from "react";
|
|
2
2
|
import { ActionRendererProps, AdornmentProps, AdornmentRenderer, ArrayRendererProps, ControlLayoutProps, DataRendererProps, DisplayRendererProps, FormRenderer, GroupRendererProps, LabelRendererProps, LabelType, RenderedControl, VisibilityRendererProps } from "./controlRender";
|
|
3
|
-
import { AccordionAdornment, ControlAdornment, IconAdornment, OptionalAdornment, SetFieldAdornment } from "./controlDefinition";
|
|
3
|
+
import { AccordionAdornment, ControlAdornment, IconAdornment, OptionalAdornment, RenderOptions, SetFieldAdornment } from "./controlDefinition";
|
|
4
4
|
export interface DefaultRenderers {
|
|
5
5
|
data: DataRendererRegistration;
|
|
6
6
|
label: LabelRendererRegistration;
|
|
@@ -23,7 +23,7 @@ export interface DataRendererRegistration {
|
|
|
23
23
|
renderType?: string | string[];
|
|
24
24
|
options?: boolean;
|
|
25
25
|
collection?: boolean;
|
|
26
|
-
match?: (props: DataRendererProps) => boolean;
|
|
26
|
+
match?: (props: DataRendererProps, renderOptions: RenderOptions) => boolean;
|
|
27
27
|
render: (props: DataRendererProps, renderers: FormRenderer) => ReactNode | ((layout: ControlLayoutProps) => ControlLayoutProps);
|
|
28
28
|
}
|
|
29
29
|
export interface LabelRendererRegistration {
|
package/lib/util.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ControlActionHandler, ControlDefinition, DataControlDefinition, DisplayOnlyRenderOptions, GroupRenderOptions } from "./controlDefinition";
|
|
1
|
+
import { ControlActionHandler, ControlDataVisitor, ControlDefinition, DataControlDefinition, DisplayOnlyRenderOptions, GroupRenderOptions } from "./controlDefinition";
|
|
2
2
|
import { MutableRefObject } from "react";
|
|
3
3
|
import { CompoundField, FieldOption, SchemaDataNode, SchemaField, SchemaNode } from "./schemaField";
|
|
4
4
|
import { Control } from "@react-typed-forms/core";
|
|
@@ -247,9 +247,13 @@ export declare function isControlDisplayOnly(def: ControlDefinition): boolean;
|
|
|
247
247
|
export declare function actionHandlers(...handlers: (ControlActionHandler | undefined)[]): ControlActionHandler;
|
|
248
248
|
export declare function getDiffObject(dataNode: SchemaDataNode, force?: boolean): any;
|
|
249
249
|
export declare function getNullToggler(c: Control<any>): Control<boolean>;
|
|
250
|
+
export interface ExternalEditAction {
|
|
251
|
+
action: ActionRendererProps;
|
|
252
|
+
dontValidate?: boolean;
|
|
253
|
+
}
|
|
250
254
|
export interface ExternalEditData {
|
|
251
255
|
data: unknown;
|
|
252
|
-
actions:
|
|
256
|
+
actions: ExternalEditAction[];
|
|
253
257
|
}
|
|
254
258
|
export declare function getExternalEditData(c: Control<any>): Control<ExternalEditData | undefined>;
|
|
255
259
|
export declare function getLastDefinedValue<V>(control: Control<V>): Control<V>;
|
|
@@ -260,3 +264,4 @@ export declare function collectDifferences(dataNode: SchemaDataNode, values: unk
|
|
|
260
264
|
editable: number;
|
|
261
265
|
editing: number;
|
|
262
266
|
};
|
|
267
|
+
export declare function validationVisitor(onInvalid: (data: Control<unknown>) => void): ControlDataVisitor<any>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@react-typed-forms/schemas",
|
|
3
|
-
"version": "14.
|
|
3
|
+
"version": "14.3.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.cjs",
|
|
@@ -60,9 +60,10 @@
|
|
|
60
60
|
},
|
|
61
61
|
"gitHead": "698e16cd3ab31b7dd0528fc76536f4d3205ce8c6",
|
|
62
62
|
"scripts": {
|
|
63
|
-
"build": "rimraf ./lib/ node_modules/.cache && microbundle -f modern,cjs --jsx React.createElement --jsxFragment React.Fragment",
|
|
63
|
+
"build": "rimraf ./lib/ node_modules/.cache && microbundle -f modern,cjs --no-compress --jsx React.createElement --jsxFragment React.Fragment",
|
|
64
64
|
"watch": "microbundle -w -f modern,cjs --no-compress --jsx React.createElement --jsxFragment React.Fragment",
|
|
65
65
|
"test": "jest --coverage",
|
|
66
|
+
"play": "tsx test/play.ts",
|
|
66
67
|
"update-readme": "md-magic --path README.md",
|
|
67
68
|
"gencode": "nswag swagger2tsclient /input:http://localhost:5216/swagger/v1/swagger.json /runtime:Net60 /output:src/types.ts /GenerateClientClasses:false /MarkOptionalProperties:false /Template:Fetch /TypeStyle:Interface /DateTimeType:string"
|
|
68
69
|
}
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AccordionAdornment,
|
|
3
|
+
ActionControlDefinition,
|
|
4
|
+
AutocompleteRenderOptions,
|
|
5
|
+
CheckListRenderOptions,
|
|
6
|
+
ControlAdornmentType,
|
|
7
|
+
ControlDefinition,
|
|
8
|
+
ControlDefinitionType,
|
|
9
|
+
DataControlDefinition,
|
|
10
|
+
DataRenderType,
|
|
11
|
+
DisplayControlDefinition,
|
|
12
|
+
DisplayDataType,
|
|
13
|
+
DisplayOnlyRenderOptions,
|
|
14
|
+
DynamicProperty,
|
|
15
|
+
DynamicPropertyType,
|
|
16
|
+
GroupedControlsDefinition,
|
|
17
|
+
GroupRenderType,
|
|
18
|
+
HtmlDisplay,
|
|
19
|
+
JsonataRenderOptions,
|
|
20
|
+
RadioButtonRenderOptions,
|
|
21
|
+
RenderOptions,
|
|
22
|
+
TextDisplay,
|
|
23
|
+
TextfieldRenderOptions,
|
|
24
|
+
} from "./controlDefinition";
|
|
25
|
+
import { ActionRendererProps } from "./controlRender";
|
|
26
|
+
import { useMemo } from "react";
|
|
27
|
+
import { addMissingControls } from "./util";
|
|
28
|
+
import { mergeFields, resolveSchemas } from "./schemaBuilder";
|
|
29
|
+
import {
|
|
30
|
+
DateValidator,
|
|
31
|
+
JsonataValidator,
|
|
32
|
+
LengthValidator,
|
|
33
|
+
ValidatorType,
|
|
34
|
+
} from "./schemaValidator";
|
|
35
|
+
import { SchemaField, SchemaMap, SchemaNode } from "./schemaField";
|
|
36
|
+
import {
|
|
37
|
+
DataExpression,
|
|
38
|
+
DataMatchExpression,
|
|
39
|
+
EntityExpression,
|
|
40
|
+
ExpressionType,
|
|
41
|
+
JsonataExpression,
|
|
42
|
+
} from "./entityExpression";
|
|
43
|
+
|
|
44
|
+
export function dataControl(
|
|
45
|
+
field: string,
|
|
46
|
+
title?: string | null,
|
|
47
|
+
options?: Partial<DataControlDefinition>,
|
|
48
|
+
): DataControlDefinition {
|
|
49
|
+
return { type: ControlDefinitionType.Data, field, title, ...options };
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function validatorOptions<A extends { type: string }>(
|
|
53
|
+
type: ValidatorType,
|
|
54
|
+
): (options: Omit<A, "type">) => A {
|
|
55
|
+
return (o) => ({ type, ...o }) as A;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function adornmentOptions<A extends { type: string }>(
|
|
59
|
+
type: ControlAdornmentType,
|
|
60
|
+
): (options: Omit<A, "type">) => A {
|
|
61
|
+
return (o) => ({ type, ...o }) as A;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function renderOptionsFor<A extends RenderOptions>(
|
|
65
|
+
type: DataRenderType,
|
|
66
|
+
): (options: Omit<A, "type">) => { renderOptions: A } {
|
|
67
|
+
return (o) => ({ renderOptions: { type, ...o } as A });
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export const autocompleteOptions = renderOptionsFor<AutocompleteRenderOptions>(
|
|
71
|
+
DataRenderType.Autocomplete,
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
export const checkListOptions = renderOptionsFor<CheckListRenderOptions>(
|
|
75
|
+
DataRenderType.CheckList,
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
export const radioButtonOptions = renderOptionsFor<RadioButtonRenderOptions>(
|
|
79
|
+
DataRenderType.Radio,
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
export const lengthValidatorOptions = validatorOptions<LengthValidator>(
|
|
83
|
+
ValidatorType.Length,
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
export const jsonataValidatorOptions = validatorOptions<JsonataValidator>(
|
|
87
|
+
ValidatorType.Jsonata,
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
export const dateValidatorOptions = validatorOptions<DateValidator>(
|
|
91
|
+
ValidatorType.Date,
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
export const accordionOptions = adornmentOptions<AccordionAdornment>(
|
|
95
|
+
ControlAdornmentType.Accordion,
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
export const textfieldOptions = renderOptionsFor<TextfieldRenderOptions>(
|
|
99
|
+
DataRenderType.Textfield,
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
export const displayOnlyOptions = renderOptionsFor<DisplayOnlyRenderOptions>(
|
|
103
|
+
DataRenderType.DisplayOnly,
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
export const jsonataOptions = renderOptionsFor<JsonataRenderOptions>(
|
|
107
|
+
DataRenderType.Jsonata,
|
|
108
|
+
);
|
|
109
|
+
|
|
110
|
+
export function textDisplayControl(
|
|
111
|
+
text: string,
|
|
112
|
+
options?: Partial<DisplayControlDefinition>,
|
|
113
|
+
): DisplayControlDefinition {
|
|
114
|
+
return {
|
|
115
|
+
type: ControlDefinitionType.Display,
|
|
116
|
+
displayData: { type: DisplayDataType.Text, text } as TextDisplay,
|
|
117
|
+
...options,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export function htmlDisplayControl(
|
|
122
|
+
html: string,
|
|
123
|
+
options?: Partial<DisplayControlDefinition>,
|
|
124
|
+
): DisplayControlDefinition {
|
|
125
|
+
return {
|
|
126
|
+
type: ControlDefinitionType.Display,
|
|
127
|
+
displayData: { type: DisplayDataType.Html, html } as HtmlDisplay,
|
|
128
|
+
...options,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export function dynamicDefaultValue(expr: EntityExpression): DynamicProperty {
|
|
133
|
+
return { type: DynamicPropertyType.DefaultValue, expr };
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export function dynamicReadonly(expr: EntityExpression): DynamicProperty {
|
|
137
|
+
return { type: DynamicPropertyType.Readonly, expr };
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export function dynamicVisibility(expr: EntityExpression): DynamicProperty {
|
|
141
|
+
return { type: DynamicPropertyType.Visible, expr };
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export function dynamicDisabled(expr: EntityExpression): DynamicProperty {
|
|
145
|
+
return { type: DynamicPropertyType.Disabled, expr };
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export function fieldExpr(field: string): DataExpression {
|
|
149
|
+
return { type: ExpressionType.Data, field };
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export function fieldEqExpr(field: string, value: any): DataMatchExpression {
|
|
153
|
+
return { type: ExpressionType.DataMatch, field, value };
|
|
154
|
+
}
|
|
155
|
+
export function jsonataExpr(expression: string): JsonataExpression {
|
|
156
|
+
return { type: ExpressionType.Jsonata, expression };
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export function groupedControl(
|
|
160
|
+
children: ControlDefinition[],
|
|
161
|
+
title?: string,
|
|
162
|
+
options?: Partial<GroupedControlsDefinition>,
|
|
163
|
+
): GroupedControlsDefinition {
|
|
164
|
+
return {
|
|
165
|
+
type: ControlDefinitionType.Group,
|
|
166
|
+
children,
|
|
167
|
+
title,
|
|
168
|
+
groupOptions: { type: "Standard", hideTitle: !title },
|
|
169
|
+
...options,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
export function compoundControl(
|
|
173
|
+
field: string,
|
|
174
|
+
title: string | undefined,
|
|
175
|
+
children: ControlDefinition[],
|
|
176
|
+
options?: Partial<DataControlDefinition>,
|
|
177
|
+
): DataControlDefinition {
|
|
178
|
+
return {
|
|
179
|
+
type: ControlDefinitionType.Data,
|
|
180
|
+
field,
|
|
181
|
+
children,
|
|
182
|
+
title,
|
|
183
|
+
renderOptions: { type: "Standard" },
|
|
184
|
+
...options,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
export function actionControl(
|
|
189
|
+
actionText: string,
|
|
190
|
+
actionId: string,
|
|
191
|
+
options?: Partial<ActionControlDefinition>,
|
|
192
|
+
): ActionControlDefinition {
|
|
193
|
+
return {
|
|
194
|
+
type: ControlDefinitionType.Action,
|
|
195
|
+
title: actionText,
|
|
196
|
+
actionId,
|
|
197
|
+
...options,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
export function createAction(
|
|
201
|
+
actionId: string,
|
|
202
|
+
onClick: () => void,
|
|
203
|
+
actionText?: string,
|
|
204
|
+
options?: Partial<ActionRendererProps>,
|
|
205
|
+
): ActionRendererProps {
|
|
206
|
+
return { actionId, onClick, actionText: actionText ?? actionId, ...options };
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
export const emptyGroupDefinition: GroupedControlsDefinition = {
|
|
210
|
+
type: ControlDefinitionType.Group,
|
|
211
|
+
children: [],
|
|
212
|
+
groupOptions: { type: GroupRenderType.Standard, hideTitle: true },
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
export function useControlDefinitionForSchema(
|
|
216
|
+
sf: SchemaField[],
|
|
217
|
+
definition: GroupedControlsDefinition = emptyGroupDefinition,
|
|
218
|
+
): GroupedControlsDefinition {
|
|
219
|
+
return useMemo<GroupedControlsDefinition>(
|
|
220
|
+
() => ({
|
|
221
|
+
...definition,
|
|
222
|
+
children: addMissingControls(sf, definition.children ?? []),
|
|
223
|
+
}),
|
|
224
|
+
[sf, definition],
|
|
225
|
+
);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
export interface EditorGroup {
|
|
229
|
+
parent: string;
|
|
230
|
+
group: GroupedControlsDefinition;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
export interface CustomRenderOptions {
|
|
234
|
+
value: string;
|
|
235
|
+
name: string;
|
|
236
|
+
fields?: SchemaField[];
|
|
237
|
+
groups?: EditorGroup[];
|
|
238
|
+
applies?: (sf: SchemaNode) => boolean;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
export type ControlDefinitionExtension = {
|
|
242
|
+
RenderOptions?: CustomRenderOptions | CustomRenderOptions[];
|
|
243
|
+
GroupRenderOptions?: CustomRenderOptions | CustomRenderOptions[];
|
|
244
|
+
ControlAdornment?: CustomRenderOptions | CustomRenderOptions[];
|
|
245
|
+
SchemaValidator?: CustomRenderOptions | CustomRenderOptions[];
|
|
246
|
+
DisplayData?: CustomRenderOptions | CustomRenderOptions[];
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
export function applyExtensionToSchema<A extends SchemaMap>(
|
|
250
|
+
schemaMap: A,
|
|
251
|
+
extension: ControlDefinitionExtension,
|
|
252
|
+
): A {
|
|
253
|
+
const outMap = { ...schemaMap };
|
|
254
|
+
Object.entries(extension).forEach(([field, cro]) => {
|
|
255
|
+
outMap[field as keyof A] = (Array.isArray(cro) ? cro : [cro]).reduce(
|
|
256
|
+
(a, cr) => mergeFields(a, cr.name, cr.value, cr.fields ?? []),
|
|
257
|
+
outMap[field],
|
|
258
|
+
) as A[string];
|
|
259
|
+
});
|
|
260
|
+
return outMap;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
export function applyExtensionsToSchema<A extends SchemaMap>(
|
|
264
|
+
schemaMap: A,
|
|
265
|
+
extensions: ControlDefinitionExtension[],
|
|
266
|
+
) {
|
|
267
|
+
return resolveSchemas(extensions.reduce(applyExtensionToSchema, schemaMap));
|
|
268
|
+
}
|