@react-typed-forms/schemas 5.0.3 → 7.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/src/types.ts CHANGED
@@ -52,9 +52,19 @@ export type AnyControlDefinition =
52
52
  | ActionControlDefinition
53
53
  | DisplayControlDefinition;
54
54
 
55
+ export interface SchemaInterface {
56
+ isEmptyValue(field: SchemaField, value: any): boolean;
57
+ textValue(
58
+ field: SchemaField,
59
+ value: any,
60
+ element?: boolean,
61
+ ): string | undefined;
62
+ }
55
63
  export interface ControlDefinition {
56
64
  type: string;
57
65
  title?: string | null;
66
+ styleClass?: string | null;
67
+ layoutClass?: string | null;
58
68
  dynamic?: DynamicProperty[] | null;
59
69
  adornments?: ControlAdornment[] | null;
60
70
  children?: ControlDefinition[] | null;
@@ -77,6 +87,9 @@ export enum DynamicPropertyType {
77
87
  DefaultValue = "DefaultValue",
78
88
  Readonly = "Readonly",
79
89
  Disabled = "Disabled",
90
+ Display = "Display",
91
+ Style = "Style",
92
+ LayoutStyle = "LayoutStyle",
80
93
  }
81
94
 
82
95
  export interface EntityExpression {
@@ -85,7 +98,8 @@ export interface EntityExpression {
85
98
 
86
99
  export enum ExpressionType {
87
100
  Jsonata = "Jsonata",
88
- FieldValue = "FieldValue",
101
+ Data = "Data",
102
+ DataMatch = "FieldValue",
89
103
  UserMatch = "UserMatch",
90
104
  }
91
105
 
@@ -94,8 +108,13 @@ export interface JsonataExpression extends EntityExpression {
94
108
  expression: string;
95
109
  }
96
110
 
97
- export interface FieldValueExpression extends EntityExpression {
98
- type: ExpressionType.FieldValue;
111
+ export interface DataExpression extends EntityExpression {
112
+ type: ExpressionType.Data;
113
+ field: string;
114
+ }
115
+
116
+ export interface DataMatchExpression extends EntityExpression {
117
+ type: ExpressionType.DataMatch;
99
118
  field: string;
100
119
  value: any;
101
120
  }
@@ -120,6 +139,13 @@ export enum ControlAdornmentType {
120
139
  Tooltip = "Tooltip",
121
140
  Accordion = "Accordion",
122
141
  HelpText = "HelpText",
142
+ Icon = "Icon",
143
+ }
144
+
145
+ export interface IconAdornment extends ControlAdornment {
146
+ type: ControlAdornmentType.Icon;
147
+ iconClass: string;
148
+ placement?: AdornmentPlacement | null;
123
149
  }
124
150
 
125
151
  export interface TooltipAdornment extends ControlAdornment {
@@ -136,7 +162,7 @@ export interface AccordionAdornment extends ControlAdornment {
136
162
  export interface HelpTextAdornment extends ControlAdornment {
137
163
  type: ControlAdornmentType.HelpText;
138
164
  helpText: string;
139
- placement: AdornmentPlacement;
165
+ placement?: AdornmentPlacement | null;
140
166
  }
141
167
 
142
168
  export interface DataControlDefinition extends ControlDefinition {
@@ -148,6 +174,7 @@ export interface DataControlDefinition extends ControlDefinition {
148
174
  readonly?: boolean | null;
149
175
  validators?: SchemaValidator[] | null;
150
176
  hideTitle?: boolean | null;
177
+ dontClearHidden?: boolean | null;
151
178
  }
152
179
 
153
180
  export interface RenderOptions {
@@ -166,6 +193,7 @@ export enum DataRenderType {
166
193
  DateTime = "DateTime",
167
194
  Checkbox = "Checkbox",
168
195
  Dropdown = "Dropdown",
196
+ DisplayOnly = "DisplayOnly",
169
197
  }
170
198
 
171
199
  export interface RadioButtonRenderOptions extends RenderOptions {
@@ -191,6 +219,11 @@ export interface IconListRenderOptions extends RenderOptions {
191
219
  iconMappings: IconMapping[];
192
220
  }
193
221
 
222
+ export interface DisplayOnlyRenderOptions extends RenderOptions {
223
+ type: DataRenderType.DisplayOnly;
224
+ emptyText?: string | null;
225
+ sampleText?: string | null;
226
+ }
194
227
  export interface IconMapping {
195
228
  value: string;
196
229
  materialIcon?: string | null;
@@ -236,6 +269,7 @@ export interface GroupRenderOptions {
236
269
  export enum GroupRenderType {
237
270
  Standard = "Standard",
238
271
  Grid = "Grid",
272
+ Flex = "Flex",
239
273
  GroupElement = "GroupElement",
240
274
  }
241
275
 
@@ -243,6 +277,12 @@ export interface StandardGroupRenderer extends GroupRenderOptions {
243
277
  type: GroupRenderType.Standard;
244
278
  }
245
279
 
280
+ export interface FlexRenderer extends GroupRenderOptions {
281
+ type: GroupRenderType.Flex;
282
+ direction?: string | null;
283
+ gap?: string | null;
284
+ }
285
+
246
286
  export interface GroupElementRenderer extends GroupRenderOptions {
247
287
  type: GroupRenderType.GroupElement;
248
288
  value: any;
@@ -265,13 +305,18 @@ export interface DisplayData {
265
305
  export enum DisplayDataType {
266
306
  Text = "Text",
267
307
  Html = "Html",
308
+ Icon = "Icon",
268
309
  }
269
-
270
310
  export interface TextDisplay extends DisplayData {
271
311
  type: DisplayDataType.Text;
272
312
  text: string;
273
313
  }
274
314
 
315
+ export interface IconDisplay extends DisplayData {
316
+ type: DisplayDataType.Icon;
317
+ iconClass: string;
318
+ }
319
+
275
320
  export interface HtmlDisplay extends DisplayData {
276
321
  type: DisplayDataType.Html;
277
322
  html: string;
@@ -361,3 +406,15 @@ export function isGridRenderer(
361
406
  ): options is GridRenderer {
362
407
  return options.type === GroupRenderType.Grid;
363
408
  }
409
+
410
+ export function isFlexRenderer(
411
+ options: GroupRenderOptions,
412
+ ): options is FlexRenderer {
413
+ return options.type === GroupRenderType.Flex;
414
+ }
415
+
416
+ export function isDisplayOnlyRenderer(
417
+ options: RenderOptions,
418
+ ): options is DisplayOnlyRenderOptions {
419
+ return options.type === DataRenderType.DisplayOnly;
420
+ }
package/src/util.ts CHANGED
@@ -1,27 +1,30 @@
1
1
  import {
2
- ActionControlDefinition,
3
2
  CompoundField,
4
3
  ControlDefinition,
5
4
  ControlDefinitionType,
6
5
  DataControlDefinition,
7
6
  DataRenderType,
8
- DisplayControlDefinition,
7
+ DisplayOnlyRenderOptions,
9
8
  FieldOption,
10
9
  FieldType,
11
10
  GridRenderer,
12
11
  GroupedControlsDefinition,
13
12
  GroupRenderType,
13
+ isDataControlDefinition,
14
+ isDisplayOnlyRenderer,
14
15
  SchemaField,
16
+ SchemaInterface,
15
17
  visitControlDefinition,
16
18
  } from "./types";
17
19
  import { MutableRefObject, useRef } from "react";
18
20
  import { Control } from "@react-typed-forms/core";
21
+ import clsx from "clsx";
19
22
 
20
- export interface ControlGroupContext {
23
+ export interface ControlDataContext {
21
24
  groupControl: Control<any>;
22
25
  fields: SchemaField[];
26
+ schemaInterface: SchemaInterface;
23
27
  }
24
-
25
28
  export function applyDefaultValues(
26
29
  v: { [k: string]: any } | undefined,
27
30
  fields: SchemaField[],
@@ -144,20 +147,15 @@ export function hasOptions(o: { options: FieldOption[] | undefined | null }) {
144
147
  return (o.options?.length ?? 0) > 0;
145
148
  }
146
149
 
147
- export function defaultControlForField(
148
- sf: SchemaField,
149
- ): DataControlDefinition | GroupedControlsDefinition {
150
+ export function defaultControlForField(sf: SchemaField): DataControlDefinition {
150
151
  if (isCompoundField(sf)) {
151
152
  return {
152
- type: ControlDefinitionType.Group,
153
+ type: ControlDefinitionType.Data,
153
154
  title: sf.displayName,
154
- compoundField: sf.field,
155
- groupOptions: {
156
- type: GroupRenderType.Grid,
157
- hideTitle: false,
158
- } as GridRenderer,
155
+ field: sf.field,
156
+ required: sf.required,
159
157
  children: sf.children.map(defaultControlForField),
160
- } satisfies GroupedControlsDefinition;
158
+ };
161
159
  } else if (isScalarField(sf)) {
162
160
  const htmlEditor = sf.tags?.includes("_HtmlEditor");
163
161
  return {
@@ -168,7 +166,7 @@ export function defaultControlForField(
168
166
  renderOptions: {
169
167
  type: htmlEditor ? DataRenderType.HtmlEditor : DataRenderType.Standard,
170
168
  },
171
- } satisfies DataControlDefinition;
169
+ };
172
170
  }
173
171
  throw "Unknown schema field";
174
172
  }
@@ -238,8 +236,18 @@ export function isControlReadonly(c: ControlDefinition): boolean {
238
236
  return isDataControl(c) && !!c.readonly;
239
237
  }
240
238
 
239
+ export function getDisplayOnlyOptions(
240
+ d: ControlDefinition,
241
+ ): DisplayOnlyRenderOptions | undefined {
242
+ return isDataControlDefinition(d) &&
243
+ d.renderOptions &&
244
+ isDisplayOnlyRenderer(d.renderOptions)
245
+ ? d.renderOptions
246
+ : undefined;
247
+ }
248
+
241
249
  export function getTypeField(
242
- context: ControlGroupContext,
250
+ context: ControlDataContext,
243
251
  ): Control<string> | undefined {
244
252
  const typeSchemaField = context.fields.find((x) => x.isTypeField);
245
253
  return typeSchemaField
@@ -249,7 +257,7 @@ export function getTypeField(
249
257
 
250
258
  export function visitControlDataArray<A>(
251
259
  controls: ControlDefinition[] | undefined | null,
252
- context: ControlGroupContext,
260
+ context: ControlDataContext,
253
261
  cb: (
254
262
  definition: DataControlDefinition,
255
263
  field: SchemaField,
@@ -267,7 +275,7 @@ export function visitControlDataArray<A>(
267
275
 
268
276
  export function visitControlData<A>(
269
277
  definition: ControlDefinition,
270
- ctx: ControlGroupContext,
278
+ ctx: ControlDataContext,
271
279
  cb: (
272
280
  definition: DataControlDefinition,
273
281
  field: SchemaField,
@@ -309,7 +317,11 @@ export function visitControlData<A>(
309
317
  if (isCompoundField(fieldData)) {
310
318
  const cfResult = visitControlDataArray(
311
319
  children,
312
- { fields: fieldData.children, groupControl: c },
320
+ {
321
+ fields: fieldData.children,
322
+ groupControl: c,
323
+ schemaInterface: ctx.schemaInterface,
324
+ },
313
325
  cb,
314
326
  );
315
327
  if (cfResult !== undefined) return cfResult;
@@ -362,3 +374,12 @@ export function cleanDataForSchema(
362
374
  });
363
375
  return out;
364
376
  }
377
+
378
+ export function getAllReferencedClasses(c: ControlDefinition): string[] {
379
+ const childClasses = c.children?.flatMap(getAllReferencedClasses);
380
+ const tc = clsx(c.styleClass, c.layoutClass);
381
+ if (childClasses && !tc) return childClasses;
382
+ if (!tc) return [];
383
+ if (childClasses) return [tc, ...childClasses];
384
+ return [tc];
385
+ }
package/src/validators.ts CHANGED
@@ -14,7 +14,7 @@ import {
14
14
  useValueChangeEffect,
15
15
  } from "@react-typed-forms/core";
16
16
  import { useCallback } from "react";
17
- import { ControlGroupContext, useUpdatedRef } from "./util";
17
+ import { ControlDataContext, useUpdatedRef } from "./util";
18
18
  import { useJsonataExpression } from "./hooks";
19
19
 
20
20
  export function useValidationHook(
@@ -22,7 +22,7 @@ export function useValidationHook(
22
22
  ): (
23
23
  control: Control<any>,
24
24
  hidden: boolean,
25
- groupContext: ControlGroupContext,
25
+ groupContext: ControlDataContext,
26
26
  ) => void {
27
27
  const validatorTypes = isDataControlDefinition(definition)
28
28
  ? definition.validators?.map((x) => x.type) ?? []
@@ -65,7 +65,7 @@ export function useValidationHook(
65
65
 
66
66
  function useJsonataValidator(
67
67
  control: Control<any>,
68
- context: ControlGroupContext,
68
+ context: ControlDataContext,
69
69
  expr: JsonataValidator,
70
70
  hidden: boolean,
71
71
  i: number,