AutoViews
AutoViews
AutoViews
is a utility to render generic data forms given a
set of components and data schema.
- no coupling with any components
- based on standarts, like JSONSchema, JSONPatch and JSONPointer
- build with TypeScript
Additional Resources: GitHub, Get Started
AutoViews showcase
import React, {useCallback, useMemo, useState} from 'react'; import {applyPatch} from 'fast-json-patch'; import { AutoView, ComponentsRepo, RepositoryProvider, UISchema } from '@autoviews/core'; import { Box, Button, ButtonGroup, Card, CardContent, FormControl, InputLabel, MenuItem, Select, SelectChangeEvent, Divider, CardHeader } from '@mui/material'; import {availableUISchemas} from './uiSchemas'; import './styles.css'; import {dataStore, SchemaNames, schemas} from './Data'; import {MUIFormRepo, MUITableRepo} from './MUIRepos'; import {BootstrapFormRepo, BootstrapTableRepo} from './BootstrapRepos'; export default function App() { // data const [data, setData] = useState<any[]>(dataStore.user); // JSON Schema const [schemaName, setSchemaName] = useState('user'); const schema = useMemo(() => schemas[schemaName], [schemaName]); // UI Schema const [tableUISchemaName, setTableUISchemaName] = useState('Default'); const [formUISchemaName, setFormUISchemaName] = useState('Default'); const [[formUISchema, tableUISchema], setUISchemas] = useState< [UISchema, UISchema] >([ availableUISchemas['user'].form[formUISchemaName], availableUISchemas['user'].table[tableUISchemaName] ]); // Item to be edited in the form const [item, setItem] = useState<any>({}); const onSchemaChange = useCallback((e: SelectChangeEvent<string>) => { const name = e.target.value as SchemaNames; setSchemaName(name); setData(dataStore[name]); setTableUISchemaName('Default'); setFormUISchemaName('Default'); setUISchemas([ availableUISchemas[name].form['Default'], availableUISchemas[name].table['Default'] ]); }, []); const onTableUISchemaChange = useCallback( (e: SelectChangeEvent<string>) => { const name = e.target.value as string; setTableUISchemaName(name); setUISchemas([ formUISchema, availableUISchemas[schemaName].table[name] ]); }, [formUISchema, schemaName] ); const onFormUISchemaChange = useCallback( (e: SelectChangeEvent<string>) => { const name = e.target.value as string; setFormUISchemaName(name); setUISchemas([ availableUISchemas[schemaName].form[name], tableUISchema ]); }, [tableUISchema, schemaName] ); const onFormChange = useCallback( (_: any, {patch}) => { setItem({...applyPatch(item, patch).newDocument}); }, [setItem, item] ); const [tableRepo, setTableRepo] = useState<ComponentsRepo>(MUITableRepo); const [formRepo, setFormRepo] = useState<ComponentsRepo>(MUIFormRepo); const onSetRepo = useCallback( (name: 'mui' | 'bootstrap') => { switch (name) { case 'mui': setTableRepo(MUITableRepo); setFormRepo(MUIFormRepo); break; case 'bootstrap': setTableRepo(BootstrapTableRepo); setFormRepo(BootstrapFormRepo); break; } }, [setTableRepo, setFormRepo] ); const onAddItem = useCallback( (_, e) => { switch (e.data.action) { case 'SAVE': setData([...data, item]); setItem({}); break; } }, [item, data] ); interface DropdownProps { id: string; title: string; value: string; values: string[]; onChange: (e: SelectChangeEvent<string>) => void; } const Dropdown = ({id, title, value, values, onChange}: DropdownProps) => { return ( <FormControl sx={{width: '140px', margin: '0 10px'}}> <InputLabel id={`${id}-select-label`}>{title}</InputLabel> <Select labelId={`${id}-select-label`} id={`${id}-select`} value={value} label={title} onChange={onChange} > {values.map(key => ( <MenuItem value={key} key={key} > {key} </MenuItem> ))} </Select> </FormControl> ); }; return ( <div className="App"> <Box style={{margin: '0 20px'}}> <Card sx={{margin: '20px 0'}}> <CardHeader title="Controls" subheader="Change UI Library, Schema or UI Schema" /> <Divider /> <CardContent> <ButtonGroup aria-label="outlined button group"> <Button onClick={() => onSetRepo('mui')} variant={ tableRepo === MUITableRepo ? 'contained' : 'outlined' } > Mateial UI </Button> <Button onClick={() => onSetRepo('bootstrap')} variant={ tableRepo === BootstrapTableRepo ? 'contained' : 'outlined' } > Bootstrap </Button> <Dropdown id={'schema'} title={'Schema'} value={schemaName} values={Object.keys(schemas)} onChange={onSchemaChange} /> </ButtonGroup> </CardContent> </Card> <Card variant="outlined"> <CardHeader title="Table" subheader="First instance of AutoView" action={ <Dropdown id={'table-ui-schema'} title={'Table UI Schema'} value={tableUISchemaName} values={Object.keys( availableUISchemas[schemaName].table )} onChange={onTableUISchemaChange} /> } /> <Divider /> <CardContent> <RepositoryProvider components={tableRepo}> <AutoView schema={schema} data={data} uiSchema={tableUISchema} /> </RepositoryProvider> </CardContent> </Card> <Card variant="outlined" sx={{margin: '20px 0'}} > <CardHeader title="Form" subheader="Second instance of AutoView" action={ <Dropdown id={'form-ui-schema'} title={'Form UI Schema'} value={formUISchemaName} values={Object.keys( availableUISchemas[schemaName].form )} onChange={onFormUISchemaChange} /> } /> <Divider /> <CardContent> <RepositoryProvider components={formRepo}> <AutoView data={item} uiSchema={formUISchema} schema={schema.items!} onChange={onFormChange} onClick={onAddItem} /> </RepositoryProvider> </CardContent> </Card> </Box> </div> ); }
The Elements of AutoViews
‘AutoViews’ renders UI by combining 4 elements
Your Components
AutoViews Repository serves as a map of data types to the components to be used when rendering data of that type. The library does not include the actual components, rather it allows injecting different React component libraries such as material UI or others.
More about the Components Repository
Your Data Schema
JSON Schema that describes your data. The schema provides nested structure, field types, titles and descriptions as well as constraints such as min, max, required.
More about the Data JSONSchema
Your Data
AutoViews interact with data using two properties - the
data
property and theonChange
event, which provide a unified data and events model regardless of the nesting level, data type or control used.More about the AutoView Data property and the Events model
Your UI Schema
The UI Schema adds another layer of hints that can be used by components to fine tune the rendered UI. UI Schema includes field ordering/layouting, grouping, component selection, field hiding and auto focus hints.
More about the UI Schema