@remoteoss/json-schema-form 0.11.14-dev.20250514093749 â 0.11.15-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 +12 -0
- package/README.md +12 -4
- package/dist/index.cjs +25 -13
- package/dist/index.js +25 -13
- package/dist/standalone.js +25 -13
- package/package.json +1 -1
- package/src/tests/helpers.custom.js +1 -1
- package/src/tests/helpers.js +1 -1
- package/src/tests/jsonLogic.fixtures.js +49 -0
- package/src/tests/jsonLogic.test.js +12 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
#### 0.11.15-beta.0 (2025-06-06)
|
|
2
|
+
|
|
3
|
+
##### Bug Fixes
|
|
4
|
+
|
|
5
|
+
* **v0:** Handle computed presentational attributes correctly ([#195](https://github.com/remoteoss/json-schema-form/pull/195)) ([19c7ff5b](https://github.com/remoteoss/json-schema-form/commit/19c7ff5b4c5cc90bd1025a3ad3032076e4e25b65))
|
|
6
|
+
|
|
7
|
+
#### 0.11.14-beta.0 (2025-05-14)
|
|
8
|
+
|
|
9
|
+
##### Chores
|
|
10
|
+
|
|
11
|
+
* Reminder to publish GitHub release ([#183](https://github.com/remoteoss/json-schema-form/pull/183)) ([adfa8c14](https://github.com/remoteoss/json-schema-form/commit/adfa8c14ca118b1012642f39c8388cf2ba1614c9))
|
|
12
|
+
|
|
1
13
|
#### 0.11.13-beta.0 (2025-05-05)
|
|
2
14
|
|
|
3
15
|
##### Bug Fixes
|
package/README.md
CHANGED
|
@@ -5,14 +5,16 @@
|
|
|
5
5
|
<p align="center">
|
|
6
6
|
<code>json-schema-form</code> is a headless UI form library powered by <a href="https://json-schema.org/">JSON Schemas</a>.
|
|
7
7
|
<br/>
|
|
8
|
-
It transforms JSON schemas into Javascript to be consumed by your UI libraries.
|
|
8
|
+
It transforms JSON schemas into Javascript `fields` to be more easily consumed by your UI libraries.
|
|
9
9
|
</p>
|
|
10
10
|
|
|
11
11
|
---
|
|
12
12
|
|
|
13
13
|
### Why JSON Schemas for forms?
|
|
14
14
|
|
|
15
|
-
JSON Schemas are the SSoT (Single Source of Truth) that allows you to share form's _structure_ and _validations_ between
|
|
15
|
+
JSON Schemas are the SSoT (Single Source of Truth) that allows you to share form's data _structure_ and _validations_ between the server (backend) and the client (frontend), regardless of the language used.
|
|
16
|
+
|
|
17
|
+
You can use it beyond UI Forms, like lists, tables, and any other UI that needs structured JSON data.
|
|
16
18
|
|
|
17
19
|
## Installation
|
|
18
20
|
|
|
@@ -25,12 +27,18 @@ npm install @remoteoss/json-schema-form
|
|
|
25
27
|
yarn install @remoteoss/json-schema-form
|
|
26
28
|
```
|
|
27
29
|
|
|
28
|
-
##
|
|
30
|
+
## Getting Started
|
|
31
|
+
|
|
32
|
+
Check the đ **[JSF website](https://json-schema-form.vercel.app/)** for documentation.
|
|
29
33
|
|
|
30
|
-
|
|
34
|
+
### Playground
|
|
35
|
+
|
|
36
|
+
Check the đšī¸ **[JSF Playground](https://json-schema-form.vercel.app/?path=/docs/playground--docs)** for demos.
|
|
31
37
|
|
|
32
38
|
## Contributing
|
|
33
39
|
|
|
34
40
|
Read [CONTRIBUTING](CONTRIBUTING.md) to get started.
|
|
35
41
|
|
|
42
|
+
We are working on the [next version v1.0](/next). A rewrite in TypeScript with major bugfixes and missing features. It aims to support the latest JSON Schema dialect 2020-12.
|
|
43
|
+
|
|
36
44
|
_Backed by [Remote.com](https://remote.com/)_
|
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.
|
|
5
|
-
Generated:
|
|
4
|
+
NPM Package: @remoteoss/json-schema-form@0.11.15-beta.0
|
|
5
|
+
Generated: Fri, 06 Jun 2025 13:25:38 GMT
|
|
6
6
|
|
|
7
7
|
MIT License
|
|
8
8
|
|
|
@@ -967,9 +967,16 @@ function replaceHandlebarsTemplates({
|
|
|
967
967
|
function calculateComputedAttributes(fieldParams, { parentID = "root" } = {}) {
|
|
968
968
|
return ({ logic, isRequired, config, formValues }) => {
|
|
969
969
|
const { name, computedAttributes } = fieldParams;
|
|
970
|
-
|
|
970
|
+
let attributes = Object.fromEntries(
|
|
971
971
|
Object.entries(computedAttributes).map(handleComputedAttribute(logic, formValues, parentID, name)).filter(([, value]) => value !== null)
|
|
972
972
|
);
|
|
973
|
+
const { "x-jsf-presentation": presentation, ...rest } = attributes;
|
|
974
|
+
if (presentation) {
|
|
975
|
+
attributes = {
|
|
976
|
+
...rest,
|
|
977
|
+
...presentation
|
|
978
|
+
};
|
|
979
|
+
}
|
|
973
980
|
return {
|
|
974
981
|
...attributes,
|
|
975
982
|
schema: buildYupSchema(
|
|
@@ -993,16 +1000,21 @@ function handleComputedAttribute(logic, formValues, parentID, name) {
|
|
|
993
1000
|
handleNestedObjectForComputedValues(value, formValues, parentID, logic, name)
|
|
994
1001
|
];
|
|
995
1002
|
case "x-jsf-presentation": {
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
handleNestedObjectForComputedValues(
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1003
|
+
const values = {};
|
|
1004
|
+
Object.entries(value).forEach(([presentationKey, presentationValue]) => {
|
|
1005
|
+
if (typeof presentationValue === "object") {
|
|
1006
|
+
values[presentationKey] = handleNestedObjectForComputedValues(
|
|
1007
|
+
presentationValue,
|
|
1008
|
+
formValues,
|
|
1009
|
+
parentID,
|
|
1010
|
+
logic,
|
|
1011
|
+
name
|
|
1012
|
+
);
|
|
1013
|
+
} else {
|
|
1014
|
+
values[presentationKey] = logic.getScope(parentID).applyComputedValueInField(presentationValue, formValues, name);
|
|
1015
|
+
}
|
|
1016
|
+
});
|
|
1017
|
+
return [key, values];
|
|
1006
1018
|
}
|
|
1007
1019
|
case "const":
|
|
1008
1020
|
default: {
|
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.
|
|
5
|
-
Generated:
|
|
4
|
+
NPM Package: @remoteoss/json-schema-form@0.11.15-beta.0
|
|
5
|
+
Generated: Fri, 06 Jun 2025 13:25:38 GMT
|
|
6
6
|
|
|
7
7
|
MIT License
|
|
8
8
|
|
|
@@ -930,9 +930,16 @@ function replaceHandlebarsTemplates({
|
|
|
930
930
|
function calculateComputedAttributes(fieldParams, { parentID = "root" } = {}) {
|
|
931
931
|
return ({ logic, isRequired, config, formValues }) => {
|
|
932
932
|
const { name, computedAttributes } = fieldParams;
|
|
933
|
-
|
|
933
|
+
let attributes = Object.fromEntries(
|
|
934
934
|
Object.entries(computedAttributes).map(handleComputedAttribute(logic, formValues, parentID, name)).filter(([, value]) => value !== null)
|
|
935
935
|
);
|
|
936
|
+
const { "x-jsf-presentation": presentation, ...rest } = attributes;
|
|
937
|
+
if (presentation) {
|
|
938
|
+
attributes = {
|
|
939
|
+
...rest,
|
|
940
|
+
...presentation
|
|
941
|
+
};
|
|
942
|
+
}
|
|
936
943
|
return {
|
|
937
944
|
...attributes,
|
|
938
945
|
schema: buildYupSchema(
|
|
@@ -956,16 +963,21 @@ function handleComputedAttribute(logic, formValues, parentID, name) {
|
|
|
956
963
|
handleNestedObjectForComputedValues(value, formValues, parentID, logic, name)
|
|
957
964
|
];
|
|
958
965
|
case "x-jsf-presentation": {
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
handleNestedObjectForComputedValues(
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
966
|
+
const values = {};
|
|
967
|
+
Object.entries(value).forEach(([presentationKey, presentationValue]) => {
|
|
968
|
+
if (typeof presentationValue === "object") {
|
|
969
|
+
values[presentationKey] = handleNestedObjectForComputedValues(
|
|
970
|
+
presentationValue,
|
|
971
|
+
formValues,
|
|
972
|
+
parentID,
|
|
973
|
+
logic,
|
|
974
|
+
name
|
|
975
|
+
);
|
|
976
|
+
} else {
|
|
977
|
+
values[presentationKey] = logic.getScope(parentID).applyComputedValueInField(presentationValue, formValues, name);
|
|
978
|
+
}
|
|
979
|
+
});
|
|
980
|
+
return [key, values];
|
|
969
981
|
}
|
|
970
982
|
case "const":
|
|
971
983
|
default: {
|
package/dist/standalone.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.
|
|
5
|
-
Generated:
|
|
4
|
+
NPM Package: @remoteoss/json-schema-form@0.11.15-beta.0
|
|
5
|
+
Generated: Fri, 06 Jun 2025 13:25:38 GMT
|
|
6
6
|
|
|
7
7
|
MIT License
|
|
8
8
|
|
|
@@ -12446,9 +12446,16 @@ function replaceHandlebarsTemplates({
|
|
|
12446
12446
|
function calculateComputedAttributes(fieldParams, { parentID = "root" } = {}) {
|
|
12447
12447
|
return ({ logic, isRequired, config, formValues }) => {
|
|
12448
12448
|
const { name, computedAttributes } = fieldParams;
|
|
12449
|
-
|
|
12449
|
+
let attributes = Object.fromEntries(
|
|
12450
12450
|
Object.entries(computedAttributes).map(handleComputedAttribute(logic, formValues, parentID, name)).filter(([, value]) => value !== null)
|
|
12451
12451
|
);
|
|
12452
|
+
const { "x-jsf-presentation": presentation, ...rest } = attributes;
|
|
12453
|
+
if (presentation) {
|
|
12454
|
+
attributes = {
|
|
12455
|
+
...rest,
|
|
12456
|
+
...presentation
|
|
12457
|
+
};
|
|
12458
|
+
}
|
|
12452
12459
|
return {
|
|
12453
12460
|
...attributes,
|
|
12454
12461
|
schema: buildYupSchema(
|
|
@@ -12472,16 +12479,21 @@ function handleComputedAttribute(logic, formValues, parentID, name) {
|
|
|
12472
12479
|
handleNestedObjectForComputedValues(value, formValues, parentID, logic, name)
|
|
12473
12480
|
];
|
|
12474
12481
|
case "x-jsf-presentation": {
|
|
12475
|
-
|
|
12476
|
-
|
|
12477
|
-
|
|
12478
|
-
handleNestedObjectForComputedValues(
|
|
12479
|
-
|
|
12480
|
-
|
|
12481
|
-
|
|
12482
|
-
|
|
12483
|
-
|
|
12484
|
-
|
|
12482
|
+
const values2 = {};
|
|
12483
|
+
Object.entries(value).forEach(([presentationKey, presentationValue]) => {
|
|
12484
|
+
if (typeof presentationValue === "object") {
|
|
12485
|
+
values2[presentationKey] = handleNestedObjectForComputedValues(
|
|
12486
|
+
presentationValue,
|
|
12487
|
+
formValues,
|
|
12488
|
+
parentID,
|
|
12489
|
+
logic,
|
|
12490
|
+
name
|
|
12491
|
+
);
|
|
12492
|
+
} else {
|
|
12493
|
+
values2[presentationKey] = logic.getScope(parentID).applyComputedValueInField(presentationValue, formValues, name);
|
|
12494
|
+
}
|
|
12495
|
+
});
|
|
12496
|
+
return [key, values2];
|
|
12485
12497
|
}
|
|
12486
12498
|
case "const":
|
|
12487
12499
|
default: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remoteoss/json-schema-form",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.15-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",
|
|
@@ -205,7 +205,7 @@ export const schemaInputTypeHidden = {
|
|
|
205
205
|
a_hidden_select_multiple: {
|
|
206
206
|
...schemaInputTypeCountriesMultiple.properties.nationality,
|
|
207
207
|
title: 'Select multi hidden',
|
|
208
|
-
default: ['Albania, Algeria'],
|
|
208
|
+
default: ['Albania', 'Algeria'],
|
|
209
209
|
'x-jsf-presentation': { inputType: 'hidden' },
|
|
210
210
|
type: 'array',
|
|
211
211
|
},
|
package/src/tests/helpers.js
CHANGED
|
@@ -1468,7 +1468,6 @@ export const schemaDynamicValidationConst = {
|
|
|
1468
1468
|
required: ['a_fieldset', 'validate_tabs', 'mandatory_group_array'],
|
|
1469
1469
|
'x-jsf-order': ['validate_tabs', 'a_fieldset', 'mandatory_group_array', 'a_group_array'],
|
|
1470
1470
|
};
|
|
1471
|
-
|
|
1472
1471
|
export const schemaDynamicValidationMinimumMaximum = JSONSchemaBuilder()
|
|
1473
1472
|
.addInput({
|
|
1474
1473
|
a_number: mockNumberInput,
|
|
@@ -1542,6 +1541,7 @@ export const schemaDynamicValidationContains = JSONSchemaBuilder()
|
|
|
1542
1541
|
},
|
|
1543
1542
|
'x-jsf-presentation': {
|
|
1544
1543
|
inputType: 'select',
|
|
1544
|
+
multiple: true,
|
|
1545
1545
|
options: [
|
|
1546
1546
|
{
|
|
1547
1547
|
label: 'All',
|
|
@@ -364,6 +364,55 @@ export const schemaWithComputedAttributesAndErrorMessages = {
|
|
|
364
364
|
},
|
|
365
365
|
};
|
|
366
366
|
|
|
367
|
+
export const schemaWithComputedPresentationAttributes = {
|
|
368
|
+
properties: {
|
|
369
|
+
amount: {
|
|
370
|
+
description: 'Total amount to be reimbursed, including taxes.',
|
|
371
|
+
minimum: 0,
|
|
372
|
+
title: 'Total amount',
|
|
373
|
+
type: 'number',
|
|
374
|
+
'x-jsf-logic-computedAttrs': {
|
|
375
|
+
'x-jsf-presentation': {
|
|
376
|
+
currency: 'currency_selected',
|
|
377
|
+
},
|
|
378
|
+
},
|
|
379
|
+
'x-jsf-presentation': {
|
|
380
|
+
currency: '---',
|
|
381
|
+
inputType: 'money',
|
|
382
|
+
},
|
|
383
|
+
},
|
|
384
|
+
currency: {
|
|
385
|
+
default: 'USD',
|
|
386
|
+
description: 'Currency in which the expense was paid.',
|
|
387
|
+
oneOf: [
|
|
388
|
+
{
|
|
389
|
+
const: 'UGX',
|
|
390
|
+
title: 'UGX - Ugandan Shilling',
|
|
391
|
+
},
|
|
392
|
+
{
|
|
393
|
+
const: 'USD',
|
|
394
|
+
title: 'USD - United States Dollar',
|
|
395
|
+
},
|
|
396
|
+
],
|
|
397
|
+
title: 'Currency',
|
|
398
|
+
type: 'string',
|
|
399
|
+
'x-jsf-presentation': {
|
|
400
|
+
inputType: 'select',
|
|
401
|
+
},
|
|
402
|
+
},
|
|
403
|
+
},
|
|
404
|
+
type: 'object',
|
|
405
|
+
'x-jsf-logic': {
|
|
406
|
+
computedValues: {
|
|
407
|
+
currency_selected: {
|
|
408
|
+
rule: {
|
|
409
|
+
var: 'currency',
|
|
410
|
+
},
|
|
411
|
+
},
|
|
412
|
+
},
|
|
413
|
+
},
|
|
414
|
+
};
|
|
415
|
+
|
|
367
416
|
export const schemaWithDeepVarThatDoesNotExist = {
|
|
368
417
|
properties: {
|
|
369
418
|
field_a: {
|
|
@@ -35,6 +35,7 @@ import {
|
|
|
35
35
|
schemaWithValidationThatDoesNotExistOnProperty,
|
|
36
36
|
badSchemaThatWillNotSetAForcedValue,
|
|
37
37
|
schemaWithReduceAccumulator,
|
|
38
|
+
schemaWithComputedPresentationAttributes,
|
|
38
39
|
} from './jsonLogic.fixtures';
|
|
39
40
|
import { mockConsole, restoreConsoleAndEnsureItWasNotCalled } from './testUtils';
|
|
40
41
|
import { createHeadlessForm } from '@/createHeadlessForm';
|
|
@@ -385,6 +386,17 @@ describe('jsonLogic: cross-values validations', () => {
|
|
|
385
386
|
expect(fieldB.statement).toEqual({ description: 'Must be bigger than 4 and smaller than 8' });
|
|
386
387
|
});
|
|
387
388
|
|
|
389
|
+
it('presentation attributes work', () => {
|
|
390
|
+
const { fields, handleValidation } = createHeadlessForm(
|
|
391
|
+
schemaWithComputedPresentationAttributes,
|
|
392
|
+
{ strictInputType: false }
|
|
393
|
+
);
|
|
394
|
+
const fieldB = fields.find((i) => i.name === 'amount');
|
|
395
|
+
expect(handleValidation({ currency: 'UGX' }).formErrors).toEqual(undefined);
|
|
396
|
+
expect(fieldB.inputType).toEqual('money');
|
|
397
|
+
expect(fieldB.currency).toEqual('UGX');
|
|
398
|
+
});
|
|
399
|
+
|
|
388
400
|
it('Use a inline-rule in a schema for a title attribute', () => {
|
|
389
401
|
const { fields, handleValidation } = createHeadlessForm(
|
|
390
402
|
schemaWithInlineRuleForComputedAttributeWithCopy,
|