Creating Array components
AutoViews does not come with pre-made components to render arrays (doing so will defeat the idea of using your own components). However, AutoViews provides utilities and APIs to create your own components to render arrays.
The simplest array component will be
new ComponentsRepo('ArrayRepo').register('array', {
name: 'tableComponent',
component: props => <AutoItems {...props} />
});
AutoItems
AutoItems is a utility element used to render the elements of the array.
Internally it apply AutoViews for each of the items of the array.
It can be used with array of objects, strings, numbers or other types, including mixed type arrays, delegating
to AutoViews to render the actual item.
AutoItems props
- extending
AutoViewProps- getting the same properties asAutoViews render- optional callback to apply to each of the rendered array elements
the render function
declare function render(
item: React.ReactNode,
props: AutoViewProps,
index: number
): React.ReactNode;
The render callback parameters
item- the rendered item, rendered usingAutoViews.props- theAutoViewPropsused to render the item.index- the index of the item in the array
Example - rendering a plain list
new ComponentsRepo('ArrayRepo').register('array', {
name: 'tableComponent',
component: props => <AutoItems {...props} />
});
Example - rendering an HTML list
This example renders an HTML list.
The example is using AutoItems.render to wrap the per item element (node below) with the list <li> element.
new ComponentsRepo('ArrayRepo').register('array', {
name: 'tableComponent',
component: props => (
<ul>
<AutoItems
{...props}
render={node => <li>node</li>}
></AutoItems>
</ul>
)
});
Example - rending an HTML table
Assuming out data has the form Array<object>,
This example renders the table using AutoItems which delegates to AutoViews to render
the object. AutoViews will then use the tablrRowComponent, which renders the <tr> element
and is using the AutoFields to render the members of the object.
the example is also using the AutoFields.render property to wrap the fields controls with <td> elements.
new ComponentsRepo('ArrayRepo')
.register('array', {
name: 'tableComponent',
component: props => (
<table>
<tbody>
<AutoItems {...props} />
</tbody>
</table>
)
})
.register('object', {
name: 'tableRowComponent',
component: props => (
<tr>
<AutoFields
{...props}
render={node => <td>node</td>}
/>
</tr>
)
});
Example - rending an HTML Table with headers (AutoHeaders)
While rendering an array of objects as a table, displaying a proper header based on JSONSchema is tricky. First, you must extract the title from each node or the object's field name.
Moreover, it is needed to consider all structural rules applied for that schema, like UIHints or pick and omit properties.
It was inconvenient to do it manually, even though we provided utils to extract UIHints and order fields according to rules. So we are introducing the AutoHeaders component.
AutoHeaders
To render a table with a header, you can find the AutoHeaders helpful component.
This component requires you to path AutoViewProps and an optional:
path: theJSONPointerto object schema relative to itsprops.schema; if your schema type isarray, then you might want to path/items. The default value is root:''.useAsValue: possible values arefieldortitle; by using it, you define what should be used as header value, either object's property name or schema'stitlefield value.
The children type is (props: AutoViewProps) => JSX.Element;.
A function that would get a new AutoViewProps as an argument and would contain data as an string[] and a new JSONSchema for an array of strings.
// Having this schema
const schema: CoreSchemaMetaSchema = {
type: 'object',
properties: {
foo: {type: 'string', title: 'Foo'},
bar: {type: 'string', title: 'Bar'},
baz: {type: 'number', title: 'Baz'}
}
//...
<AutoHeaders schema={schema}>
{props => {
/*
* The new `props.data` would be `['Foo', 'Bar', 'Baz']`.
* And the new `props.schema` would complement this data
*/
return <AutoItems {...props} />
}}
</AutoHeaders>
Let's look at full example of table with header.
import React from 'react';
import {
RepositoryProvider,
AutoView,
CoreSchemaMetaSchema
} from '@autoviews/core';
import {data} from './data';
import schema from './schema.json';
import {repo} from './repo';
import {userUISchema} from './UISchema';
export default function App() {
return (
<RepositoryProvider components={repo}>
<AutoView
schema={schema as CoreSchemaMetaSchema}
data={data}
uiSchema={userUISchema}
/>
</RepositoryProvider>
);
}