Empty State
<sl-empty-state> | SlEmptyState
Displays a centered empty state with optional icon or image, headline, and message. Content is set via properties only.
Content properties (icon, imageSrc, headline, message)
are property-only and are not available as HTML attributes. In plain HTML, assign them with
JavaScript as shown in the examples below. Use the variant attribute to align
content — centered (default), left, or right.
<sl-empty-state id="empty-state-demo"></sl-empty-state> <script type="module"> Object.assign(document.getElementById('empty-state-demo'), { icon: 'mdi:inbox-outline', headline: 'No items yet', message: 'Add your first item to get started.' }); </script>
import SlEmptyState from '@yoummday/ymmd-shoelace/dist/react/empty-state'; const App = () => ( <SlEmptyState icon="mdi:inbox-outline" headline="No items yet" message="Add your first item to get started." /> );
Examples
Set only the properties you need. Each content prop is independent — if it is not set, that section is not
rendered. Use icon or imageSrc, not both; only one graphic is shown at a time. When headline is set, it is used as the image
alt text and the icon aria-label.
Variants
Use the variant attribute to horizontally align the icon or image, headline, and message.
Accepts centered (default), left, or right.
<div class="empty-state-variants"> <div> <sl-txt span>Centered</sl-txt> <sl-empty-state id="empty-state-centered"></sl-empty-state> </div> <div> <sl-txt span>Left</sl-txt> <sl-empty-state id="empty-state-left" variant="left"></sl-empty-state> </div> <div> <sl-txt span>Right</sl-txt> <sl-empty-state id="empty-state-right" variant="right"></sl-empty-state> </div> </div> <script type="module"> for (const id of ['empty-state-centered', 'empty-state-left', 'empty-state-right']) { Object.assign(document.getElementById(id), { icon: 'mdi:inbox-outline', headline: 'No items yet', message: 'Add your first item to get started.' }); } </script> <style> .empty-state-variants { display: grid; grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); gap: var(--sl-spacing-large); width: 100%; } .empty-state-variants > div { display: flex; flex-direction: column; gap: var(--sl-spacing-x-small); } </style>
import SlEmptyState from '@yoummday/ymmd-shoelace/dist/react/empty-state'; const props = { icon: 'mdi:inbox-outline', headline: 'No items yet', message: 'Add your first item to get started.' }; const App = () => ( <> <SlEmptyState {...props} /> <SlEmptyState {...props} variant="left" /> <SlEmptyState {...props} variant="right" /> </> );
With image
When icon is not set, set the imageSrc property with a URL. If both are set,
icon takes precedence. Images are displayed at 160×160px by default; icons
render at 52px.
<sl-empty-state id="empty-state-image-demo"></sl-empty-state> <script type="module"> Object.assign(document.getElementById('empty-state-image-demo'), { imageSrc: 'https://picsum.photos/160', headline: 'No results', message: 'Try adjusting your filters.' }); </script>
Override the graphic size with the graphic CSS part.
<sl-empty-state id="empty-state-image-size" class="empty-state-image-size"></sl-empty-state> <script type="module"> Object.assign(document.getElementById('empty-state-image-size'), { imageSrc: 'https://picsum.photos/160', headline: 'No results', message: 'Try adjusting your filters.' }); </script> <style> .empty-state-image-size::part(graphic) { width: 6rem; height: 6rem; } </style>
import SlEmptyState from '@yoummday/ymmd-shoelace/dist/react/empty-state'; const css = ` .empty-state-image-size::part(graphic) { width: 6rem; height: 6rem; } `; const App = () => ( <> <style>{css}</style> <SlEmptyState className="empty-state-image-size" imageSrc="https://picsum.photos/160" headline="No results" message="Try adjusting your filters." /> </> );
Layout
The host applies padding-block: var(--sl-spacing-large) and a default
min-height of 8rem. Use --empty-state-min-height to override the
minimum height, and padding-block to override block padding.
<sl-empty-state id="empty-state-layout-demo" class="empty-state-layout-demo"></sl-empty-state> <script type="module"> Object.assign(document.getElementById('empty-state-layout-demo'), { icon: 'mdi:inbox-outline', headline: 'No items yet', message: 'Add your first item to get started.' }); </script> <style> .empty-state-layout-demo { --empty-state-min-height: 12rem; padding-block: var(--sl-spacing-2x-large); } </style>
import SlEmptyState from '@yoummday/ymmd-shoelace/dist/react/empty-state'; const App = () => ( <SlEmptyState icon="mdi:inbox-outline" headline="No items yet" message="Add your first item to get started." style={{ '--empty-state-min-height': '12rem', paddingBlock: 'var(--sl-spacing-2x-large)' }} /> );
No content
When no properties are set, nothing is rendered inside the component. The host still reserves space via its default 8rem min-height and block padding.
<sl-empty-state></sl-empty-state>
import SlEmptyState from '@yoummday/ymmd-shoelace/dist/react/empty-state'; const App = () => <SlEmptyState />;
Single property
<div class="empty-state-combos"> <div> <sl-txt span>Icon only</sl-txt> <sl-empty-state id="empty-state-icon-only"></sl-empty-state> </div> <div> <sl-txt span>Image only</sl-txt> <sl-empty-state id="empty-state-image-only"></sl-empty-state> </div> <div> <sl-txt span>Headline only</sl-txt> <sl-empty-state id="empty-state-headline-only"></sl-empty-state> </div> <div> <sl-txt span>Message only</sl-txt> <sl-empty-state id="empty-state-message-only"></sl-empty-state> </div> </div> <script type="module"> Object.assign(document.getElementById('empty-state-icon-only'), { icon: 'mdi:inbox-outline' }); Object.assign(document.getElementById('empty-state-image-only'), { imageSrc: 'https://picsum.photos/160' }); Object.assign(document.getElementById('empty-state-headline-only'), { headline: 'No items yet' }); Object.assign(document.getElementById('empty-state-message-only'), { message: 'Add your first item to get started.' }); </script> <style> .empty-state-combos { display: grid; grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr)); gap: var(--sl-spacing-large); width: 100%; } .empty-state-combos > div { display: flex; flex-direction: column; align-items: center; gap: var(--sl-spacing-x-small); } </style>
import SlEmptyState from '@yoummday/ymmd-shoelace/dist/react/empty-state'; const App = () => ( <> <SlEmptyState icon="mdi:inbox-outline" /> <SlEmptyState imageSrc="https://picsum.photos/160" /> <SlEmptyState headline="No items yet" /> <SlEmptyState message="Add your first item to get started." /> </> );
Pairs
<div class="empty-state-combos"> <div> <sl-txt span>Icon + headline</sl-txt> <sl-empty-state id="empty-state-icon-headline"></sl-empty-state> </div> <div> <sl-txt span>Icon + message</sl-txt> <sl-empty-state id="empty-state-icon-message"></sl-empty-state> </div> <div> <sl-txt span>Image + headline</sl-txt> <sl-empty-state id="empty-state-image-headline"></sl-empty-state> </div> <div> <sl-txt span>Image + message</sl-txt> <sl-empty-state id="empty-state-image-message"></sl-empty-state> </div> <div> <sl-txt span>Headline + message</sl-txt> <sl-empty-state id="empty-state-headline-message"></sl-empty-state> </div> </div> <script type="module"> Object.assign(document.getElementById('empty-state-icon-headline'), { icon: 'mdi:inbox-outline', headline: 'No items yet' }); Object.assign(document.getElementById('empty-state-icon-message'), { icon: 'mdi:inbox-outline', message: 'Add your first item to get started.' }); Object.assign(document.getElementById('empty-state-image-headline'), { imageSrc: 'https://picsum.photos/160', headline: 'No results' }); Object.assign(document.getElementById('empty-state-image-message'), { imageSrc: 'https://picsum.photos/160', message: 'Try adjusting your filters.' }); Object.assign(document.getElementById('empty-state-headline-message'), { headline: 'Nothing here', message: 'Content will appear when data is available.' }); </script> <style> .empty-state-combos { display: grid; grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr)); gap: var(--sl-spacing-large); width: 100%; } .empty-state-combos > div { display: flex; flex-direction: column; align-items: center; gap: var(--sl-spacing-x-small); } </style>
import SlEmptyState from '@yoummday/ymmd-shoelace/dist/react/empty-state'; const App = () => ( <> <SlEmptyState icon="mdi:inbox-outline" headline="No items yet" /> <SlEmptyState icon="mdi:inbox-outline" message="Add your first item to get started." /> <SlEmptyState imageSrc="https://picsum.photos/160" headline="No results" /> <SlEmptyState imageSrc="https://picsum.photos/160" message="Try adjusting your filters." /> <SlEmptyState headline="Nothing here" message="Content will appear when data is available." /> </> );
Triples
<div class="empty-state-combos"> <div> <sl-txt span>Icon + headline + message</sl-txt> <sl-empty-state id="empty-state-icon-all"></sl-empty-state> </div> <div> <sl-txt span>Image + headline + message</sl-txt> <sl-empty-state id="empty-state-image-all"></sl-empty-state> </div> </div> <script type="module"> Object.assign(document.getElementById('empty-state-icon-all'), { icon: 'mdi:inbox-outline', headline: 'No items yet', message: 'Add your first item to get started.' }); Object.assign(document.getElementById('empty-state-image-all'), { imageSrc: 'https://picsum.photos/160', headline: 'No results', message: 'Try adjusting your filters.' }); </script> <style> .empty-state-combos { display: grid; grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr)); gap: var(--sl-spacing-large); width: 100%; } .empty-state-combos > div { display: flex; flex-direction: column; align-items: center; gap: var(--sl-spacing-x-small); } </style>
import SlEmptyState from '@yoummday/ymmd-shoelace/dist/react/empty-state'; const App = () => ( <> <SlEmptyState icon="mdi:inbox-outline" headline="No items yet" message="Add your first item to get started." /> <SlEmptyState imageSrc="https://picsum.photos/160" headline="No results" message="Try adjusting your filters." /> </> );
With table and card
Use a card to frame a table and render the empty state below the column headers when there are no rows to show.
<sl-card class="empty-state-table-card"> <div slot="header"> <sl-txt h3>Team members</sl-txt> </div> <sl-table> <sl-table-row slot="head"> <sl-table-cell>Name</sl-table-cell> <sl-table-cell>Email</sl-table-cell> <sl-table-cell>Role</sl-table-cell> </sl-table-row> </sl-table> <sl-empty-state id="empty-state-table-demo"></sl-empty-state> </sl-card> <script type="module"> Object.assign(document.getElementById('empty-state-table-demo'), { icon: 'mdi:account-group-outline', headline: 'No team members yet', message: 'Invite colleagues to collaborate on this project.' }); </script> <style> .empty-state-table-card { width: 100%; } .empty-state-table-card::part(body) { display: flex; flex-direction: column; padding: 0; } .empty-state-table-card sl-empty-state { --empty-state-min-height: 12rem; } </style>
import SlCard from '@yoummday/ymmd-shoelace/dist/react/card'; import SlEmptyState from '@yoummday/ymmd-shoelace/dist/react/empty-state'; import SlTable from '@yoummday/ymmd-shoelace/dist/react/table'; import SlTableCell from '@yoummday/ymmd-shoelace/dist/react/table-cell'; import SlTableRow from '@yoummday/ymmd-shoelace/dist/react/table-row'; import SlTxt from '@yoummday/ymmd-shoelace/dist/react/txt'; const css = ` .empty-state-table-card { width: 100%; } .empty-state-table-card::part(body) { display: flex; flex-direction: column; padding: 0; } .empty-state-table-card sl-empty-state { --empty-state-min-height: 12rem; } `; const App = () => ( <> <style>{css}</style> <SlCard className="empty-state-table-card"> <div slot="header"> <SlTxt h3>Team members</SlTxt> </div> <SlTable> <SlTableRow slot="head"> <SlTableCell>Name</SlTableCell> <SlTableCell>Email</SlTableCell> <SlTableCell>Role</SlTableCell> </SlTableRow> </SlTable> <SlEmptyState icon="mdi:account-group-outline" headline="No team members yet" message="Invite colleagues to collaborate on this project." /> </SlCard> </> );
Importing
If you’re using the autoloader or the traditional loader, you can ignore this section. Otherwise, feel free to use any of the following snippets to cherry pick this component.
To import this component from the CDN using a script tag:
<script type="module" src="https://v3-10-10.yoummday-theme.pages.dev/components/empty-state/empty-state.js"></script>
To import this component from the CDN using a JavaScript import:
import 'https://v3-10-10.yoummday-theme.pages.dev/components/empty-state/empty-state.js';
To import this component using a bundler:
import '@yoummday/ymmd-shoelace/dist/components/empty-state/empty-state.js';
To import this component as a React component:
import SlEmptyState from '@yoummday/ymmd-shoelace/dist/react/empty-state';
Properties
| Name | Description | Reflects | Type | Default |
|---|---|---|---|---|
icon
|
The icon to show, passed to <sl-icon name="...">. Use icon or
imageSrc, not both. Omitted when empty.
|
string
|
''
|
|
imageSrc
|
Image src URL. Use icon or imageSrc, not both. Omitted when
empty.
|
string
|
''
|
|
headline
|
The headline text. Omitted when empty. Also used as the image alt and icon
aria-label when set.
|
string
|
''
|
|
message
|
The message text shown below the headline. Omitted when empty. |
string
|
''
|
|
variant
|
Aligns the empty state content. Accepts centered, left, or
right.
|
|
'centered' | 'left' | 'right'
|
'centered'
|
updateComplete |
A read-only promise that resolves when the component has finished updating. |
Learn more about attributes and properties.
Custom Properties
| Name | Description | Default |
|---|---|---|
--empty-state-min-height |
The minimum height of the host. | 8rem |
Learn more about customizing CSS custom properties.
Parts
| Name | Description |
|---|---|
content |
The container for the empty state content. |
graphic |
The wrapper around the icon or image. |
headline |
The headline element. |
message |
The message element. |
Learn more about customizing CSS parts.
Dependencies
This component automatically imports the following dependencies.
<sl-icon><sl-txt>