Skip to content

Commit 43a9ea7

Browse files
authored
feat: add arraySchema prop for array renderers
Add "arraySchema" prop to provide access to the array's schema in array renderers. It would have been a breaking change if the existing "schema" prop had been modified instead.
1 parent 576d9e0 commit 43a9ea7

File tree

3 files changed

+128
-1
lines changed

3 files changed

+128
-1
lines changed

packages/core/src/mappers/renderer.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -853,6 +853,7 @@ export interface ControlWithDetailProps
853853
*/
854854
export interface StatePropsOfArrayControl
855855
extends StatePropsOfControlWithDetail {
856+
arraySchema: JsonSchema;
856857
childErrors?: ErrorObject[];
857858
}
858859

@@ -879,6 +880,7 @@ export const mapStateToArrayControlProps = (
879880
path,
880881
uischema,
881882
schema: resolvedSchema,
883+
arraySchema: schema,
882884
childErrors,
883885
renderers: ownProps.renderers || getRenderers(state),
884886
cells: ownProps.cells || getCells(state),
@@ -1207,6 +1209,10 @@ export const mapStateToOneOfProps = (
12071209

12081210
export interface StatePropsOfArrayLayout extends StatePropsOfControlWithDetail {
12091211
data: number;
1212+
arraySchema: JsonSchema;
1213+
/**
1214+
* @deprecated Use `arraySchema.minItems` instead.
1215+
*/
12101216
minItems?: number;
12111217
disableRemove?: boolean;
12121218
disableAdd?: boolean;
@@ -1247,6 +1253,7 @@ export const mapStateToArrayLayoutProps = (
12471253
path,
12481254
uischema,
12491255
schema: resolvedSchema,
1256+
arraySchema: schema,
12501257
data: props.data ? props.data.length : 0,
12511258
errors: allErrors,
12521259
minItems: schema.minItems,

packages/core/test/mappers/renderer.test.ts

Lines changed: 119 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ import {
5454
mapDispatchToControlProps,
5555
mapDispatchToMultiEnumProps,
5656
mapStateToAnyOfProps,
57+
mapStateToArrayControlProps,
5758
mapStateToArrayLayoutProps,
5859
mapStateToControlProps,
5960
mapStateToEnumControlProps,
@@ -938,6 +939,84 @@ test('mapStateToLayoutProps - visible via state with path from ownProps ', (t) =
938939
t.true(props.visible);
939940
});
940941

942+
test('mapStateToArrayControlProps - should include minItems in array control props', (t) => {
943+
const schema: JsonSchema = {
944+
type: 'array',
945+
minItems: 42,
946+
items: {
947+
type: 'object',
948+
properties: {
949+
message: {
950+
type: 'string',
951+
default: 'foo',
952+
},
953+
},
954+
},
955+
};
956+
957+
const uischema: ControlElement = {
958+
type: 'Control',
959+
scope: '#',
960+
};
961+
962+
const state = {
963+
jsonforms: {
964+
core: {
965+
schema,
966+
data: {},
967+
uischema,
968+
errors: [] as ErrorObject[],
969+
},
970+
},
971+
};
972+
973+
const ownProps = {
974+
uischema,
975+
};
976+
977+
const props = mapStateToArrayControlProps(state, ownProps);
978+
t.is(props.arraySchema.minItems, 42);
979+
});
980+
981+
test('mapStateToArrayControlProps - should include maxItems in array control props', (t) => {
982+
const schema: JsonSchema = {
983+
type: 'array',
984+
maxItems: 42,
985+
items: {
986+
type: 'object',
987+
properties: {
988+
message: {
989+
type: 'string',
990+
default: 'foo',
991+
},
992+
},
993+
},
994+
};
995+
996+
const uischema: ControlElement = {
997+
type: 'Control',
998+
scope: '#',
999+
};
1000+
1001+
const state = {
1002+
jsonforms: {
1003+
core: {
1004+
schema,
1005+
data: {},
1006+
uischema,
1007+
errors: [] as ErrorObject[],
1008+
},
1009+
},
1010+
};
1011+
1012+
const ownProps = {
1013+
uischema,
1014+
};
1015+
1016+
const props = mapStateToArrayControlProps(state, ownProps);
1017+
t.is(props.arraySchema.maxItems, 42);
1018+
});
1019+
9411020
test('mapStateToArrayLayoutProps - should include minItems in array layout props', (t) => {
9421021
const schema: JsonSchema = {
9431022
type: 'array',
@@ -974,7 +1053,46 @@ test('mapStateToArrayLayoutProps - should include minItems in array layout props
9741053
};
9751054

9761055
const props = mapStateToArrayLayoutProps(state, ownProps);
977-
t.is(props.minItems, 42);
1056+
t.is(props.arraySchema.minItems, 42);
1057+
});
1058+
1059+
test('mapStateToArrayLayoutProps - should include maxItems in array layout props', (t) => {
1060+
const schema: JsonSchema = {
1061+
type: 'array',
1062+
maxItems: 42,
1063+
items: {
1064+
type: 'object',
1065+
properties: {
1066+
message: {
1067+
type: 'string',
1068+
default: 'foo',
1069+
},
1070+
},
1071+
},
1072+
};
1073+
1074+
const uischema: ControlElement = {
1075+
type: 'Control',
1076+
scope: '#',
1077+
};
1078+
1079+
const state = {
1080+
jsonforms: {
1081+
core: {
1082+
schema,
1083+
data: {},
1084+
uischema,
1085+
errors: [] as ErrorObject[],
1086+
},
1087+
},
1088+
};
1089+
1090+
const ownProps = {
1091+
uischema,
1092+
};
1093+
1094+
const props = mapStateToArrayLayoutProps(state, ownProps);
1095+
t.is(props.arraySchema.maxItems, 42);
9781096
});
9791097

9801098
test('mapStateToLayoutProps should return renderers prop via ownProps', (t) => {

packages/vanilla-renderers/src/complex/array/ArrayControlRenderer.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ export const ArrayControlRenderer = ({
193193
enabled,
194194
errors,
195195
translations,
196+
arraySchema,
196197
}: ArrayControlProps &
197198
VanillaRendererProps & { translations: ArrayTranslations }) => {
198199
const controlElement = uischema as ControlElement;
@@ -221,6 +222,7 @@ export const ArrayControlRenderer = ({
221222
label={label}
222223
path={path}
223224
schema={schema}
225+
arraySchema={arraySchema}
224226
errors={errors}
225227
addItem={addItem}
226228
removeItems={removeItems}

0 commit comments

Comments
 (0)