@json-layout/core
Advanced tools
Comparing version 0.13.0 to 0.14.0
{ | ||
"name": "@json-layout/core", | ||
"version": "0.13.0", | ||
"version": "0.14.0", | ||
"description": "Compilation and state management utilities for JSON Layout.", | ||
@@ -62,3 +62,3 @@ "type": "module", | ||
"dependencies": { | ||
"@json-layout/vocabulary": "^0.13.0", | ||
"@json-layout/vocabulary": "^0.14.0", | ||
"@types/markdown-it": "^13.0.1", | ||
@@ -65,0 +65,0 @@ "ajv": "^8.12.0", |
@@ -73,2 +73,4 @@ // eslint-disable-next-line import/no-named-default | ||
initialValidation: 'withData', | ||
updateOn: 'input', | ||
debounceInputMs: 300, | ||
defaultOn: 'empty', | ||
@@ -78,3 +80,2 @@ removeAdditional: 'error', | ||
readOnlyPropertiesMode: 'show', | ||
debounceInputMs: 300, | ||
...partialOptions, | ||
@@ -180,2 +181,14 @@ messages | ||
* @private | ||
* @type {unknown} | ||
*/ | ||
_previousData | ||
/** | ||
* @private | ||
* @type {boolean} | ||
*/ | ||
_dataWaitingForBlur = false | ||
/** | ||
* @private | ||
* @type {CreateStateTreeContext} | ||
@@ -264,2 +277,3 @@ */ | ||
this.events.emit('update', this) | ||
this.emitData() | ||
} | ||
@@ -269,2 +283,14 @@ | ||
* @private | ||
*/ | ||
emitData () { | ||
// emit data event only if the data has changed, as it is immutable this simple comparison should suffice | ||
if (!this._dataWaitingForBlur && this._data !== this._previousData) { | ||
logDataBinding('emit data event', this._data) | ||
this.events.emit('data', this._data) | ||
this._previousData = this._data | ||
} | ||
} | ||
/** | ||
* @private | ||
* @param {boolean} rehydrate | ||
@@ -354,5 +380,6 @@ */ | ||
* @param {unknown} data | ||
* @param {boolean} [validated] | ||
* @param {number} [activateKey] | ||
*/ | ||
applyInput (node, data, activateKey) { | ||
applyInput (node, data, validated, activateKey) { | ||
logDataBinding('received input event from node', node, data) | ||
@@ -381,8 +408,6 @@ | ||
if ( | ||
(node.options.validateOn === 'input' || (node.options.validateOne === 'blur' && !editableCompNames.includes(node.layout.comp))) && | ||
!this.validationState.validatedChildren.includes(node.fullKey) | ||
) { | ||
if (validated && !this.validationState.validatedChildren.includes(node.fullKey)) { | ||
this.validationState = { validatedChildren: this.validationState.validatedChildren.concat([node.fullKey]) } | ||
} | ||
if (activateKey !== undefined) { | ||
@@ -393,4 +418,4 @@ this.activeItems = produce(this.activeItems, draft => { draft[node.fullKey] = activateKey }) | ||
if (node.parentFullKey === null) { | ||
this.data = data | ||
this.events.emit('input', this.data) | ||
this._data = data | ||
this.updateState() | ||
return | ||
@@ -401,3 +426,3 @@ } | ||
const newParentValue = producePatchedData(parentNode.data ?? (typeof node.key === 'number' ? [] : {}), node, data) | ||
this.applyInput(parentNode, newParentValue) | ||
this.applyInput(parentNode, newParentValue, validated) | ||
@@ -411,3 +436,3 @@ if (activateKey !== undefined) { | ||
* @private | ||
* @type {null | [StateNode, unknown, number | undefined, ReturnType<typeof setTimeout>]} | ||
* @type {null | [StateNode, unknown, boolean, number | undefined, ReturnType<typeof setTimeout>]} | ||
*/ | ||
@@ -419,3 +444,3 @@ debouncedInput = null | ||
clearTimeout(this.debouncedInput[3]) | ||
this.applyInput(this.debouncedInput[0], this.debouncedInput[1], this.debouncedInput[2]) | ||
this.applyInput(this.debouncedInput[0], this.debouncedInput[1], this.debouncedInput[2], this.debouncedInput[3]) | ||
this.debouncedInput = null | ||
@@ -434,10 +459,18 @@ } | ||
if (this.debouncedInput) { | ||
if (this.debouncedInput[0] === node) clearTimeout(this.debouncedInput[3]) | ||
if (this.debouncedInput[0] === node) clearTimeout(this.debouncedInput[4]) | ||
else this.applyDebouncedInput() | ||
} | ||
if (editableCompNames.includes(node.layout.comp) && node.options.debounceInputMs) { | ||
this.debouncedInput = [node, data, activateKey, setTimeout(() => this.applyDebouncedInput(), node.options.debounceInputMs)] | ||
const isEditableComp = editableCompNames.includes(node.layout.comp) | ||
if (node.options.updateOn === 'blur' && isEditableComp) { | ||
this._dataWaitingForBlur = true | ||
} | ||
const validated = node.options.validateOn === 'input' || (node.options.validateOn === 'blur' && !isEditableComp) | ||
if (isEditableComp && node.options.debounceInputMs) { | ||
this.debouncedInput = [node, data, validated, activateKey, setTimeout(() => this.applyDebouncedInput(), node.options.debounceInputMs)] | ||
} else { | ||
this.applyInput(node, data, activateKey) | ||
this.applyInput(node, data, validated, activateKey) | ||
} | ||
@@ -460,2 +493,8 @@ } | ||
} | ||
// in case of updateOn=blur option | ||
if (this._dataWaitingForBlur) { | ||
this._dataWaitingForBlur = false | ||
this.emitData() | ||
} | ||
} | ||
@@ -462,0 +501,0 @@ |
@@ -101,5 +101,4 @@ import { type ErrorObject } from 'ajv/dist/2019.js' | ||
export type StatefulLayoutEvents = { | ||
// input: { value: unknown, child: { pointer: string, dataPointer: string, value: unknown } } | ||
input: unknown | ||
'update': StatefulLayout | ||
data: any | ||
update: StatefulLayout | ||
autofocus: string | ||
@@ -106,0 +105,0 @@ } |
@@ -93,2 +93,16 @@ import en from '../i18n/en.js' | ||
{ | ||
key: 'updateOn', | ||
description: 'Control when the new data will be emitted by the form.', | ||
default: 'input', | ||
values: { | ||
input: 'The data will be updated in realtime when the user makes any input (except for the application of debounceInputMs).', | ||
blur: 'The data will be updated only when the user interacts with a form input then leaves it.' | ||
} | ||
}, | ||
{ | ||
key: 'debounceInputMs', | ||
description: 'The debounce time for the input event of editable fields.', | ||
default: 300 | ||
}, | ||
{ | ||
key: 'defaultOn', | ||
@@ -127,8 +141,3 @@ description: 'Control the use of default values in the form.', | ||
} | ||
}, | ||
{ | ||
key: 'debounceInputMs', | ||
description: 'The debounce time for the input event of editable fields.', | ||
default: 300 | ||
} | ||
] |
@@ -109,2 +109,12 @@ export { Display } from "./utils/display.js"; | ||
* @private | ||
* @type {unknown} | ||
*/ | ||
private _previousData; | ||
/** | ||
* @private | ||
* @type {boolean} | ||
*/ | ||
private _dataWaitingForBlur; | ||
/** | ||
* @private | ||
* @type {CreateStateTreeContext} | ||
@@ -146,2 +156,6 @@ */ | ||
* @private | ||
*/ | ||
private emitData; | ||
/** | ||
* @private | ||
* @param {boolean} rehydrate | ||
@@ -176,2 +190,3 @@ */ | ||
* @param {unknown} data | ||
* @param {boolean} [validated] | ||
* @param {number} [activateKey] | ||
@@ -182,3 +197,3 @@ */ | ||
* @private | ||
* @type {null | [StateNode, unknown, number | undefined, ReturnType<typeof setTimeout>]} | ||
* @type {null | [StateNode, unknown, boolean, number | undefined, ReturnType<typeof setTimeout>]} | ||
*/ | ||
@@ -185,0 +200,0 @@ private debouncedInput; |
@@ -64,4 +64,4 @@ import { type ErrorObject } from 'ajv/dist/2019.js'; | ||
export type StatefulLayoutEvents = { | ||
input: unknown; | ||
'update': StatefulLayout; | ||
data: any; | ||
update: StatefulLayout; | ||
autofocus: string; | ||
@@ -68,0 +68,0 @@ }; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
130731
2970
7
+ Added@json-layout/vocabulary@0.14.0(transitive)
- Removed@json-layout/vocabulary@0.13.0(transitive)