@react-typed-forms/schemas 1.0.0-dev.20 → 1.0.0-dev.21
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/.rush/temp/operation/build/state.json +1 -1
- package/.rush/temp/operation/update-readme/state.json +3 -0
- package/.rush/temp/shrinkwrap-deps.json +124 -2
- package/README.md +223 -0
- package/lib/controlRender.d.ts +11 -11
- package/lib/hooks.d.ts +1 -1
- package/lib/index.js +61 -94
- package/lib/index.js.map +1 -1
- package/lib/renderers.d.ts +2 -2
- package/package.json +4 -2
- package/src/controlRender.tsx +37 -88
- package/src/hooks.tsx +20 -22
- package/src/renderers.tsx +8 -8
package/lib/renderers.d.ts
CHANGED
|
@@ -50,8 +50,8 @@ export interface AdornmentRendererRegistration {
|
|
|
50
50
|
adornmentType?: string | string[];
|
|
51
51
|
render: (props: AdornmentProps) => AdornmentRenderer;
|
|
52
52
|
}
|
|
53
|
-
export type
|
|
54
|
-
export declare function createFormRenderer(customRenderers?:
|
|
53
|
+
export type RendererRegistration = DataRendererRegistration | GroupRendererRegistration | DisplayRendererRegistration | ActionRendererRegistration | LabelRendererRegistration | ArrayRendererRegistration | AdornmentRendererRegistration | VisibilityRendererRegistration;
|
|
54
|
+
export declare function createFormRenderer(customRenderers?: RendererRegistration[], defaultRenderers?: DefaultRenderers): FormRenderer;
|
|
55
55
|
interface DefaultLabelRendererOptions {
|
|
56
56
|
className?: string;
|
|
57
57
|
groupLabelClass?: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@react-typed-forms/schemas",
|
|
3
|
-
"version": "1.0.0-dev.
|
|
3
|
+
"version": "1.0.0-dev.21",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -36,12 +36,14 @@
|
|
|
36
36
|
"nswag": "^13.18.2",
|
|
37
37
|
"prettier": "^3.0.3",
|
|
38
38
|
"rimraf": "^3.0.2",
|
|
39
|
-
"typescript": "^5.2.2"
|
|
39
|
+
"typescript": "^5.2.2",
|
|
40
|
+
"markdown-magic": "^2.6.1"
|
|
40
41
|
},
|
|
41
42
|
"gitHead": "698e16cd3ab31b7dd0528fc76536f4d3205ce8c6",
|
|
42
43
|
"scripts": {
|
|
43
44
|
"build": "rimraf ./lib/ && microbundle -f cjs --no-compress --jsx React.createElement --jsxFragment React.Fragment",
|
|
44
45
|
"watch": "microbundle -w -f cjs --no-compress --jsx React.createElement --jsxFragment React.Fragment",
|
|
46
|
+
"update-readme": "md-magic --path README.md",
|
|
45
47
|
"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"
|
|
46
48
|
}
|
|
47
49
|
}
|
package/src/controlRender.tsx
CHANGED
|
@@ -15,9 +15,16 @@ import {
|
|
|
15
15
|
SchemaValidator,
|
|
16
16
|
visitControlDefinition,
|
|
17
17
|
} from "./types";
|
|
18
|
-
import React, {
|
|
19
|
-
import {Control, newControl} from "@react-typed-forms/core";
|
|
20
|
-
import {
|
|
18
|
+
import React, { Key, ReactElement, ReactNode } from "react";
|
|
19
|
+
import { Control, newControl } from "@react-typed-forms/core";
|
|
20
|
+
import {
|
|
21
|
+
fieldDisplayName,
|
|
22
|
+
findCompoundField,
|
|
23
|
+
findField,
|
|
24
|
+
findScalarField,
|
|
25
|
+
isDataControl,
|
|
26
|
+
isGroupControl,
|
|
27
|
+
} from "./util";
|
|
21
28
|
|
|
22
29
|
export interface SchemaHooks {
|
|
23
30
|
useExpression(
|
|
@@ -38,13 +45,10 @@ export interface FormEditHooks {
|
|
|
38
45
|
formState: FormEditState,
|
|
39
46
|
definition: DataControlDefinition,
|
|
40
47
|
field: SchemaField,
|
|
41
|
-
renderers: FormRenderer,
|
|
42
48
|
): DataRendererProps;
|
|
43
49
|
useGroupProperties(
|
|
44
50
|
formState: FormEditState,
|
|
45
51
|
definition: GroupedControlsDefinition,
|
|
46
|
-
currentHooks: FormEditHooks,
|
|
47
|
-
renderers: FormRenderer,
|
|
48
52
|
): GroupRendererProps;
|
|
49
53
|
useDisplayProperties(
|
|
50
54
|
formState: FormEditState,
|
|
@@ -87,13 +91,19 @@ export interface ControlData {
|
|
|
87
91
|
[field: string]: any;
|
|
88
92
|
}
|
|
89
93
|
|
|
90
|
-
export interface
|
|
94
|
+
export interface FormDataContext {
|
|
91
95
|
fields: SchemaField[];
|
|
92
96
|
data: Control<ControlData>;
|
|
97
|
+
}
|
|
98
|
+
export interface FormEditState extends FormDataContext {
|
|
99
|
+
hooks: FormEditHooks;
|
|
100
|
+
renderer: FormRenderer;
|
|
93
101
|
readonly?: boolean;
|
|
94
102
|
invisible?: boolean;
|
|
95
103
|
}
|
|
96
104
|
|
|
105
|
+
export type RenderControlOptions = Omit<FormEditState, "data">;
|
|
106
|
+
|
|
97
107
|
export interface ArrayRendererProps {
|
|
98
108
|
definition: DataControlDefinition | GroupedControlsDefinition;
|
|
99
109
|
control: Control<any[]>;
|
|
@@ -126,37 +136,6 @@ export interface FormRenderer {
|
|
|
126
136
|
renderAdornment: (props: AdornmentProps) => AdornmentRenderer;
|
|
127
137
|
}
|
|
128
138
|
|
|
129
|
-
let _FormRendererComponentsContext: Context<FormRenderer | undefined> | null =
|
|
130
|
-
null;
|
|
131
|
-
|
|
132
|
-
function FormRendererComponentsContext() {
|
|
133
|
-
if (!_FormRendererComponentsContext) {
|
|
134
|
-
_FormRendererComponentsContext = createContext<FormRenderer | undefined>(
|
|
135
|
-
undefined,
|
|
136
|
-
);
|
|
137
|
-
}
|
|
138
|
-
return _FormRendererComponentsContext;
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
export function FormRendererProvider({
|
|
142
|
-
value,
|
|
143
|
-
children,
|
|
144
|
-
}: {
|
|
145
|
-
value: FormRenderer;
|
|
146
|
-
children: ReactNode;
|
|
147
|
-
}) {
|
|
148
|
-
const { Provider } = FormRendererComponentsContext();
|
|
149
|
-
return <Provider value={value} children={children} />;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
export function useFormRendererComponents() {
|
|
153
|
-
const c = useContext(FormRendererComponentsContext());
|
|
154
|
-
if (!c) {
|
|
155
|
-
throw "Need to use FormRendererComponentContext.Provider";
|
|
156
|
-
}
|
|
157
|
-
return c;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
139
|
export interface Visibility {
|
|
161
140
|
value: boolean;
|
|
162
141
|
canChange: boolean;
|
|
@@ -195,11 +174,12 @@ export function controlTitle(
|
|
|
195
174
|
|
|
196
175
|
export function renderControl<S extends ControlDefinition>(
|
|
197
176
|
definition: S,
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
key
|
|
177
|
+
data: Control<any>,
|
|
178
|
+
options: RenderControlOptions,
|
|
179
|
+
key?: Key,
|
|
201
180
|
): ReactElement {
|
|
202
|
-
const { fields } =
|
|
181
|
+
const { fields } = options;
|
|
182
|
+
const formState = { ...options, data };
|
|
203
183
|
return visitControlDefinition(
|
|
204
184
|
definition,
|
|
205
185
|
{
|
|
@@ -211,35 +191,19 @@ export function renderControl<S extends ControlDefinition>(
|
|
|
211
191
|
<DataRenderer
|
|
212
192
|
key={key}
|
|
213
193
|
formState={formState}
|
|
214
|
-
hooks={hooks}
|
|
215
194
|
controlDef={def}
|
|
216
195
|
fieldData={fieldData}
|
|
217
196
|
/>
|
|
218
197
|
);
|
|
219
198
|
},
|
|
220
199
|
group: (d: GroupedControlsDefinition) => (
|
|
221
|
-
<GroupRenderer
|
|
222
|
-
key={key}
|
|
223
|
-
hooks={hooks}
|
|
224
|
-
groupDef={d}
|
|
225
|
-
formState={formState}
|
|
226
|
-
/>
|
|
200
|
+
<GroupRenderer key={key} groupDef={d} formState={formState} />
|
|
227
201
|
),
|
|
228
202
|
action: (d: ActionControlDefinition) => (
|
|
229
|
-
<ActionRenderer
|
|
230
|
-
key={key}
|
|
231
|
-
hooks={hooks}
|
|
232
|
-
formState={formState}
|
|
233
|
-
actionDef={d}
|
|
234
|
-
/>
|
|
203
|
+
<ActionRenderer key={key} formState={formState} actionDef={d} />
|
|
235
204
|
),
|
|
236
205
|
display: (d: DisplayControlDefinition) => (
|
|
237
|
-
<DisplayRenderer
|
|
238
|
-
key={key}
|
|
239
|
-
hooks={hooks}
|
|
240
|
-
formState={formState}
|
|
241
|
-
displayDef={d}
|
|
242
|
-
/>
|
|
206
|
+
<DisplayRenderer key={key} formState={formState} displayDef={d} />
|
|
243
207
|
),
|
|
244
208
|
},
|
|
245
209
|
() => <h1>Unknown control: {(definition as any).type}</h1>,
|
|
@@ -248,77 +212,62 @@ export function renderControl<S extends ControlDefinition>(
|
|
|
248
212
|
|
|
249
213
|
/** @trackControls */
|
|
250
214
|
function DataRenderer({
|
|
251
|
-
hooks,
|
|
252
215
|
formState,
|
|
253
216
|
controlDef,
|
|
254
217
|
fieldData,
|
|
255
218
|
}: {
|
|
256
|
-
hooks: FormEditHooks;
|
|
257
219
|
controlDef: DataControlDefinition;
|
|
258
220
|
formState: FormEditState;
|
|
259
221
|
fieldData: SchemaField;
|
|
260
222
|
}) {
|
|
261
|
-
const
|
|
262
|
-
const props = hooks.useDataProperties(
|
|
223
|
+
const props = formState.hooks.useDataProperties(
|
|
263
224
|
formState,
|
|
264
225
|
controlDef,
|
|
265
226
|
fieldData,
|
|
266
|
-
renderer,
|
|
267
227
|
);
|
|
268
|
-
return (props.customRender ?? renderer.renderData)(props);
|
|
228
|
+
return (props.customRender ?? formState.renderer.renderData)(props);
|
|
269
229
|
}
|
|
270
230
|
|
|
271
231
|
/** @trackControls */
|
|
272
232
|
function ActionRenderer({
|
|
273
|
-
hooks,
|
|
274
233
|
formState,
|
|
275
234
|
actionDef,
|
|
276
235
|
}: {
|
|
277
|
-
hooks: FormEditHooks;
|
|
278
236
|
actionDef: ActionControlDefinition;
|
|
279
237
|
formState: FormEditState;
|
|
280
238
|
}) {
|
|
281
|
-
const
|
|
282
|
-
const actionControlProperties = hooks.useActionProperties(
|
|
239
|
+
const actionControlProperties = formState.hooks.useActionProperties(
|
|
283
240
|
formState,
|
|
284
241
|
actionDef,
|
|
285
242
|
);
|
|
286
|
-
return renderAction(actionControlProperties);
|
|
243
|
+
return formState.renderer.renderAction(actionControlProperties);
|
|
287
244
|
}
|
|
288
245
|
|
|
289
246
|
/** @trackControls */
|
|
290
247
|
function GroupRenderer({
|
|
291
|
-
hooks,
|
|
292
248
|
formState,
|
|
293
249
|
groupDef,
|
|
294
250
|
}: {
|
|
295
|
-
hooks: FormEditHooks;
|
|
296
251
|
groupDef: GroupedControlsDefinition;
|
|
297
252
|
formState: FormEditState;
|
|
298
253
|
}) {
|
|
299
|
-
const
|
|
300
|
-
|
|
301
|
-
formState,
|
|
302
|
-
groupDef,
|
|
303
|
-
hooks,
|
|
304
|
-
renderers,
|
|
305
|
-
);
|
|
306
|
-
return renderers.renderGroup(groupProps);
|
|
254
|
+
const groupProps = formState.hooks.useGroupProperties(formState, groupDef);
|
|
255
|
+
return formState.renderer.renderGroup(groupProps);
|
|
307
256
|
}
|
|
308
257
|
|
|
309
258
|
/** @trackControls */
|
|
310
259
|
function DisplayRenderer({
|
|
311
|
-
hooks,
|
|
312
260
|
formState,
|
|
313
261
|
displayDef,
|
|
314
262
|
}: {
|
|
315
|
-
hooks: FormEditHooks;
|
|
316
263
|
displayDef: DisplayControlDefinition;
|
|
317
264
|
formState: FormEditState;
|
|
318
265
|
}) {
|
|
319
|
-
const
|
|
320
|
-
|
|
321
|
-
|
|
266
|
+
const displayProps = formState.hooks.useDisplayProperties(
|
|
267
|
+
formState,
|
|
268
|
+
displayDef,
|
|
269
|
+
);
|
|
270
|
+
return formState.renderer.renderDisplay(displayProps);
|
|
322
271
|
}
|
|
323
272
|
|
|
324
273
|
export function controlForField(
|
|
@@ -359,7 +308,7 @@ export function createAction(
|
|
|
359
308
|
|
|
360
309
|
export function visitControlData<S extends ControlDefinition, A>(
|
|
361
310
|
definition: S,
|
|
362
|
-
{ fields, data }:
|
|
311
|
+
{ fields, data }: FormDataContext,
|
|
363
312
|
cb: (
|
|
364
313
|
definition: DataControlDefinition,
|
|
365
314
|
control: Control<any>,
|
package/src/hooks.tsx
CHANGED
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
FieldOption,
|
|
13
13
|
FieldValueExpression,
|
|
14
14
|
GroupedControlsDefinition,
|
|
15
|
+
GroupRenderType,
|
|
15
16
|
JsonataExpression,
|
|
16
17
|
SchemaField,
|
|
17
18
|
SchemaValidator,
|
|
@@ -28,6 +29,7 @@ import {
|
|
|
28
29
|
FormEditState,
|
|
29
30
|
GroupRendererProps,
|
|
30
31
|
renderControl,
|
|
32
|
+
RenderControlOptions,
|
|
31
33
|
SchemaHooks,
|
|
32
34
|
Visibility,
|
|
33
35
|
} from "./controlRender";
|
|
@@ -262,12 +264,7 @@ export const defaultFormEditHooks = createFormEditHooks(
|
|
|
262
264
|
export function createFormEditHooks(schemaHooks: SchemaHooks): FormEditHooks {
|
|
263
265
|
return {
|
|
264
266
|
schemaHooks,
|
|
265
|
-
useDataProperties(
|
|
266
|
-
formState,
|
|
267
|
-
definition,
|
|
268
|
-
field,
|
|
269
|
-
renderer,
|
|
270
|
-
): DataRendererProps {
|
|
267
|
+
useDataProperties(formState, definition, field): DataRendererProps {
|
|
271
268
|
const visible = useIsControlVisible(definition, formState, schemaHooks);
|
|
272
269
|
const isVisible = visible.value && !formState.invisible;
|
|
273
270
|
const defaultValue = useDefaultValue(
|
|
@@ -318,7 +315,7 @@ export function createFormEditHooks(schemaHooks: SchemaHooks): FormEditHooks {
|
|
|
318
315
|
field,
|
|
319
316
|
definition,
|
|
320
317
|
dataProps.readonly,
|
|
321
|
-
(c) => renderer.renderData({ ...dataProps, control: c }),
|
|
318
|
+
(c) => formState.renderer.renderData({ ...dataProps, control: c }),
|
|
322
319
|
),
|
|
323
320
|
};
|
|
324
321
|
},
|
|
@@ -326,45 +323,40 @@ export function createFormEditHooks(schemaHooks: SchemaHooks): FormEditHooks {
|
|
|
326
323
|
const visible = useIsControlVisible(definition, fs, schemaHooks);
|
|
327
324
|
return { visible, definition };
|
|
328
325
|
},
|
|
329
|
-
useGroupProperties: (fs, definition
|
|
326
|
+
useGroupProperties: (fs, definition) => {
|
|
330
327
|
const visible = useIsControlVisible(definition, fs, schemaHooks);
|
|
331
328
|
const field = definition.compoundField
|
|
332
329
|
? findCompoundField(fs.fields, definition.compoundField)
|
|
333
330
|
: undefined;
|
|
334
|
-
const newFs:
|
|
331
|
+
const newFs: RenderControlOptions = {
|
|
335
332
|
...fs,
|
|
336
333
|
fields: field ? field.children : fs.fields,
|
|
337
|
-
data: field ? fs.data.fields[field.field] : fs.data,
|
|
338
334
|
invisible: !visible.value || fs.invisible,
|
|
339
335
|
};
|
|
336
|
+
const data = field ? fs.data.fields[field.field] : fs.data;
|
|
340
337
|
const groupProps = {
|
|
341
338
|
visible,
|
|
342
|
-
hooks,
|
|
339
|
+
hooks: fs.hooks,
|
|
343
340
|
hideTitle: definition.groupOptions.hideTitle ?? false,
|
|
344
341
|
childCount: definition.children.length,
|
|
345
342
|
renderChild: (i) =>
|
|
346
|
-
renderControl(definition.children[i],
|
|
343
|
+
renderControl(definition.children[i], data, newFs, i),
|
|
347
344
|
definition,
|
|
348
345
|
} satisfies GroupRendererProps;
|
|
349
346
|
if (field?.collection) {
|
|
350
347
|
return {
|
|
351
348
|
...groupProps,
|
|
352
349
|
array: defaultArrayRendererProps(
|
|
353
|
-
|
|
350
|
+
data,
|
|
354
351
|
field,
|
|
355
352
|
definition,
|
|
356
353
|
fs.readonly,
|
|
357
354
|
(e) =>
|
|
358
|
-
|
|
355
|
+
fs.renderer.renderGroup({
|
|
359
356
|
...groupProps,
|
|
360
357
|
hideTitle: true,
|
|
361
358
|
renderChild: (i) =>
|
|
362
|
-
renderControl(
|
|
363
|
-
definition.children[i],
|
|
364
|
-
{ ...newFs, data: e },
|
|
365
|
-
hooks,
|
|
366
|
-
i,
|
|
367
|
-
),
|
|
359
|
+
renderControl(definition.children[i], e, newFs, i),
|
|
368
360
|
}),
|
|
369
361
|
),
|
|
370
362
|
};
|
|
@@ -427,9 +419,15 @@ function defaultArrayRendererProps(
|
|
|
427
419
|
};
|
|
428
420
|
}
|
|
429
421
|
|
|
430
|
-
|
|
431
|
-
|
|
422
|
+
const emptyGroupDefinition: GroupedControlsDefinition = {
|
|
423
|
+
type: ControlDefinitionType.Group,
|
|
424
|
+
children: [],
|
|
425
|
+
groupOptions: { type: GroupRenderType.Standard, hideTitle: true },
|
|
426
|
+
};
|
|
427
|
+
|
|
428
|
+
export function useControlDefinitionForSchema(
|
|
432
429
|
sf: SchemaField[],
|
|
430
|
+
definition: GroupedControlsDefinition = emptyGroupDefinition,
|
|
433
431
|
) {
|
|
434
432
|
return useMemo(
|
|
435
433
|
() =>
|
package/src/renderers.tsx
CHANGED
|
@@ -106,7 +106,7 @@ export interface AdornmentRendererRegistration {
|
|
|
106
106
|
render: (props: AdornmentProps) => AdornmentRenderer;
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
-
export type
|
|
109
|
+
export type RendererRegistration =
|
|
110
110
|
| DataRendererRegistration
|
|
111
111
|
| GroupRendererRegistration
|
|
112
112
|
| DisplayRendererRegistration
|
|
@@ -117,7 +117,7 @@ export type AnyRendererRegistration =
|
|
|
117
117
|
| VisibilityRendererRegistration;
|
|
118
118
|
|
|
119
119
|
export function createFormRenderer(
|
|
120
|
-
customRenderers:
|
|
120
|
+
customRenderers: RendererRegistration[] = [],
|
|
121
121
|
defaultRenderers: DefaultRenderers = createClassStyledRenderers(),
|
|
122
122
|
): FormRenderer {
|
|
123
123
|
const dataRegistrations = customRenderers.filter(isDataRegistration);
|
|
@@ -672,37 +672,37 @@ function createClassStyledRenderers() {
|
|
|
672
672
|
}
|
|
673
673
|
|
|
674
674
|
function isAdornmentRegistration(
|
|
675
|
-
x:
|
|
675
|
+
x: RendererRegistration,
|
|
676
676
|
): x is AdornmentRendererRegistration {
|
|
677
677
|
return x.type === "adornment";
|
|
678
678
|
}
|
|
679
679
|
|
|
680
680
|
function isDataRegistration(
|
|
681
|
-
x:
|
|
681
|
+
x: RendererRegistration,
|
|
682
682
|
): x is DataRendererRegistration {
|
|
683
683
|
return x.type === "data";
|
|
684
684
|
}
|
|
685
685
|
|
|
686
686
|
function isLabelRegistration(
|
|
687
|
-
x:
|
|
687
|
+
x: RendererRegistration,
|
|
688
688
|
): x is LabelRendererRegistration {
|
|
689
689
|
return x.type === "label";
|
|
690
690
|
}
|
|
691
691
|
|
|
692
692
|
function isActionRegistration(
|
|
693
|
-
x:
|
|
693
|
+
x: RendererRegistration,
|
|
694
694
|
): x is ActionRendererRegistration {
|
|
695
695
|
return x.type === "action";
|
|
696
696
|
}
|
|
697
697
|
|
|
698
698
|
function isArrayRegistration(
|
|
699
|
-
x:
|
|
699
|
+
x: RendererRegistration,
|
|
700
700
|
): x is ArrayRendererRegistration {
|
|
701
701
|
return x.type === "array";
|
|
702
702
|
}
|
|
703
703
|
|
|
704
704
|
function isVisibilityRegistration(
|
|
705
|
-
x:
|
|
705
|
+
x: RendererRegistration,
|
|
706
706
|
): x is VisibilityRendererRegistration {
|
|
707
707
|
return x.type === "visibility";
|
|
708
708
|
}
|