@remoteoss/json-schema-form 0.7.0-dev.20230928101050 → 0.7.1-beta.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/CHANGELOG.md CHANGED
@@ -1,13 +1,40 @@
1
+ #### 0.7.1-beta.0 (2023-10-31)
2
+
3
+ ##### Bug Fixes
4
+
5
+ - **select:** support string type ([#54](https://github.com/remoteoss/json-schema-form/pull/54)) ([b00f8776](https://github.com/remoteoss/json-schema-form/commit/b00f8776aa244803375ba64fbdd52c8fff9b9bd8))
6
+
7
+ #### 0.7.0-beta.0 (2023-10-23)
8
+
9
+ ##### Chores
10
+
11
+ BREAKING CHANGES:
12
+
13
+ - **Description/Extra/Statement fields:** We have removed the sorrounding spans that we output in these fields ([#17](https://github.com/remoteoss/json-schema-form/pull/27)) ([6257533](https://github.com/remoteoss/json-schema-form/commit/6257533bead9c0f7391f240c2e5bacc801a90af7))
14
+
15
+ ```diff
16
+ -description: '<span class="jsf-description">Write in <b>hh:ss</b> format</span>',
17
+ +description: 'Write in <b>hh:ss</b> format',
18
+ ```
19
+
20
+ #### 0.6.6-beta.0 (2023-10-17)
21
+
22
+ ##### Chores
23
+
24
+ - **github:** Add template for issues and pull requests ([#45](https://github.com/remoteoss/json-schema-form/pull/45)) ([621e3338](https://github.com/remoteoss/json-schema-form/commit/621e33389638541e771d2229c91655e430ea7ec4))
25
+
26
+ ##### Bug Fixes
27
+
28
+ - allow 0 in const validation ([#48](https://github.com/remoteoss/json-schema-form/pull/48)) ([cde19fc9](https://github.com/remoteoss/json-schema-form/commit/cde19fc960c4eacdde476ddcdd8c650a4ff5ce96))
29
+
1
30
  #### 0.6.5-beta.0 (2023-09-18)
2
31
 
3
32
  ##### Changes
4
33
 
5
34
  - json-logic: Add conditional logic checking. ([#41](https://github.com/remoteoss/json-schema-form/pull/41)) ([6292b01e](https://github.com/remoteoss/json-schema-form/commit/6292b01e3f77a9038328d7375080ffc4cb30dbc8))
6
35
 
7
-
8
36
  ###### Full API additions now supported from 0.6.5 onwards.
9
37
 
10
-
11
38
  - New custom JSON Schema keyword `x-jsf-logic` added to support cross-field validations. Built on top of [JsonLogic](https://jsonlogic.com/).
12
39
 
13
40
  - `x-jsf-logic` can contain:
@@ -26,16 +53,11 @@ While docs are underway, you can read examples from all the [tests](https://gith
26
53
 
27
54
  In short: `x-jsf-logic` is added to support complex conditional cross-field validations. Properties like `x-jsf-logic-validations` allow hooking those up to individual fields.
28
55
 
29
-
30
56
  #### 0.6.4-beta.0 (2023-09-15)
31
57
 
32
-
33
-
34
58
  ##### Changes
35
- - json-logic: computedAttrs - handle inline rules ([#40](https://github.com/remoteoss/json-schema-form/pull/40)) ([860ad91b](https://github.com/remoteoss/json-schema-form/commit/860ad91b034ab35d4d4bc51c0c04675f102bf278))
36
-
37
-
38
59
 
60
+ - json-logic: computedAttrs - handle inline rules ([#40](https://github.com/remoteoss/json-schema-form/pull/40)) ([860ad91b](https://github.com/remoteoss/json-schema-form/commit/860ad91b034ab35d4d4bc51c0c04675f102bf278))
39
61
 
40
62
  #### 0.6.1-beta.0 (2023-09-13)
41
63
 
@@ -43,50 +65,43 @@ In short: `x-jsf-logic` is added to support complex conditional cross-field vali
43
65
 
44
66
  - json-logic: Computed string based values ([#37](https://github.com/remoteoss/json-schema-form/pull/37)) ([6e042ea5](https://github.com/remoteoss/json-schema-form/commit/6e042ea579497ea573710c307a6ff7ee2f19b931))
45
67
 
46
-
47
-
48
-
49
68
  #### 0.5.0-beta.0 (2023-09-12)
50
69
 
51
70
  ##### Changes
71
+
52
72
  - json-logic: Computed Attributes ([#36](https://github.com/remoteoss/json-schema-form/pull/36)) ([80c29589](https://github.com/remoteoss/json-schema-form/commit/80c29589ac0972e0f33add70a59df15a46db1b43))
53
73
  - json-logic: Initial skeleton implementation ([#35](https://github.com/remoteoss/json-schema-form/pull/35)) ([63149ae8](https://github.com/remoteoss/json-schema-form/commit/63149ae863cf1b5ad76a3b2a49c7f343e55ce07b))
54
74
 
55
-
56
-
57
-
58
75
  #### 0.4.5-beta.0 (2023-08-31)
76
+
59
77
  ##### Bug fixes
60
78
 
61
79
  - Validate values based on `const` key ([#34](https://github.com/remoteoss/json-schema-form/pull/34)) ([bf07870d](https://github.com/remoteoss/json-schema-form/commit/bf07870d407d9b9b078882a078b9e4c7928df868))
62
80
 
63
-
64
-
65
-
66
81
  #### 0.4.4-beta.0 (2023-08-30)
67
82
 
68
83
  ##### Chores
69
84
 
70
- * **fieldset:** ignore values not matching the field type ([#44](https://github.com/remoteoss/json-schema-form/pull/44)) ([f0af54e5](https://github.com/remoteoss/json-schema-form/commit/f0af54e5d425fb78524ab150bb31629d00369a61))
85
+ - **fieldset:** ignore values not matching the field type ([#44](https://github.com/remoteoss/json-schema-form/pull/44)) ([f0af54e5](https://github.com/remoteoss/json-schema-form/commit/f0af54e5d425fb78524ab150bb31629d00369a61))
71
86
 
72
87
  #### 0.4.3-beta.0 (2023-08-09)
73
88
 
74
89
  ##### Bug fixes
75
90
 
76
- * **conditions:** Validate a deeply nested if (e.g. checking an object with a number property) in an if property now doesn't break the form. ([#33](https://github.com/remoteoss/json-schema-form/pull/33)) ([e34cfcc](https://github.com/remoteoss/json-schema-form/commit/e34cfccaf45f1460b346f3cff0c797b3d11259e3))
91
+ - **conditions:** Validate a deeply nested if (e.g. checking an object with a number property) in an if property now doesn't break the form. ([#33](https://github.com/remoteoss/json-schema-form/pull/33)) ([e34cfcc](https://github.com/remoteoss/json-schema-form/commit/e34cfccaf45f1460b346f3cff0c797b3d11259e3))
77
92
 
78
93
  #### 0.4.2-beta.0 (2023-07-20)
79
94
 
80
95
  ##### Bug Fixes
81
96
 
82
- * **date:** Validate based on minDate and maxDate ([#30](https://github.com/remoteoss/json-schema-form/pull/30)) ([01c0143e](https://github.com/remoteoss/json-schema-form/commit/01c0143ea4a3775f9489ae6cb8fd99a90b3f1394))
97
+ - **date:** Validate based on minDate and maxDate ([#30](https://github.com/remoteoss/json-schema-form/pull/30)) ([01c0143e](https://github.com/remoteoss/json-schema-form/commit/01c0143ea4a3775f9489ae6cb8fd99a90b3f1394))
83
98
 
84
99
  #### 0.4.1-beta.0 (2023-07-03)
85
100
 
86
101
  ##### Bug Fixes
87
102
 
88
- * **fieldset:** support root conditionals for fieldsets ([#23](https://github.com/remoteoss/json-schema-form/pull/23)) ([65d87b3a](https://github.com/remoteoss/json-schema-form/commit/65d87b3a93018f0729aed565000eb2a2ce1f2ce7))
89
- * **select/radio:** Accept just the values in options (plus `''` and `null` for backward-compatibility) ([#18](https://github.com/remoteoss/json-schema-form/pull/18)) ([37501d2d](https://github.com/remoteoss/json-schema-form/commit/37501d2ddafdd5e207b34d2ca3f6b7b7a1006e9d))
103
+ - **fieldset:** support root conditionals for fieldsets ([#23](https://github.com/remoteoss/json-schema-form/pull/23)) ([65d87b3a](https://github.com/remoteoss/json-schema-form/commit/65d87b3a93018f0729aed565000eb2a2ce1f2ce7))
104
+ - **select/radio:** Accept just the values in options (plus `''` and `null` for backward-compatibility) ([#18](https://github.com/remoteoss/json-schema-form/pull/18)) ([37501d2d](https://github.com/remoteoss/json-schema-form/commit/37501d2ddafdd5e207b34d2ca3f6b7b7a1006e9d))
90
105
 
91
106
  #### 0.4.0-beta.0 (2023-06-22)
92
107
 
package/dist/index.cjs CHANGED
@@ -1,8 +1,8 @@
1
1
 
2
2
  /*!
3
3
  Copyright (c) 2023 Remote Technology, Inc.
4
- NPM Package: @remoteoss/json-schema-form@0.7.0-dev.20230928101050
5
- Generated: Thu, 28 Sep 2023 10:11:18 GMT
4
+ NPM Package: @remoteoss/json-schema-form@0.7.1-beta.0
5
+ Generated: Tue, 31 Oct 2023 14:25:25 GMT
6
6
 
7
7
  MIT License
8
8
 
@@ -461,17 +461,22 @@ var validateMaxDate = (value, minDate) => {
461
461
  };
462
462
  var yupSchemas = {
463
463
  text: validateOnlyStrings,
464
- radioOrSelect: (options) => (0, import_yup.string)().nullable().transform((value) => {
465
- if (value === "") {
466
- return void 0;
464
+ radioOrSelect: (options, isString) => {
465
+ if (isString) {
466
+ return (0, import_yup.string)().nullable();
467
467
  }
468
- if (options?.includes(null)) {
469
- return value;
470
- }
471
- return value === null ? void 0 : value;
472
- }).oneOf(options, ({ value }) => {
473
- return `The option ${JSON.stringify(value)} is not valid.`;
474
- }),
468
+ return (0, import_yup.string)().nullable().transform((value) => {
469
+ if (value === "") {
470
+ return void 0;
471
+ }
472
+ if (options?.includes(null)) {
473
+ return value;
474
+ }
475
+ return value === null ? void 0 : value;
476
+ }).oneOf(options, ({ value }) => {
477
+ return `The option ${JSON.stringify(value)} is not valid.`;
478
+ });
479
+ },
475
480
  date: ({ minDate, maxDate }) => {
476
481
  let dateString = (0, import_yup.string)().nullable().transform((value) => {
477
482
  if (value === "") {
@@ -539,8 +544,9 @@ var getOptions = (field) => {
539
544
  var getYupSchema = ({ inputType, ...field }) => {
540
545
  const jsonType = getJsonTypeInArray(field.jsonType);
541
546
  if (field.options?.length > 0) {
547
+ const isString = field.options?.findIndex((option) => option.type === "string") > -1;
542
548
  const optionValues = getOptions(field);
543
- return yupSchemas.radioOrSelect(optionValues);
549
+ return yupSchemas.radioOrSelect(optionValues, isString);
544
550
  }
545
551
  if (field.format === "date") {
546
552
  return yupSchemas.date({ minDate: field.minDate, maxDate: field.maxDate });
@@ -694,7 +700,7 @@ function buildYupSchema(field, config, logic) {
694
700
  if (propertyFields.accept) {
695
701
  validators.push(withFileFormat);
696
702
  }
697
- if (propertyFields.const) {
703
+ if (typeof propertyFields.const !== "undefined") {
698
704
  validators.push(withConst);
699
705
  }
700
706
  if (propertyFields.jsonLogicValidations) {
@@ -1323,10 +1329,11 @@ function extractParametersFromNode(schemaNode) {
1323
1329
  const node = (0, import_omit.default)(schemaNode, ["x-jsf-presentation", "presentation"]);
1324
1330
  const description = presentation?.description || node.description;
1325
1331
  const statementDescription = presentation.statement?.description;
1332
+ const value = typeof node.const !== "undefined" && typeof node.default !== "undefined" ? { value: node.const } : {};
1326
1333
  return (0, import_omitBy.default)(
1327
1334
  {
1328
1335
  const: node.const,
1329
- ...node.const && node.default ? { value: node.const } : {},
1336
+ ...value,
1330
1337
  label: node.title,
1331
1338
  readOnly: node.readOnly,
1332
1339
  ...node.deprecated && {
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
 
2
2
  /*!
3
3
  Copyright (c) 2023 Remote Technology, Inc.
4
- NPM Package: @remoteoss/json-schema-form@0.7.0-dev.20230928101050
5
- Generated: Thu, 28 Sep 2023 10:11:18 GMT
4
+ NPM Package: @remoteoss/json-schema-form@0.7.1-beta.0
5
+ Generated: Tue, 31 Oct 2023 14:25:25 GMT
6
6
 
7
7
  MIT License
8
8
 
@@ -425,17 +425,22 @@ var validateMaxDate = (value, minDate) => {
425
425
  };
426
426
  var yupSchemas = {
427
427
  text: validateOnlyStrings,
428
- radioOrSelect: (options) => string().nullable().transform((value) => {
429
- if (value === "") {
430
- return void 0;
428
+ radioOrSelect: (options, isString) => {
429
+ if (isString) {
430
+ return string().nullable();
431
431
  }
432
- if (options?.includes(null)) {
433
- return value;
434
- }
435
- return value === null ? void 0 : value;
436
- }).oneOf(options, ({ value }) => {
437
- return `The option ${JSON.stringify(value)} is not valid.`;
438
- }),
432
+ return string().nullable().transform((value) => {
433
+ if (value === "") {
434
+ return void 0;
435
+ }
436
+ if (options?.includes(null)) {
437
+ return value;
438
+ }
439
+ return value === null ? void 0 : value;
440
+ }).oneOf(options, ({ value }) => {
441
+ return `The option ${JSON.stringify(value)} is not valid.`;
442
+ });
443
+ },
439
444
  date: ({ minDate, maxDate }) => {
440
445
  let dateString = string().nullable().transform((value) => {
441
446
  if (value === "") {
@@ -503,8 +508,9 @@ var getOptions = (field) => {
503
508
  var getYupSchema = ({ inputType, ...field }) => {
504
509
  const jsonType = getJsonTypeInArray(field.jsonType);
505
510
  if (field.options?.length > 0) {
511
+ const isString = field.options?.findIndex((option) => option.type === "string") > -1;
506
512
  const optionValues = getOptions(field);
507
- return yupSchemas.radioOrSelect(optionValues);
513
+ return yupSchemas.radioOrSelect(optionValues, isString);
508
514
  }
509
515
  if (field.format === "date") {
510
516
  return yupSchemas.date({ minDate: field.minDate, maxDate: field.maxDate });
@@ -658,7 +664,7 @@ function buildYupSchema(field, config, logic) {
658
664
  if (propertyFields.accept) {
659
665
  validators.push(withFileFormat);
660
666
  }
661
- if (propertyFields.const) {
667
+ if (typeof propertyFields.const !== "undefined") {
662
668
  validators.push(withConst);
663
669
  }
664
670
  if (propertyFields.jsonLogicValidations) {
@@ -1287,10 +1293,11 @@ function extractParametersFromNode(schemaNode) {
1287
1293
  const node = omit(schemaNode, ["x-jsf-presentation", "presentation"]);
1288
1294
  const description = presentation?.description || node.description;
1289
1295
  const statementDescription = presentation.statement?.description;
1296
+ const value = typeof node.const !== "undefined" && typeof node.default !== "undefined" ? { value: node.const } : {};
1290
1297
  return omitBy(
1291
1298
  {
1292
1299
  const: node.const,
1293
- ...node.const && node.default ? { value: node.const } : {},
1300
+ ...value,
1294
1301
  label: node.title,
1295
1302
  readOnly: node.readOnly,
1296
1303
  ...node.deprecated && {
@@ -1,8 +1,8 @@
1
1
 
2
2
  /*!
3
3
  Copyright (c) 2023 Remote Technology, Inc.
4
- NPM Package: @remoteoss/json-schema-form@0.7.0-dev.20230928101050
5
- Generated: Thu, 28 Sep 2023 10:11:18 GMT
4
+ NPM Package: @remoteoss/json-schema-form@0.7.1-beta.0
5
+ Generated: Tue, 31 Oct 2023 14:25:25 GMT
6
6
 
7
7
  MIT License
8
8
 
@@ -11779,17 +11779,22 @@ var validateMaxDate = (value, minDate) => {
11779
11779
  };
11780
11780
  var yupSchemas = {
11781
11781
  text: validateOnlyStrings,
11782
- radioOrSelect: (options) => StringSchema().nullable().transform((value) => {
11783
- if (value === "") {
11784
- return void 0;
11782
+ radioOrSelect: (options, isString2) => {
11783
+ if (isString2) {
11784
+ return StringSchema().nullable();
11785
11785
  }
11786
- if (options?.includes(null)) {
11787
- return value;
11788
- }
11789
- return value === null ? void 0 : value;
11790
- }).oneOf(options, ({ value }) => {
11791
- return `The option ${JSON.stringify(value)} is not valid.`;
11792
- }),
11786
+ return StringSchema().nullable().transform((value) => {
11787
+ if (value === "") {
11788
+ return void 0;
11789
+ }
11790
+ if (options?.includes(null)) {
11791
+ return value;
11792
+ }
11793
+ return value === null ? void 0 : value;
11794
+ }).oneOf(options, ({ value }) => {
11795
+ return `The option ${JSON.stringify(value)} is not valid.`;
11796
+ });
11797
+ },
11793
11798
  date: ({ minDate, maxDate }) => {
11794
11799
  let dateString = StringSchema().nullable().transform((value) => {
11795
11800
  if (value === "") {
@@ -11857,8 +11862,9 @@ var getOptions = (field) => {
11857
11862
  var getYupSchema = ({ inputType, ...field }) => {
11858
11863
  const jsonType = getJsonTypeInArray(field.jsonType);
11859
11864
  if (field.options?.length > 0) {
11865
+ const isString2 = field.options?.findIndex((option) => option.type === "string") > -1;
11860
11866
  const optionValues = getOptions(field);
11861
- return yupSchemas.radioOrSelect(optionValues);
11867
+ return yupSchemas.radioOrSelect(optionValues, isString2);
11862
11868
  }
11863
11869
  if (field.format === "date") {
11864
11870
  return yupSchemas.date({ minDate: field.minDate, maxDate: field.maxDate });
@@ -12012,7 +12018,7 @@ function buildYupSchema(field, config, logic) {
12012
12018
  if (propertyFields.accept) {
12013
12019
  validators.push(withFileFormat);
12014
12020
  }
12015
- if (propertyFields.const) {
12021
+ if (typeof propertyFields.const !== "undefined") {
12016
12022
  validators.push(withConst);
12017
12023
  }
12018
12024
  if (propertyFields.jsonLogicValidations) {
@@ -12641,10 +12647,11 @@ function extractParametersFromNode(schemaNode) {
12641
12647
  const node = (0, import_omit.default)(schemaNode, ["x-jsf-presentation", "presentation"]);
12642
12648
  const description = presentation?.description || node.description;
12643
12649
  const statementDescription = presentation.statement?.description;
12650
+ const value = typeof node.const !== "undefined" && typeof node.default !== "undefined" ? { value: node.const } : {};
12644
12651
  return (0, import_omitBy.default)(
12645
12652
  {
12646
12653
  const: node.const,
12647
- ...node.const && node.default ? { value: node.const } : {},
12654
+ ...value,
12648
12655
  label: node.title,
12649
12656
  readOnly: node.readOnly,
12650
12657
  ...node.deprecated && {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remoteoss/json-schema-form",
3
- "version": "0.7.0-dev.20230928101050",
3
+ "version": "0.7.1-beta.0",
4
4
  "description": "Headless UI form powered by JSON Schemas",
5
5
  "author": "Remote.com <engineering@remote.com> (https://remote.com/)",
6
6
  "license": "MIT",
@@ -20,6 +20,25 @@ describe('validations: const', () => {
20
20
  expect(handleValidation({ ten_only: null }).formErrors).toBeUndefined();
21
21
  });
22
22
 
23
+ it('Should work for when the number is 0', () => {
24
+ const { handleValidation } = createHeadlessForm(
25
+ {
26
+ properties: {
27
+ zero_only: { type: 'number', const: 0 },
28
+ },
29
+ },
30
+ { strictInputType: false }
31
+ );
32
+ expect(handleValidation({}).formErrors).toEqual(undefined);
33
+ expect(handleValidation({ zero_only: 1 }).formErrors).toEqual({
34
+ zero_only: 'The only accepted value is 0.',
35
+ });
36
+ expect(handleValidation({ zero_only: 0 }).formErrors).toBeUndefined();
37
+ // null is also considered valid until we fix @BUG RMT-518
38
+ // Expectation: To fail with error "The only accepted value is 0."
39
+ expect(handleValidation({ zero_only: null }).formErrors).toBeUndefined();
40
+ });
41
+
23
42
  it('Should work for text', () => {
24
43
  const { handleValidation } = createHeadlessForm(
25
44
  {
@@ -96,3 +115,45 @@ describe('validations: const', () => {
96
115
  expect(fields[0]).toMatchObject({ value: 10, const: 10, default: 10 });
97
116
  });
98
117
  });
118
+
119
+ describe('const/default with forced values', () => {
120
+ it('Should work for when the number is 0', () => {
121
+ const { fields, handleValidation } = createHeadlessForm(
122
+ {
123
+ properties: {
124
+ zero_only: { type: 'number', const: 0, default: 0 },
125
+ },
126
+ },
127
+ { strictInputType: false }
128
+ );
129
+ expect(handleValidation({}).formErrors).toEqual(undefined);
130
+ expect(handleValidation({ zero_only: 1 }).formErrors).toEqual({
131
+ zero_only: 'The only accepted value is 0.',
132
+ });
133
+ expect(fields[0]).toMatchObject({ value: 0, const: 0, default: 0 });
134
+ expect(handleValidation({ zero_only: 0 }).formErrors).toBeUndefined();
135
+ // null is also considered valid until we fix @BUG RMT-518
136
+ // Expectation: To fail with error "The only accepted value is 0."
137
+ expect(handleValidation({ zero_only: null }).formErrors).toBeUndefined();
138
+ });
139
+
140
+ it('Should work for number', () => {
141
+ const { fields, handleValidation } = createHeadlessForm(
142
+ {
143
+ properties: {
144
+ ten_only: { type: 'number', const: 10, default: 10 },
145
+ },
146
+ },
147
+ { strictInputType: false }
148
+ );
149
+ expect(handleValidation({}).formErrors).toEqual(undefined);
150
+ expect(handleValidation({ ten_only: 1 }).formErrors).toEqual({
151
+ ten_only: 'The only accepted value is 10.',
152
+ });
153
+ expect(handleValidation({ ten_only: 10 }).formErrors).toBeUndefined();
154
+ expect(fields[0]).toMatchObject({ value: 10, const: 10, default: 10 });
155
+ // null is also considered valid until we fix @BUG RMT-518
156
+ // Expectation: To fail with error "The only accepted value is 10."
157
+ expect(handleValidation({ ten_only: null }).formErrors).toBeUndefined();
158
+ });
159
+ });
@@ -15,6 +15,7 @@ import {
15
15
  schemaInputTypeRadioOptionsWithDetails,
16
16
  schemaInputTypeSelectSoloDeprecated,
17
17
  schemaInputTypeSelectSolo,
18
+ schemaInputTypeSelectString,
18
19
  schemaInputTypeSelectMultipleDeprecated,
19
20
  schemaInputTypeSelectMultiple,
20
21
  schemaInputTypeSelectMultipleOptional,
@@ -430,7 +431,7 @@ describe('createHeadlessForm', () => {
430
431
  });
431
432
 
432
433
  describe('field support', () => {
433
- function assertOptionsAllowed({ handleValidation, fieldName, validOptions }) {
434
+ function assertOptionsAllowed({ handleValidation, fieldName, validOptions, isString = false }) {
434
435
  const validateForm = (vals) => friendlyError(handleValidation(vals));
435
436
 
436
437
  // All allowed options are valid
@@ -438,27 +439,34 @@ describe('createHeadlessForm', () => {
438
439
  expect(validateForm({ [fieldName]: value })).toBeUndefined();
439
440
  });
440
441
 
441
- // Any other arbitrary value is not valid.
442
- expect(validateForm({ [fieldName]: 'blah-blah' })).toEqual({
443
- [fieldName]: 'The option "blah-blah" is not valid.',
444
- });
442
+ if (!isString) {
443
+ // Any other arbitrary value is not valid.
444
+ expect(validateForm({ [fieldName]: 'blah-blah' })).toEqual({
445
+ [fieldName]: 'The option "blah-blah" is not valid.',
446
+ });
445
447
 
446
- // Given undefined, it says it's a required field.
447
- expect(validateForm({})).toEqual({
448
- [fieldName]: 'Required field',
449
- });
448
+ // Given undefined, it says it's a required field.
449
+ expect(validateForm({})).toEqual({
450
+ [fieldName]: 'Required field',
451
+ });
450
452
 
451
- // As required field, empty string ("") is also considered empty. @BUG RMT-518
452
- // Expectation: The error to be "The option '' is not valid."
453
- expect(validateForm({ [fieldName]: '' })).toEqual({
454
- [fieldName]: 'Required field',
455
- });
453
+ // As required field, empty string ("") is also considered empty. @BUG RMT-518
454
+ // Expectation: The error to be "The option '' is not valid."
455
+ expect(validateForm({ [fieldName]: '' })).toEqual({
456
+ [fieldName]: 'Required field',
457
+ });
456
458
 
457
- // As required field, null is also considered empty @BUG RMT-518
458
- // Expectation: The error to be "The option null is not valid."
459
- expect(validateForm({ [fieldName]: null })).toEqual({
460
- [fieldName]: 'Required field',
461
- });
459
+ // As required field, null is also considered empty @BUG RMT-518
460
+ // Expectation: The error to be "The option null is not valid."
461
+ expect(validateForm({ [fieldName]: null })).toEqual({
462
+ [fieldName]: 'Required field',
463
+ });
464
+ }
465
+
466
+ if (isString) {
467
+ // Any other arbitrary value is valid.
468
+ expect(validateForm({ [fieldName]: 'blah-blah' })).toBeUndefined();
469
+ }
462
470
  }
463
471
 
464
472
  it('support "text" field type', () => {
@@ -630,6 +638,41 @@ describe('createHeadlessForm', () => {
630
638
  });
631
639
  });
632
640
 
641
+ it('supports "select" field type with string option', () => {
642
+ const { fields, handleValidation } = createHeadlessForm(schemaInputTypeSelectString);
643
+ const fieldSelect = fields[0];
644
+ expect(fieldSelect).toMatchObject({
645
+ name: 'browsers',
646
+ label: 'Browsers (solo)',
647
+ description: 'This solo select also includes a disabled option.',
648
+ options: [
649
+ {
650
+ value: 'chr',
651
+ label: 'Chrome',
652
+ },
653
+ {
654
+ value: 'ff',
655
+ label: 'Firefox',
656
+ },
657
+ {
658
+ value: 'ie',
659
+ label: 'Internet Explorer',
660
+ disabled: true,
661
+ },
662
+ { value: undefined, type: 'string', label: '{Create another}' },
663
+ ],
664
+ });
665
+
666
+ expect(fieldSelect).not.toHaveProperty('multiple');
667
+
668
+ assertOptionsAllowed({
669
+ handleValidation,
670
+ fieldName: 'browsers',
671
+ validOptions: ['chr', 'ff', 'ie'],
672
+ isString: true,
673
+ });
674
+ });
675
+
633
676
  it('supports "select" field type with multiple options @deprecated', () => {
634
677
  const result = createHeadlessForm(schemaInputTypeSelectMultipleDeprecated);
635
678
  expect(result).toMatchObject({
@@ -1947,9 +1990,9 @@ describe('createHeadlessForm', () => {
1947
1990
  },
1948
1991
  },
1949
1992
  {
1950
- name: 'a_or_b',
1951
- label: 'A dropdown',
1952
- type: 'select',
1993
+ name: 'role',
1994
+ label: 'Role',
1995
+ type: 'text',
1953
1996
  statement: {
1954
1997
  description: 'This is another statement message, but more severe.',
1955
1998
  inputType: 'statement',
@@ -238,6 +238,11 @@ export const mockSelectInputSolo = {
238
238
  },
239
239
  };
240
240
 
241
+ export const mockSelectInputSoloCreatable = {
242
+ ...mockSelectInputSolo,
243
+ oneOf: [...mockSelectInputSolo.oneOf, { type: 'string', title: '{Create another}' }],
244
+ };
245
+
241
246
  export const mockSelectInputMultiple = {
242
247
  title: 'Browsers (multiple)',
243
248
  description: 'This multi-select also includes a disabled option.',
@@ -463,6 +468,12 @@ export const mockCheckboxInput = {
463
468
  })
464
469
  .build();
465
470
  */
471
+
472
+ /**
473
+ * @deprecated in favor of normal JSON schema.
474
+ * Why? This adds extra complexity to read and to
475
+ * copy-paste into the Playground, validators, etc
476
+ * */
466
477
  export function JSONSchemaBuilder() {
467
478
  return {
468
479
  addInput: function addInput(input) {
@@ -658,15 +669,15 @@ export const schemaWithoutTypes = {
658
669
  },
659
670
  };
660
671
 
661
- export const schemaInputTypeText = JSONSchemaBuilder()
662
- .addInput({
672
+ export const schemaInputTypeText = {
673
+ properties: {
663
674
  id_number: mockTextInput,
664
- })
665
- .setRequiredFields(['id_number'])
666
- .build();
675
+ },
676
+ required: ['id_number'],
677
+ };
667
678
 
668
- export const schemaInputWithStatement = JSONSchemaBuilder()
669
- .addInput({
679
+ export const schemaInputWithStatement = {
680
+ properties: {
670
681
  bonus: {
671
682
  title: 'Bonus',
672
683
  'x-jsf-presentation': {
@@ -678,71 +689,10 @@ export const schemaInputWithStatement = JSONSchemaBuilder()
678
689
  },
679
690
  },
680
691
  },
681
- })
682
- .addInput({
683
- a_or_b: {
684
- title: 'A dropdown',
685
- description: 'Some options to chose from',
686
- items: {
687
- enum: ['A', 'B'],
688
- },
692
+ role: {
693
+ title: 'Role',
689
694
  'x-jsf-presentation': {
690
- inputType: 'select',
691
- options: [
692
- {
693
- label: 'A',
694
- value: 'A',
695
- },
696
- {
697
- label: 'B',
698
- value: 'B',
699
- },
700
- ],
701
- placeholder: 'Select...',
702
- statement: {
703
- description: 'This is another statement message, but more severe.',
704
- inputType: 'statement',
705
- severity: 'warning',
706
- },
707
- },
708
- },
709
- })
710
- .build();
711
-
712
- export const schemaInputWithStatementDeprecated = JSONSchemaBuilder()
713
- .addInput({
714
- bonus: {
715
- title: 'Bonus',
716
- presentation: {
717
695
  inputType: 'text',
718
- statement: {
719
- description: 'This is a custom statement message.',
720
- inputType: 'statement',
721
- severity: 'info',
722
- },
723
- },
724
- },
725
- })
726
- .addInput({
727
- a_or_b: {
728
- title: 'A dropdown',
729
- description: 'Some options to chose from',
730
- items: {
731
- enum: ['A', 'B'],
732
- },
733
- presentation: {
734
- inputType: 'select',
735
- options: [
736
- {
737
- label: 'A',
738
- value: 'A',
739
- },
740
- {
741
- label: 'B',
742
- value: 'B',
743
- },
744
- ],
745
- placeholder: 'Select...',
746
696
  statement: {
747
697
  description: 'This is another statement message, but more severe.',
748
698
  inputType: 'statement',
@@ -750,11 +700,11 @@ export const schemaInputWithStatementDeprecated = JSONSchemaBuilder()
750
700
  },
751
701
  },
752
702
  },
753
- })
754
- .build();
703
+ },
704
+ };
755
705
 
756
- export const schemaInputWithExtra = JSONSchemaBuilder()
757
- .addInput({
706
+ export const schemaInputWithExtra = {
707
+ properties: {
758
708
  bonus: {
759
709
  title: 'Bonus',
760
710
  'x-jsf-presentation': {
@@ -772,11 +722,11 @@ export const schemaInputWithExtra = JSONSchemaBuilder()
772
722
  `,
773
723
  },
774
724
  },
775
- })
776
- .build();
725
+ },
726
+ };
777
727
 
778
- export const schemaInputWithCustomDescription = JSONSchemaBuilder()
779
- .addInput({
728
+ export const schemaInputWithCustomDescription = {
729
+ properties: {
780
730
  other: {
781
731
  title: 'Other',
782
732
  'x-jsf-presentation': {
@@ -785,8 +735,8 @@ export const schemaInputWithCustomDescription = JSONSchemaBuilder()
785
735
  },
786
736
  type: 'string',
787
737
  },
788
- })
789
- .build();
738
+ },
739
+ };
790
740
 
791
741
  export const schemaInputDeprecated = JSONSchemaBuilder()
792
742
  .addInput({
@@ -952,6 +902,10 @@ export const schemaInputTypeSelectSolo = JSONSchemaBuilder()
952
902
  .setRequiredFields(['browsers'])
953
903
  .build();
954
904
 
905
+ export const schemaInputTypeSelectString = JSONSchemaBuilder().addInput({
906
+ browsers: mockSelectInputSoloCreatable,
907
+ });
908
+
955
909
  /** @deprecated */
956
910
  export const schemaInputTypeSelectMultipleDeprecated = JSONSchemaBuilder()
957
911
  .addInput({