UISchema
The optional UISchema represents additional instructions for how AutoView is to render the data.
It is used to modify the rendered components, by selecting a specific component for a specific property,
ordering object properties or grouping properties.
Usage of UISchema
The best practice is to use UISchema allowing users to order or group fields or change which component to use for a field.
It can be used as a base for saving user setting views or as a way for applications to fine tune forms.
The UISchema is not the best tool to switch layouts (from gallery to cards to table) as it assumes all the components are available
for rendering. To switch layouts, replacing a component repository is a better solution.
Properties of UISchema
| Name | Type | Default Value | Description |
|---|---|---|---|
hints | UIHintsOverrides | {} | Hints to modify |
hints[pointer:string] | UIHints | Hints to modify | |
hints[pointer:string] .order | (string/string[])[] | Defines the desired order and/or layout of the fields to be rendered for an object. It is up to the object component to use the order hints. | |
hints[pointer:string] .hidden | string[] | Defines which fields should be hidden. It is up to the object component to use the hidden hints. | |
hints[pointer:string] .uiGroups | UIGroup[] | Defines field groups. It is up to the object component to support field groups. | |
hints[pointer:string] .uiGroups.name | string | Defines the name of a fields group. | |
hints[pointer:string] .uiGroups.title | string | Defines the title of a fields group. | |
hints[pointer:string] .uiGroups.fields | string[] | Defines which object fields are included in the group. | |
hints[pointer:string] .autoFocus | JSONPointer | Defines which component should be focused when first rendering the form. It is up to the components to implement support for Autofocus. | |
components | RepoPointersCollection | {} | Defines component overrides and component options |
components[name: string] | RepoPointers | The name of the Components Repository to apply the component hints to. | |
compoennts[name: string] [pointer: string] | ComponentOptions | The location in the JSONSchema using JSONPointer to apply the component override | |
compoennts[name: string] [pointer: string].name | string | The name of the component to use at the above location, which has to be available in the above component repository | |
compoennts[name: string] [pointer: string].options | any | Options to pass to the component at the above location |
the components overrides
The components field in UISchema is responsible for component overrides -
defining which component <AutoView/> should choose for a given field and what options this component should get.
By default, <AutoView/> picks last component record registered in the components repository for each type.
When registering two (or more) components for a specific type, the last one will be used by default.
The components overrides defines that for a specific JSONPointer in the data JSONSchema
a component with specific name should be chosen.
the getComponentOptions utility
The getComponentOptions utility function enables a component to extract the component options from the UISchema.
In most cases, it will be used as
export const myFunctionalComponent = props => {
let componentOptions = getComponentOptions(
props.uiSchema!,
props.repositoryName,
props.schemaPointer
)
return (/*... the actual component */)
}
Example - component override and options
In this example we show how to use the components overrides to render texts using one of three text components
- A styled text component, which gets the styles from the component options
- A header text component
- A Default paragraph component
The example shows how to render
- the
titlefield using the header component - the
authorfield using the styled component, with blue text - the
contentfield using the paragraph component - the
statusfield using the styled component, with blue background and white text
The UISchema to use is then
export const uiSchema: UISchema = {
components: {
MyRepo: {
title: {
name: 'headerText'
},
author: {
name: 'styledText',
options: {color: 'blue'}
},
status: {
name: 'styledText',
options: {color: 'white', backgroundColor: 'blue'}
}
}
}
};
Notice there is no need to define that the content field is using the paragraphText as it is the default component for the string type.
Given the components repository
const myRepo = new ComponentsRepo('MyRepo')
.register('string', {
name: 'styledText',
component: props => (
<span
style={getComponentOptions(
props.uiSchema!,
props.repositoryName,
props.schemaPointer
)}
>
{props.data}
</span>
)
})
.register('string', {
name: 'headerText',
component: props => <h1>{props.data}</h1>
})
.register('string', {
name: 'paragraphText',
component: props => <p>{props.data}</p>
});
//... other components;
And given the Schema
const postSchema: CoreSchemaMetaSchema = {
$id: 'post',
type: 'object',
properties: {
title: {
type: 'string',
title: 'Post Title'
},
author: {
type: 'string',
title: 'Author'
},
content: {
type: 'string',
title: 'The Full Comment'
},
status: {
type: 'string',
title: 'Approval Status'
}
}
};
The hints UI hint
The hints member of UI hints defines additional instructions that object components in ComponentsRepo might implement.
The instructions, or hints, are field ordering, field hiding, grouping or autofocus.
The hints UI hint defines that for a specific JSONPointer in the data JSONSchema specific instructions should be applied.
The Hints can be applied in two ways -
- without ui groups
orderdefines fields to be rendered in a specific order, it is also possible to provide 2d array of strings inorderand useorderToTemplateAreasutility for nice use within CSS Grid: examplehiddendefines fields to be hiddenautofocusdefines a field to be autofocused
- with ui groups
uiGroupsdefines a field group. Groups are to be rendered in the order defineduiGroup.namedefines the group nameuiGroup.titledefines the group titleuiGroup.fieldsdefines the fields of the group, to be rendered in the specified order
When using groups, there are two 'special' keys - OTHER_PROPERTIES and UNGROUPED.
OTHER_PROPERTIESis a special 'field' key that signifies a named group includes all properties that are not included in any other groupUNGROUPEDis a special group that includes all properties that are not included in any other group
Example - the order and hidden hints
This example shows how to use the order and hidden hints on the above postSchema schema, to
- order the fields as
title,content,author. - hide the
statusfield.
The UISchema in this case will be
export const uiSchema: UISchema = {
hints: {
'': {
order: ['title', 'content', 'author'],
hidden: ['status']
}
},
components: {
MyRepo: {
title: {
name: 'headerText'
},
author: {
name: 'styledText',
options: {color: 'blue'}
},
status: {
name: 'styledText',
options: {color: 'white', backgroundColor: 'blue'}
}
}
}
};
The repo object component has to support the hidden and order hints - see more about creating object components.
For this example, the object component can be
const myRepo = new ComponentsRepo('MyRepo')
// ... other components
.register('object', {
name: 'MyObjectComponent',
component: props => <AutoFields {...props} />
});
Example - the uiGroups hint
This example shows how to use the uiGroups hint to group fields:
- The
titleandcontentfields as one group - The
authorandstatusfields as a second group.
The example also shows how to build an object component that renders
- The groups separated with an
<hr/>line - The groups with a
<h2>group title based on the group title field.
The UISchema in this case will be
export const uiSchema: UISchema = {
hints: {
'': {
uiGroups: [
{
name: 'group 1',
title: 'The Post',
fields: ['title', 'content']
},
{
name: 'group 2',
title: 'The Post Metadata',
fields: ['author', 'status']
}
]
}
},
components: {
MyRepo: {
title: {
name: 'headerText'
},
author: {
name: 'styledText',
options: {color: 'blue'}
},
status: {
name: 'styledText',
options: {color: 'white', backgroundColor: 'blue'}
}
}
}
};
and the object component will be
const myRepo = new ComponentsRepo('MyRepo')
// ... other components
.register('object', {
name: 'MyObjectComponent',
component: props => {
const {uiGroups} = getHints(props.uiSchema, props.schemaPointer);
if (!uiGroups) {
return <AutoFields {...props} />;
}
return (
<>
{uiGroups.map(group => (
<>
<h2>{group.title}</h2>
<AutoFields
{...props}
pick={
// this utility retrieves `OTHER_PROPERTIES` used in `UIGroups` as well
getPropertiesByGroupName(
uiGroups,
group.name,
Object.keys(props.data)
)
}
/>
<hr />
</>
))}
</>
);
}
});
With the above object component the example
- extracts the
uiGroupsusing thegetHintsutility. - then for each group renders the
<h2>title. - using the
AutoFieldsutility and thepickproperty to only render the fields of that group.- using the
getPropertiesByGroupNameto get the field names of the group, taking into account theOTHER_PROPERTIESandUNGROUPEDkeys.
- using the
the getHints utility
This example shows how to access the order and hidden hints of the UISchema for the current object component to be rendered.
The getHints utility function lookups the hints given the current JSONPointer.
Example - extract the order and hidden hints
The following component will only render the list of hints, not the actual object data.
const myRepo = new ComponentsRepo('MyRepo')
// ... other components
.register('object', {
name: 'MyObjectComponent',
component: props => {
return (
<>
<div>
order list is:
{' ' +
getHints(props.uiSchema, props.schemaPointer).order?.join(', ')}
</div>
<div>
hidden list is:
{' ' +
getHints(props.uiSchema, props.schemaPointer).hidden?.join(', ')}
</div>
</>
);
}
});