CollectionState
Variants
Use a specific title and explanation to help someone recover. empty means the source contains no records. no-results means valid filters matched none of the supplied records. error and access-denied describe outcomes supplied by the application.
No equipment yet
No matching equipment
Equipment unavailable
Equipment access denied
Supplied recovery
Pass recovery controls through actions only when the application supports them. Activating a control invokes its handler; the component continues to display the supplied state until the application replaces it.
Equipment unavailable
Retry requests recovery; the host supplies the result.
This training example lets you supply the replacement response explicitly.
In this example, Retry requests recovery. Supply empty response explicitly delivers the next training result. The example owns its request feedback and state replacement.
import { Button, CollectionState } from "@operator-ds/react";
<CollectionState
variant="error"
title="Equipment unavailable"
description="The source did not respond. Your filters have been retained."
headingLevel={3}
actions={
<Button variant="secondary" onClick={retry}>
Retry
</Button>
}
/>;
Actions retain their own disabled state, link semantics, focus indicator, and keyboard behavior. The application owns request handling, authorization, and any result after activation. Explain unavailable recovery next to a disabled control.
Names and announcements
The title renders as a real heading and names the region. Choose headingLevel from 2–6 to match the surrounding page. Each instance creates unique heading and description IDs, including repeated titles. description accepts rich content; provide the key recovery guidance as readable text.
Static collection states do not announce themselves automatically. If a transition needs announcement, the host can supply native aria-live and aria-atomic attributes, or present its own status message. Choose an announcement scope that avoids repeating unrelated action content. Updating a state does not move focus; the host manages focus when replacing an active control.
Props
| PROP | TYPE | DEFAULT | REQUIRED |
|---|---|---|---|
variantSupplied collection outcome. Empty means no source records; no-results means no matching records. | enumempty | no-results | error | access-denied | — | yes |
titleVisible heading that names the region and explains its state. | string | — | yes |
descriptionOptional supporting content associated with the region. | node | — | no |
actionsCaller-supplied recovery controls. Activation never changes the supplied collection state. | node | — | no |
headingLevelNative heading level from 2 through 6; match the surrounding document hierarchy. | number | 2 | no |
aria-liveOptional caller-owned live-region behavior. No announcement is added by default. | enumoff | polite | assertive | — | no |
className | string | — | no |
The forwarded ref targets the root div. Native div attributes are supported. The region keeps its generated heading association, and caller aria-labelledby and aria-describedby references are appended to the generated references. Use description and actions for content; arbitrary children are not part of the API.
Accessibility
- A named region contains a native heading and an associated optional description.
- The written title explains the outcome; no decorative icon is required.
- Supplied controls preserve their own keyboard and focus behavior.
- Long title and description content wraps, and action controls can wrap onto another line.
- The component adds no live-region behavior or focus movement by default.
Manifest entry
<CollectionState variant="error" title="Equipment unavailable" description="The source did not respond." actions={<Button onClick={retry}>Retry</Button>} />View agent manifest
{
"description": "Named collection state with supplied explanation and recovery actions.",
"props": {
"variant": {
"type": "enum",
"values": [
"empty",
"no-results",
"error",
"access-denied"
],
"required": true,
"description": "Supplied collection outcome. Empty means no source records; no-results means no matching records."
},
"title": {
"type": "string",
"required": true,
"description": "Visible heading that names the region and explains its state."
},
"description": {
"type": "node",
"description": "Optional supporting content associated with the region."
},
"actions": {
"type": "node",
"description": "Caller-supplied recovery controls. Activation never changes the supplied collection state."
},
"headingLevel": {
"type": "number",
"default": 2,
"description": "Native heading level from 2 through 6; match the surrounding document hierarchy."
},
"aria-live": {
"type": "enum",
"values": [
"off",
"polite",
"assertive"
],
"description": "Optional caller-owned live-region behavior. No announcement is added by default."
},
"className": {
"type": "string"
}
},
"composable_with": [
"Button",
"Link",
"DataGrid",
"PropertyFilter"
],
"never_inside": [
"Button"
],
"example": "<CollectionState variant=\"error\" title=\"Equipment unavailable\" description=\"The source did not respond.\" actions={<Button onClick={retry}>Retry</Button>} />"
}