For a short message about the result of an operation take CdsToast, and while the data is still loading show CdsSkeletonLoader instead of an empty state.
Anatomy
An empty state is a vertical stack of zones. Each zone appears only when its prop or slot is set, so you pick the composition that fits the situation: from a single heading line to the full set with media and a button.
Variations
Content
Every text zone has its own prop: headline is the large accent ("404", "Empty"), title states the situation, text gives the details and hints what to do. The width of the text is capped by text-width (500 by default), so a long description does not stretch across the whole screen.
Media
The icon prop shows an icon, image shows an image (it wins over the icon). The size of the media comes from size: 96 for an icon and 200 for an image by default. The color of the icon is changed by the color prop.
Illustrations
Legacy illustrations from the @central-design-system/illustrations package (CDS 3): the illustration prop accepts the kebab-case name of a globally registered component (they are registered through the illustrations option of createCds). You can render your own illustration through the illustration slot.
Alignment
The justify prop pushes the content to the edge of the container: start, center (default) or end. The dashed frame in the demo shows the bounds of the container.
Actions
The action-text prop adds a button below the content; a click on it arrives as the click:action event. When there is more than one action, render your own buttons in the actions slot — bind props.onClick from the slot to the main button so that the click:action event keeps working.
Slots
Slots replace the content coming from props when you need full control over the markup.
| Slot | Description |
|---|---|
media | Media area. Replaces the content from icon and image |
illustration | Illustration. Replaces the content from illustration |
headline | Accent heading. Replaces the text from headline |
title | Heading. Replaces the text from title |
text | Description. Replaces the text from text |
description | Extra description. Replaces the text from description |
default | Arbitrary content between the description and the actions |
actions | Action buttons; receives props with an onClick handler |
Guidelines
Scenarios
Search with no results
When nothing matches the query, an empty state replaces the list. The button from action-text clears the query on click:action — the user returns to the full list in one click. Try typing a query that is not in the list.
Empty list
The first visit to a section is a reason not to apologize for the emptiness but to help the user start: title names the situation, text promises a result, and the button from action-text creates the first record. Once a record is added, the list replaces the placeholder.
Loading error
If the data failed to load, explain the reason and let the user retry right there. The button in the actions slot shows loading while the retry is in flight, and props.onClick from the slot keeps the click:action event.
404 page
headline prints the large error code, and href (or to for vue-router) is passed to the action button — it works as a link and takes the user away from the dead-end page.
API
Props
| Name | Type | Default | Description |
|---|---|---|---|
actionText | string | undefined | — | Text of the action button. When set, a button is rendered below the content. |
bgColor | string | undefined | — | Background color of the component |
color | string | undefined | — | Component color |
content | string | number | undefined | — | Content displayed in the component. |
description | string | undefined | — | Description |
headline | string | undefined | — | Large accent heading above the main heading. |
height | string | number | undefined | — | Component height |
href | string | undefined | — | The href attribute of the link. When set, the component behaves as a regular link |
icon | IconValue | undefined | — | Icon in the media area. |
illustration | string | undefined | — | Legacy illustration from the @central-design-system/illustrations package (CDS 3): the kebab-case name of a globally registered component, for example rocket. Illustrations are registered through the illustrations option of createCds. |
image | string | undefined | — | Source of the image in the media area (takes priority over icon). |
justify | "start" | "end" | "center" | undefined | 'center' | Horizontal alignment of the content: start, center, end. |
maxHeight | string | number | undefined | — | Maximum component height |
maxWidth | string | number | undefined | — | Maximum component width |
minHeight | string | number | undefined | — | Minimum component height |
minWidth | string | number | undefined | — | Minimum component width |
size | number | "xs" | "sm" | "md" | "lg" | "xl" | undefined | 'md' | Size of the component |
text | string | number | undefined | — | Text displayed in the component. |
textWidth | string | number | undefined | 500 | Maximum width of the description block. |
theme | string | undefined | — | Component theme |
title | string | undefined | — | Heading. |
to | LinkTo | undefined | — | Target route or route location object for RouterLink. When set, the component behaves as a RouterLink |
width | string | number | undefined | — | Component width |
Events
| Name | Type | Description |
|---|---|---|
click:action | [event: MouseEvent] | Click on the action button. |
Slots
| Name | Type | Description |
|---|---|---|
actions | { props: { onClick: (event: MouseEvent) => void; }; } | Actions slot; receives props with an onClick handler to bind to your own element. |
default | any | Arbitrary content between the description and the actions. |
description | any | Description slot (instead of the description prop). |
headline | any | Accent heading slot (instead of the headline prop). |
illustration | any | Media area slot for an illustration (instead of the illustration prop). |
media | any | Media area slot (instead of the image / icon props). |
text | any | Description slot (instead of the text prop). |
title | any | Heading slot (instead of the title prop). |