@jsonforms/core 3.0.0-beta.5 → 3.0.0-rc.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.
Files changed (71) hide show
  1. package/docs/assets/js/search.json +1 -1
  2. package/docs/globals.html +206 -101
  3. package/docs/index.html +21 -3
  4. package/docs/interfaces/arraycontrolprops.html +21 -21
  5. package/docs/interfaces/arraylayoutprops.html +21 -21
  6. package/docs/interfaces/categorization.html +1 -1
  7. package/docs/interfaces/category.html +1 -1
  8. package/docs/interfaces/cellprops.html +12 -12
  9. package/docs/interfaces/combinatorrendererprops.html +18 -18
  10. package/docs/interfaces/controlelement.html +2 -2
  11. package/docs/interfaces/controlprops.html +16 -16
  12. package/docs/interfaces/controlstate.html +2 -2
  13. package/docs/interfaces/controlwithdetailprops.html +17 -17
  14. package/docs/interfaces/dispatchcellprops.html +10 -10
  15. package/docs/interfaces/dispatchcellstateprops.html +10 -10
  16. package/docs/interfaces/dispatchpropsofarraycontrol.html +4 -4
  17. package/docs/interfaces/dispatchpropsofcontrol.html +1 -1
  18. package/docs/interfaces/dispatchpropsofmultienumcontrol.html +2 -2
  19. package/docs/interfaces/enumcellprops.html +13 -13
  20. package/docs/interfaces/enumoption.html +2 -2
  21. package/docs/interfaces/grouplayout.html +2 -2
  22. package/docs/interfaces/internationalizable.html +3 -0
  23. package/docs/interfaces/jsonformsprops.html +24 -9
  24. package/docs/interfaces/{lableable.html → labelable.html} +7 -7
  25. package/docs/interfaces/labeled.html +2 -2
  26. package/docs/interfaces/labelelement.html +18 -0
  27. package/docs/interfaces/labelprops.html +339 -0
  28. package/docs/interfaces/layoutprops.html +25 -10
  29. package/docs/interfaces/ownpropsofcell.html +9 -9
  30. package/docs/interfaces/ownpropsofcontrol.html +9 -9
  31. package/docs/interfaces/ownpropsofenum.html +1 -1
  32. package/docs/interfaces/ownpropsofenumcell.html +10 -10
  33. package/docs/interfaces/ownpropsofjsonformsrenderer.html +8 -8
  34. package/docs/interfaces/ownpropsoflabel.html +286 -0
  35. package/docs/interfaces/ownpropsoflayout.html +9 -9
  36. package/docs/interfaces/ownpropsofmasterlistitem.html +6 -6
  37. package/docs/interfaces/ownpropsofrenderer.html +11 -8
  38. package/docs/interfaces/rendererprops.html +9 -9
  39. package/docs/interfaces/statepropsofarraycontrol.html +17 -17
  40. package/docs/interfaces/statepropsofarraylayout.html +17 -17
  41. package/docs/interfaces/statepropsofcell.html +11 -11
  42. package/docs/interfaces/statepropsofcombinator.html +17 -17
  43. package/docs/interfaces/statepropsofcontrol.html +15 -15
  44. package/docs/interfaces/statepropsofcontrolwithdetail.html +16 -16
  45. package/docs/interfaces/statepropsofenumcell.html +12 -12
  46. package/docs/interfaces/statepropsofjsonformsrenderer.html +23 -9
  47. package/docs/interfaces/statepropsoflabel.html +343 -0
  48. package/docs/interfaces/statepropsoflayout.html +24 -10
  49. package/docs/interfaces/statepropsofmasteritem.html +7 -7
  50. package/docs/interfaces/statepropsofrenderer.html +12 -9
  51. package/docs/interfaces/statepropsofscopedrenderer.html +12 -12
  52. package/docs/interfaces/testercontext.html +184 -0
  53. package/docs/interfaces/withclassname.html +1 -1
  54. package/lib/i18n/i18nUtil.d.ts +9 -4
  55. package/lib/jsonforms-core.cjs.js +61 -32
  56. package/lib/jsonforms-core.cjs.js.map +1 -1
  57. package/lib/jsonforms-core.esm.js +59 -33
  58. package/lib/jsonforms-core.esm.js.map +1 -1
  59. package/lib/models/uischema.d.ts +7 -7
  60. package/lib/reducers/i18n.d.ts +1 -1
  61. package/lib/testers/testers.d.ts +15 -6
  62. package/lib/util/renderer.d.ts +18 -1
  63. package/package.json +2 -2
  64. package/src/i18n/i18nUtil.ts +24 -7
  65. package/src/models/uischema.ts +8 -8
  66. package/src/reducers/i18n.ts +1 -1
  67. package/src/testers/testers.ts +33 -23
  68. package/src/util/renderer.ts +52 -25
  69. package/stats.html +1 -1
  70. package/test/testers.test.ts +40 -23
  71. package/test/util/renderer.test.ts +105 -7
@@ -22,7 +22,7 @@ export interface Scoped extends Scopable {
22
22
  /**
23
23
  * Interface for describing an UI schema element that may be labeled.
24
24
  */
25
- export interface Lableable<T = string> {
25
+ export interface Labelable<T = string> {
26
26
  /**
27
27
  * Label for UI schema element.
28
28
  */
@@ -31,7 +31,7 @@ export interface Lableable<T = string> {
31
31
  /**
32
32
  * Interface for describing an UI schema element that is labeled.
33
33
  */
34
- export interface Labeled<T = string> extends Lableable<T> {
34
+ export interface Labeled<T = string> extends Labelable<T> {
35
35
  label: string | T;
36
36
  }
37
37
  export interface Internationalizable {
@@ -157,7 +157,7 @@ export interface HorizontalLayout extends Layout {
157
157
  * A group resembles a vertical layout, but additionally might have a label.
158
158
  * This layout is useful when grouping different elements by a certain criteria.
159
159
  */
160
- export interface GroupLayout extends Layout, Lableable {
160
+ export interface GroupLayout extends Layout, Labelable {
161
161
  type: 'Group';
162
162
  }
163
163
  /**
@@ -176,7 +176,7 @@ export interface LabelDescription {
176
176
  /**
177
177
  * A label element.
178
178
  */
179
- export interface LabelElement extends UISchemaElement {
179
+ export interface LabelElement extends UISchemaElement, Internationalizable {
180
180
  type: 'Label';
181
181
  /**
182
182
  * The text of label.
@@ -187,7 +187,7 @@ export interface LabelElement extends UISchemaElement {
187
187
  * A control element. The scope property of the control determines
188
188
  * to which part of the schema the control should be bound.
189
189
  */
190
- export interface ControlElement extends UISchemaElement, Scoped, Lableable<string | boolean | LabelDescription>, Internationalizable {
190
+ export interface ControlElement extends UISchemaElement, Scoped, Labelable<string | boolean | LabelDescription>, Internationalizable {
191
191
  type: 'Control';
192
192
  }
193
193
  /**
@@ -214,5 +214,5 @@ export declare const isGroup: (layout: Layout) => layout is GroupLayout;
214
214
  export declare const isLayout: (uischema: UISchemaElement) => uischema is Layout;
215
215
  export declare const isScopable: (obj: unknown) => obj is Scopable;
216
216
  export declare const isScoped: (obj: unknown) => obj is Scoped;
217
- export declare const isLabelable: (obj: unknown) => obj is Lableable<string>;
218
- export declare const isLabeled: (obj: unknown) => obj is Labeled<string>;
217
+ export declare const isLabelable: (obj: unknown) => obj is Labelable<string>;
218
+ export declare const isLabeled: <T = never>(obj: unknown) => obj is Labeled<T>;
@@ -1,7 +1,7 @@
1
1
  import { JsonFormsI18nState } from '../i18n';
2
2
  import { I18nActions } from '../actions';
3
3
  import { Reducer } from '../util';
4
- export declare const defaultJsonFormsI18nState: JsonFormsI18nState;
4
+ export declare const defaultJsonFormsI18nState: Required<JsonFormsI18nState>;
5
5
  export declare const i18nReducer: Reducer<JsonFormsI18nState, I18nActions>;
6
6
  export declare const fetchLocale: (state?: JsonFormsI18nState) => string;
7
7
  export declare const fetchTranslator: (state?: JsonFormsI18nState) => import("../i18n").Translator;
@@ -9,11 +9,20 @@ export declare const NOT_APPLICABLE = -1;
9
9
  * A tester is a function that receives an UI schema and a JSON schema and returns a boolean.
10
10
  * The rootSchema is handed over as context. Can be used to resolve references.
11
11
  */
12
- export declare type Tester = (uischema: UISchemaElement, schema: JsonSchema, rootSchema: JsonSchema) => boolean;
12
+ export declare type Tester = (uischema: UISchemaElement, schema: JsonSchema, context: TesterContext) => boolean;
13
13
  /**
14
14
  * A ranked tester associates a tester with a number.
15
15
  */
16
- export declare type RankedTester = (uischema: UISchemaElement, schema: JsonSchema, rootSchema: JsonSchema) => number;
16
+ export declare type RankedTester = (uischema: UISchemaElement, schema: JsonSchema, context: TesterContext) => number;
17
+ /**
18
+ * Additional context given to a tester in addition to UISchema and JsonSchema.
19
+ */
20
+ export interface TesterContext {
21
+ /** The root JsonSchema of the form. Can be used to resolve references. */
22
+ rootSchema: JsonSchema;
23
+ /** The form wide configuration object given to JsonForms. */
24
+ config: any;
25
+ }
17
26
  export declare const isControl: (uischema: any) => uischema is ControlElement;
18
27
  /**
19
28
  * Only applicable for Controls.
@@ -97,8 +106,8 @@ export declare const or: (...testers: Tester[]) => Tester;
97
106
  * @param {number} rank the rank to be returned in case the tester returns true
98
107
  * @param {Tester} tester a tester
99
108
  */
100
- export declare const rankWith: (rank: number, tester: Tester) => (uischema: UISchemaElement, schema: JsonSchema, rootSchema: JsonSchema) => number;
101
- export declare const withIncreasedRank: (by: number, rankedTester: RankedTester) => (uischema: UISchemaElement, schema: JsonSchema, rootSchema: JsonSchema) => number;
109
+ export declare const rankWith: (rank: number, tester: Tester) => (uischema: UISchemaElement, schema: JsonSchema, context: TesterContext) => number;
110
+ export declare const withIncreasedRank: (by: number, rankedTester: RankedTester) => (uischema: UISchemaElement, schema: JsonSchema, context: TesterContext) => number;
102
111
  /**
103
112
  * Default tester for boolean.
104
113
  * @type {RankedTester}
@@ -173,7 +182,7 @@ export declare const isObjectArray: Tester;
173
182
  * @type {Tester}
174
183
  */
175
184
  export declare const isObjectArrayControl: Tester;
176
- export declare const isObjectArrayWithNesting: (uischema: UISchemaElement, schema: JsonSchema, rootSchema: JsonSchema) => boolean;
185
+ export declare const isObjectArrayWithNesting: (uischema: UISchemaElement, schema: JsonSchema, context: TesterContext) => boolean;
177
186
  /**
178
187
  * Synonym for isObjectArrayControl
179
188
  */
@@ -193,7 +202,7 @@ export declare const isPrimitiveArrayControl: Tester;
193
202
  export declare const isRangeControl: Tester;
194
203
  /**
195
204
  * Tests whether the given UI schema is of type Control, if the schema
196
- * is of type string and has option format
205
+ * is of type integer and has option format
197
206
  * @type {Tester}
198
207
  */
199
208
  export declare const isNumberFormatControl: Tester;
@@ -1,4 +1,4 @@
1
- import { ControlElement, JsonSchema, UISchemaElement } from '../models';
1
+ import { ControlElement, JsonSchema, LabelElement, UISchemaElement } from '../models';
2
2
  import { JsonFormsCellRendererRegistryEntry, JsonFormsRendererRegistryEntry } from '../reducers';
3
3
  import { JsonFormsUISchemaRegistryEntry } from '../reducers';
4
4
  import { RankedTester } from '../testers';
@@ -82,6 +82,9 @@ export interface OwnPropsOfControl extends OwnPropsOfRenderer {
82
82
  id?: string;
83
83
  uischema?: ControlElement;
84
84
  }
85
+ export interface OwnPropsOfLabel extends OwnPropsOfRenderer {
86
+ uischema?: LabelElement;
87
+ }
85
88
  export interface OwnPropsOfEnum {
86
89
  options?: EnumOption[];
87
90
  }
@@ -202,6 +205,7 @@ export interface StatePropsOfLayout extends StatePropsOfRenderer {
202
205
  * Direction for the layout to flow
203
206
  */
204
207
  direction: 'row' | 'column';
208
+ label?: string;
205
209
  }
206
210
  export interface LayoutProps extends StatePropsOfLayout {
207
211
  }
@@ -348,6 +352,7 @@ export interface OwnPropsOfJsonFormsRenderer extends OwnPropsOfRenderer {
348
352
  }
349
353
  export interface StatePropsOfJsonFormsRenderer extends OwnPropsOfJsonFormsRenderer {
350
354
  rootSchema: JsonSchema;
355
+ config: any;
351
356
  }
352
357
  export interface JsonFormsProps extends StatePropsOfJsonFormsRenderer {
353
358
  }
@@ -396,3 +401,15 @@ export declare const mapStateToArrayLayoutProps: (state: JsonFormsState, ownProp
396
401
  */
397
402
  export interface ArrayLayoutProps extends StatePropsOfArrayLayout, DispatchPropsOfArrayControl {
398
403
  }
404
+ export interface StatePropsOfLabel extends StatePropsOfRenderer {
405
+ text?: string;
406
+ }
407
+ export interface LabelProps extends StatePropsOfLabel {
408
+ }
409
+ export declare const mapStateToLabelProps: (state: JsonFormsState, props: OwnPropsOfLabel) => {
410
+ text: string;
411
+ visible: boolean;
412
+ config: any;
413
+ renderers: JsonFormsRendererRegistryEntry[];
414
+ cells: JsonFormsCellRendererRegistryEntry[];
415
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsonforms/core",
3
- "version": "3.0.0-beta.5",
3
+ "version": "3.0.0-rc.0",
4
4
  "description": "Core module of JSON Forms",
5
5
  "repository": "https://github.com/eclipsesource/jsonforms",
6
6
  "bugs": "https://github.com/eclipsesource/jsonforms/issues",
@@ -88,5 +88,5 @@
88
88
  "typedoc": "^0.19.2",
89
89
  "typescript": "4.2.3"
90
90
  },
91
- "gitHead": "b66023cf081e56baa3194ac3d6658e23fd267bf9"
91
+ "gitHead": "5ef030e8b3f91bcdc3e6b8d232a0b191bf1195ce"
92
92
  }
@@ -1,12 +1,12 @@
1
1
  import { ErrorObject } from 'ajv';
2
- import { isInternationalized, UISchemaElement } from '../models';
2
+ import { isInternationalized, Labelable, UISchemaElement } from '../models';
3
3
  import { getControlPath } from '../reducers';
4
4
  import { formatErrorMessage } from '../util';
5
5
  import { i18nJsonSchema, ErrorTranslator, Translator } from './i18nTypes';
6
6
 
7
7
  export const getI18nKeyPrefixBySchema = (
8
8
  schema: i18nJsonSchema | undefined,
9
- uischema: UISchemaElement | undefined
9
+ uischema: unknown | undefined
10
10
  ): string | undefined => {
11
11
  if (isInternationalized(uischema)) {
12
12
  return uischema.i18n;
@@ -18,7 +18,7 @@ export const getI18nKeyPrefixBySchema = (
18
18
  * Transforms a given path to a prefix which can be used for i18n keys.
19
19
  * Returns 'root' for empty paths and removes array indices
20
20
  */
21
- export const transformPathToI18nPrefix = (path: string) => {
21
+ export const transformPathToI18nPrefix = (path: string): string => {
22
22
  return (
23
23
  path
24
24
  ?.split('.')
@@ -29,9 +29,9 @@ export const transformPathToI18nPrefix = (path: string) => {
29
29
 
30
30
  export const getI18nKeyPrefix = (
31
31
  schema: i18nJsonSchema | undefined,
32
- uischema: UISchemaElement | undefined,
32
+ uischema: unknown | undefined,
33
33
  path: string | undefined
34
- ): string | undefined => {
34
+ ): string => {
35
35
  return (
36
36
  getI18nKeyPrefixBySchema(schema, uischema) ??
37
37
  transformPathToI18nPrefix(path)
@@ -40,10 +40,10 @@ export const getI18nKeyPrefix = (
40
40
 
41
41
  export const getI18nKey = (
42
42
  schema: i18nJsonSchema | undefined,
43
- uischema: UISchemaElement | undefined,
43
+ uischema: unknown | undefined,
44
44
  path: string | undefined,
45
45
  key: string
46
- ): string | undefined => {
46
+ ): string => {
47
47
  return `${getI18nKeyPrefix(schema, uischema, path)}.${key}`;
48
48
  };
49
49
 
@@ -106,3 +106,20 @@ export const getCombinedErrorMessage = (
106
106
  errors.map(error => et(error, t, uischema))
107
107
  );
108
108
  };
109
+
110
+ /**
111
+ * This can be used to internationalize the label of the given Labelable (e.g. UI Schema elements).
112
+ * This should not be used for controls as there we have additional context in the form of the JSON Schema available.
113
+ */
114
+ export const deriveLabelForUISchemaElement = (uischema: Labelable<boolean>, t: Translator): string | undefined => {
115
+ if (uischema.label === false) {
116
+ return undefined;
117
+ }
118
+ if ((uischema.label === undefined || uischema.label === null || uischema.label === true) && !isInternationalized(uischema)) {
119
+ return undefined;
120
+ }
121
+ const stringifiedLabel = typeof uischema.label === 'string' ? uischema.label : JSON.stringify(uischema.label);
122
+ const i18nKeyPrefix = getI18nKeyPrefixBySchema(undefined, uischema);
123
+ const i18nKey = typeof i18nKeyPrefix === 'string' ? `${i18nKeyPrefix}.label` : stringifiedLabel;
124
+ return t(i18nKey, stringifiedLabel, { uischema: uischema });
125
+ }
@@ -50,7 +50,7 @@ export interface Scoped extends Scopable {
50
50
  /**
51
51
  * Interface for describing an UI schema element that may be labeled.
52
52
  */
53
- export interface Lableable<T = string> {
53
+ export interface Labelable<T = string> {
54
54
  /**
55
55
  * Label for UI schema element.
56
56
  */
@@ -60,7 +60,7 @@ export interface Lableable<T = string> {
60
60
  /**
61
61
  * Interface for describing an UI schema element that is labeled.
62
62
  */
63
- export interface Labeled<T = string> extends Lableable<T> {
63
+ export interface Labeled<T = string> extends Labelable<T> {
64
64
  label: string | T;
65
65
  }
66
66
 
@@ -207,7 +207,7 @@ export interface HorizontalLayout extends Layout {
207
207
  * A group resembles a vertical layout, but additionally might have a label.
208
208
  * This layout is useful when grouping different elements by a certain criteria.
209
209
  */
210
- export interface GroupLayout extends Layout, Lableable {
210
+ export interface GroupLayout extends Layout, Labelable {
211
211
  type: 'Group';
212
212
  }
213
213
 
@@ -228,7 +228,7 @@ export interface LabelDescription {
228
228
  /**
229
229
  * A label element.
230
230
  */
231
- export interface LabelElement extends UISchemaElement {
231
+ export interface LabelElement extends UISchemaElement, Internationalizable {
232
232
  type: 'Label';
233
233
  /**
234
234
  * The text of label.
@@ -240,7 +240,7 @@ export interface LabelElement extends UISchemaElement {
240
240
  * A control element. The scope property of the control determines
241
241
  * to which part of the schema the control should be bound.
242
242
  */
243
- export interface ControlElement extends UISchemaElement, Scoped, Lableable<string | boolean | LabelDescription>, Internationalizable {
243
+ export interface ControlElement extends UISchemaElement, Scoped, Labelable<string | boolean | LabelDescription>, Internationalizable {
244
244
  type: 'Control';
245
245
  }
246
246
 
@@ -280,8 +280,8 @@ export const isScopable = (obj: unknown): obj is Scopable =>
280
280
  export const isScoped = (obj: unknown): obj is Scoped =>
281
281
  isScopable(obj) && typeof obj.scope === 'string';
282
282
 
283
- export const isLabelable = (obj: unknown): obj is Lableable =>
283
+ export const isLabelable = (obj: unknown): obj is Labelable =>
284
284
  obj && typeof obj === 'object';
285
285
 
286
- export const isLabeled = (obj: unknown): obj is Labeled =>
287
- isLabelable(obj) && ['string', 'object'].includes(typeof obj.label);
286
+ export const isLabeled = <T = never>(obj: unknown): obj is Labeled<T> =>
287
+ isLabelable(obj) && ['string', 'boolean'].includes(typeof obj.label);
@@ -27,7 +27,7 @@ import { defaultErrorTranslator, defaultTranslator, JsonFormsI18nState } from '.
27
27
  import { I18nActions, SET_LOCALE, SET_TRANSLATOR, UPDATE_I18N } from '../actions';
28
28
  import { Reducer } from '../util';
29
29
 
30
- export const defaultJsonFormsI18nState: JsonFormsI18nState = {
30
+ export const defaultJsonFormsI18nState: Required<JsonFormsI18nState> = {
31
31
  locale: 'en',
32
32
  translate: defaultTranslator,
33
33
  translateError: defaultErrorTranslator
@@ -49,7 +49,7 @@ export const NOT_APPLICABLE = -1;
49
49
  * A tester is a function that receives an UI schema and a JSON schema and returns a boolean.
50
50
  * The rootSchema is handed over as context. Can be used to resolve references.
51
51
  */
52
- export type Tester = (uischema: UISchemaElement, schema: JsonSchema, rootSchema: JsonSchema) => boolean;
52
+ export type Tester = (uischema: UISchemaElement, schema: JsonSchema, context: TesterContext) => boolean;
53
53
 
54
54
  /**
55
55
  * A ranked tester associates a tester with a number.
@@ -57,9 +57,19 @@ export type Tester = (uischema: UISchemaElement, schema: JsonSchema, rootSchema:
57
57
  export type RankedTester = (
58
58
  uischema: UISchemaElement,
59
59
  schema: JsonSchema,
60
- rootSchema: JsonSchema
60
+ context: TesterContext
61
61
  ) => number;
62
62
 
63
+ /**
64
+ * Additional context given to a tester in addition to UISchema and JsonSchema.
65
+ */
66
+ export interface TesterContext {
67
+ /** The root JsonSchema of the form. Can be used to resolve references. */
68
+ rootSchema: JsonSchema;
69
+ /** The form wide configuration object given to JsonForms. */
70
+ config: any;
71
+ }
72
+
63
73
  export const isControl = (uischema: any): uischema is ControlElement =>
64
74
  !isEmpty(uischema) && uischema.scope !== undefined;
65
75
 
@@ -75,7 +85,7 @@ export const isControl = (uischema: any): uischema is ControlElement =>
75
85
  */
76
86
  export const schemaMatches = (
77
87
  predicate: (schema: JsonSchema, rootSchema: JsonSchema) => boolean
78
- ): Tester => (uischema: UISchemaElement, schema: JsonSchema, rootSchema: JsonSchema): boolean => {
88
+ ): Tester => (uischema: UISchemaElement, schema: JsonSchema, context: TesterContext): boolean => {
79
89
  if (isEmpty(uischema) || !isControl(uischema)) {
80
90
  return false;
81
91
  }
@@ -88,26 +98,26 @@ export const schemaMatches = (
88
98
  }
89
99
  let currentDataSchema = schema;
90
100
  if (hasType(schema, 'object')) {
91
- currentDataSchema = resolveSchema(schema, schemaPath, rootSchema);
101
+ currentDataSchema = resolveSchema(schema, schemaPath, context?.rootSchema);
92
102
  }
93
103
  if (currentDataSchema === undefined) {
94
104
  return false;
95
105
  }
96
106
 
97
- return predicate(currentDataSchema, rootSchema);
107
+ return predicate(currentDataSchema, context?.rootSchema);
98
108
  };
99
109
 
100
110
  export const schemaSubPathMatches = (
101
111
  subPath: string,
102
112
  predicate: (schema: JsonSchema, rootSchema: JsonSchema) => boolean
103
- ): Tester => (uischema: UISchemaElement, schema: JsonSchema, rootSchema: JsonSchema): boolean => {
113
+ ): Tester => (uischema: UISchemaElement, schema: JsonSchema, context: TesterContext): boolean => {
104
114
  if (isEmpty(uischema) || !isControl(uischema)) {
105
115
  return false;
106
116
  }
107
117
  const schemaPath = uischema.scope;
108
118
  let currentDataSchema: JsonSchema = schema;
109
119
  if (hasType(schema, 'object')) {
110
- currentDataSchema = resolveSchema(schema, schemaPath, rootSchema);
120
+ currentDataSchema = resolveSchema(schema, schemaPath, context?.rootSchema);
111
121
  }
112
122
  currentDataSchema = get(currentDataSchema, subPath);
113
123
 
@@ -115,7 +125,7 @@ export const schemaSubPathMatches = (
115
125
  return false;
116
126
  }
117
127
 
118
- return predicate(currentDataSchema, rootSchema);
128
+ return predicate(currentDataSchema, context?.rootSchema);
119
129
  };
120
130
 
121
131
  /**
@@ -218,8 +228,8 @@ export const scopeEndIs = (expected: string): Tester => (
218
228
  export const and = (...testers: Tester[]): Tester => (
219
229
  uischema: UISchemaElement,
220
230
  schema: JsonSchema,
221
- rootSchema: JsonSchema
222
- ) => testers.reduce((acc, tester) => acc && tester(uischema, schema, rootSchema), true);
231
+ context: TesterContext
232
+ ) => testers.reduce((acc, tester) => acc && tester(uischema, schema, context), true);
223
233
 
224
234
  /**
225
235
  * A tester that allow composing other testers by || them.
@@ -229,8 +239,8 @@ export const and = (...testers: Tester[]): Tester => (
229
239
  export const or = (...testers: Tester[]): Tester => (
230
240
  uischema: UISchemaElement,
231
241
  schema: JsonSchema,
232
- rootSchema: JsonSchema
233
- ) => testers.reduce((acc, tester) => acc || tester(uischema, schema, rootSchema), false);
242
+ context: TesterContext
243
+ ) => testers.reduce((acc, tester) => acc || tester(uischema, schema, context), false);
234
244
  /**
235
245
  * Create a ranked tester that will associate a number with a given tester, if the
236
246
  * latter returns true.
@@ -241,9 +251,9 @@ export const or = (...testers: Tester[]): Tester => (
241
251
  export const rankWith = (rank: number, tester: Tester) => (
242
252
  uischema: UISchemaElement,
243
253
  schema: JsonSchema,
244
- rootSchema: JsonSchema
254
+ context: TesterContext
245
255
  ): number => {
246
- if (tester(uischema, schema, rootSchema)) {
256
+ if (tester(uischema, schema, context)) {
247
257
  return rank;
248
258
  }
249
259
 
@@ -253,9 +263,9 @@ export const rankWith = (rank: number, tester: Tester) => (
253
263
  export const withIncreasedRank = (by: number, rankedTester: RankedTester) => (
254
264
  uischema: UISchemaElement,
255
265
  schema: JsonSchema,
256
- rootSchema: JsonSchema
266
+ context: TesterContext
257
267
  ): number => {
258
- const rank = rankedTester(uischema, schema, rootSchema);
268
+ const rank = rankedTester(uischema, schema, context);
259
269
  if (rank === NOT_APPLICABLE) {
260
270
  return NOT_APPLICABLE;
261
271
  }
@@ -438,13 +448,13 @@ const traverse = (
438
448
  export const isObjectArrayWithNesting = (
439
449
  uischema: UISchemaElement,
440
450
  schema: JsonSchema,
441
- rootSchema: JsonSchema
451
+ context: TesterContext
442
452
  ): boolean => {
443
- if (!uiTypeIs('Control')(uischema, schema, rootSchema)) {
453
+ if (!uiTypeIs('Control')(uischema, schema, context)) {
444
454
  return false;
445
455
  }
446
456
  const schemaPath = (uischema as ControlElement).scope;
447
- const resolvedSchema = resolveSchema(schema, schemaPath, rootSchema ?? schema);
457
+ const resolvedSchema = resolveSchema(schema, schemaPath, context?.rootSchema ?? schema);
448
458
  let objectDepth = 0;
449
459
  if (resolvedSchema !== undefined && resolvedSchema.items !== undefined) {
450
460
  // check if nested arrays
@@ -466,7 +476,7 @@ export const isObjectArrayWithNesting = (
466
476
  return true;
467
477
  }
468
478
  return false;
469
- }, rootSchema)
479
+ }, context?.rootSchema)
470
480
  ) {
471
481
  return true;
472
482
  }
@@ -532,7 +542,7 @@ export const isRangeControl = and(
532
542
 
533
543
  /**
534
544
  * Tests whether the given UI schema is of type Control, if the schema
535
- * is of type string and has option format
545
+ * is of type integer and has option format
536
546
  * @type {Tester}
537
547
  */
538
548
  export const isNumberFormatControl = and(
@@ -566,6 +576,6 @@ export const categorizationHasCategory = (uischema: UISchemaElement) =>
566
576
  export const not = (tester: Tester): Tester => (
567
577
  uischema: UISchemaElement,
568
578
  schema: JsonSchema,
569
- rootSchema: JsonSchema
579
+ context: TesterContext
570
580
 
571
- ) => !tester(uischema, schema, rootSchema);
581
+ ) => !tester(uischema, schema, context);
@@ -24,7 +24,7 @@
24
24
  */
25
25
 
26
26
  import get from 'lodash/get';
27
- import { ControlElement, JsonSchema, UISchemaElement } from '../models';
27
+ import { ControlElement, isLabelable, JsonSchema, LabelElement, UISchemaElement } from '../models';
28
28
  import find from 'lodash/find';
29
29
  import {
30
30
  getUISchemas,
@@ -32,7 +32,6 @@ import {
32
32
  JsonFormsRendererRegistryEntry,
33
33
  } from '../reducers';
34
34
  import {
35
- findUISchema,
36
35
  getAjv,
37
36
  getCells,
38
37
  getConfig,
@@ -57,7 +56,7 @@ import { composePaths, composeWithUi } from './path';
57
56
  import { CoreActions, update } from '../actions';
58
57
  import { ErrorObject } from 'ajv';
59
58
  import { JsonFormsState } from '../store';
60
- import { getCombinedErrorMessage, getI18nKey, getI18nKeyPrefix, Translator } from '../i18n';
59
+ import { deriveLabelForUISchemaElement, getCombinedErrorMessage, getI18nKey, getI18nKeyPrefix, getI18nKeyPrefixBySchema, Translator } from '../i18n';
61
60
 
62
61
  const isRequired = (
63
62
  schema: JsonSchema,
@@ -255,6 +254,10 @@ export interface OwnPropsOfControl extends OwnPropsOfRenderer {
255
254
  uischema?: ControlElement;
256
255
  }
257
256
 
257
+ export interface OwnPropsOfLabel extends OwnPropsOfRenderer {
258
+ uischema?: LabelElement;
259
+ }
260
+
258
261
  export interface OwnPropsOfEnum {
259
262
  options?: EnumOption[];
260
263
  }
@@ -398,6 +401,7 @@ export interface StatePropsOfLayout extends StatePropsOfRenderer {
398
401
  * Direction for the layout to flow
399
402
  */
400
403
  direction: 'row' | 'column';
404
+ label?: string;
401
405
  }
402
406
 
403
407
  export interface LayoutProps extends StatePropsOfLayout {}
@@ -857,6 +861,10 @@ export const mapStateToLayoutProps = (
857
861
  config
858
862
  );
859
863
 
864
+ // some layouts have labels which might need to be translated
865
+ const t = getTranslator()(state);
866
+ const label = isLabelable(uischema) ? deriveLabelForUISchemaElement(uischema, t) : undefined;
867
+
860
868
  return {
861
869
  ...layoutDefaultProps,
862
870
  renderers: ownProps.renderers || getRenderers(state),
@@ -868,7 +876,8 @@ export const mapStateToLayoutProps = (
868
876
  uischema: ownProps.uischema,
869
877
  schema: ownProps.schema,
870
878
  direction: ownProps.direction ?? getDirection(uischema),
871
- config
879
+ config,
880
+ label
872
881
  };
873
882
  };
874
883
 
@@ -879,6 +888,7 @@ export interface OwnPropsOfJsonFormsRenderer extends OwnPropsOfRenderer {}
879
888
  export interface StatePropsOfJsonFormsRenderer
880
889
  extends OwnPropsOfJsonFormsRenderer {
881
890
  rootSchema: JsonSchema;
891
+ config: any;
882
892
  }
883
893
 
884
894
  export interface JsonFormsProps extends StatePropsOfJsonFormsRenderer {}
@@ -887,30 +897,15 @@ export const mapStateToJsonFormsRendererProps = (
887
897
  state: JsonFormsState,
888
898
  ownProps: OwnPropsOfJsonFormsRenderer
889
899
  ): StatePropsOfJsonFormsRenderer => {
890
- let uischema = ownProps.uischema;
891
- if (uischema === undefined) {
892
- if (ownProps.schema) {
893
- uischema = findUISchema(
894
- state.jsonforms.uischemas,
895
- ownProps.schema,
896
- undefined,
897
- ownProps.path,
898
- undefined,
899
- undefined,
900
- state.jsonforms.core.schema
901
- );
902
- } else {
903
- uischema = getUiSchema(state);
904
- }
905
- }
906
-
907
900
  return {
908
- renderers: ownProps.renderers || get(state.jsonforms, 'renderers') || [],
909
- cells: ownProps.cells || get(state.jsonforms, 'cells') || [],
901
+ renderers: ownProps.renderers || get(state.jsonforms, 'renderers'),
902
+ cells: ownProps.cells || get(state.jsonforms, 'cells'),
910
903
  schema: ownProps.schema || getSchema(state),
911
904
  rootSchema: getSchema(state),
912
- uischema: uischema,
913
- path: ownProps.path
905
+ uischema: ownProps.uischema || getUiSchema(state),
906
+ path: ownProps.path,
907
+ enabled: ownProps.enabled,
908
+ config: getConfig(state)
914
909
  };
915
910
  };
916
911
 
@@ -1064,3 +1059,35 @@ export const mapStateToArrayLayoutProps = (
1064
1059
  export interface ArrayLayoutProps
1065
1060
  extends StatePropsOfArrayLayout,
1066
1061
  DispatchPropsOfArrayControl {}
1062
+
1063
+ export interface StatePropsOfLabel extends StatePropsOfRenderer {
1064
+ text?: string;
1065
+ }
1066
+ export interface LabelProps extends StatePropsOfLabel{
1067
+ }
1068
+
1069
+ export const mapStateToLabelProps = (
1070
+ state: JsonFormsState,
1071
+ props: OwnPropsOfLabel
1072
+ ) => {
1073
+ const { uischema } = props;
1074
+
1075
+ const visible: boolean =
1076
+ props.visible === undefined || hasShowRule(uischema)
1077
+ ? isVisible(props.uischema, getData(state), props.path, getAjv(state))
1078
+ : props.visible;
1079
+
1080
+ const text = uischema.text;
1081
+ const t = getTranslator()(state);
1082
+ const i18nKeyPrefix = getI18nKeyPrefixBySchema(undefined, uischema);
1083
+ const i18nKey = i18nKeyPrefix ? `${i18nKeyPrefix}.text` : text ?? '';
1084
+ const i18nText = t(i18nKey, text, { uischema });
1085
+
1086
+ return {
1087
+ text: i18nText,
1088
+ visible,
1089
+ config: getConfig(state),
1090
+ renderers: props.renderers || getRenderers(state),
1091
+ cells: props.cells || getCells(state),
1092
+ }
1093
+ }