@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.
@@ -50,8 +50,8 @@ export interface AdornmentRendererRegistration {
50
50
  adornmentType?: string | string[];
51
51
  render: (props: AdornmentProps) => AdornmentRenderer;
52
52
  }
53
- export type AnyRendererRegistration = DataRendererRegistration | GroupRendererRegistration | DisplayRendererRegistration | ActionRendererRegistration | LabelRendererRegistration | ArrayRendererRegistration | AdornmentRendererRegistration | VisibilityRendererRegistration;
54
- export declare function createFormRenderer(customRenderers?: AnyRendererRegistration[], defaultRenderers?: DefaultRenderers): FormRenderer;
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.20",
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
  }
@@ -15,9 +15,16 @@ import {
15
15
  SchemaValidator,
16
16
  visitControlDefinition,
17
17
  } from "./types";
18
- import React, {Context, createContext, Key, ReactElement, ReactNode, useContext,} from "react";
19
- import {Control, newControl} from "@react-typed-forms/core";
20
- import {fieldDisplayName, findCompoundField, findField, findScalarField, isDataControl, isGroupControl} from "./util";
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 FormEditState {
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
- formState: FormEditState,
199
- hooks: FormEditHooks,
200
- key: Key,
177
+ data: Control<any>,
178
+ options: RenderControlOptions,
179
+ key?: Key,
201
180
  ): ReactElement {
202
- const { fields } = formState;
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 renderer = useFormRendererComponents();
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 { renderAction } = useFormRendererComponents();
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 renderers = useFormRendererComponents();
300
- const groupProps = hooks.useGroupProperties(
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 { renderDisplay } = useFormRendererComponents();
320
- const displayProps = hooks.useDisplayProperties(formState, displayDef);
321
- return renderDisplay(displayProps);
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 }: FormEditState,
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, hooks, renderers) => {
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: Omit<FormEditState, "data"> & { data: Control<any> } = {
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], newFs, hooks, 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
- newFs.data,
350
+ data,
354
351
  field,
355
352
  definition,
356
353
  fs.readonly,
357
354
  (e) =>
358
- renderers.renderGroup({
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
- export function useControlsWithDefaults(
431
- definition: GroupedControlsDefinition,
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 AnyRendererRegistration =
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: AnyRendererRegistration[] = [],
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: AnyRendererRegistration,
675
+ x: RendererRegistration,
676
676
  ): x is AdornmentRendererRegistration {
677
677
  return x.type === "adornment";
678
678
  }
679
679
 
680
680
  function isDataRegistration(
681
- x: AnyRendererRegistration,
681
+ x: RendererRegistration,
682
682
  ): x is DataRendererRegistration {
683
683
  return x.type === "data";
684
684
  }
685
685
 
686
686
  function isLabelRegistration(
687
- x: AnyRendererRegistration,
687
+ x: RendererRegistration,
688
688
  ): x is LabelRendererRegistration {
689
689
  return x.type === "label";
690
690
  }
691
691
 
692
692
  function isActionRegistration(
693
- x: AnyRendererRegistration,
693
+ x: RendererRegistration,
694
694
  ): x is ActionRendererRegistration {
695
695
  return x.type === "action";
696
696
  }
697
697
 
698
698
  function isArrayRegistration(
699
- x: AnyRendererRegistration,
699
+ x: RendererRegistration,
700
700
  ): x is ArrayRendererRegistration {
701
701
  return x.type === "array";
702
702
  }
703
703
 
704
704
  function isVisibilityRegistration(
705
- x: AnyRendererRegistration,
705
+ x: RendererRegistration,
706
706
  ): x is VisibilityRendererRegistration {
707
707
  return x.type === "visibility";
708
708
  }