@react-typed-forms/schemas 15.2.0 → 16.0.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/RenderForm.d.ts +39 -0
- package/lib/controlBuilder.d.ts +3 -6
- package/lib/controlRender.d.ts +107 -87
- package/lib/index.cjs +535 -2117
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.ts +3 -9
- package/lib/index.js +402 -1639
- package/lib/index.js.map +1 -1
- package/lib/renderers.d.ts +3 -3
- package/lib/types.d.ts +31 -0
- package/lib/util.d.ts +8 -54
- package/package.json +5 -4
- package/src/RenderForm.tsx +301 -0
- package/src/controlBuilder.ts +22 -19
- package/src/controlRender.tsx +228 -507
- package/src/createFormRenderer.tsx +4 -5
- package/src/index.ts +3 -9
- package/src/renderers.tsx +2 -3
- package/src/types.ts +52 -0
- package/src/util.ts +149 -183
- package/lib/controlDefinition.d.ts +0 -398
- package/lib/defaultSchemaInterface.d.ts +0 -24
- package/lib/dynamicHooks.d.ts +0 -54
- package/lib/entityExpression.d.ts +0 -32
- package/lib/hooks.d.ts +0 -28
- package/lib/schemaBuilder.d.ts +0 -67
- package/lib/schemaField.d.ts +0 -252
- package/lib/schemaValidator.d.ts +0 -27
- package/lib/validators.d.ts +0 -19
- package/src/controlDefinition.ts +0 -821
- package/src/defaultSchemaInterface.ts +0 -191
- package/src/dynamicHooks.ts +0 -98
- package/src/entityExpression.ts +0 -38
- package/src/hooks.tsx +0 -469
- package/src/schemaBuilder.ts +0 -318
- package/src/schemaField.ts +0 -552
- package/src/schemaValidator.ts +0 -32
- package/src/validators.ts +0 -217
package/lib/renderers.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ReactElement, ReactNode } from "react";
|
|
2
|
-
import {
|
|
3
|
-
import { AccordionAdornment, ControlAdornment, IconAdornment, OptionalAdornment, RenderOptions, SetFieldAdornment } from "
|
|
2
|
+
import { AdornmentProps, AdornmentRenderer, ArrayRendererProps, ControlLayoutProps, DataRendererProps, DisplayRendererProps, FormRenderer, GroupRendererProps, HtmlComponents, LabelRendererProps, LabelType, RenderedControl, VisibilityRendererProps } from "./controlRender";
|
|
3
|
+
import { AccordionAdornment, ControlAdornment, IconAdornment, OptionalAdornment, RenderOptions, SetFieldAdornment } from "@astroapps/forms-core";
|
|
4
|
+
import { ActionRendererProps } from "./types";
|
|
4
5
|
export interface DefaultRenderers {
|
|
5
6
|
data: DataRendererRegistration;
|
|
6
7
|
label: LabelRendererRegistration;
|
|
@@ -12,7 +13,6 @@ export interface DefaultRenderers {
|
|
|
12
13
|
renderLayout: LayoutRendererRegistration;
|
|
13
14
|
visibility: VisibilityRendererRegistration;
|
|
14
15
|
extraRenderers: RendererRegistration[];
|
|
15
|
-
renderText: (props: ReactNode) => ReactNode;
|
|
16
16
|
html: HtmlComponents;
|
|
17
17
|
}
|
|
18
18
|
export interface LayoutRendererRegistration {
|
package/lib/types.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { ActionStyle, EntityExpression, FormContextData, IconPlacement, IconReference, SchemaDataNode, SchemaInterface } from "@astroapps/forms-core";
|
|
2
|
+
import React, { Key, ReactNode } from "react";
|
|
3
|
+
import { CleanupScope } from "@react-typed-forms/core";
|
|
4
|
+
/**
|
|
5
|
+
* Interface representing the control data context.
|
|
6
|
+
*/
|
|
7
|
+
export interface ControlDataContext {
|
|
8
|
+
schemaInterface: SchemaInterface;
|
|
9
|
+
dataNode: SchemaDataNode | undefined;
|
|
10
|
+
parentNode: SchemaDataNode;
|
|
11
|
+
variables: Record<string, any>;
|
|
12
|
+
}
|
|
13
|
+
export type ControlActionHandler = (actionId: string, actionData: any, ctx: ControlDataContext) => (() => void) | undefined;
|
|
14
|
+
export interface ActionRendererProps {
|
|
15
|
+
key?: Key;
|
|
16
|
+
actionId: string;
|
|
17
|
+
actionContent?: ReactNode;
|
|
18
|
+
actionText: string;
|
|
19
|
+
actionData?: any;
|
|
20
|
+
actionStyle?: ActionStyle | null;
|
|
21
|
+
icon?: IconReference | null;
|
|
22
|
+
iconPlacement?: IconPlacement | null;
|
|
23
|
+
onClick: () => void;
|
|
24
|
+
className?: string | null;
|
|
25
|
+
textClass?: string | null;
|
|
26
|
+
style?: React.CSSProperties;
|
|
27
|
+
disabled?: boolean;
|
|
28
|
+
hidden?: boolean;
|
|
29
|
+
inline?: boolean;
|
|
30
|
+
}
|
|
31
|
+
export type RunExpression = (scope: CleanupScope, expression: EntityExpression, returnResult: (v: unknown) => void, bindings?: FormContextData) => void;
|
package/lib/util.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CompoundField, ControlDataVisitor, ControlDefinition, DataControlDefinition, EntityExpression, FieldOption, SchemaDataNode, SchemaField, SchemaNode } from "@astroapps/forms-core";
|
|
2
2
|
import { MutableRefObject } from "react";
|
|
3
|
-
import { CompoundField, FieldOption, SchemaDataNode, SchemaField, SchemaNode } from "./schemaField";
|
|
4
3
|
import { Control } from "@react-typed-forms/core";
|
|
5
|
-
import { ActionRendererProps } from "./
|
|
4
|
+
import { ActionRendererProps, ControlActionHandler, RunExpression } from "./types";
|
|
6
5
|
/**
|
|
7
6
|
* Interface representing the classes for a control.
|
|
8
7
|
*/
|
|
@@ -10,11 +9,9 @@ export interface ControlClasses {
|
|
|
10
9
|
styleClass?: string;
|
|
11
10
|
layoutClass?: string;
|
|
12
11
|
labelClass?: string;
|
|
12
|
+
textClass?: string;
|
|
13
|
+
labelTextClass?: string;
|
|
13
14
|
}
|
|
14
|
-
/**
|
|
15
|
-
* Type representing a JSON path, which can be a string or a number.
|
|
16
|
-
*/
|
|
17
|
-
export type JsonPath = string | number;
|
|
18
15
|
/**
|
|
19
16
|
* Applies default values to the given record based on the provided schema fields.
|
|
20
17
|
* @param v - The record to apply default values to.
|
|
@@ -117,47 +114,22 @@ export declare function addMissingControls(fields: SchemaField[], controls: Cont
|
|
|
117
114
|
* @returns The control definitions with missing controls added.
|
|
118
115
|
*/
|
|
119
116
|
export declare function addMissingControlsForSchema(schema: SchemaNode, controls: ControlDefinition[], warning?: (msg: string) => void): ControlDefinition[];
|
|
120
|
-
/**
|
|
121
|
-
* Adds missing controls to the provided form tree based on the schema fields.
|
|
122
|
-
* @param schema - The root schema node to use for adding missing controls.
|
|
123
|
-
* @param tree - The form tree to add missing controls to.
|
|
124
|
-
* @param warning - An optional function to call with warning messages.
|
|
125
|
-
*/
|
|
126
|
-
export declare function addMissingControlsToForm(schema: SchemaNode, tree: FormTree, warning?: (msg: string) => void): void;
|
|
127
117
|
/**
|
|
128
118
|
* Custom hook to use an updated reference.
|
|
129
119
|
* @param a - The value to create a reference for.
|
|
130
120
|
* @returns A mutable reference object.
|
|
131
121
|
*/
|
|
132
122
|
export declare function useUpdatedRef<A>(a: A): MutableRefObject<A>;
|
|
133
|
-
/**
|
|
134
|
-
* Checks if a control definition is readonly.
|
|
135
|
-
* @param c - The control definition to check.
|
|
136
|
-
* @returns True if the control definition is readonly, false otherwise.
|
|
137
|
-
*/
|
|
138
|
-
export declare function isControlReadonly(c: ControlDefinition): boolean;
|
|
139
|
-
/**
|
|
140
|
-
* Checks if a control definition is disabled.
|
|
141
|
-
* @param c - The control definition to check.
|
|
142
|
-
* @returns True if the control definition is disabled, false otherwise.
|
|
143
|
-
*/
|
|
144
|
-
export declare function isControlDisabled(c: ControlDefinition): boolean;
|
|
145
|
-
/**
|
|
146
|
-
* Returns the display-only render options for a control definition.
|
|
147
|
-
* @param d - The control definition to get the display-only render options for.
|
|
148
|
-
* @returns The display-only render options, or undefined if not applicable.
|
|
149
|
-
*/
|
|
150
|
-
export declare function getDisplayOnlyOptions(d: ControlDefinition): DisplayOnlyRenderOptions | undefined;
|
|
151
123
|
/**
|
|
152
124
|
* Cleans data for a schema based on the provided schema fields.
|
|
153
125
|
* @param v - The data to clean.
|
|
154
|
-
* @param
|
|
126
|
+
* @param schemaNode
|
|
155
127
|
* @param removeIfDefault - Flag indicating if default values should be removed.
|
|
156
128
|
* @returns The cleaned data.
|
|
157
129
|
*/
|
|
158
130
|
export declare function cleanDataForSchema(v: {
|
|
159
131
|
[k: string]: any;
|
|
160
|
-
} | undefined,
|
|
132
|
+
} | undefined, schemaNode: SchemaNode, removeIfDefault?: boolean): any;
|
|
161
133
|
/**
|
|
162
134
|
* Returns all referenced classes for a control definition.
|
|
163
135
|
* @param c - The control definition to get the referenced classes for.
|
|
@@ -165,13 +137,6 @@ export declare function cleanDataForSchema(v: {
|
|
|
165
137
|
* @returns An array of referenced classes.
|
|
166
138
|
*/
|
|
167
139
|
export declare function getAllReferencedClasses(c: ControlDefinition, collectExtra?: (c: ControlDefinition) => (string | undefined | null)[]): string[];
|
|
168
|
-
/**
|
|
169
|
-
* Converts a JSON path array to a string.
|
|
170
|
-
* @param jsonPath - The JSON path array to convert.
|
|
171
|
-
* @param customIndex - Optional function to customize the index format.
|
|
172
|
-
* @returns The JSON path string.
|
|
173
|
-
*/
|
|
174
|
-
export declare function jsonPathString(jsonPath: JsonPath[], customIndex?: (n: number) => string): string;
|
|
175
140
|
/**
|
|
176
141
|
* Finds a child control definition within a parent control definition.
|
|
177
142
|
* @param parent - The parent control definition.
|
|
@@ -231,30 +196,18 @@ export declare function deepMerge<A>(value: A, fallback: A): A;
|
|
|
231
196
|
* @returns {string} - The coerced string.
|
|
232
197
|
*/
|
|
233
198
|
export declare function coerceToString(v: unknown): string;
|
|
234
|
-
/**
|
|
235
|
-
* Returns the group renderer options for a control definition.
|
|
236
|
-
* @param {ControlDefinition} def - The control definition to get the group renderer options for.
|
|
237
|
-
* @returns {GroupRenderOptions | undefined} - The group renderer options, or undefined if not applicable.
|
|
238
|
-
*/
|
|
239
|
-
export declare function getGroupRendererOptions(def: ControlDefinition): GroupRenderOptions | undefined;
|
|
240
199
|
/**
|
|
241
200
|
* Returns the group class overrides for a control definition.
|
|
242
201
|
* @param {ControlDefinition} def - The control definition to get the group class overrides for.
|
|
243
202
|
* @returns {ControlClasses} - The group class overrides.
|
|
244
203
|
*/
|
|
245
204
|
export declare function getGroupClassOverrides(def: ControlDefinition): ControlClasses;
|
|
246
|
-
/**
|
|
247
|
-
* Checks if a control definition is display-only.
|
|
248
|
-
* @param {ControlDefinition} def - The control definition to check.
|
|
249
|
-
* @returns {boolean} - True if the control definition is display-only, false otherwise.
|
|
250
|
-
*/
|
|
251
|
-
export declare function isControlDisplayOnly(def: ControlDefinition): boolean;
|
|
252
205
|
/**
|
|
253
206
|
* Combines multiple action handlers into a single handler.
|
|
254
207
|
* @param {...(ControlActionHandler | undefined)[]} handlers - The action handlers to combine.
|
|
255
208
|
* @returns {ControlActionHandler} - The combined action handler.
|
|
256
209
|
*/
|
|
257
|
-
export declare function actionHandlers(...handlers: (ControlActionHandler | undefined)[]): ControlActionHandler;
|
|
210
|
+
export declare function actionHandlers(...handlers: (ControlActionHandler | undefined)[]): ControlActionHandler | undefined;
|
|
258
211
|
export declare function getDiffObject(dataNode: SchemaDataNode, force?: boolean): any;
|
|
259
212
|
export declare function getNullToggler(c: Control<any>): Control<boolean>;
|
|
260
213
|
export interface ExternalEditAction {
|
|
@@ -275,3 +228,4 @@ export declare function collectDifferences(dataNode: SchemaDataNode, values: unk
|
|
|
275
228
|
editing: number;
|
|
276
229
|
};
|
|
277
230
|
export declare function validationVisitor(onInvalid: (data: Control<unknown>) => void): ControlDataVisitor<any>;
|
|
231
|
+
export declare function useExpression<T>(defaultValue: T, runExpression: RunExpression, expression: EntityExpression | null | undefined, coerce: (x: any) => T, bindings?: Record<string, any>): Control<T>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@react-typed-forms/schemas",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "16.0.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.cjs",
|
|
@@ -33,15 +33,16 @@
|
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"clsx": "^1 || ^2",
|
|
35
35
|
"uuid": "^10.0.0",
|
|
36
|
-
"jsonata": "^2.0.4"
|
|
36
|
+
"jsonata": "^2.0.4",
|
|
37
|
+
"@astroapps/forms-core": "^1.0.0"
|
|
37
38
|
},
|
|
38
39
|
"peerDependencies": {
|
|
39
40
|
"react": "^18.2.0 || ^19",
|
|
40
|
-
"@react-typed-forms/core": "^4.
|
|
41
|
+
"@react-typed-forms/core": "^4.4.0"
|
|
41
42
|
},
|
|
42
43
|
"devDependencies": {
|
|
43
44
|
"react": "^18.2.0 || ^19",
|
|
44
|
-
"@react-typed-forms/core": "^4.
|
|
45
|
+
"@react-typed-forms/core": "^4.4.0",
|
|
45
46
|
"@react-typed-forms/transform": "^0.2.0",
|
|
46
47
|
"jest": "^29.7.0",
|
|
47
48
|
"tsx": "^4.19.1",
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ControlLayoutProps,
|
|
3
|
+
ControlRenderOptions,
|
|
4
|
+
ControlRenderProps,
|
|
5
|
+
defaultDataProps,
|
|
6
|
+
FormRenderer,
|
|
7
|
+
renderControlLayout,
|
|
8
|
+
Visibility,
|
|
9
|
+
} from "./controlRender";
|
|
10
|
+
import React, {
|
|
11
|
+
FC,
|
|
12
|
+
useCallback,
|
|
13
|
+
useEffect,
|
|
14
|
+
useMemo,
|
|
15
|
+
useRef,
|
|
16
|
+
useState,
|
|
17
|
+
} from "react";
|
|
18
|
+
import {
|
|
19
|
+
ControlDefinition,
|
|
20
|
+
ControlState,
|
|
21
|
+
createFormState,
|
|
22
|
+
createSchemaDataNode,
|
|
23
|
+
createSchemaTree,
|
|
24
|
+
defaultSchemaInterface,
|
|
25
|
+
FormNode,
|
|
26
|
+
FormState,
|
|
27
|
+
isDataControl,
|
|
28
|
+
JsonPath,
|
|
29
|
+
legacyFormNode,
|
|
30
|
+
SchemaDataNode,
|
|
31
|
+
SchemaField,
|
|
32
|
+
} from "@astroapps/forms-core";
|
|
33
|
+
import { ControlDataContext } from "./types";
|
|
34
|
+
import {
|
|
35
|
+
actionHandlers,
|
|
36
|
+
getGroupClassOverrides,
|
|
37
|
+
rendererClass,
|
|
38
|
+
useUpdatedRef,
|
|
39
|
+
} from "./util";
|
|
40
|
+
import { Control, useControl } from "@react-typed-forms/core";
|
|
41
|
+
|
|
42
|
+
export interface RenderFormProps {
|
|
43
|
+
data: SchemaDataNode;
|
|
44
|
+
form: FormNode;
|
|
45
|
+
renderer: FormRenderer;
|
|
46
|
+
options?: ControlRenderOptions;
|
|
47
|
+
}
|
|
48
|
+
/* @trackControls */
|
|
49
|
+
export function RenderForm({
|
|
50
|
+
data,
|
|
51
|
+
form,
|
|
52
|
+
renderer,
|
|
53
|
+
options = {},
|
|
54
|
+
}: RenderFormProps) {
|
|
55
|
+
const schemaInterface = options.schemaInterface ?? defaultSchemaInterface;
|
|
56
|
+
const [formState, setFormState] = useState(
|
|
57
|
+
() => options?.formState ?? createFormState(schemaInterface),
|
|
58
|
+
);
|
|
59
|
+
const state = formState.getControlState(data, form, options);
|
|
60
|
+
|
|
61
|
+
useEffect(() => {
|
|
62
|
+
if (!options?.formState) {
|
|
63
|
+
return () => formState.cleanup();
|
|
64
|
+
}
|
|
65
|
+
}, [formState, options?.formState]);
|
|
66
|
+
|
|
67
|
+
const definition = state.definition;
|
|
68
|
+
|
|
69
|
+
const visible = !state.hidden;
|
|
70
|
+
|
|
71
|
+
const visibility = useControl<Visibility | undefined>(() =>
|
|
72
|
+
visible != null
|
|
73
|
+
? {
|
|
74
|
+
visible,
|
|
75
|
+
showing: visible,
|
|
76
|
+
}
|
|
77
|
+
: undefined,
|
|
78
|
+
);
|
|
79
|
+
visibility.fields.visible.value = visible;
|
|
80
|
+
|
|
81
|
+
const dataContext: ControlDataContext = {
|
|
82
|
+
schemaInterface: state.schemaInterface,
|
|
83
|
+
dataNode: state.dataNode,
|
|
84
|
+
parentNode: data,
|
|
85
|
+
variables: state.variables,
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
const adornments =
|
|
89
|
+
definition.adornments?.map((x) =>
|
|
90
|
+
renderer.renderAdornment({
|
|
91
|
+
adornment: x,
|
|
92
|
+
dataContext,
|
|
93
|
+
formOptions: state,
|
|
94
|
+
}),
|
|
95
|
+
) ?? [];
|
|
96
|
+
|
|
97
|
+
const {
|
|
98
|
+
styleClass,
|
|
99
|
+
labelClass,
|
|
100
|
+
layoutClass,
|
|
101
|
+
labelTextClass,
|
|
102
|
+
textClass,
|
|
103
|
+
...inheritableOptions
|
|
104
|
+
} = options;
|
|
105
|
+
const { readonly, hidden, disabled, variables } = state;
|
|
106
|
+
const childOptions: ControlRenderOptions = {
|
|
107
|
+
...inheritableOptions,
|
|
108
|
+
readonly,
|
|
109
|
+
disabled,
|
|
110
|
+
variables,
|
|
111
|
+
formState,
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
const labelAndChildren = renderControlLayout({
|
|
115
|
+
formNode: form,
|
|
116
|
+
renderer,
|
|
117
|
+
state,
|
|
118
|
+
renderChild: (k, child, options) => {
|
|
119
|
+
const overrideClasses = getGroupClassOverrides(definition);
|
|
120
|
+
const { parentDataNode, actionOnClick, variables, ...renderOptions } =
|
|
121
|
+
options ?? {};
|
|
122
|
+
const dContext = parentDataNode ?? dataContext.dataNode ?? data;
|
|
123
|
+
const allChildOptions = {
|
|
124
|
+
...childOptions,
|
|
125
|
+
...overrideClasses,
|
|
126
|
+
...renderOptions,
|
|
127
|
+
variables: { ...childOptions.variables, ...variables },
|
|
128
|
+
actionOnClick: actionHandlers(
|
|
129
|
+
actionOnClick,
|
|
130
|
+
childOptions.actionOnClick,
|
|
131
|
+
),
|
|
132
|
+
};
|
|
133
|
+
return (
|
|
134
|
+
<RenderForm
|
|
135
|
+
key={k}
|
|
136
|
+
form={child}
|
|
137
|
+
renderer={renderer}
|
|
138
|
+
data={dContext}
|
|
139
|
+
options={allChildOptions}
|
|
140
|
+
/>
|
|
141
|
+
);
|
|
142
|
+
},
|
|
143
|
+
inline: options?.inline,
|
|
144
|
+
displayOnly: options?.displayOnly,
|
|
145
|
+
createDataProps: defaultDataProps,
|
|
146
|
+
formOptions: state,
|
|
147
|
+
dataContext,
|
|
148
|
+
control: dataContext.dataNode?.control,
|
|
149
|
+
schemaInterface,
|
|
150
|
+
style: state.style,
|
|
151
|
+
allowedOptions: state.allowedOptions,
|
|
152
|
+
customDisplay: options.customDisplay,
|
|
153
|
+
actionOnClick: options.actionOnClick,
|
|
154
|
+
styleClass: styleClass,
|
|
155
|
+
labelClass: labelClass,
|
|
156
|
+
labelTextClass: labelTextClass,
|
|
157
|
+
textClass: textClass,
|
|
158
|
+
getChildState(child: FormNode, parent?: SchemaDataNode): ControlState {
|
|
159
|
+
return formState.getControlState(
|
|
160
|
+
parent ?? state.dataNode ?? data,
|
|
161
|
+
child,
|
|
162
|
+
childOptions,
|
|
163
|
+
);
|
|
164
|
+
},
|
|
165
|
+
runExpression: (scope, expr, returnResult) => {
|
|
166
|
+
if (expr?.type) {
|
|
167
|
+
formState.evalExpression(expr, {
|
|
168
|
+
scope,
|
|
169
|
+
dataNode: data,
|
|
170
|
+
schemaInterface,
|
|
171
|
+
returnResult,
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
},
|
|
175
|
+
});
|
|
176
|
+
const layoutProps: ControlLayoutProps = {
|
|
177
|
+
...labelAndChildren,
|
|
178
|
+
adornments,
|
|
179
|
+
className: rendererClass(options.layoutClass, definition.layoutClass),
|
|
180
|
+
style: state.layoutStyle,
|
|
181
|
+
};
|
|
182
|
+
const renderedControl = renderer.renderLayout(
|
|
183
|
+
options.adjustLayout?.(dataContext, layoutProps) ?? layoutProps,
|
|
184
|
+
);
|
|
185
|
+
return renderer.renderVisibility({ visibility, ...renderedControl });
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* @deprecated Use RenderForm instead.
|
|
190
|
+
*/
|
|
191
|
+
export function useControlRendererComponent(
|
|
192
|
+
controlOrFormNode: ControlDefinition | FormNode,
|
|
193
|
+
renderer: FormRenderer,
|
|
194
|
+
options: ControlRenderOptions = {},
|
|
195
|
+
parentDataNode: SchemaDataNode,
|
|
196
|
+
): FC<{}> {
|
|
197
|
+
const [definition, formNode] =
|
|
198
|
+
"definition" in controlOrFormNode
|
|
199
|
+
? [controlOrFormNode.definition, controlOrFormNode]
|
|
200
|
+
: [controlOrFormNode, legacyFormNode(controlOrFormNode)];
|
|
201
|
+
|
|
202
|
+
const r = useUpdatedRef({
|
|
203
|
+
options,
|
|
204
|
+
renderer,
|
|
205
|
+
parentDataNode,
|
|
206
|
+
formNode,
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
return useMemo(
|
|
210
|
+
() => () => {
|
|
211
|
+
const { options, parentDataNode, formNode, renderer } = r.current;
|
|
212
|
+
return (
|
|
213
|
+
<RenderForm
|
|
214
|
+
data={parentDataNode}
|
|
215
|
+
form={formNode}
|
|
216
|
+
renderer={renderer}
|
|
217
|
+
options={options}
|
|
218
|
+
/>
|
|
219
|
+
);
|
|
220
|
+
},
|
|
221
|
+
[r],
|
|
222
|
+
);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* @deprecated Use RenderForm instead.
|
|
227
|
+
*/
|
|
228
|
+
export function ControlRenderer({
|
|
229
|
+
definition,
|
|
230
|
+
fields,
|
|
231
|
+
renderer,
|
|
232
|
+
options,
|
|
233
|
+
control,
|
|
234
|
+
parentPath,
|
|
235
|
+
}: {
|
|
236
|
+
definition: ControlDefinition;
|
|
237
|
+
fields: SchemaField[];
|
|
238
|
+
renderer: FormRenderer;
|
|
239
|
+
options?: ControlRenderOptions;
|
|
240
|
+
control: Control<any>;
|
|
241
|
+
parentPath?: JsonPath[];
|
|
242
|
+
}) {
|
|
243
|
+
const schemaDataNode = createSchemaDataNode(
|
|
244
|
+
createSchemaTree(fields).rootNode,
|
|
245
|
+
control,
|
|
246
|
+
);
|
|
247
|
+
const Render = useControlRendererComponent(
|
|
248
|
+
definition,
|
|
249
|
+
renderer,
|
|
250
|
+
options,
|
|
251
|
+
schemaDataNode,
|
|
252
|
+
);
|
|
253
|
+
return <Render />;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* @deprecated Use RenderForm instead.
|
|
258
|
+
*/
|
|
259
|
+
export function NewControlRenderer({
|
|
260
|
+
definition,
|
|
261
|
+
renderer,
|
|
262
|
+
options,
|
|
263
|
+
parentDataNode,
|
|
264
|
+
}: {
|
|
265
|
+
definition: ControlDefinition | FormNode;
|
|
266
|
+
renderer: FormRenderer;
|
|
267
|
+
options?: ControlRenderOptions;
|
|
268
|
+
parentDataNode: SchemaDataNode;
|
|
269
|
+
}) {
|
|
270
|
+
const Render = useControlRendererComponent(
|
|
271
|
+
definition,
|
|
272
|
+
renderer,
|
|
273
|
+
options,
|
|
274
|
+
parentDataNode,
|
|
275
|
+
);
|
|
276
|
+
return <Render />;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* @deprecated Use RenderForm instead.
|
|
281
|
+
*/
|
|
282
|
+
export function useControlRenderer(
|
|
283
|
+
definition: ControlDefinition,
|
|
284
|
+
fields: SchemaField[],
|
|
285
|
+
renderer: FormRenderer,
|
|
286
|
+
options: ControlRenderOptions = {},
|
|
287
|
+
): FC<ControlRenderProps> {
|
|
288
|
+
const r = useUpdatedRef({ definition, fields, renderer, options });
|
|
289
|
+
return useCallback(
|
|
290
|
+
({ control, parentPath }) => {
|
|
291
|
+
return (
|
|
292
|
+
<ControlRenderer
|
|
293
|
+
{...r.current}
|
|
294
|
+
control={control}
|
|
295
|
+
parentPath={parentPath}
|
|
296
|
+
/>
|
|
297
|
+
);
|
|
298
|
+
},
|
|
299
|
+
[r],
|
|
300
|
+
);
|
|
301
|
+
}
|
package/src/controlBuilder.ts
CHANGED
|
@@ -7,39 +7,37 @@ import {
|
|
|
7
7
|
ControlDefinition,
|
|
8
8
|
ControlDefinitionType,
|
|
9
9
|
DataControlDefinition,
|
|
10
|
+
DataExpression,
|
|
11
|
+
DataMatchExpression,
|
|
10
12
|
DataRenderType,
|
|
13
|
+
DateValidator,
|
|
11
14
|
DisplayControlDefinition,
|
|
12
15
|
DisplayDataType,
|
|
13
16
|
DisplayOnlyRenderOptions,
|
|
14
17
|
DynamicProperty,
|
|
15
18
|
DynamicPropertyType,
|
|
19
|
+
EntityExpression,
|
|
20
|
+
ExpressionType,
|
|
16
21
|
GroupedControlsDefinition,
|
|
17
22
|
GroupRenderType,
|
|
18
23
|
HtmlDisplay,
|
|
24
|
+
JsonataExpression,
|
|
19
25
|
JsonataRenderOptions,
|
|
26
|
+
JsonataValidator,
|
|
27
|
+
LengthValidator,
|
|
20
28
|
RadioButtonRenderOptions,
|
|
21
29
|
RenderOptions,
|
|
30
|
+
SchemaField,
|
|
31
|
+
SchemaMap,
|
|
32
|
+
SchemaNode,
|
|
22
33
|
TextDisplay,
|
|
23
34
|
TextfieldRenderOptions,
|
|
24
|
-
|
|
25
|
-
|
|
35
|
+
ValidatorType,
|
|
36
|
+
} from "@astroapps/forms-core";
|
|
26
37
|
import { useMemo } from "react";
|
|
27
38
|
import { addMissingControls } from "./util";
|
|
28
|
-
import { mergeFields, resolveSchemas } from "
|
|
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";
|
|
39
|
+
import { mergeFields, resolveSchemas } from "@astroapps/forms-core";
|
|
40
|
+
import { ActionRendererProps } from "./types";
|
|
43
41
|
|
|
44
42
|
export function dataControl(
|
|
45
43
|
field: string,
|
|
@@ -200,10 +198,15 @@ export function actionControl(
|
|
|
200
198
|
export function createAction(
|
|
201
199
|
actionId: string,
|
|
202
200
|
onClick: () => void,
|
|
203
|
-
actionText?: string,
|
|
201
|
+
actionText?: string | null,
|
|
204
202
|
options?: Partial<ActionRendererProps>,
|
|
205
203
|
): ActionRendererProps {
|
|
206
|
-
return {
|
|
204
|
+
return {
|
|
205
|
+
actionId,
|
|
206
|
+
onClick,
|
|
207
|
+
actionText: actionText ?? actionId,
|
|
208
|
+
...options,
|
|
209
|
+
};
|
|
207
210
|
}
|
|
208
211
|
|
|
209
212
|
export const emptyGroupDefinition: GroupedControlsDefinition = {
|