@react-typed-forms/schemas 5.0.2 → 6.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/controlBuilder.d.ts +2 -2
- package/lib/controlRender.d.ts +63 -16
- package/lib/hooks.d.ts +10 -5
- package/lib/index.d.ts +1 -0
- package/lib/index.js +434 -162
- package/lib/index.js.map +1 -1
- package/lib/internal.d.ts +1 -0
- package/lib/renderers.d.ts +20 -10
- package/lib/schemaInterface.d.ts +4 -0
- package/lib/types.d.ts +47 -8
- package/lib/util.d.ts +7 -5
- package/lib/validators.d.ts +2 -2
- package/package.json +2 -2
- package/src/controlBuilder.ts +3 -3
- package/src/controlRender.tsx +198 -82
- package/src/hooks.tsx +102 -17
- package/src/index.ts +1 -0
- package/src/internal.ts +4 -0
- package/src/renderers.tsx +196 -65
- package/src/schemaInterface.ts +31 -0
- package/src/tailwind.tsx +5 -1
- package/src/types.ts +61 -5
- package/src/util.ts +24 -8
- package/src/validators.ts +3 -3
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { FieldType, SchemaField, SchemaInterface } from "./types";
|
|
2
|
+
|
|
3
|
+
export const defaultSchemaInterface: SchemaInterface = {
|
|
4
|
+
isEmptyValue: defaultIsEmpty,
|
|
5
|
+
textValue: defaultTextValue,
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export function defaultIsEmpty(f: SchemaField, value: any): boolean {
|
|
9
|
+
if (f.collection)
|
|
10
|
+
return Array.isArray(value) ? value.length === 0 : value == null;
|
|
11
|
+
switch (f.type) {
|
|
12
|
+
case FieldType.String:
|
|
13
|
+
return !value;
|
|
14
|
+
default:
|
|
15
|
+
return value == null;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function defaultTextValue(
|
|
20
|
+
f: SchemaField,
|
|
21
|
+
value: any,
|
|
22
|
+
): string | undefined {
|
|
23
|
+
switch (f.type) {
|
|
24
|
+
case FieldType.DateTime:
|
|
25
|
+
return new Date(value).toLocaleDateString();
|
|
26
|
+
case FieldType.Date:
|
|
27
|
+
return new Date(value).toLocaleDateString();
|
|
28
|
+
default:
|
|
29
|
+
return value != null ? value.toString() : undefined;
|
|
30
|
+
}
|
|
31
|
+
}
|
package/src/tailwind.tsx
CHANGED
|
@@ -12,8 +12,9 @@ export const defaultTailwindTheme: DefaultRendererOptions = {
|
|
|
12
12
|
addActionClass: "my-2",
|
|
13
13
|
},
|
|
14
14
|
group: {
|
|
15
|
-
standardClassName: "
|
|
15
|
+
standardClassName: "flex flex-col gap-4",
|
|
16
16
|
gridClassName: "gap-x-2 gap-y-4",
|
|
17
|
+
flexClassName: "gap-2",
|
|
17
18
|
},
|
|
18
19
|
action: {
|
|
19
20
|
className: "bg-primary rounded-lg p-3 text-white",
|
|
@@ -22,4 +23,7 @@ export const defaultTailwindTheme: DefaultRendererOptions = {
|
|
|
22
23
|
className: "flex flex-col",
|
|
23
24
|
errorClass: "text-sm text-danger-500",
|
|
24
25
|
},
|
|
26
|
+
data: {
|
|
27
|
+
displayOnlyClass: "flex flex-row items-center gap-2",
|
|
28
|
+
},
|
|
25
29
|
};
|
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
|
-
|
|
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
|
|
98
|
-
type: ExpressionType.
|
|
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
|
|
165
|
+
placement?: AdornmentPlacement | null;
|
|
140
166
|
}
|
|
141
167
|
|
|
142
168
|
export interface DataControlDefinition extends ControlDefinition {
|
|
@@ -166,6 +192,7 @@ export enum DataRenderType {
|
|
|
166
192
|
DateTime = "DateTime",
|
|
167
193
|
Checkbox = "Checkbox",
|
|
168
194
|
Dropdown = "Dropdown",
|
|
195
|
+
DisplayOnly = "DisplayOnly",
|
|
169
196
|
}
|
|
170
197
|
|
|
171
198
|
export interface RadioButtonRenderOptions extends RenderOptions {
|
|
@@ -191,6 +218,11 @@ export interface IconListRenderOptions extends RenderOptions {
|
|
|
191
218
|
iconMappings: IconMapping[];
|
|
192
219
|
}
|
|
193
220
|
|
|
221
|
+
export interface DisplayOnlyRenderOptions extends RenderOptions {
|
|
222
|
+
type: DataRenderType.DisplayOnly;
|
|
223
|
+
emptyText?: string | null;
|
|
224
|
+
sampleText?: string | null;
|
|
225
|
+
}
|
|
194
226
|
export interface IconMapping {
|
|
195
227
|
value: string;
|
|
196
228
|
materialIcon?: string | null;
|
|
@@ -236,6 +268,7 @@ export interface GroupRenderOptions {
|
|
|
236
268
|
export enum GroupRenderType {
|
|
237
269
|
Standard = "Standard",
|
|
238
270
|
Grid = "Grid",
|
|
271
|
+
Flex = "Flex",
|
|
239
272
|
GroupElement = "GroupElement",
|
|
240
273
|
}
|
|
241
274
|
|
|
@@ -243,6 +276,12 @@ export interface StandardGroupRenderer extends GroupRenderOptions {
|
|
|
243
276
|
type: GroupRenderType.Standard;
|
|
244
277
|
}
|
|
245
278
|
|
|
279
|
+
export interface FlexRenderer extends GroupRenderOptions {
|
|
280
|
+
type: GroupRenderType.Flex;
|
|
281
|
+
direction?: string | null;
|
|
282
|
+
gap?: string | null;
|
|
283
|
+
}
|
|
284
|
+
|
|
246
285
|
export interface GroupElementRenderer extends GroupRenderOptions {
|
|
247
286
|
type: GroupRenderType.GroupElement;
|
|
248
287
|
value: any;
|
|
@@ -265,13 +304,18 @@ export interface DisplayData {
|
|
|
265
304
|
export enum DisplayDataType {
|
|
266
305
|
Text = "Text",
|
|
267
306
|
Html = "Html",
|
|
307
|
+
Icon = "Icon",
|
|
268
308
|
}
|
|
269
|
-
|
|
270
309
|
export interface TextDisplay extends DisplayData {
|
|
271
310
|
type: DisplayDataType.Text;
|
|
272
311
|
text: string;
|
|
273
312
|
}
|
|
274
313
|
|
|
314
|
+
export interface IconDisplay extends DisplayData {
|
|
315
|
+
type: DisplayDataType.Icon;
|
|
316
|
+
iconClass: string;
|
|
317
|
+
}
|
|
318
|
+
|
|
275
319
|
export interface HtmlDisplay extends DisplayData {
|
|
276
320
|
type: DisplayDataType.Html;
|
|
277
321
|
html: string;
|
|
@@ -361,3 +405,15 @@ export function isGridRenderer(
|
|
|
361
405
|
): options is GridRenderer {
|
|
362
406
|
return options.type === GroupRenderType.Grid;
|
|
363
407
|
}
|
|
408
|
+
|
|
409
|
+
export function isFlexRenderer(
|
|
410
|
+
options: GroupRenderOptions,
|
|
411
|
+
): options is FlexRenderer {
|
|
412
|
+
return options.type === GroupRenderType.Flex;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
export function isDisplayOnlyRenderer(
|
|
416
|
+
options: RenderOptions,
|
|
417
|
+
): options is DisplayOnlyRenderOptions {
|
|
418
|
+
return options.type === DataRenderType.DisplayOnly;
|
|
419
|
+
}
|
package/src/util.ts
CHANGED
|
@@ -1,27 +1,29 @@
|
|
|
1
1
|
import {
|
|
2
|
-
ActionControlDefinition,
|
|
3
2
|
CompoundField,
|
|
4
3
|
ControlDefinition,
|
|
5
4
|
ControlDefinitionType,
|
|
6
5
|
DataControlDefinition,
|
|
7
6
|
DataRenderType,
|
|
8
|
-
|
|
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";
|
|
19
21
|
|
|
20
|
-
export interface
|
|
22
|
+
export interface ControlDataContext {
|
|
21
23
|
groupControl: Control<any>;
|
|
22
24
|
fields: SchemaField[];
|
|
25
|
+
schemaInterface: SchemaInterface;
|
|
23
26
|
}
|
|
24
|
-
|
|
25
27
|
export function applyDefaultValues(
|
|
26
28
|
v: { [k: string]: any } | undefined,
|
|
27
29
|
fields: SchemaField[],
|
|
@@ -238,8 +240,18 @@ export function isControlReadonly(c: ControlDefinition): boolean {
|
|
|
238
240
|
return isDataControl(c) && !!c.readonly;
|
|
239
241
|
}
|
|
240
242
|
|
|
243
|
+
export function getDisplayOnlyOptions(
|
|
244
|
+
d: ControlDefinition,
|
|
245
|
+
): DisplayOnlyRenderOptions | undefined {
|
|
246
|
+
return isDataControlDefinition(d) &&
|
|
247
|
+
d.renderOptions &&
|
|
248
|
+
isDisplayOnlyRenderer(d.renderOptions)
|
|
249
|
+
? d.renderOptions
|
|
250
|
+
: undefined;
|
|
251
|
+
}
|
|
252
|
+
|
|
241
253
|
export function getTypeField(
|
|
242
|
-
context:
|
|
254
|
+
context: ControlDataContext,
|
|
243
255
|
): Control<string> | undefined {
|
|
244
256
|
const typeSchemaField = context.fields.find((x) => x.isTypeField);
|
|
245
257
|
return typeSchemaField
|
|
@@ -249,7 +261,7 @@ export function getTypeField(
|
|
|
249
261
|
|
|
250
262
|
export function visitControlDataArray<A>(
|
|
251
263
|
controls: ControlDefinition[] | undefined | null,
|
|
252
|
-
context:
|
|
264
|
+
context: ControlDataContext,
|
|
253
265
|
cb: (
|
|
254
266
|
definition: DataControlDefinition,
|
|
255
267
|
field: SchemaField,
|
|
@@ -267,7 +279,7 @@ export function visitControlDataArray<A>(
|
|
|
267
279
|
|
|
268
280
|
export function visitControlData<A>(
|
|
269
281
|
definition: ControlDefinition,
|
|
270
|
-
ctx:
|
|
282
|
+
ctx: ControlDataContext,
|
|
271
283
|
cb: (
|
|
272
284
|
definition: DataControlDefinition,
|
|
273
285
|
field: SchemaField,
|
|
@@ -309,7 +321,11 @@ export function visitControlData<A>(
|
|
|
309
321
|
if (isCompoundField(fieldData)) {
|
|
310
322
|
const cfResult = visitControlDataArray(
|
|
311
323
|
children,
|
|
312
|
-
{
|
|
324
|
+
{
|
|
325
|
+
fields: fieldData.children,
|
|
326
|
+
groupControl: c,
|
|
327
|
+
schemaInterface: ctx.schemaInterface,
|
|
328
|
+
},
|
|
313
329
|
cb,
|
|
314
330
|
);
|
|
315
331
|
if (cfResult !== undefined) return cfResult;
|
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 {
|
|
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:
|
|
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:
|
|
68
|
+
context: ControlDataContext,
|
|
69
69
|
expr: JsonataValidator,
|
|
70
70
|
hidden: boolean,
|
|
71
71
|
i: number,
|