@react-typed-forms/schemas 14.1.3 → 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 +21 -2
- package/lib/controlRender.d.ts +3 -2
- 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 +12 -1
- 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,7 +1,8 @@
|
|
|
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";
|
|
5
|
+
import { ActionRendererProps } from "./controlRender";
|
|
5
6
|
/**
|
|
6
7
|
* Interface representing the classes for a control.
|
|
7
8
|
*/
|
|
@@ -246,6 +247,15 @@ export declare function isControlDisplayOnly(def: ControlDefinition): boolean;
|
|
|
246
247
|
export declare function actionHandlers(...handlers: (ControlActionHandler | undefined)[]): ControlActionHandler;
|
|
247
248
|
export declare function getDiffObject(dataNode: SchemaDataNode, force?: boolean): any;
|
|
248
249
|
export declare function getNullToggler(c: Control<any>): Control<boolean>;
|
|
250
|
+
export interface ExternalEditAction {
|
|
251
|
+
action: ActionRendererProps;
|
|
252
|
+
dontValidate?: boolean;
|
|
253
|
+
}
|
|
254
|
+
export interface ExternalEditData {
|
|
255
|
+
data: unknown;
|
|
256
|
+
actions: ExternalEditAction[];
|
|
257
|
+
}
|
|
258
|
+
export declare function getExternalEditData(c: Control<any>): Control<ExternalEditData | undefined>;
|
|
249
259
|
export declare function getLastDefinedValue<V>(control: Control<V>): Control<V>;
|
|
250
260
|
export declare function getIsEditing(control: Control<any>): Control<boolean | undefined>;
|
|
251
261
|
export declare function getAllValues(control: Control<any>): Control<unknown[]>;
|
|
@@ -254,3 +264,4 @@ export declare function collectDifferences(dataNode: SchemaDataNode, values: unk
|
|
|
254
264
|
editable: number;
|
|
255
265
|
editing: number;
|
|
256
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
|
+
}
|