@remoteoss/json-schema-form 0.11.11-dev.20250220174843 → 0.11.12-dev.20250313084704

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,3 +1,9 @@
1
+ #### 0.11.11-beta.0 (2025-02-20)
2
+
3
+ ##### Bug Fixes
4
+
5
+ * **conditionals:** Add support to `oneOf` ([#136](https://github.com/remoteoss/json-schema-form/pull/136)) ([966cec59](https://github.com/remoteoss/json-schema-form/commit/966cec595ed2a1ff35f9d15e22acaea16cdd5113))
6
+
1
7
  #### 0.11.10-beta.0 (2025-01-22)
2
8
 
3
9
  ##### Bug Fixes
package/dist/index.cjs CHANGED
@@ -1,8 +1,8 @@
1
1
 
2
2
  /*!
3
3
  Copyright (c) 2025 Remote Technology, Inc.
4
- NPM Package: @remoteoss/json-schema-form@0.11.11-dev.20250220174843
5
- Generated: Thu, 20 Feb 2025 17:48:57 GMT
4
+ NPM Package: @remoteoss/json-schema-form@0.11.12-dev.20250313084704
5
+ Generated: Thu, 13 Mar 2025 08:47:14 GMT
6
6
 
7
7
  MIT License
8
8
 
@@ -101,6 +101,11 @@ function checkIfConditionMatchesProperties(node, formValues, formFields, logic)
101
101
  if (typeof node.if === "boolean") {
102
102
  return node.if;
103
103
  }
104
+ if (node.if.anyOf) {
105
+ return node.if.anyOf.some(
106
+ (property) => checkIfConditionMatchesProperties({ if: property }, formValues, formFields, logic)
107
+ );
108
+ }
104
109
  return Object.keys(node.if.properties ?? {}).every((name) => {
105
110
  const currentProperty = node.if.properties[name];
106
111
  const value = formValues[name];
@@ -608,6 +613,8 @@ var getYupSchema = ({ inputType, ...field }) => {
608
613
  switch (type) {
609
614
  case "number":
610
615
  return yupSchemas.radioOrSelectNumber(optionValues);
616
+ case "integer":
617
+ return yupSchemas.radioOrSelectNumber(optionValues);
611
618
  case "boolean":
612
619
  return yupSchemas.radioOrSelectBoolean(optionValues);
613
620
  default:
@@ -768,7 +775,8 @@ function buildYupSchema(field, config, logic) {
768
775
  if (inputType === supportedTypes.FILE) {
769
776
  validators.push(withFile);
770
777
  }
771
- if (jsonType === "integer") {
778
+ const hasOptions = field.options?.length > 0;
779
+ if (jsonType === "integer" && !hasOptions) {
772
780
  validators.push(withInteger);
773
781
  }
774
782
  if (typeof propertyFields.minimum !== "undefined") {
@@ -1164,11 +1172,7 @@ function hasType(type, typeName) {
1164
1172
  return Array.isArray(type) ? type.includes(typeName) : type === typeName;
1165
1173
  }
1166
1174
  function getField(fieldName, fields) {
1167
- if (Array.isArray(fields)) {
1168
- return fields.find(({ name }) => name === fieldName);
1169
- } else {
1170
- return fields[fieldName];
1171
- }
1175
+ return fields.find(({ name }) => name === fieldName);
1172
1176
  }
1173
1177
  function validateFieldSchema(field, value, logic) {
1174
1178
  const validator = buildYupSchema(field, {}, logic);
@@ -1382,25 +1386,6 @@ function processNode({
1382
1386
  logic
1383
1387
  });
1384
1388
  }
1385
- if (inputType === supportedTypes.GROUP_ARRAY) {
1386
- const values = formValues[name];
1387
- if (Array.isArray(values)) {
1388
- const newFields = [];
1389
- const field = getField(name, formFields);
1390
- values.forEach((value) => {
1391
- const fields = field.fields();
1392
- processNode({
1393
- node: nestedNode.items,
1394
- formValues: value,
1395
- formFields: fields,
1396
- parentID: name,
1397
- logic
1398
- });
1399
- newFields.push(fields);
1400
- });
1401
- field.dynamicFields = newFields;
1402
- }
1403
- }
1404
1389
  });
1405
1390
  }
1406
1391
  if (node["x-jsf-logic"]) {
@@ -1772,16 +1757,6 @@ function buildFieldParameters(name, fieldProperties, required = [], config = {},
1772
1757
  logic
1773
1758
  );
1774
1759
  }
1775
- if (inputType === supportedTypes.GROUP_ARRAY) {
1776
- fields = () => getFieldsFromJSONSchema(
1777
- fieldProperties.items,
1778
- {
1779
- customProperties: (0, import_get3.default)(config, `customProperties.${name}.customProperties`, {}),
1780
- parentID: name
1781
- },
1782
- logic
1783
- );
1784
- }
1785
1760
  const result = {
1786
1761
  name,
1787
1762
  inputType,
@@ -1875,10 +1850,12 @@ function getFieldsFromJSONSchema(scopedJsonSchema, config, logic) {
1875
1850
  if (fieldParams.inputType === "group-array") {
1876
1851
  const groupArrayItems = convertJSONSchemaPropertiesToFieldParameters(fieldParams.items);
1877
1852
  const groupArrayFields = groupArrayItems.map((groupArrayItem) => {
1853
+ groupArrayItem.nameKey = groupArrayItem.name;
1878
1854
  const customProperties = null;
1879
1855
  const composeFn = getComposeFunctionForField(groupArrayItem, !!customProperties);
1880
1856
  return composeFn(groupArrayItem);
1881
1857
  });
1858
+ fieldParams.nameKey = fieldParams.name;
1882
1859
  fieldParams.nthFieldGroup = {
1883
1860
  name: fieldParams.name,
1884
1861
  label: fieldParams.label,
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
 
2
2
  /*!
3
3
  Copyright (c) 2025 Remote Technology, Inc.
4
- NPM Package: @remoteoss/json-schema-form@0.11.11-dev.20250220174843
5
- Generated: Thu, 20 Feb 2025 17:48:57 GMT
4
+ NPM Package: @remoteoss/json-schema-form@0.11.12-dev.20250313084704
5
+ Generated: Thu, 13 Mar 2025 08:47:14 GMT
6
6
 
7
7
  MIT License
8
8
 
@@ -64,6 +64,11 @@ function checkIfConditionMatchesProperties(node, formValues, formFields, logic)
64
64
  if (typeof node.if === "boolean") {
65
65
  return node.if;
66
66
  }
67
+ if (node.if.anyOf) {
68
+ return node.if.anyOf.some(
69
+ (property) => checkIfConditionMatchesProperties({ if: property }, formValues, formFields, logic)
70
+ );
71
+ }
67
72
  return Object.keys(node.if.properties ?? {}).every((name) => {
68
73
  const currentProperty = node.if.properties[name];
69
74
  const value = formValues[name];
@@ -571,6 +576,8 @@ var getYupSchema = ({ inputType, ...field }) => {
571
576
  switch (type) {
572
577
  case "number":
573
578
  return yupSchemas.radioOrSelectNumber(optionValues);
579
+ case "integer":
580
+ return yupSchemas.radioOrSelectNumber(optionValues);
574
581
  case "boolean":
575
582
  return yupSchemas.radioOrSelectBoolean(optionValues);
576
583
  default:
@@ -731,7 +738,8 @@ function buildYupSchema(field, config, logic) {
731
738
  if (inputType === supportedTypes.FILE) {
732
739
  validators.push(withFile);
733
740
  }
734
- if (jsonType === "integer") {
741
+ const hasOptions = field.options?.length > 0;
742
+ if (jsonType === "integer" && !hasOptions) {
735
743
  validators.push(withInteger);
736
744
  }
737
745
  if (typeof propertyFields.minimum !== "undefined") {
@@ -1127,11 +1135,7 @@ function hasType(type, typeName) {
1127
1135
  return Array.isArray(type) ? type.includes(typeName) : type === typeName;
1128
1136
  }
1129
1137
  function getField(fieldName, fields) {
1130
- if (Array.isArray(fields)) {
1131
- return fields.find(({ name }) => name === fieldName);
1132
- } else {
1133
- return fields[fieldName];
1134
- }
1138
+ return fields.find(({ name }) => name === fieldName);
1135
1139
  }
1136
1140
  function validateFieldSchema(field, value, logic) {
1137
1141
  const validator = buildYupSchema(field, {}, logic);
@@ -1345,25 +1349,6 @@ function processNode({
1345
1349
  logic
1346
1350
  });
1347
1351
  }
1348
- if (inputType === supportedTypes.GROUP_ARRAY) {
1349
- const values = formValues[name];
1350
- if (Array.isArray(values)) {
1351
- const newFields = [];
1352
- const field = getField(name, formFields);
1353
- values.forEach((value) => {
1354
- const fields = field.fields();
1355
- processNode({
1356
- node: nestedNode.items,
1357
- formValues: value,
1358
- formFields: fields,
1359
- parentID: name,
1360
- logic
1361
- });
1362
- newFields.push(fields);
1363
- });
1364
- field.dynamicFields = newFields;
1365
- }
1366
- }
1367
1352
  });
1368
1353
  }
1369
1354
  if (node["x-jsf-logic"]) {
@@ -1735,16 +1720,6 @@ function buildFieldParameters(name, fieldProperties, required = [], config = {},
1735
1720
  logic
1736
1721
  );
1737
1722
  }
1738
- if (inputType === supportedTypes.GROUP_ARRAY) {
1739
- fields = () => getFieldsFromJSONSchema(
1740
- fieldProperties.items,
1741
- {
1742
- customProperties: get3(config, `customProperties.${name}.customProperties`, {}),
1743
- parentID: name
1744
- },
1745
- logic
1746
- );
1747
- }
1748
1723
  const result = {
1749
1724
  name,
1750
1725
  inputType,
@@ -1838,10 +1813,12 @@ function getFieldsFromJSONSchema(scopedJsonSchema, config, logic) {
1838
1813
  if (fieldParams.inputType === "group-array") {
1839
1814
  const groupArrayItems = convertJSONSchemaPropertiesToFieldParameters(fieldParams.items);
1840
1815
  const groupArrayFields = groupArrayItems.map((groupArrayItem) => {
1816
+ groupArrayItem.nameKey = groupArrayItem.name;
1841
1817
  const customProperties = null;
1842
1818
  const composeFn = getComposeFunctionForField(groupArrayItem, !!customProperties);
1843
1819
  return composeFn(groupArrayItem);
1844
1820
  });
1821
+ fieldParams.nameKey = fieldParams.name;
1845
1822
  fieldParams.nthFieldGroup = {
1846
1823
  name: fieldParams.name,
1847
1824
  label: fieldParams.label,
@@ -1,8 +1,8 @@
1
1
 
2
2
  /*!
3
3
  Copyright (c) 2025 Remote Technology, Inc.
4
- NPM Package: @remoteoss/json-schema-form@0.11.11-dev.20250220174843
5
- Generated: Thu, 20 Feb 2025 17:48:57 GMT
4
+ NPM Package: @remoteoss/json-schema-form@0.11.12-dev.20250313084704
5
+ Generated: Thu, 13 Mar 2025 08:47:14 GMT
6
6
 
7
7
  MIT License
8
8
 
@@ -11581,6 +11581,11 @@ function checkIfConditionMatchesProperties(node, formValues, formFields, logic)
11581
11581
  if (typeof node.if === "boolean") {
11582
11582
  return node.if;
11583
11583
  }
11584
+ if (node.if.anyOf) {
11585
+ return node.if.anyOf.some(
11586
+ (property2) => checkIfConditionMatchesProperties({ if: property2 }, formValues, formFields, logic)
11587
+ );
11588
+ }
11584
11589
  return Object.keys(node.if.properties ?? {}).every((name) => {
11585
11590
  const currentProperty = node.if.properties[name];
11586
11591
  const value = formValues[name];
@@ -12087,6 +12092,8 @@ var getYupSchema = ({ inputType, ...field }) => {
12087
12092
  switch (type) {
12088
12093
  case "number":
12089
12094
  return yupSchemas.radioOrSelectNumber(optionValues);
12095
+ case "integer":
12096
+ return yupSchemas.radioOrSelectNumber(optionValues);
12090
12097
  case "boolean":
12091
12098
  return yupSchemas.radioOrSelectBoolean(optionValues);
12092
12099
  default:
@@ -12247,7 +12254,8 @@ function buildYupSchema(field, config, logic) {
12247
12254
  if (inputType === supportedTypes.FILE) {
12248
12255
  validators.push(withFile);
12249
12256
  }
12250
- if (jsonType === "integer") {
12257
+ const hasOptions = field.options?.length > 0;
12258
+ if (jsonType === "integer" && !hasOptions) {
12251
12259
  validators.push(withInteger);
12252
12260
  }
12253
12261
  if (typeof propertyFields.minimum !== "undefined") {
@@ -12643,11 +12651,7 @@ function hasType(type, typeName) {
12643
12651
  return Array.isArray(type) ? type.includes(typeName) : type === typeName;
12644
12652
  }
12645
12653
  function getField(fieldName, fields) {
12646
- if (Array.isArray(fields)) {
12647
- return fields.find(({ name }) => name === fieldName);
12648
- } else {
12649
- return fields[fieldName];
12650
- }
12654
+ return fields.find(({ name }) => name === fieldName);
12651
12655
  }
12652
12656
  function validateFieldSchema(field, value, logic) {
12653
12657
  const validator = buildYupSchema(field, {}, logic);
@@ -12861,25 +12865,6 @@ function processNode({
12861
12865
  logic
12862
12866
  });
12863
12867
  }
12864
- if (inputType === supportedTypes.GROUP_ARRAY) {
12865
- const values2 = formValues[name];
12866
- if (Array.isArray(values2)) {
12867
- const newFields = [];
12868
- const field = getField(name, formFields);
12869
- values2.forEach((value) => {
12870
- const fields = field.fields();
12871
- processNode({
12872
- node: nestedNode.items,
12873
- formValues: value,
12874
- formFields: fields,
12875
- parentID: name,
12876
- logic
12877
- });
12878
- newFields.push(fields);
12879
- });
12880
- field.dynamicFields = newFields;
12881
- }
12882
- }
12883
12868
  });
12884
12869
  }
12885
12870
  if (node["x-jsf-logic"]) {
@@ -13251,16 +13236,6 @@ function buildFieldParameters(name, fieldProperties, required2 = [], config = {}
13251
13236
  logic
13252
13237
  );
13253
13238
  }
13254
- if (inputType === supportedTypes.GROUP_ARRAY) {
13255
- fields = () => getFieldsFromJSONSchema(
13256
- fieldProperties.items,
13257
- {
13258
- customProperties: (0, import_get4.default)(config, `customProperties.${name}.customProperties`, {}),
13259
- parentID: name
13260
- },
13261
- logic
13262
- );
13263
- }
13264
13239
  const result = {
13265
13240
  name,
13266
13241
  inputType,
@@ -13354,10 +13329,12 @@ function getFieldsFromJSONSchema(scopedJsonSchema, config, logic) {
13354
13329
  if (fieldParams.inputType === "group-array") {
13355
13330
  const groupArrayItems = convertJSONSchemaPropertiesToFieldParameters(fieldParams.items);
13356
13331
  const groupArrayFields = groupArrayItems.map((groupArrayItem) => {
13332
+ groupArrayItem.nameKey = groupArrayItem.name;
13357
13333
  const customProperties = null;
13358
13334
  const composeFn = getComposeFunctionForField(groupArrayItem, !!customProperties);
13359
13335
  return composeFn(groupArrayItem);
13360
13336
  });
13337
+ fieldParams.nameKey = fieldParams.name;
13361
13338
  fieldParams.nthFieldGroup = {
13362
13339
  name: fieldParams.name,
13363
13340
  label: fieldParams.label,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remoteoss/json-schema-form",
3
- "version": "0.11.11-dev.20250220174843",
3
+ "version": "0.11.12-dev.20250313084704",
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",
@@ -422,233 +422,6 @@ describe('Conditional attributes updated', () => {
422
422
  handleValidation({ is_full_time: 'no' });
423
423
  expect(fields[1].visibilityCondition).toEqual(expect.any(Function));
424
424
  });
425
-
426
- it('Group array nested condition', () => {
427
- const { fields, handleValidation } = createHeadlessForm({
428
- type: 'object',
429
- additionalProperties: false,
430
- properties: {
431
- companies: {
432
- type: 'array',
433
- 'x-jsf-presentation': {
434
- inputType: 'group-array',
435
- },
436
- items: {
437
- type: 'object',
438
- properties: {
439
- company: {
440
- type: 'string',
441
- oneOf: [
442
- {
443
- title: 'A',
444
- const: 'A',
445
- },
446
- {
447
- title: 'B',
448
- const: 'B',
449
- },
450
- ],
451
- 'x-jsf-presentation': {
452
- inputType: 'select',
453
- },
454
- },
455
- role: {
456
- title: 'Role',
457
- oneOf: [],
458
- 'x-jsf-presentation': {
459
- inputType: 'select',
460
- },
461
- },
462
- },
463
- allOf: [
464
- {
465
- if: {
466
- properties: {
467
- company: {
468
- const: 'A',
469
- },
470
- },
471
- required: ['company'],
472
- },
473
- then: {
474
- properties: {
475
- role: {
476
- oneOf: [
477
- {
478
- title: 'adminA',
479
- const: 'adminA',
480
- },
481
- {
482
- title: 'userA',
483
- const: 'userA',
484
- },
485
- ],
486
- 'x-jsf-presentation': {
487
- inputType: 'select',
488
- },
489
- },
490
- },
491
- required: ['role'],
492
- },
493
- },
494
- {
495
- if: {
496
- properties: {
497
- company: {
498
- const: 'B',
499
- },
500
- },
501
- required: ['company'],
502
- },
503
- then: {
504
- properties: {
505
- role: {
506
- oneOf: [
507
- {
508
- title: 'adminB',
509
- const: 'adminB',
510
- },
511
- {
512
- title: 'userB',
513
- const: 'userB',
514
- },
515
- ],
516
- 'x-jsf-presentation': {
517
- inputType: 'select',
518
- },
519
- },
520
- },
521
- required: ['role'],
522
- },
523
- },
524
- ],
525
- required: ['company', 'role'],
526
- },
527
- },
528
- },
529
- required: ['companies'],
530
- });
531
-
532
- handleValidation({ companies: [{ company: 'A' }, { company: 'B' }] });
533
- expect(fields[0].dynamicFields[0][1].options).toEqual([
534
- { label: 'adminA', value: 'adminA' },
535
- { label: 'userA', value: 'userA' },
536
- ]);
537
- expect(fields[0].dynamicFields[1][1].options).toEqual([
538
- { label: 'adminB', value: 'adminB' },
539
- { label: 'userB', value: 'userB' },
540
- ]);
541
- handleValidation({ companies: [] });
542
- expect(fields[0].dynamicFields).toEqual([]);
543
- });
544
-
545
- it('select multiple conditions', () => {
546
- const { fields, handleValidation } = createHeadlessForm({
547
- type: 'object',
548
- additionalProperties: false,
549
- properties: {
550
- company: {
551
- title: 'Select Company',
552
- type: 'string',
553
- description: 'Choose a company',
554
- oneOf: [
555
- {
556
- title: 'A',
557
- const: 'A',
558
- },
559
- {
560
- title: 'B',
561
- const: 'B',
562
- },
563
- ],
564
- 'x-jsf-presentation': {
565
- inputType: 'select',
566
- },
567
- },
568
- role: {
569
- title: 'Role',
570
- oneOf: [],
571
- 'x-jsf-presentation': {
572
- inputType: 'select',
573
- },
574
- },
575
- },
576
- allOf: [
577
- {
578
- if: {
579
- properties: {
580
- company: {
581
- const: 'A',
582
- },
583
- },
584
- required: ['company'],
585
- },
586
- then: {
587
- properties: {
588
- role: {
589
- oneOf: [
590
- {
591
- title: 'adminA',
592
- const: 'adminA',
593
- },
594
- {
595
- title: 'userA',
596
- const: 'userA',
597
- },
598
- ],
599
- 'x-jsf-presentation': {
600
- inputType: 'select',
601
- },
602
- },
603
- },
604
- required: ['role'],
605
- },
606
- },
607
- {
608
- if: {
609
- properties: {
610
- company: {
611
- const: 'B',
612
- },
613
- },
614
- required: ['company'],
615
- },
616
- then: {
617
- properties: {
618
- role: {
619
- oneOf: [
620
- {
621
- title: 'adminB',
622
- const: 'adminB',
623
- },
624
- {
625
- title: 'userB',
626
- const: 'userB',
627
- },
628
- ],
629
- 'x-jsf-presentation': {
630
- inputType: 'select',
631
- },
632
- },
633
- },
634
- required: ['role'],
635
- },
636
- },
637
- ],
638
- required: ['company', 'role'],
639
- });
640
-
641
- handleValidation({ company: 'A' });
642
- expect(fields[1].options).toEqual([
643
- { label: 'adminA', value: 'adminA' },
644
- { label: 'userA', value: 'userA' },
645
- ]);
646
- handleValidation({ company: 'B' });
647
- expect(fields[1].options).toEqual([
648
- { label: 'adminB', value: 'adminB' },
649
- { label: 'userB', value: 'userB' },
650
- ]);
651
- });
652
425
  });
653
426
 
654
427
  describe('Conditional with a minimum value check', () => {
@@ -775,6 +548,54 @@ describe('Conditional with literal booleans', () => {
775
548
  });
776
549
  });
777
550
 
551
+ describe('Conditional with anyOf', () => {
552
+ const schema = {
553
+ additionalProperties: false,
554
+ type: 'object',
555
+ properties: {
556
+ field_a: { type: 'string' },
557
+ field_b: { type: 'string' },
558
+ field_c: { type: 'string' },
559
+ },
560
+ allOf: [
561
+ {
562
+ if: {
563
+ anyOf: [
564
+ { properties: { field_a: { const: '1' } }, required: ['field_a'] },
565
+ { properties: { field_b: { const: '2' } }, required: ['field_b'] },
566
+ ],
567
+ },
568
+ then: {
569
+ required: ['field_c'],
570
+ },
571
+ else: {
572
+ properties: {
573
+ field_c: false,
574
+ },
575
+ },
576
+ },
577
+ ],
578
+ };
579
+
580
+ it('handles true case', () => {
581
+ const { fields, handleValidation } = createHeadlessForm(schema, { strictInputType: false });
582
+
583
+ expect(fields[2].isVisible).toBe(false);
584
+ expect(handleValidation({ field_a: 'x', field_b: '2' }).formErrors).toEqual({
585
+ field_c: 'Required field',
586
+ });
587
+ expect(fields[2].isVisible).toBe(true);
588
+ });
589
+
590
+ it('handles false case', () => {
591
+ const { fields, handleValidation } = createHeadlessForm(schema, { strictInputType: false });
592
+
593
+ expect(fields[2].isVisible).toBe(false);
594
+ expect(handleValidation({ field_a: 'x', field_b: 'x' }).formErrors).toBeUndefined();
595
+ expect(fields[2].isVisible).toBe(false);
596
+ });
597
+ });
598
+
778
599
  describe('Conditionals - bugs and code-smells', () => {
779
600
  // Why do we have these bugs?
780
601
  // To be honest we never realized it much later later.
@@ -63,7 +63,7 @@ import {
63
63
  schemaForErrorMessageSpecificity,
64
64
  jsfConfigForErrorMessageSpecificity,
65
65
  schemaInputTypeFile,
66
- nestedGroupArrayForm,
66
+ schemaWithSelectInteger,
67
67
  } from './helpers';
68
68
  import { mockConsole, restoreConsoleAndEnsureItWasNotCalled } from './testUtils';
69
69
  import { createHeadlessForm } from '@/createHeadlessForm';
@@ -658,6 +658,27 @@ describe('createHeadlessForm', () => {
658
658
  ],
659
659
  });
660
660
  });
661
+
662
+ it('supports "select" field with integer values', async () => {
663
+ const { handleValidation } = createHeadlessForm(schemaWithSelectInteger);
664
+ const validateForm = (vals) => friendlyError(handleValidation(vals));
665
+
666
+ // Check for invalid option
667
+ expect(
668
+ validateForm({
669
+ account_type: 4,
670
+ })
671
+ ).toEqual({
672
+ account_type: 'The option 4 is not valid.',
673
+ });
674
+
675
+ // Check for valid option
676
+ expect(
677
+ validateForm({
678
+ account_type: 1,
679
+ })
680
+ ).toBeUndefined();
681
+ });
661
682
  });
662
683
  describe('support "radio" field type', () => {
663
684
  it('support "radio" field type @deprecated', () => {
@@ -1605,6 +1626,7 @@ describe('createHeadlessForm', () => {
1605
1626
  type: 'text',
1606
1627
  description: 'Enter your child’s full name',
1607
1628
  maxLength: 255,
1629
+ nameKey: 'full_name',
1608
1630
  label: 'Child Full Name',
1609
1631
  name: 'full_name',
1610
1632
  required: true,
@@ -1616,6 +1638,7 @@ describe('createHeadlessForm', () => {
1616
1638
  required: true,
1617
1639
  description: 'Enter your child’s date of birth',
1618
1640
  maxLength: 255,
1641
+ nameKey: 'birthdate',
1619
1642
  },
1620
1643
  {
1621
1644
  type: 'radio',
@@ -1634,6 +1657,7 @@ describe('createHeadlessForm', () => {
1634
1657
  required: true,
1635
1658
  description:
1636
1659
  'We know sex is non-binary but for insurance and payroll purposes, we need to collect this information.',
1660
+ nameKey: 'sex',
1637
1661
  },
1638
1662
  ]);
1639
1663
  });
@@ -1735,63 +1759,6 @@ describe('createHeadlessForm', () => {
1735
1759
  });
1736
1760
  });
1737
1761
 
1738
- it('nested "group-array" fields', () => {
1739
- const result = createHeadlessForm({
1740
- properties: {
1741
- nestedGroupArray: nestedGroupArrayForm,
1742
- },
1743
- });
1744
-
1745
- expect(result.fields[0]).toMatchObject({
1746
- label: 'Parent object',
1747
- name: 'nestedGroupArray',
1748
- required: false,
1749
- type: 'group-array',
1750
- inputType: 'group-array',
1751
- jsonType: 'array',
1752
- fields: expect.any(Function),
1753
- });
1754
-
1755
- expect(result.fields[0].fields()).toMatchObject([
1756
- {
1757
- type: 'text',
1758
- description: 'Simple text field',
1759
- maxLength: 255,
1760
- label: 'Outer Field',
1761
- name: 'notNested',
1762
- required: true,
1763
- },
1764
- {
1765
- label: 'Nested group-array',
1766
- name: 'nested',
1767
- required: true,
1768
- type: 'group-array',
1769
- inputType: 'group-array',
1770
- jsonType: 'array',
1771
- fields: expect.any(Function),
1772
- },
1773
- ]);
1774
-
1775
- expect(result.fields[0].fields()[1].fields()).toMatchObject([
1776
- {
1777
- type: 'text',
1778
- description: 'First nested text field',
1779
- maxLength: 255,
1780
- label: 'Inner Field 1',
1781
- name: 'nestedField1',
1782
- required: true,
1783
- },
1784
- {
1785
- type: 'text',
1786
- description: 'Second nested text field',
1787
- maxLength: 255,
1788
- label: 'Inner Field 2',
1789
- name: 'nestedField2',
1790
- required: true,
1791
- },
1792
- ]);
1793
- });
1794
-
1795
1762
  it('can pass custom field attributes', () => {
1796
1763
  const result = createHeadlessForm(
1797
1764
  {
@@ -2328,58 +2328,23 @@ export const schemaWithCustomValidationsAndConditionals = {
2328
2328
  ],
2329
2329
  };
2330
2330
 
2331
- export const nestedGroupArrayForm = {
2332
- items: {
2333
- properties: {
2334
- notNested: {
2335
- description: 'Simple text field',
2336
- 'x-jsf-presentation': {
2337
- inputType: 'text',
2338
- },
2339
- title: 'Outer Field',
2340
- type: 'string',
2341
- maxLength: 255,
2342
- },
2343
- nested: {
2344
- items: {
2345
- properties: {
2346
- nestedField1: {
2347
- description: 'First nested text field',
2348
- 'x-jsf-presentation': {
2349
- inputType: 'text',
2350
- },
2351
- title: 'Inner Field 1',
2352
- type: 'string',
2353
- maxLength: 255,
2354
- },
2355
- nestedField2: {
2356
- description: 'Second nested text field',
2357
- 'x-jsf-presentation': {
2358
- inputType: 'text',
2359
- },
2360
- title: 'Inner Field 2',
2361
- type: 'string',
2362
- maxLength: 255,
2363
- },
2364
- },
2365
- 'x-jsf-order': ['nestedField1', 'nestedField2'],
2366
- required: ['nestedField1', 'nestedField2'],
2367
- type: 'object',
2368
- },
2369
- 'x-jsf-presentation': {
2370
- inputType: 'group-array',
2371
- },
2372
- title: 'Nested group-array',
2373
- type: 'array',
2331
+ export const schemaWithSelectInteger = {
2332
+ additionalProperties: false,
2333
+ type: 'object',
2334
+ properties: {
2335
+ account_type: {
2336
+ title: 'Select an account type',
2337
+ description: '',
2338
+ 'x-jsf-presentation': {
2339
+ inputType: 'select',
2374
2340
  },
2341
+ oneOf: [
2342
+ { title: 'Normal User', const: 0 },
2343
+ { title: 'Business', const: 1 },
2344
+ { title: 'Services Provider', const: 2 },
2345
+ ],
2346
+ type: 'integer',
2375
2347
  },
2376
- 'x-jsf-order': ['notNested', 'nested'],
2377
- required: ['notNested', 'nested'],
2378
- type: 'object',
2379
2348
  },
2380
- 'x-jsf-presentation': {
2381
- inputType: 'group-array',
2382
- },
2383
- title: 'Parent object',
2384
- type: 'array',
2349
+ required: [],
2385
2350
  };