Skip to main content

Schema

What is a schema?​

A schema declaratively describes the visual and functional structure of a DyonaForm. Import the component and its schema type, define an object, and pass that object to schema:

import {
DyonaForm,
type DyonaFormSchema,
} from '@typhonsoftware/dyona-form';

const schema: DyonaFormSchema = {
// ...
};

<DyonaForm schema={schema} />

DyonaForm receives a JavaScript or TypeScript object with a JSON-compatible structure; it does not receive a JSON string directly.

Root structure​

type DyonaFormSchema = {
title: string;
actions?: DyonaFormActionsConfig;
tabs: DyonaFormTab[];
hideSingleTab?: boolean;
};
  • title is required, must be a non-empty string, and is the form's general title.
  • tabs is required, is an array of DyonaFormTab, must contain at least one tab, and contains the form's main structure.
  • hideSingleTab is optional and boolean. When there is exactly one tab and it is true, only the visual tab bar is hidden; its content still renders. With two or more tabs, tabs are always shown.
  • actions is optional and configures the form's own buttons. It is not the generic DYONA Action Engine.

Visual hierarchy​

DyonaFormSchema
↓
tabs[]
↓
rows[]
↓
columns[]
↓
DyonaFormField

A schema contains tabs; each tab contains rows; each row contains columns; and every item in columns is a field.

Tabs​

type DyonaFormTab = {
id: string;
title: string;
helpUrl?: string;
rows: DyonaFormRow[];
};
  • id is required, must be a non-empty string, and must be unique within the schema.
  • title is required, must be a non-empty string, and is the visible tab text.
  • helpUrl is optional and is a string that can define access to help for that section.
  • rows is the array of rows in the tab.

Rows and columns​

type DyonaFormRow = {
columns: DyonaFormField[];
};

A row is a logical form row. columns is required, is an array, and an existing row must contain at least one field. Each item is a DyonaFormField.

The public property name is columns, not fields.

rows: [
{
columns: [
{name: 'firstName', label: 'First name', type: 'text'},
{name: 'lastName', label: 'Last name', type: 'text'},
],
},
]

Fields: basic structure​

Field-specific properties are documented in Fields. At schema level, the minimum structure is:

{name: 'name', label: 'Name', type: 'text'}
  • name identifies the data, must be a non-empty string, and must be unique across the whole form.
  • label is the visible field text.
  • type defines which control DYONA Form renders.

The current field types are text, number, date, datetime, select, autocomplete, checkbox, textarea, email, password, link, and label. Their type-specific properties are covered in Fields.

Layout and grid​

A field can define its responsive width with grid:

grid: {xs: 12, md: 6}

xs, sm, md, lg, and xl use values from 1 through 12.

Form actions​

type DyonaFormActionsConfig = {
submit?: DyonaFormActionButtonConfig;
back?: DyonaFormActionButtonConfig;
custom?: DyonaFormCustomActionConfig[];
disableOtherActionsWhileRunning?: boolean;
layout?: 'horizontal' | 'vertical';
wrap?: boolean;
};

type DyonaFormActionButtonConfig = {
label?: string;
icon?: string;
shortcut?: string;
tooltip?: string;
variant?: 'text' | 'outlined' | 'contained';
loadingLabel?: string;
showSpinner?: boolean;
cancelable?: boolean;
};

type DyonaFormCustomActionConfig = DyonaFormActionButtonConfig & {
id: string;
label: string;
validate?: boolean;
};
actions: {
submit: {label: 'Save', icon: 'Save', shortcut: 'Alt+S', tooltip: 'Save changes'},
back: {label: 'Back', icon: 'ArrowBack'},
custom: [{id: 'preview', label: 'Preview', validate: false}],
}

These actions configure DyonaForm's built-in submit and back buttons and its custom buttons. They are not DyonaAction instances and do not belong to the generic Action Engine. See Form Actions for handlers, validation, async execution, cancellation, defaults, and layout.

What does not belong in the schema?​

These are DyonaForm props, not schema properties: locale, initialValues, onSubmit, onBack, onAction, styles, and dataSourceExecutor.

<DyonaForm
locale="..."
schema={schema}
initialValues={{...}}
onSubmit={...}
onAction={...}
/>

This separates declarative schema configuration from React component integration.

Complete minimum example​

const schema: DyonaFormSchema = {
title: 'Customer',
hideSingleTab: true,
tabs: [{
id: 'general',
title: 'General',
rows: [{
columns: [{name: 'name', label: 'Name', type: 'text', required: true}],
}],
}],
};

<DyonaForm schema={schema} />

Structural example​

const schema: DyonaFormSchema = {
title: 'Customer editor',
tabs: [
{
id: 'general', title: 'General',
rows: [
{columns: [
{name: 'firstName', label: 'First name', type: 'text', grid: {xs: 12, md: 6}},
{name: 'lastName', label: 'Last name', type: 'text', grid: {xs: 12, md: 6}},
]},
{columns: [{name: 'email', label: 'Email', type: 'email'}]},
],
},
{
id: 'preferences', title: 'Preferences',
rows: [{columns: [{name: 'newsletter', label: 'Receive newsletter', type: 'checkbox'}]}],
},
],
actions: {
submit: {label: 'Save', icon: 'Save'},
back: {label: 'Back', icon: 'ArrowBack'},
},
};

Schema as JSON​

The same basic structure can be represented with real JSON syntax:

{
"title": "Customer",
"tabs": [{
"id": "general",
"title": "General",
"rows": [{
"columns": [{"name": "name", "label": "Name", "type": "text"}]
}]
}]
}

The structure is JSON-compatible; the application ultimately supplies the resulting object to schema.

Structural validation​

DYONA Form validates a schema before normal rendering. Useful structural rules include a required title, at least one tab, unique tab ids, unique field names across the form, supported field types, valid row columns, and rejection of incompatible properties. Internal validation codes are not part of this guide.

Next steps​

  • Fields — field types and properties.
  • Validation — declarative and built-in validation.
  • Conditions — conditional visibility and requirements.
  • Label — visual/no-data informational fields.