<SimpleShowLayout>

The <SimpleShowLayout> pulls the record from the RecordContext. It renders the record fields in a single-column layout (via Material UI’s <Stack> component). <SimpleShowLayout> delegates the actual rendering of fields to its children. It wraps each field inside a <Labeled> component to add a label.

Simple Show Layout

Usage

Use <SimpleShowLayout> as descendant of a <Show> component (or any component creating a <RecordContext>), and set the fields to be displayed as children:

const PostShow = () => (
    <Show>
        <SimpleShowLayout>
            <TextField source="title" />
            <RichTextField source="body" />
            <NumberField source="nb_views" />
        </SimpleShowLayout>
    </Show>
);

Props

The <SimpleShowLayout> component accepts the following props:

Prop Required Type Default Description
children Required ReactNode Β  The components rendering the record fields
className Optional string Β  The class name applied to the root element
direction Optional string column The direction of the layout. Passed to the <Stack> component
divider Optional ReactElement Β  Optional element to render between each field
record Optional object Β  The record to render. Passed to the RecordContext
spacing Optional number 1 The spacing between fields. Passed to the <Stack> component
sx Optional object Β  Override the styles applied to the root element

Additional props are passed to the root component (<div>).

children

<SimpleShowLayout> renders each child inside a <Labeled> component. The above snippet roughly translates to:

const PostShow = () => (
    <Show>
        <Stack>
            <Labeled label="Title">
                <TextField source="title" />
            </Labeled>
            <Labeled label="Body">
                <RichTextField source="body" />
            </Labeled>
            <Labeled label="Nb Views">
                <NumberField source="nb_views" />
            </Labeled>
        </Stack>
    </Show>
);

The <Labeled label> uses the humanized source by default. You can customize it by passing a label prop to the fields:

const PostShow = () => (
    <Show>
        <SimpleShowLayout>
            <TextField label="My Custom Title" source="title" />
            <TextField label="my.custom.translationKey" source="description" />
        </SimpleShowLayout>
    </Show>
);

// translates to
const PostShow = () => (
    <Show>
        <Stack>
            <Labeled label="My Custom Title">
                <TextField source="title" />
            </Labeled>
            <Labeled label="my.custom.translationKey">
                <TextField source="description" />
            </Labeled>
        </Stack>
    </Show>
);

You can disable the <Labeled> decoration by passing setting label={false} on a field:

const PostShow = () => (
    <Show>
        <SimpleShowLayout>
            <TextField label={false} source="title" />
        </SimpleShowLayout>
    </Show>
);

// translates to
const PostShow = () => (
    <Show>
        <Stack>
            <TextField source="title" />
        </Stack>
    </Show>
);

<SimpleShowLayout> children can be anything you want. Try passing your own components:

const PostTitle = () => {
    const record = useRecordContext();
    return <span>Post "{record.title}"</span>;
};

const PostShow = () => (
    <Show>
        <SimpleShowLayout>
            <PostTitle label="title" />
        </SimpleShowLayout>
    </Show>
);

spacing

<SimpleShowLayout> renders a Material UI <Stack>. You can customize the spacing of each row by passing a spacing prop:

const PostShow = () => (
    <Show>
        <SimpleShowLayout spacing={2}>
            <PostTitle label="title" />
        </SimpleShowLayout>
    </Show>
);

The default spacing is 1.

direction

<SimpleShowLayout> renders a Material UI <Stack>. You can customize the direction of the layout by passing a direction prop:

const PostShow = () => (
    <Show>
        <SimpleShowLayout direction="row">
            <PostTitle label="title" />
            <PostTitle label="author" />
            <PostTitle label="published_at" />
        </SimpleShowLayout>
    </Show>
);

divider

<Stack> accepts an optional divider prop - a component rendered between each row. <SimpleShowLayout> also accepts this props, and passes it to the <Stack> component.

import { Divider } from '@mui/material';

const PostShow = () => (
    <Show>
        <SimpleShowLayout divider={<Divider flexItem />}>
            <PostTitle label="title" />
        </SimpleShowLayout>
    </Show>
);

sx: CSS API

The <SimpleShowLayout> component accepts the usual className prop, but you can override many class names injected to the inner components by React-admin thanks to the sx property (see the sx documentation for syntax and examples). This property accepts the following subclasses:

Rule name Description
& .RaSimpleShowLayout-stack Applied to the <Stack> element
& .RaSimpleShowLayout-row Applied to each child of the stack (i.e. to each field)

To override the style of all instances of <SimpleShowLayout> using the application-wide style overrides, use the RaSimpleShowLayout key.

Controlled Mode

By default, <SimpleShowLayout> reads the record from the ResourceContext. But by passing a record prop, you can render the component outside a ResourceContext.

const StaticPostShow = () => (
    <SimpleShowLayout record={{ id: 123, title: 'Hello world' }}>
        <TextField source="title" />
    </SimpleShowLayout>
);

When passed a record, <SimpleShowLayout> creates a RecordContext with the given record.

Rendering More Than One Column

<SimpleShowLayout> arranges fields with labels in a single column. If you need more than one column, you can use this component several times, for instance in a grid:

const BookShow = () => (
    <Show>
        <Grid container spacing={2}>
            <Grid item xs={6}>
                <SimpleShowLayout>
                    <TextField source="id" />
                    <TextField source="title" />
                </SimpleShowLayout>
            </Grid>
            <Grid item xs={6}>
                <SimpleShowLayout>
                    <TextField source="author" />
                    <TextField source="summary" />
                    <NumberField source="year" />
                </SimpleShowLayout>
            </Grid>
        </Grid>
    </Show>
);

You can also nest <SimpleShowLayout> components with different direction props to create complex layouts:

const BookShow = () => (
    <Show>
        <SimpleShowLayout>
            <TextField source="title" />
            <TextField source="summary" />
            <SimpleShowLayout direction="row">
                <TextField source="author" />
                <TextField source="category" />
                <NumberField source="year" />
            </SimpleShowLayout>
        </SimpleShowLayout>
    </Show>
);

Hiding The Field Labels

You can disable the <Labeled> decoration added by <SimpleShowLayout> by setting label={false} on a field:

const PostShow = () => (
    <Show>
        <SimpleShowLayout>
            <TextField label={false} source="title" />
        </SimpleShowLayout>
    </Show>
);

Access Control

If you need to hide some fields based on a set of permissions, use the <SimpleShowLayout> component from the @react-admin/ra-rbac package.

-import { SimpleShowLayout } from 'react-admin';
+import { SimpleShowLayout } from '@react-admin/ra-rbac';

This component adds the following RBAC controls:

  • To see a column, the user must have the β€œread” permission on the resource column:
{ action: "read", resource: `${resource}.${source}` }
// Or
{ action: "read", resource: `${resource}.*` }

Here is an example of how to use the <SimpleShowLayout> component with RBAC:

import { SimpleShowLayout } from '@react-admin/ra-rbac';

const authProvider = {
    // ...
    canAccess: async ({ action, record, resource }) =>
        canAccessWithPermissions({
            permissions: [
                { action: ['list', 'show'], resource: 'products' },
                { action: 'read', resource: 'products.reference' },
                { action: 'read', resource: 'products.width' },
                { action: 'read', resource: 'products.height' },
                // 'products.description' is missing
                // 'products.image' is missing
                { action: 'read', resource: 'products.thumbnail' },
                // 'products.stock' is missing
            ],
            action,
            record,
            resource,
        }),
};

const ProductShow = () => (
    <Show>
        <SimpleShowLayout>
            {/* └── RBAC SimpleShowLayout */}
            <TextField source="reference" />
            <TextField source="width" />
            <TextField source="height" />
            {/* not displayed */}
            <TextField source="description" />
            {/* not displayed */}
            <TextField source="image" />
            <TextField source="thumbnail" />
            {/* not displayed */}
            <TextField source="stock" />
        </SimpleShowLayout>
    </Show>
);

See Also

API