Skip to main content

Placeholder

Centered empty-state block — a graphic, a title, a description, and an optional action. Use it for empty lists, "no results" states, offline/error screens, and onboarding prompts.

Basic Usage​

import { Button, Icon, Placeholder } from '@multinaire/expo-ui';

function Example() {
return (
<Placeholder
flex={1}
graphic={<Icon icon="Box" size={64} color="neutral" />}
title="Nothing here yet"
description="Items you create will show up on this screen."
action={<Button title="Create item" onPress={handleCreate} />}
/>
);
}

Props​

PropTypeDefaultDescription
flexnumber—Flex grow value. Pass 1 to fill the remaining space of the parent and center the content vertically within it
paddingSpacingProps—Inner padding. Accepts a number for uniform padding, or an object for per-side control
textAlignment'left' | 'center' | 'right''center'Alignment of the title and description, and of the block's content within its own width
graphicReactElement—Required. Element rendered above the text — typically an Icon, Photo, or an illustration
titleTranslationKey—Required. Headline text describing the empty or error state
descriptionTranslationKey—Required. Supporting text explaining the state or what to do next
actionReactElement—Element rendered below the text — typically a Button offering the primary recovery action

Examples​

Empty List​

Render it in place of the list once the data resolves to an empty array.

function Contacts() {
const { data, isLoading } = useContacts();

if (!isLoading && data.length === 0) {
return (
<Placeholder
flex={1}
padding={variables.padding.large}
graphic={<Icon icon="Profile2User" size={64} color="neutral" />}
title="No contacts"
description="Add your first contact to get started."
action={<Button title="Add contact" onPress={openAddContact} />}
/>
);
}

return <ListContainer data={data} renderItem={renderContact} />;
}

No Search Results​

An action isn't always needed — leave action off when there's nothing useful to offer.

<Placeholder
flex={1}
graphic={<Icon icon="SearchNormal1" size={64} color="neutral" />}
title="No results"
description="Try a different search term."
/>

Error State​

<Placeholder
flex={1}
graphic={<Icon icon="CloseCircle" size={64} color="error" />}
title="Something went wrong"
description="We couldn't load this page. Check your connection and try again."
action={<Button type="secondary" title="Retry" onPress={refetch} />}
/>

Left-Aligned​

Pass textAlignment="left" when the placeholder sits inside a form or a left-aligned content column, so its text lines up with the surrounding copy.

<Placeholder
textAlignment="left"
graphic={<Icon icon="DocumentText" size={48} color="neutral" />}
title="No attachments"
description="Files you upload will be listed here."
/>

With an Illustration​

graphic accepts any element, so a Photo or a custom SVG works just as well as an Icon.

<Placeholder
flex={1}
graphic={
<Photo
source={require('../assets/empty-inbox.png')}
width={200}
height={160}
/>
}
title="Inbox zero"
description="You're all caught up."
/>

Inside a Card​

Without flex, the placeholder shrinks to its content — useful for an empty section inside a larger screen.

<Card padding={variables.padding.large}>
<Placeholder
graphic={<Icon icon="Chart" size={48} color="neutral" />}
title="No data for this period"
description="Pick a different date range to see results."
/>
</Card>

Notes​

  • Content is capped at BREAKPOINTS.mobile (640px) wide and centered in its parent, so the text stays readable on tablets and on the web instead of stretching across the full viewport.
  • title and description are TranslationKeys — they're passed through Typography, so string literals are translated automatically via the LocalizationProvider.
  • The title renders as subheading / bold and the description as title in the neutral color; both follow textAlignment.
  • Without flex, the block sizes to its content. Pass flex={1} to have it fill the remaining space of its parent — the usual choice when it replaces a full-screen list.
  • The graphic is always horizontally centered, whatever textAlignment is set to.
  • textAlignment also drives the block's own alignItems: 'center' centers, 'right' aligns to the end, and anything else ('left', 'auto', 'justify') aligns to the start.