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
- theAutoViewProps
used 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
: theJSONPointer
to 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 arefield
ortitle
; by using it, you define what should be used as header value, either object's property name or schema'stitle
field 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> ); }