@json-layout/core
Advanced tools
Comparing version 0.2.0 to 0.3.0
{ | ||
"name": "@json-layout/core", | ||
"version": "0.2.0", | ||
"version": "0.3.0", | ||
"description": "Compilation and state management utilities for JSON Layout.", | ||
@@ -50,3 +50,3 @@ "type": "module", | ||
"dependencies": { | ||
"@json-layout/vocabulary": "^0.2.0", | ||
"@json-layout/vocabulary": "^0.3.0", | ||
"@types/markdown-it": "^13.0.1", | ||
@@ -53,0 +53,0 @@ "ajv": "^8.12.0", |
@@ -58,2 +58,9 @@ // import Debug from 'debug' | ||
let defaultData | ||
if ('default' in schema) defaultData = schema.default | ||
else if (required) { | ||
if (schema.type === 'object') defaultData = {} | ||
if (schema.type === 'array') defaultData = [] | ||
} | ||
const compObjects = isSwitchStruct(normalizedLayout) ? normalizedLayout.switch : [normalizedLayout] | ||
@@ -63,2 +70,9 @@ for (const compObject of compObjects) { | ||
if (compObject.if) pushExpression(expressions, compObject.if) | ||
if ('const' in schema) compObject.constData = { type: 'js-eval', expr: JSON.stringify(schema.const) } | ||
if (compObject.constData) pushExpression(expressions, compObject.constData) | ||
if (defaultData && !compObject.defaultData) compObject.defaultData = { type: 'js-eval', expr: JSON.stringify(defaultData) } | ||
if (compObject.defaultData) pushExpression(expressions, compObject.defaultData) | ||
if (isItemsLayout(compObject) && compObject.getItems) { | ||
@@ -75,14 +89,4 @@ if (isGetItemsExpression(compObject.getItems)) pushExpression(expressions, compObject.getItems) | ||
let defaultData | ||
if (schema.const) defaultData = schema.const | ||
else if (schema.default) defaultData = schema.default | ||
if (required) { | ||
if (schema.type === 'object') defaultData = {} // TODO: this is only true if property is required ? | ||
if (schema.type === 'array') defaultData = [] | ||
if (schema.type === 'string' && !schema.format) defaultData = '' | ||
} | ||
/** @type {import('./types.js').SkeletonNode} */ | ||
const node = { key: key ?? '', pointer, parentPointer, defaultData } | ||
if (schema.const) node.const = schema.const | ||
const node = { key: key ?? '', pointer, parentPointer } | ||
if (schema.type === 'object') { | ||
@@ -89,0 +93,0 @@ if (schema.properties) { |
@@ -47,6 +47,4 @@ import type ajvModule from 'ajv' | ||
parentPointer: string | null | ||
defaultData?: unknown | ||
const?: unknown | ||
children?: SkeletonNode[] // optional children in the case of arrays and object nodes | ||
childrenTrees?: SkeletonTree[] // other trees that can be instantiated with separate validation (for example in the case of new array items of oneOfs, etc) | ||
} |
@@ -10,3 +10,24 @@ /** @type {import('./types.js').LocaleMessages} */ | ||
sort: 'Sort', | ||
showHelp: 'Show a help message' | ||
up: 'Move up', | ||
down: 'Move down', | ||
showHelp: 'Show a help message', | ||
mdeLink1: '[Link title', | ||
mdeLink2: '](link url)', | ||
mdeImg1: '![](', | ||
mdeImg2: 'image url)', | ||
mdeTable1: '', | ||
mdeTable2: '\n\n| Column 1 | Column 2 | ColoColumnnne 3 |\n| -------- | -------- | -------- |\n| Text | Text | Text |\n\n', | ||
bold: 'Bold', | ||
italic: 'Italic', | ||
heading: 'Title', | ||
quote: 'Quote', | ||
unorderedList: 'Unordered list', | ||
orderedList: 'Ordered list', | ||
createLink: 'Create a link', | ||
insertImage: 'Insert an image', | ||
createTable: 'Create a table', | ||
preview: 'Aperçu du rendu', | ||
mdeGuide: 'Documentation de la syntaxe', | ||
undo: 'Undo', | ||
redo: 'Redo' | ||
} |
@@ -10,3 +10,24 @@ /** @type {import('./types.js').LocaleMessages} */ | ||
sort: 'Trier', | ||
showHelp: 'Afficher un message d\'aide' | ||
up: 'Décaler vers le haut', | ||
down: 'Décaler vers le bas', | ||
showHelp: 'Afficher un message d\'aide', | ||
mdeLink1: '[titre du lien', | ||
mdeLink2: '](adresse du lien)', | ||
mdeImg1: '![](', | ||
mdeImg2: 'adresse de l\'image)', | ||
mdeTable1: '', | ||
mdeTable2: '\n\n| Colonne 1 | Colonne 2 | Colonne 3 |\n| -------- | -------- | -------- |\n| Texte | Texte | Texte |\n\n', | ||
bold: 'Gras', | ||
italic: 'Italique', | ||
heading: 'Titre', | ||
quote: 'Citation', | ||
unorderedList: 'Liste à puce', | ||
orderedList: 'Liste numérotée', | ||
createLink: 'Créer un lien', | ||
insertImage: 'Insérer une image', | ||
createTable: 'Créer un tableau', | ||
preview: 'Preview', | ||
mdeGuide: 'Syntax documentation', | ||
undo: 'Défaire', | ||
redo: 'Refaire' | ||
} |
@@ -12,5 +12,26 @@ export interface CompileOptionsMessages { | ||
sort: string | ||
up: string | ||
down: string | ||
showHelp: string | ||
mdeLink1: string | ||
mdeLink2: string | ||
mdeImg1: string | ||
mdeImg2: string | ||
mdeTable1: string | ||
mdeTable2: string | ||
bold: string | ||
italic: string | ||
heading: string | ||
quote: string | ||
unorderedList: string | ||
orderedList: string | ||
createLink: string | ||
insertImage: string | ||
createTable: string | ||
preview: string | ||
mdeGuide: string | ||
undo: string | ||
redo: string | ||
} | ||
export type LocaleMessages = CompileOptionsMessages & StateOptionsMessages |
@@ -34,2 +34,3 @@ // eslint-disable-next-line import/no-named-default | ||
* @typedef {import('./types.js').VerticalTabsNode} VerticalTabsNode | ||
* @typedef {import('./types.js').StepperNode} StepperNode | ||
* @typedef {import('./types.js').OneOfSelectNode} OneOfSelectNode | ||
@@ -67,2 +68,4 @@ * @typedef {import('./types.js').ListNode} ListNode | ||
initialValidation: 'withData', | ||
defaultOn: 'empty', | ||
autofocus: false, | ||
...partialOptions, | ||
@@ -174,8 +177,19 @@ messages | ||
/** | ||
* @private | ||
* @type {string | null} | ||
*/ | ||
_autofocusTarget | ||
/** | ||
* @private | ||
* @type {string | null} | ||
*/ | ||
_previousAutofocusTarget | ||
/** | ||
* @param {import("../index.js").CompiledLayout} compiledLayout | ||
* @param {import("../index.js").SkeletonTree} skeletonTree | ||
* @param {Partial<StatefulLayoutOptions>} options | ||
* @param {unknown} data | ||
* @param {unknown} [data] | ||
*/ | ||
constructor (compiledLayout, skeletonTree, options, data = {}) { | ||
constructor (compiledLayout, skeletonTree, options, data) { | ||
this._compiledLayout = compiledLayout | ||
@@ -186,2 +200,4 @@ this.skeletonTree = skeletonTree | ||
this.prepareOptions(options) | ||
this._autofocusTarget = this.options.autofocus ? '' : null | ||
this._previousAutofocusTarget = null | ||
this._data = data | ||
@@ -191,2 +207,3 @@ this.initValidationState() | ||
this.updateState() | ||
this.handleAutofocus() | ||
} | ||
@@ -220,6 +237,7 @@ | ||
this.createStateTree() | ||
if (this._data !== this._stateTree.root.data) { | ||
if (this._data !== this._stateTree.root.data || this._autofocusTarget !== this._lastCreateStateTreeContext.autofocusTarget) { | ||
logDataBinding('hydrating state tree changed the data, do it again', this._data, this._stateTree.root.data) | ||
// this is necessary because a first hydration can add default values and change validity, etc | ||
this._data = this._stateTree.root.data | ||
this._autofocusTarget = this._lastCreateStateTreeContext.autofocusTarget | ||
this.createStateTree() | ||
@@ -236,3 +254,8 @@ } | ||
/** @type {CreateStateTreeContext} */ | ||
const createStateTreeContext = { nodes: [], activeItems: this.activeItems } | ||
const createStateTreeContext = { | ||
nodes: [], | ||
activeItems: this.activeItems, | ||
autofocusTarget: this._autofocusTarget, | ||
initial: !this._lastCreateStateTreeContext | ||
} | ||
this._stateTree = createStateTree( | ||
@@ -250,3 +273,7 @@ createStateTreeContext, | ||
if (!this.validationState.initialized) { | ||
this.validationState = { initialized: true, validatedChildren: createStateTreeContext.nodes.filter(n => n.validated).map(n => n.fullKey) } | ||
this._validationState = { | ||
initialized: true, | ||
validatedForm: this._validationState.validatedForm, | ||
validatedChildren: createStateTreeContext.nodes.filter(n => n.validated).map(n => n.fullKey) | ||
} | ||
} | ||
@@ -272,2 +299,9 @@ } | ||
/** | ||
* @returns {string[]} | ||
*/ | ||
get errors () { | ||
return this._lastCreateStateTreeContext.nodes.filter(n => !!n.error).map(n => /** @type {string} */(n.error)) | ||
} | ||
/** | ||
* @returns {boolean} | ||
@@ -291,2 +325,3 @@ */ | ||
this.activeItems[node.fullKey] = activateKey | ||
this._autofocusTarget = node.fullKey + '/' + activateKey | ||
} | ||
@@ -302,2 +337,6 @@ if (node.parentFullKey === null) { | ||
this.input(parentNode, newParentValue) | ||
if (activateKey !== undefined) { | ||
this.handleAutofocus() | ||
} | ||
} | ||
@@ -319,2 +358,14 @@ | ||
/** | ||
* @param {StateNode} node | ||
*/ | ||
validateNodeRecurse (node) { | ||
this.validationState = { validatedChildren: this.validationState.validatedChildren.concat([node.fullKey]) } | ||
if (node.children) { | ||
for (const child of node.children) { | ||
this.validateNodeRecurse(child) | ||
} | ||
} | ||
} | ||
/** | ||
* @private | ||
@@ -408,7 +459,9 @@ * @param {StateNode} node | ||
this.activeItems[node.fullKey] = key | ||
this._autofocusTarget = node.fullKey + '/' + key | ||
if (node.key === '$oneOf') { | ||
this.input(node, node.skeleton.childrenTrees?.[key].root.defaultData) | ||
this.input(node, undefined) | ||
} else { | ||
this.updateState() | ||
} | ||
this.handleAutofocus() | ||
} | ||
@@ -423,2 +476,13 @@ | ||
} | ||
handleAutofocus () { | ||
const autofocusTarget = this._autofocusTarget | ||
if (autofocusTarget !== null && this._autofocusTarget !== this._previousAutofocusTarget) { | ||
this._previousAutofocusTarget = autofocusTarget | ||
setTimeout(() => { | ||
logDataBinding('emit autofocus event', autofocusTarget) | ||
this.events.emit('autofocus', autofocusTarget) | ||
}) | ||
} | ||
} | ||
} |
@@ -1,2 +0,2 @@ | ||
import { isSwitchStruct, childIsCompObject, isCompositeLayout } from '@json-layout/vocabulary' | ||
import { isSwitchStruct, childIsCompObject, isCompositeLayout, isFocusableLayout } from '@json-layout/vocabulary' | ||
import { produce } from 'immer' | ||
@@ -13,14 +13,21 @@ import { getChildDisplay } from './utils/display.js' | ||
if (Array.isArray(data) && !data.length) return true | ||
if (typeof data === 'object' && !Array.isArray(data) && !!data && Object.values(data).findIndex(prop => !isDataEmpty(prop)) === -1) return true | ||
if (typeof data === 'object' && !Array.isArray(data) && !!data && Object.values(data).findIndex(prop => prop !== undefined) === -1) return true | ||
return false | ||
} | ||
/** | ||
* @param {unknown} data | ||
* @param {import('@json-layout/vocabulary').CompObject} layout | ||
* @param {import('./types.js').StatefulLayoutOptions} options | ||
* @returns {boolean} | ||
*/ | ||
const useDefaultData = (data, layout, options) => { | ||
if (options.defaultOn === 'missing' && data === undefined) return true | ||
if (options.defaultOn === 'empty' && isDataEmpty(data)) return true | ||
return false | ||
} | ||
// use Immer for efficient updating with immutability and no-op detection | ||
/** @type {(draft: import('./types.js').StateNode, key: string | number, fullKey: string, parentFullKey: string | null, dataPath: string, parentDataPath: string | null, skeleton: import('../index.js').SkeletonNode, layout: import('@json-layout/vocabulary').CompObject, cols: number, data: unknown, error: string | undefined, validated: boolean, options: import('./types.js').StatefulLayoutOptions, children: import('../index.js').StateNode[] | undefined) => import('../index.js').StateNode} */ | ||
const produceStateNode = produce((draft, key, fullKey, parentFullKey, dataPath, parentDataPath, skeleton, layout, cols, data, error, validated, options, children) => { | ||
data = children && layout.comp !== 'list' ? produceStateNodeData(/** @type {Record<string, unknown>} */(data ?? {}), dataPath, children) : data | ||
// empty data is removed and replaced by the default data | ||
if (isDataEmpty(data) && skeleton.defaultData === undefined) data = undefined | ||
data = skeleton.const ?? data ?? skeleton.defaultData | ||
/** @type {(draft: import('./types.js').StateNode, key: string | number, fullKey: string, parentFullKey: string | null, dataPath: string, parentDataPath: string | null, skeleton: import('../index.js').SkeletonNode, layout: import('@json-layout/vocabulary').CompObject, cols: number, data: unknown, error: string | undefined, validated: boolean, options: import('./types.js').StatefulLayoutOptions, autofocus: boolean, children: import('../index.js').StateNode[] | undefined) => import('../index.js').StateNode} */ | ||
const produceStateNode = produce((draft, key, fullKey, parentFullKey, dataPath, parentDataPath, skeleton, layout, cols, data, error, validated, options, autofocus, children) => { | ||
draft.messages = layout.messages ? produceStateNodeMessages(draft.messages || {}, layout.messages, options) : options.messages | ||
@@ -41,2 +48,12 @@ | ||
draft.validated = validated | ||
if (autofocus) { | ||
draft.autofocus = true | ||
delete draft.autofocusChild | ||
} else { | ||
delete draft.autofocus | ||
const autofocusChild = children?.find(c => c.autofocus) | ||
if (autofocusChild) draft.autofocusChild = autofocusChild.key | ||
else delete draft.autofocusChild | ||
} | ||
draft.children = children | ||
@@ -201,2 +218,6 @@ }) | ||
if (context.initial && parentOptions.autofocus && layout.autofocus) { | ||
context.autofocusTarget = fullKey | ||
} | ||
/** @type {import('./types.js').StateNode[] | undefined} */ | ||
@@ -208,22 +229,29 @@ let children | ||
const childrenOptions = produceCompositeChildrenOptions(options, layout) | ||
children = layout.children.map((child, i) => { | ||
const childSkeleton = skeleton.children?.find(c => c.key === child.key) ?? skeleton | ||
const isSameData = typeof child.key === 'string' && child.key.startsWith('$') | ||
return createStateNode( | ||
children = [] | ||
let focusChild = context.autofocusTarget === fullKey | ||
for (let i = 0; i < layout.children.length; i++) { | ||
const childLayout = layout.children[i] | ||
const childSkeleton = skeleton.children?.find(c => c.key === childLayout.key) ?? skeleton | ||
const isSameData = typeof childLayout.key === 'string' && childLayout.key.startsWith('$') | ||
const childFullKey = `${fullKey}/${childLayout.key}` | ||
if (focusChild) context.autofocusTarget = childFullKey | ||
const child = createStateNode( | ||
context, | ||
childrenOptions, | ||
compiledLayout, | ||
child.key, | ||
`${fullKey}/${child.key}`, | ||
childLayout.key, | ||
childFullKey, | ||
fullKey, | ||
isSameData ? dataPath : `${dataPath}/${child.key}`, | ||
isSameData ? dataPath : `${dataPath}/${childLayout.key}`, | ||
dataPath, | ||
childSkeleton, | ||
child, | ||
childLayout, | ||
display, | ||
isSameData ? objectData : objectData[child.key], | ||
isSameData ? objectData : objectData[childLayout.key], | ||
validationState, | ||
reusedNode?.children?.[i] | ||
) | ||
}) | ||
if (child.autofocus || child.autofocusChild !== undefined) focusChild = false | ||
children.push(child) | ||
} | ||
} | ||
@@ -237,2 +265,4 @@ | ||
context.activeItems[fullKey] = activeChildTreeIndex | ||
const activeChildKey = `${fullKey}/${activeChildTreeIndex}` | ||
if (context.autofocusTarget === fullKey) context.autofocusTarget = activeChildKey | ||
const activeChildTree = skeleton.childrenTrees[activeChildTreeIndex] | ||
@@ -245,3 +275,3 @@ children = [ | ||
activeChildTreeIndex, | ||
`${fullKey}/${activeChildTreeIndex}`, | ||
activeChildKey, | ||
fullKey, | ||
@@ -265,5 +295,9 @@ dataPath, | ||
const listItemOptions = layout.listEditMode === 'inline' ? options : produceReadonlyArrayItemOptions(options) | ||
children = arrayData.map((itemData, i) => { | ||
children = [] | ||
let focusChild = context.autofocusTarget === fullKey | ||
for (let i = 0; i < arrayData.length; i++) { | ||
const itemData = arrayData[i] | ||
const childFullKey = `${fullKey}/${i}` | ||
return createStateNode( | ||
if (focusChild) context.autofocusTarget = childFullKey | ||
const child = createStateNode( | ||
context, | ||
@@ -284,3 +318,5 @@ (layout.listEditMode === 'inline-single' && context.activeItems[fullKey] === i) ? options : listItemOptions, | ||
) | ||
}) | ||
if (child.autofocus || child.autofocusChild !== undefined) focusChild = false | ||
children.push(child) | ||
} | ||
} | ||
@@ -298,2 +334,25 @@ | ||
let nodeData = children ? produceStateNodeData(/** @type {Record<string, unknown>} */(data ?? {}), dataPath, children) : data | ||
if (layout.constData) { | ||
nodeData = evalExpression(compiledLayout.expressions, layout.constData, nodeData, options, display) | ||
} else { | ||
if (layout.defaultData && useDefaultData(nodeData, layout, options)) { | ||
nodeData = evalExpression(compiledLayout.expressions, layout.defaultData, nodeData, options, display) | ||
} else { | ||
if (isDataEmpty(nodeData)) { | ||
if (layout.nullable) { | ||
// if a property is nullable empty values are converted to null | ||
// except for undefined if we need to distinguish between empty and missing data | ||
if (options.defaultOn !== 'missing' || nodeData !== undefined) { | ||
nodeData = null | ||
} | ||
} else if (options.defaultOn !== 'missing') { | ||
// remove empty data, except if we need to distinguish between empty and missing data | ||
nodeData = undefined | ||
} | ||
} | ||
} | ||
} | ||
const autofocus = isFocusableLayout(layout) && !options.readOnly && !options.summary && context.autofocusTarget === fullKey | ||
const node = produceStateNode( | ||
@@ -309,6 +368,7 @@ reusedNode ?? /** @type {import('./types.js').StateNode} */({}), | ||
cols, | ||
data, | ||
nodeData, | ||
error?.message, | ||
validated, | ||
options, | ||
autofocus, | ||
children && shallowCompareArrays(reusedNode?.children, children) | ||
@@ -327,3 +387,2 @@ ) | ||
} | ||
} | ||
) | ||
}) |
@@ -18,3 +18,3 @@ import { produce } from 'immer' | ||
* @param {import('./utils/display.js').Display} display | ||
* @param {unknown} value | ||
* @param {unknown} data | ||
* @param {import('./types.js').ValidationState} validationState | ||
@@ -30,3 +30,3 @@ * @param {import('./types.js').StateTree} [reusedStateTree] | ||
display, | ||
value, | ||
data, | ||
validationState, | ||
@@ -36,3 +36,3 @@ reusedStateTree | ||
const validate = compiledLayout.validates[skeleton.root.pointer] | ||
const valid = validate(value) | ||
const valid = validate(data) | ||
if (validate.errors) { | ||
@@ -56,3 +56,3 @@ for (const error of validate.errors) { | ||
display, | ||
value, | ||
data, | ||
validationState, | ||
@@ -59,0 +59,0 @@ reusedStateTree?.root |
@@ -23,2 +23,3 @@ import { type ErrorObject } from 'ajv' | ||
type ExpansionPanels, | ||
type Stepper, | ||
type List, | ||
@@ -45,2 +46,4 @@ type Combobox | ||
messages: LocaleMessages | ||
autofocus?: boolean | ||
autofocusChild?: string | number | ||
children?: StateNode[] | ||
@@ -59,2 +62,4 @@ } | ||
activeItems: Record<string, number> | ||
autofocusTarget: string | null | ||
initial: boolean | ||
} | ||
@@ -73,2 +78,3 @@ | ||
'update': StatefulLayout | ||
autofocus: string | ||
} | ||
@@ -81,3 +87,5 @@ | ||
initialValidation: 'never' | 'always' | 'withData' | ||
defaultOn: 'missing' | 'empty' | 'never' | ||
messages: LocaleMessages | ||
autofocus: boolean | ||
} | ||
@@ -119,4 +127,6 @@ | ||
export type StepperNode = StateNode & { layout: Stepper, children: StateNode[] } | ||
export type ListNode = StateNode & { layout: List, data: any[], children: StateNode[], childrenTrees: SkeletonTree[] } | ||
export type ComboboxNode = Omit<StateNode, 'children'> & { layout: Combobox, data: any[] } |
@@ -39,4 +39,2 @@ import type ajvModule from 'ajv'; | ||
parentPointer: string | null; | ||
defaultData?: unknown; | ||
const?: unknown; | ||
children?: SkeletonNode[]; | ||
@@ -43,0 +41,0 @@ childrenTrees?: SkeletonTree[]; |
@@ -11,5 +11,26 @@ export interface CompileOptionsMessages { | ||
sort: string; | ||
up: string; | ||
down: string; | ||
showHelp: string; | ||
mdeLink1: string; | ||
mdeLink2: string; | ||
mdeImg1: string; | ||
mdeImg2: string; | ||
mdeTable1: string; | ||
mdeTable2: string; | ||
bold: string; | ||
italic: string; | ||
heading: string; | ||
quote: string; | ||
unorderedList: string; | ||
orderedList: string; | ||
createLink: string; | ||
insertImage: string; | ||
createTable: string; | ||
preview: string; | ||
mdeGuide: string; | ||
undo: string; | ||
redo: string; | ||
} | ||
export type LocaleMessages = CompileOptionsMessages & StateOptionsMessages; | ||
//# sourceMappingURL=types.d.ts.map |
@@ -25,2 +25,3 @@ export { Display } from "./utils/display.js"; | ||
* @typedef {import('./types.js').VerticalTabsNode} VerticalTabsNode | ||
* @typedef {import('./types.js').StepperNode} StepperNode | ||
* @typedef {import('./types.js').OneOfSelectNode} OneOfSelectNode | ||
@@ -38,3 +39,3 @@ * @typedef {import('./types.js').ListNode} ListNode | ||
* @param {Partial<StatefulLayoutOptions>} options | ||
* @param {unknown} data | ||
* @param {unknown} [data] | ||
*/ | ||
@@ -111,2 +112,12 @@ constructor(compiledLayout: import("../index.js").CompiledLayout, skeletonTree: import("../index.js").SkeletonTree, options: Partial<StatefulLayoutOptions>, data?: unknown); | ||
/** | ||
* @private | ||
* @type {string | null} | ||
*/ | ||
private _autofocusTarget; | ||
/** | ||
* @private | ||
* @type {string | null} | ||
*/ | ||
private _previousAutofocusTarget; | ||
/** | ||
* @type {Record<string, number>} | ||
@@ -139,2 +150,6 @@ */ | ||
/** | ||
* @returns {string[]} | ||
*/ | ||
get errors(): string[]; | ||
/** | ||
* @returns {boolean} | ||
@@ -154,2 +169,6 @@ */ | ||
/** | ||
* @param {StateNode} node | ||
*/ | ||
validateNodeRecurse(node: StateNode): void; | ||
/** | ||
* @private | ||
@@ -176,2 +195,3 @@ * @param {StateNode} node | ||
deactivateItem(node: StateNode): void; | ||
handleAutofocus(): void; | ||
} | ||
@@ -200,2 +220,3 @@ export type StateNode = import('./types.js').StateNode; | ||
export type VerticalTabsNode = import('./types.js').VerticalTabsNode; | ||
export type StepperNode = import('./types.js').StepperNode; | ||
export type OneOfSelectNode = import('./types.js').OneOfSelectNode; | ||
@@ -202,0 +223,0 @@ export type ListNode = import('./types.js').ListNode; |
@@ -7,3 +7,3 @@ /** | ||
* @param {import('./utils/display.js').Display} display | ||
* @param {unknown} value | ||
* @param {unknown} data | ||
* @param {import('./types.js').ValidationState} validationState | ||
@@ -13,3 +13,3 @@ * @param {import('./types.js').StateTree} [reusedStateTree] | ||
*/ | ||
export function createStateTree(context: import('./types.js').CreateStateTreeContext, options: import('./types.js').StatefulLayoutOptions, compiledLayout: import('../index.js').CompiledLayout, skeleton: import('../index.js').SkeletonTree, display: import('./utils/display.js').Display, value: unknown, validationState: import('./types.js').ValidationState, reusedStateTree?: import("./types.js").StateTree | undefined): import('./types.js').StateTree; | ||
export function createStateTree(context: import('./types.js').CreateStateTreeContext, options: import('./types.js').StatefulLayoutOptions, compiledLayout: import('../index.js').CompiledLayout, skeleton: import('../index.js').SkeletonTree, display: import('./utils/display.js').Display, data: unknown, validationState: import('./types.js').ValidationState, reusedStateTree?: import("./types.js").StateTree | undefined): import('./types.js').StateTree; | ||
//# sourceMappingURL=state-tree.d.ts.map |
import { type ErrorObject } from 'ajv'; | ||
import { type CompObject, type Cols, type StateNodeOptions, type TextField, type Textarea, type NumberField, type Slider, type Checkbox, type Switch, type DatePicker, type DateTimePicker, type TimePicker, type ColorPicker, type Section, type OneOfSelect, type Select, type Autocomplete, type Tabs, type VerticalTabs, type ExpansionPanels, type List, type Combobox } from '@json-layout/vocabulary'; | ||
import { type CompObject, type Cols, type StateNodeOptions, type TextField, type Textarea, type NumberField, type Slider, type Checkbox, type Switch, type DatePicker, type DateTimePicker, type TimePicker, type ColorPicker, type Section, type OneOfSelect, type Select, type Autocomplete, type Tabs, type VerticalTabs, type ExpansionPanels, type Stepper, type List, type Combobox } from '@json-layout/vocabulary'; | ||
import { type SkeletonTree, type SkeletonNode, type StatefulLayout } from '../index.js'; | ||
@@ -20,2 +20,4 @@ import { type LocaleMessages } from '../i18n/types.js'; | ||
messages: LocaleMessages; | ||
autofocus?: boolean; | ||
autofocusChild?: string | number; | ||
children?: StateNode[]; | ||
@@ -32,2 +34,4 @@ } | ||
activeItems: Record<string, number>; | ||
autofocusTarget: string | null; | ||
initial: boolean; | ||
} | ||
@@ -42,2 +46,3 @@ export interface ValidationState { | ||
'update': StatefulLayout; | ||
autofocus: string; | ||
}; | ||
@@ -49,3 +54,5 @@ export type StatefulLayoutOptions = Required<StateNodeOptions> & { | ||
initialValidation: 'never' | 'always' | 'withData'; | ||
defaultOn: 'missing' | 'empty' | 'never'; | ||
messages: LocaleMessages; | ||
autofocus: boolean; | ||
}; | ||
@@ -121,2 +128,6 @@ export type TextFieldNode = Omit<StateNode, 'children'> & { | ||
}; | ||
export type StepperNode = StateNode & { | ||
layout: Stepper; | ||
children: StateNode[]; | ||
}; | ||
export type ListNode = StateNode & { | ||
@@ -123,0 +134,0 @@ layout: List; |
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
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
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
102513
2279
+ Added@json-layout/vocabulary@0.3.0(transitive)
- Removed@json-layout/vocabulary@0.2.0(transitive)