@jsonforms/core 3.0.0-beta.3 → 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 (93) hide show
  1. package/README.md +11 -0
  2. package/docs/assets/js/search.json +1 -1
  3. package/docs/enums/ruleeffect.html +4 -4
  4. package/docs/globals.html +371 -115
  5. package/docs/index.html +59 -4
  6. package/docs/interfaces/andcondition.html +2 -2
  7. package/docs/interfaces/arraycontrolprops.html +21 -21
  8. package/docs/interfaces/arraylayoutprops.html +21 -21
  9. package/docs/interfaces/categorization.html +24 -16
  10. package/docs/interfaces/category.html +24 -16
  11. package/docs/interfaces/cellprops.html +12 -12
  12. package/docs/interfaces/combinatorrendererprops.html +18 -18
  13. package/docs/interfaces/composablecondition.html +2 -2
  14. package/docs/interfaces/condition.html +1 -1
  15. package/docs/interfaces/controlelement.html +38 -15
  16. package/docs/interfaces/controlprops.html +16 -16
  17. package/docs/interfaces/controlstate.html +2 -2
  18. package/docs/interfaces/controlwithdetailprops.html +17 -17
  19. package/docs/interfaces/dispatchcellprops.html +10 -10
  20. package/docs/interfaces/dispatchcellstateprops.html +10 -10
  21. package/docs/interfaces/dispatchpropsofarraycontrol.html +4 -4
  22. package/docs/interfaces/dispatchpropsofcontrol.html +1 -1
  23. package/docs/interfaces/dispatchpropsofmultienumcontrol.html +2 -2
  24. package/docs/interfaces/enumcellprops.html +13 -13
  25. package/docs/interfaces/enumoption.html +2 -2
  26. package/docs/interfaces/grouplayout.html +24 -12
  27. package/docs/interfaces/horizontallayout.html +4 -4
  28. package/docs/interfaces/internationalizable.html +161 -0
  29. package/docs/interfaces/jsonformsprops.html +24 -9
  30. package/docs/interfaces/labelable.html +184 -0
  31. package/docs/interfaces/labeldescription.html +2 -2
  32. package/docs/interfaces/labeled.html +182 -0
  33. package/docs/interfaces/labelelement.html +22 -4
  34. package/docs/interfaces/labelprops.html +339 -0
  35. package/docs/interfaces/layout.html +4 -4
  36. package/docs/interfaces/layoutprops.html +25 -10
  37. package/docs/interfaces/leafcondition.html +9 -8
  38. package/docs/interfaces/orcondition.html +2 -2
  39. package/docs/interfaces/ownpropsofcell.html +9 -9
  40. package/docs/interfaces/ownpropsofcontrol.html +9 -9
  41. package/docs/interfaces/ownpropsofenum.html +1 -1
  42. package/docs/interfaces/ownpropsofenumcell.html +10 -10
  43. package/docs/interfaces/ownpropsofjsonformsrenderer.html +8 -8
  44. package/docs/interfaces/ownpropsoflabel.html +286 -0
  45. package/docs/interfaces/ownpropsoflayout.html +9 -9
  46. package/docs/interfaces/ownpropsofmasterlistitem.html +6 -6
  47. package/docs/interfaces/ownpropsofrenderer.html +11 -8
  48. package/docs/interfaces/rendererprops.html +9 -9
  49. package/docs/interfaces/rule.html +2 -2
  50. package/docs/interfaces/schemabasedcondition.html +9 -8
  51. package/docs/interfaces/scopable.html +3 -9
  52. package/docs/interfaces/scoped.html +183 -0
  53. package/docs/interfaces/statepropsofarraycontrol.html +17 -17
  54. package/docs/interfaces/statepropsofarraylayout.html +17 -17
  55. package/docs/interfaces/statepropsofcell.html +11 -11
  56. package/docs/interfaces/statepropsofcombinator.html +17 -17
  57. package/docs/interfaces/statepropsofcontrol.html +15 -15
  58. package/docs/interfaces/statepropsofcontrolwithdetail.html +16 -16
  59. package/docs/interfaces/statepropsofenumcell.html +12 -12
  60. package/docs/interfaces/statepropsofjsonformsrenderer.html +23 -9
  61. package/docs/interfaces/statepropsoflabel.html +343 -0
  62. package/docs/interfaces/statepropsoflayout.html +24 -10
  63. package/docs/interfaces/statepropsofmasteritem.html +7 -7
  64. package/docs/interfaces/statepropsofrenderer.html +12 -9
  65. package/docs/interfaces/statepropsofscopedrenderer.html +12 -12
  66. package/docs/interfaces/testercontext.html +184 -0
  67. package/docs/interfaces/uischemaelement.html +3 -3
  68. package/docs/interfaces/verticallayout.html +4 -4
  69. package/docs/interfaces/withclassname.html +1 -1
  70. package/lib/i18n/i18nUtil.d.ts +9 -4
  71. package/lib/jsonforms-core.cjs.js +103 -50
  72. package/lib/jsonforms-core.cjs.js.map +1 -1
  73. package/lib/jsonforms-core.esm.js +85 -50
  74. package/lib/jsonforms-core.esm.js.map +1 -1
  75. package/lib/models/uischema.d.ts +41 -24
  76. package/lib/reducers/i18n.d.ts +1 -1
  77. package/lib/testers/testers.d.ts +15 -6
  78. package/lib/util/renderer.d.ts +18 -1
  79. package/lib/util/runtime.d.ts +1 -2
  80. package/lib/util/util.d.ts +6 -6
  81. package/package.json +2 -2
  82. package/src/i18n/i18nUtil.ts +28 -8
  83. package/src/models/uischema.ts +60 -24
  84. package/src/reducers/i18n.ts +1 -1
  85. package/src/testers/testers.ts +43 -36
  86. package/src/util/path.ts +9 -5
  87. package/src/util/renderer.ts +52 -25
  88. package/src/util/runtime.ts +1 -1
  89. package/src/util/util.ts +8 -8
  90. package/stats.html +1 -1
  91. package/test/i18n/i18nUtil.test.ts +41 -1
  92. package/test/testers.test.ts +40 -23
  93. package/test/util/renderer.test.ts +106 -8
@@ -1,14 +1,42 @@
1
1
  import { JsonSchema } from './jsonSchema';
2
2
  /**
3
3
  * Interface for describing an UI schema element that is referencing
4
- * a subschema. The value of the scope must be a JSON Pointer.
4
+ * a subschema. The value of the scope may be a JSON Pointer.
5
5
  */
6
6
  export interface Scopable {
7
+ /**
8
+ * The scope that determines to which part this element should be bound to.
9
+ */
10
+ scope?: string;
11
+ }
12
+ /**
13
+ * Interface for describing an UI schema element that is referencing
14
+ * a subschema. The value of the scope must be a JSON Pointer.
15
+ */
16
+ export interface Scoped extends Scopable {
7
17
  /**
8
18
  * The scope that determines to which part this element should be bound to.
9
19
  */
10
20
  scope: string;
11
21
  }
22
+ /**
23
+ * Interface for describing an UI schema element that may be labeled.
24
+ */
25
+ export interface Labelable<T = string> {
26
+ /**
27
+ * Label for UI schema element.
28
+ */
29
+ label?: string | T;
30
+ }
31
+ /**
32
+ * Interface for describing an UI schema element that is labeled.
33
+ */
34
+ export interface Labeled<T = string> extends Labelable<T> {
35
+ label: string | T;
36
+ }
37
+ export interface Internationalizable {
38
+ i18n?: string;
39
+ }
12
40
  /**
13
41
  * A rule that may be attached to any UI schema element.
14
42
  */
@@ -56,14 +84,14 @@ export interface Condition {
56
84
  /**
57
85
  * A leaf condition.
58
86
  */
59
- export interface LeafCondition extends Condition, Scopable {
87
+ export interface LeafCondition extends Condition, Scoped {
60
88
  type: 'LEAF';
61
89
  /**
62
90
  * The expected value when evaluating the condition
63
91
  */
64
92
  expectedValue: any;
65
93
  }
66
- export interface SchemaBasedCondition extends Condition, Scopable {
94
+ export interface SchemaBasedCondition extends Condition, Scoped {
67
95
  schema: JsonSchema;
68
96
  }
69
97
  /**
@@ -129,12 +157,8 @@ export interface HorizontalLayout extends Layout {
129
157
  * A group resembles a vertical layout, but additionally might have a label.
130
158
  * This layout is useful when grouping different elements by a certain criteria.
131
159
  */
132
- export interface GroupLayout extends Layout {
160
+ export interface GroupLayout extends Layout, Labelable {
133
161
  type: 'Group';
134
- /**
135
- * The label of this group layout.
136
- */
137
- label?: string;
138
162
  }
139
163
  /**
140
164
  * Represents an object that can be used to configure a label.
@@ -152,7 +176,7 @@ export interface LabelDescription {
152
176
  /**
153
177
  * A label element.
154
178
  */
155
- export interface LabelElement extends UISchemaElement {
179
+ export interface LabelElement extends UISchemaElement, Internationalizable {
156
180
  type: 'Label';
157
181
  /**
158
182
  * The text of label.
@@ -163,39 +187,32 @@ export interface LabelElement extends UISchemaElement {
163
187
  * A control element. The scope property of the control determines
164
188
  * to which part of the schema the control should be bound.
165
189
  */
166
- export interface ControlElement extends UISchemaElement, Scopable {
190
+ export interface ControlElement extends UISchemaElement, Scoped, Labelable<string | boolean | LabelDescription>, Internationalizable {
167
191
  type: 'Control';
168
- /**
169
- * An optional label that will be associated with the control
170
- */
171
- label?: string | boolean | LabelDescription;
172
192
  }
173
193
  /**
174
194
  * The category layout.
175
195
  */
176
- export interface Category extends Layout {
196
+ export interface Category extends Layout, Labeled {
177
197
  type: 'Category';
178
- /**
179
- * The label associated with this category layout.
180
- */
181
- label: string;
182
198
  }
183
199
  /**
184
200
  * The categorization element, which may have children elements.
185
201
  * A child element may either be itself a Categorization or a Category, hence
186
202
  * the categorization element can be used to represent recursive structures like trees.
187
203
  */
188
- export interface Categorization extends UISchemaElement {
204
+ export interface Categorization extends UISchemaElement, Labeled {
189
205
  type: 'Categorization';
190
- /**
191
- * The label of this categorization.
192
- */
193
- label: string;
194
206
  /**
195
207
  * The child elements of this categorization which are either of type
196
208
  * {@link Category} or {@link Categorization}.
197
209
  */
198
210
  elements: (Category | Categorization)[];
199
211
  }
212
+ export declare const isInternationalized: (element: unknown) => element is Required<Internationalizable>;
200
213
  export declare const isGroup: (layout: Layout) => layout is GroupLayout;
201
214
  export declare const isLayout: (uischema: UISchemaElement) => uischema is Layout;
215
+ export declare const isScopable: (obj: unknown) => obj is Scopable;
216
+ export declare const isScoped: (obj: unknown) => obj is Scoped;
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
+ };
@@ -1,7 +1,6 @@
1
- import { UISchemaElement } from '../models';
1
+ import { JsonSchema, UISchemaElement } from '../models';
2
2
  import Ajv from 'ajv';
3
3
  import { JsonFormsState } from '../store';
4
- import { JsonSchema } from '../models/jsonSchema';
5
4
  export declare const evalVisibility: (uischema: UISchemaElement, data: any, path: string, ajv: Ajv) => boolean;
6
5
  export declare const evalEnablement: (uischema: UISchemaElement, data: any, path: string, ajv: Ajv) => boolean;
7
6
  export declare const hasShowRule: (uischema: UISchemaElement) => boolean;
@@ -1,4 +1,4 @@
1
- import { JsonSchema, Scopable, UISchemaElement } from '..';
1
+ import { JsonSchema, Scoped, UISchemaElement } from '..';
2
2
  import Ajv from 'ajv';
3
3
  /**
4
4
  * Escape the given string such that it can be used as a class name,
@@ -11,19 +11,19 @@ export declare const convertToValidClassName: (s: string) => string;
11
11
  export declare const formatErrorMessage: (errors: string[]) => string;
12
12
  export declare const hasType: (jsonSchema: JsonSchema, expected: string) => boolean;
13
13
  /**
14
- * Derives the type of the jsonSchema element
15
- */
14
+ * Derives the type of the jsonSchema element
15
+ */
16
16
  export declare const deriveTypes: (jsonSchema: JsonSchema) => string[];
17
17
  /**
18
- * Convenience wrapper around resolveData and resolveSchema.
19
- */
18
+ * Convenience wrapper around resolveData and resolveSchema.
19
+ */
20
20
  export declare const Resolve: {
21
21
  schema(schema: JsonSchema, schemaPath: string, rootSchema: JsonSchema): JsonSchema;
22
22
  data(data: any, path: string): any;
23
23
  };
24
24
  export declare const Paths: {
25
25
  compose: (path1: string, path2: string) => string;
26
- fromScopable: (scopable: Scopable) => string;
26
+ fromScoped: (scopable: Scoped) => string;
27
27
  };
28
28
  export declare const Runtime: {
29
29
  isEnabled(uischema: UISchemaElement, data: any, ajv: Ajv): boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsonforms/core",
3
- "version": "3.0.0-beta.3",
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": "78ef46d070f9c5ac1db1f04772db1293858ce2a4"
91
+ "gitHead": "5ef030e8b3f91bcdc3e6b8d232a0b191bf1195ce"
92
92
  }
@@ -1,21 +1,24 @@
1
1
  import { ErrorObject } from 'ajv';
2
- import { 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
- return uischema?.options?.i18n ?? schema?.i18n ?? undefined;
11
+ if (isInternationalized(uischema)) {
12
+ return uischema.i18n;
13
+ }
14
+ return schema?.i18n ?? undefined;
12
15
  };
13
16
 
14
17
  /**
15
18
  * Transforms a given path to a prefix which can be used for i18n keys.
16
19
  * Returns 'root' for empty paths and removes array indices
17
20
  */
18
- export const transformPathToI18nPrefix = (path: string) => {
21
+ export const transformPathToI18nPrefix = (path: string): string => {
19
22
  return (
20
23
  path
21
24
  ?.split('.')
@@ -26,9 +29,9 @@ export const transformPathToI18nPrefix = (path: string) => {
26
29
 
27
30
  export const getI18nKeyPrefix = (
28
31
  schema: i18nJsonSchema | undefined,
29
- uischema: UISchemaElement | undefined,
32
+ uischema: unknown | undefined,
30
33
  path: string | undefined
31
- ): string | undefined => {
34
+ ): string => {
32
35
  return (
33
36
  getI18nKeyPrefixBySchema(schema, uischema) ??
34
37
  transformPathToI18nPrefix(path)
@@ -37,10 +40,10 @@ export const getI18nKeyPrefix = (
37
40
 
38
41
  export const getI18nKey = (
39
42
  schema: i18nJsonSchema | undefined,
40
- uischema: UISchemaElement | undefined,
43
+ uischema: unknown | undefined,
41
44
  path: string | undefined,
42
45
  key: string
43
- ): string | undefined => {
46
+ ): string => {
44
47
  return `${getI18nKeyPrefix(schema, uischema, path)}.${key}`;
45
48
  };
46
49
 
@@ -103,3 +106,20 @@ export const getCombinedErrorMessage = (
103
106
  errors.map(error => et(error, t, uischema))
104
107
  );
105
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
+ }
@@ -27,15 +27,52 @@ import { JsonSchema } from './jsonSchema';
27
27
 
28
28
  /**
29
29
  * Interface for describing an UI schema element that is referencing
30
- * a subschema. The value of the scope must be a JSON Pointer.
30
+ * a subschema. The value of the scope may be a JSON Pointer.
31
31
  */
32
32
  export interface Scopable {
33
+ /**
34
+ * The scope that determines to which part this element should be bound to.
35
+ */
36
+ scope?: string;
37
+ }
38
+
39
+ /**
40
+ * Interface for describing an UI schema element that is referencing
41
+ * a subschema. The value of the scope must be a JSON Pointer.
42
+ */
43
+ export interface Scoped extends Scopable {
33
44
  /**
34
45
  * The scope that determines to which part this element should be bound to.
35
46
  */
36
47
  scope: string;
37
48
  }
38
49
 
50
+ /**
51
+ * Interface for describing an UI schema element that may be labeled.
52
+ */
53
+ export interface Labelable<T = string> {
54
+ /**
55
+ * Label for UI schema element.
56
+ */
57
+ label?: string|T;
58
+ }
59
+
60
+ /**
61
+ * Interface for describing an UI schema element that is labeled.
62
+ */
63
+ export interface Labeled<T = string> extends Labelable<T> {
64
+ label: string | T;
65
+ }
66
+
67
+ /*
68
+ * Interface for describing an UI schema element that can provide an internationalization base key.
69
+ * If defined, this key is suffixed to derive applicable message keys for the UI schema element.
70
+ * For example, such suffixes are `.label` or `.description` to derive the corresponding message keys for a control element.
71
+ */
72
+ export interface Internationalizable {
73
+ i18n?: string;
74
+ }
75
+
39
76
  /**
40
77
  * A rule that may be attached to any UI schema element.
41
78
  */
@@ -87,7 +124,7 @@ export interface Condition {
87
124
  /**
88
125
  * A leaf condition.
89
126
  */
90
- export interface LeafCondition extends Condition, Scopable {
127
+ export interface LeafCondition extends Condition, Scoped {
91
128
  type: 'LEAF';
92
129
 
93
130
  /**
@@ -96,7 +133,7 @@ export interface LeafCondition extends Condition, Scopable {
96
133
  expectedValue: any;
97
134
  }
98
135
 
99
- export interface SchemaBasedCondition extends Condition, Scopable {
136
+ export interface SchemaBasedCondition extends Condition, Scoped {
100
137
  schema: JsonSchema;
101
138
  }
102
139
 
@@ -170,12 +207,8 @@ export interface HorizontalLayout extends Layout {
170
207
  * A group resembles a vertical layout, but additionally might have a label.
171
208
  * This layout is useful when grouping different elements by a certain criteria.
172
209
  */
173
- export interface GroupLayout extends Layout {
210
+ export interface GroupLayout extends Layout, Labelable {
174
211
  type: 'Group';
175
- /**
176
- * The label of this group layout.
177
- */
178
- label?: string;
179
212
  }
180
213
 
181
214
  /**
@@ -195,7 +228,7 @@ export interface LabelDescription {
195
228
  /**
196
229
  * A label element.
197
230
  */
198
- export interface LabelElement extends UISchemaElement {
231
+ export interface LabelElement extends UISchemaElement, Internationalizable {
199
232
  type: 'Label';
200
233
  /**
201
234
  * The text of label.
@@ -207,23 +240,15 @@ export interface LabelElement extends UISchemaElement {
207
240
  * A control element. The scope property of the control determines
208
241
  * to which part of the schema the control should be bound.
209
242
  */
210
- export interface ControlElement extends UISchemaElement, Scopable {
243
+ export interface ControlElement extends UISchemaElement, Scoped, Labelable<string | boolean | LabelDescription>, Internationalizable {
211
244
  type: 'Control';
212
- /**
213
- * An optional label that will be associated with the control
214
- */
215
- label?: string | boolean | LabelDescription;
216
245
  }
217
246
 
218
247
  /**
219
248
  * The category layout.
220
249
  */
221
- export interface Category extends Layout {
250
+ export interface Category extends Layout, Labeled {
222
251
  type: 'Category';
223
- /**
224
- * The label associated with this category layout.
225
- */
226
- label: string;
227
252
  }
228
253
 
229
254
  /**
@@ -231,12 +256,8 @@ export interface Category extends Layout {
231
256
  * A child element may either be itself a Categorization or a Category, hence
232
257
  * the categorization element can be used to represent recursive structures like trees.
233
258
  */
234
- export interface Categorization extends UISchemaElement {
259
+ export interface Categorization extends UISchemaElement, Labeled {
235
260
  type: 'Categorization';
236
- /**
237
- * The label of this categorization.
238
- */
239
- label: string;
240
261
  /**
241
262
  * The child elements of this categorization which are either of type
242
263
  * {@link Category} or {@link Categorization}.
@@ -244,8 +265,23 @@ export interface Categorization extends UISchemaElement {
244
265
  elements: (Category | Categorization)[];
245
266
  }
246
267
 
268
+ export const isInternationalized = (element: unknown): element is Required<Internationalizable> =>
269
+ typeof element === 'object' && element !== null && typeof (element as Internationalizable).i18n === 'string';
270
+
247
271
  export const isGroup = (layout: Layout): layout is GroupLayout =>
248
272
  layout.type === 'Group';
249
273
 
250
274
  export const isLayout = (uischema: UISchemaElement): uischema is Layout =>
251
275
  (uischema as Layout).elements !== undefined;
276
+
277
+ export const isScopable = (obj: unknown): obj is Scopable =>
278
+ obj && typeof obj === 'object';
279
+
280
+ export const isScoped = (obj: unknown): obj is Scoped =>
281
+ isScopable(obj) && typeof obj.scope === 'string';
282
+
283
+ export const isLabelable = (obj: unknown): obj is Labelable =>
284
+ obj && typeof obj === 'object';
285
+
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