2022-11-08 14:39:29 +08:00
# What is UI Schema?
2022-10-31 11:52:17 +08:00
2022-11-08 14:39:29 +08:00
A protocol for describing front-end components, based on Formily Schema 2.0, JSON Schema-like style.
2022-10-31 11:52:17 +08:00
```ts
interface ISchema {
type: 'void' | 'string' | 'number' | 'object' | 'array';
name?: string;
title?: any;
2022-11-08 14:39:29 +08:00
// wrapper component
['x-decorator']? : string;
// Wrapper component properties
['x-decorator-props']? : any;
// component
['x-component']? : string;
// Component properties
['x-component-props']? : any;
// display state, default is 'visible'
['x-display']? : 'none' | 'hidden' | 'visible';
// child node of the component, simply use
['x-content']? : any;
// children node schema
2022-10-31 11:52:17 +08:00
properties?: Record< string , ISchema > ;
2022-11-08 14:39:29 +08:00
// The following is used only for field components
2022-10-31 11:52:17 +08:00
2022-11-08 14:39:29 +08:00
// field linkage
['x-reactions']? : SchemaReactions;
// Field UI interaction mode, default is 'editable'
['x-pattern']? : 'editable' | 'disabled' | 'readPretty';
// Field validation
['x-validator']? : Validator;
// default data
default: ? :any;
2022-10-31 11:52:17 +08:00
2022-11-08 14:39:29 +08:00
// Designer related
2022-10-31 11:52:17 +08:00
2022-11-08 14:39:29 +08:00
// Designer component (toolbar), including: drag and drop to move, insert new nodes, modify parameters, remove, etc.
['x-designer']? : any;
// Initializer component (toolbar), determines what can be inserted inside the current schema
['x-initializer']? : any;
2022-10-31 11:52:17 +08:00
}
```
2022-11-08 14:39:29 +08:00
## The simplest component
2022-10-31 11:52:17 +08:00
2022-11-08 14:39:29 +08:00
All native html tags can be converted to schema writing. For example
2022-10-31 11:52:17 +08:00
```ts
{
type: 'void',
'x-component': 'h1',
2022-11-08 14:39:29 +08:00
'x-content': 'Hello, world!
2022-10-31 11:52:17 +08:00
}
```
2022-11-08 14:39:29 +08:00
JSX examples
2022-10-31 11:52:17 +08:00
```tsx | pure
< h1 > Hello, world!< / h1 >
```
2022-11-08 14:39:29 +08:00
## children components can be written in properties
2022-10-31 11:52:17 +08:00
```ts
{
type: 'void',
'x-component': 'div',
'x-component-props': { className: 'form-item' },
properties: {
title: {
type: 'string',
'x-component': 'input',
},
},
}
```
2022-11-08 14:39:29 +08:00
JSX is equivalent to
2022-10-31 11:52:17 +08:00
```tsx | pure
< div className = {'form-item'} >
< input name = {'title'} / >
< / div >
```
2022-11-08 14:39:29 +08:00
## The clever use of Decorator
2022-10-31 11:52:17 +08:00
2022-11-08 14:39:29 +08:00
The combination of decorator + component allows you to put two components in a single schema node, reducing the complexity of the schema structure and increasing the reusability of the components.
2022-10-31 11:52:17 +08:00
2022-11-08 14:39:29 +08:00
For example, in a form scenario, you can combine a FormItem component with any field component, where the FormItem is the Decorator.
2022-10-31 11:52:17 +08:00
```ts
{
type: 'void',
['x-component']: 'div',
properties: {
title: {
type: 'string',
'x-decorator': 'FormItem',
'x-component': 'Input',
},
content: {
type: 'string',
'x-decorator': 'FormItem',
'x-component': 'Input.TextArea',
},
},
}
```
2022-11-08 14:39:29 +08:00
JSX is equivalent to
2022-10-31 11:52:17 +08:00
```tsx | pure
< div >
< FormItem >
< Input name = {'title'} / >
< / FormItem >
< FormItem >
< Input.TextArea name = {'content'} / >
< / FormItem >
< / div >
```
2022-11-08 14:39:29 +08:00
It is also possible to provide a CardItem component that wraps all blocks, so that all blocks are Card wrapped.
2022-10-31 11:52:17 +08:00
```ts
{
type: 'void',
['x-component']: 'div',
properties: {
title: {
type: 'string',
'x-decorator': 'CardItem',
'x-component': 'Table',
},
content: {
type: 'string',
'x-decorator': 'CardItem',
'x-component': 'Kanban',
},
},
}
```
2022-11-08 14:39:29 +08:00
JSX is equivalent to
2022-10-31 11:52:17 +08:00
```tsx | pure
< div >
< CardItem >
< Table / >
< / CardItem >
< CardItem >
< Kanban / >
< / CardItem >
< / div >
```
2022-11-08 14:39:29 +08:00
## Display state of the component
2022-10-31 11:52:17 +08:00
2022-11-08 14:39:29 +08:00
- `'x-display': 'visible'` : the component is displayed
- `'x-display': 'hidden'` : component is hidden, data is not hidden
- `'x-display': 'none'` : component is hidden, data is also hidden
2022-10-31 11:52:17 +08:00
### `'x-display': 'visible'`
```ts
{
type: 'void',
'x-component': 'div',
'x-component-props': { className: 'form-item' },
properties: {
title: {
type: 'string',
'x-component': 'input',
'x-display': 'visible'
},
},
}
```
2022-11-08 14:39:29 +08:00
JSX is equivalent to
2022-10-31 11:52:17 +08:00
```tsx | pure
< div className = {'form-item'} >
< input name = {'title'} / >
< / div >
```
### `'x-display': 'hidden'`
```ts
{
type: 'void',
'x-component': 'div',
'x-component-props': { className: 'form-item' },
properties: {
title: {
type: 'string',
'x-component': 'input',
'x-display': 'hidden'
},
},
}
```
2022-11-08 14:39:29 +08:00
JSX is equivalent to
2022-10-31 11:52:17 +08:00
```tsx | pure
< div className = {'form-item'} >
2022-11-08 14:39:29 +08:00
{/* The input component is not output here, the corresponding field model with name=title still exists */}
2022-10-31 11:52:17 +08:00
< / div >
```
### `'x-display': 'none'`
```ts
{
type: 'void',
'x-component': 'div',
'x-component-props': { className: 'form-item' },
properties: {
title: {
type: 'string',
'x-component': 'input',
'x-display': 'none'
},
},
}
```
2022-11-08 14:39:29 +08:00
JSX is equivalent to
2022-10-31 11:52:17 +08:00
```tsx | pure
< div className = {'form-item'} >
2022-11-08 14:39:29 +08:00
{/* The input component is not output here, and the corresponding field model with name=title does not exist anymore */}
2022-10-31 11:52:17 +08:00
< / div >
```
2022-11-08 14:39:29 +08:00
## Display modes for components
2022-10-31 11:52:17 +08:00
2022-11-08 14:39:29 +08:00
For field components, there are three display modes:
2022-10-31 11:52:17 +08:00
2022-11-08 14:39:29 +08:00
- `'x-pattern': 'editable'` Editable
- `'x-pattern': 'disabled'` Non-editable
- `'x-pattern': 'readPretty'` Friendly reading
2022-10-31 11:52:17 +08:00
2022-11-08 14:39:29 +08:00
As in the case of the `<SingleText />` component, the editable and disabled modes are `<input />` and the readPretty mode is `<div />` .
2022-10-31 11:52:17 +08:00
### `'x-pattern': 'editable'`
```ts
const schema = {
name: 'test',
type: 'void',
'x-component': 'div',
'x-component-props': { className: 'form-item' },
properties: {
title: {
type: 'string',
default: 'Hello',
'x-component': 'SingleText',
'x-pattern': 'editable'
},
},
};
```
2022-11-08 14:39:29 +08:00
JSX is equivalent to
2022-10-31 11:52:17 +08:00
```tsx | pure
< div className = {'form-item'} >
< input name = {'title'} value = {'Hello'} / >
< / div >
```
### `'x-pattern': 'disabled'`
```ts
const schema = {
name: 'test',
type: 'void',
'x-component': 'div',
'x-component-props': { className: 'form-item' },
properties: {
title: {
type: 'string',
default: 'Hello',
'x-component': 'SingleText',
'x-pattern': 'disabled'
},
},
};
```
2022-11-08 14:39:29 +08:00
JSX is equivalent to
2022-10-31 11:52:17 +08:00
```tsx | pure
< div className = {'form-item'} >
< input name = {'title'} value = {'Hello'} disabled / >
< / div >
```
### `'x-pattern': 'readPretty'`
```ts
const schema = {
name: 'test',
type: 'void',
'x-component': 'div',
'x-component-props': { className: 'form-item' },
properties: {
title: {
type: 'string',
default: 'Hello',
'x-component': 'SingleText',
'x-pattern': 'readPretty',
},
},
};
```
2022-11-08 14:39:29 +08:00
JSX is equivalent to
2022-10-31 11:52:17 +08:00
```tsx | pure
< div className = {'form-item'} >
< div > Hello< / div >
< / div >
```