Skip to main content

Layout

It is possible to define and persist layout settings using order field in UIHints.

By default order is an array of strings, simply defining order of fields in the object type.

However order could be also a mix of strings and strings arrays. Like ['field-1', ['field-2', 'field-4'], 'field-3']. It is very neat to convert that type of defining the order into CSS Grid definitions, specifically grid-template-areas and then, when rendering children it becomes easy to set grid-area style with the current field name.

Examples

import React from 'react';
import {
    RepositoryProvider,
    AutoView,
    CoreSchemaMetaSchema,
    getHints,
    orderToTemplateAreas
} from '@autoviews/core';

import {data} from './data';
import schema from './schema.json';
import {repo} from './repo';
import {userUISchema} from './UISchema';

const layoutStyles = `
.root {
    display: grid;
    grid-template-columns: auto;
    grid-template-rows: 1fr;
    gap: 1rem;
    align-items: stretch;
}

.child {
    padding: 5px;
    border: 1px solid gray;
}
`;
const layoutedRepo = repo
    .clone('LayoutRepo')
    .addWrapper(
        (item, props) => {
            const {order} = getHints(props.uiSchema, props.pointer);
            return (
                <>
                    <style>{layoutStyles}</style>
                    <div
                        className="root"
                        style={{gridTemplateAreas: orderToTemplateAreas(order)}}
                    >
                        {item}
                    </div>
                </>
            );
        },
        {include: ['MyObject']}
    )
    .addWrapper(
        (item, props) => {
            return (
                <div
                    style={{gridArea: props.field}}
                    className="child"
                >
                    {props.field + ': '}
                    <strong>{item}</strong>
                </div>
            );
        },
        {exclude: ['MyObject']}
    );

export default function App() {
    return (
        <RepositoryProvider components={layoutedRepo}>
            <AutoView
                schema={schema as CoreSchemaMetaSchema}
                data={data}
                uiSchema={userUISchema}
            />
        </RepositoryProvider>
    );
}

@autoviews/core provides orderToTemplateAreas utility:

const gridTemplateAreas = orderToTemplateAreas([
'field-1',
['field-2', 'field-4'],
'field-3'
]);

/**
Result
'"field-1 field-1"
"field-2 field-4"
"field-3 field-3"'
*/

It consider some edge cases

const gridTemplateAreas = orderToTemplateAreas([
['field-1', 'field-3'][('field-1', 'field-2', 'field-4')]
]);

/**
Result
'"field-1 field-3 ."
"field-1 field-2, field-4"'
*/

And of course you can use '.':

const gridTemplateAreas = orderToTemplateAreas([
['field-1', '.', 'field-2']
'field-3'
])

/**
Result
'"field-1 . field-2"
"field-3 field-3, field-3"'
*/