Object status
The Object status pattern informs the user of the dynamic state or condition of an object.
const ObjectStatusPatternComponents = () => {const [process, setProcess] = React.useState(ProcessObject.Success);const menu = useStatusMenuState();const onClick = (status) => {setProcess(ProcessObject[status]);menu.hide();};return (<Box display="flex" flexDirection="column" rowGap="space60"><Box display="flex"><ProcessSuccessIconcolor="colorTextIconSuccess"decorative={false}title="success" /><Text marginLeft="space20">Success</Text></Box><StatusBadge variant="ProcessSuccess" size="borderless">Success</StatusBadge><StatusBadge variant="ConnectivityAvailable">Available</StatusBadge><Box><StatusMenuBadge {...menu} i18nButtonLabel="Change account" variant={process.variant}>{process.children}</StatusMenuBadge><StatusMenu {...menu} aria-label="Preferences"><StatusMenuItemRadio{...menu}name="process"value="success"checked={process.children === ProcessObject.Success.children}onClick={() => onClick('Success')}variant="default"><StatusMenuItemChild variant="ProcessSuccess">{ProcessObject.Success.children}</StatusMenuItemChild></StatusMenuItemRadio><StatusMenuItemRadio{...menu}name="process"value="neutral"checked={process.children === ProcessObject.Neutral.children}onClick={() => onClick('Neutral')}variant="default"><StatusMenuItemChild variant="ProcessNeutral">{ProcessObject.Neutral.children}</StatusMenuItemChild></StatusMenuItemRadio><StatusMenuItemRadio{...menu}name="process"value="warning"checked={process.children === ProcessObject.Warning.children}onClick={() => onClick('Warning')}variant="default"><StatusMenuItemChild variant="ProcessWarning">{ProcessObject.Warning.children}</StatusMenuItemChild></StatusMenuItemRadio><StatusMenuItemRadio{...menu}name="process"value="error"checked={process.children === ProcessObject.Error.children}onClick={() => onClick('Error')}variant="default"><StatusMenuItemChild variant="ProcessError">{ProcessObject.Error.children}</StatusMenuItemChild></StatusMenuItemRadio><StatusMenuItemRadio{...menu}name="process"value="InProgress"checked={process.children === ProcessObject.InProgress.children}onClick={() => onClick('InProgress')}variant="default"><StatusMenuItemChild variant="ProcessInProgress">{ProcessObject.InProgress.children}</StatusMenuItemChild></StatusMenuItemRadio><StatusMenuItemRadio{...menu}name="process"value="disabled"checked={process.children === ProcessObject.Disabled.children}onClick={() => onClick('Disabled')}variant="default"><StatusMenuItemChild variant="ProcessDisabled">{ProcessObject.Disabled.children}</StatusMenuItemChild></StatusMenuItemRadio><StatusMenuItemRadio{...menu}name="process"value="draft"checked={process.children === ProcessObject.Draft.children}onClick={() => onClick('Draft')}variant="default"><StatusMenuItemChild variant="ProcessDraft">{ProcessObject.Draft.children}</StatusMenuItemChild></StatusMenuItemRadio></StatusMenu></Box></Box>);};render(<ObjectStatusPatternComponents />)
// import all components for Object status patterns
import { Box } from "@twilio-paste/core/box";
import { Text } from "@twilio-paste/core/text";
import { StatusBadge } from "@twilio-paste/core/status-badge";
import { StatusMenu } from "@twilio-paste/core/status-menu";
import { ProcessDisabledIcon } from "@twilio-paste/icons/esm/ProcessDisabledIcon";
import { ProcessDraftIcon } from "@twilio-paste/icons/esm/ProcessDraftIcon";
import { ProcessErrorIcon } from "@twilio-paste/icons/esm/ProcessErrorIcon";
import { ProcessInProgressIcon } from "@twilio-paste/icons/esm/ProcessInProgressIcon";
import { ProcessNeutralIcon } from "@twilio-paste/icons/esm/ProcessNeutralIcon";
import { ProcessSuccessIcon } from "@twilio-paste/icons/esm/ProcessSuccessIcon";
import { ProcessWarningIcon } from "@twilio-paste/icons/esm/ProcessWarningIcon";
An Object status is used to communicate the dynamic state of an object. Use it to help a user identify something that requires their attention and often, their action. When a status is used to indicate to the user that they need to take action, be sure to provide clear controls to take that action (check out the example in Process status).
Object statuses are:
- Always related to an object. For example, this pattern applies to SIMs and regulatory bundles, but not to a step in a wizard flow. Instead, use the Error state pattern or Progress Steps component.
- Not used for static attributes. For example, “SMS-capable” is not a status on a phone number.
- Different from notification and feedback messaging, which is in direct response to a user action.
- Different from alert messaging, which is from the system.
- Used to draw a user’s attention to important information. Use plain text statuses when the status is not critical information for a user to know.
Non-text status indicators (such as icons or status dots) should be paired with text whenever
possible and should always be given a title
to give context and meaning to the icon or shape.
Check out the icon usage guidelines for more detailed accessibility information.
Process statuses indicate an object’s progress through a set of stages. Process statuses should always be paired with text.
<Box display="flex" rowGap="space100" flexWrap="wrap"><Box display="flex" columnGap="space50" rowGap="space60" flexWrap="wrap"><Box display="flex"><ProcessSuccessIconcolor="colorTextIconSuccess"decorative={false}title="success" /><Text marginLeft="space20">Success</Text></Box><Box display="flex"><ProcessErrorIconcolor="colorTextIconError"decorative={false}title="error" /><Text marginLeft="space20">Error</Text></Box><Box display="flex"><ProcessWarningIconcolor="colorTextIconWarning"decorative={false}title="warning" /><Text marginLeft="space20">Warning</Text></Box><Box display="flex"><ProcessNeutralIconcolor="colorTextIconNeutral"decorative={false}title="neutral" /><Text marginLeft="space20">Neutral</Text></Box><Box display="flex"><ProcessInProgressIconcolor="colorTextIconNeutral"decorative={false}title="In-progress" /><Text marginLeft="space20">In progress</Text></Box><Box display="flex"><ProcessDisabledIconcolor="colorTextIcon"decorative={false}title="disabled" /><Text marginLeft="space20">Disabled</Text></Box><Box display="flex"><ProcessDraftIconcolor="colorTextIcon"decorative={false}title="draft" /><Text marginLeft="space20">Draft</Text></Box></Box><Box display="flex" columnGap="space50" rowGap="space60" flexWrap="wrap"><StatusBadge variant="ProcessSuccess" size="borderless">Success</StatusBadge><StatusBadge variant="ProcessError" size="borderless">Error</StatusBadge><StatusBadge variant="ProcessWarning" size="borderless">Warning</StatusBadge><StatusBadge variant="ProcessNeutral" size="borderless">Neutral</StatusBadge><StatusBadge variant="ProcessInProgress" size="borderless">In progress</StatusBadge><StatusBadge variant="ProcessDisabled" size="borderless">Disabled</StatusBadge><StatusBadge variant="ProcessDraft" size="borderless">Draft</StatusBadge></Box><Box display="flex" columnGap="space50" rowGap="space60" flexWrap="wrap"><StatusBadge variant="ProcessSuccess">Success</StatusBadge><StatusBadge variant="ProcessError">Error</StatusBadge><StatusBadge variant="ProcessWarning">Warning</StatusBadge><StatusBadge variant="ProcessNeutral">Neutral</StatusBadge><StatusBadge variant="ProcessInProgress">In progress</StatusBadge><StatusBadge variant="ProcessDisabled">Disabled</StatusBadge><StatusBadge variant="ProcessDraft">Draft</StatusBadge></Box></Box>
To determine how to show a process status:
- If additional information is needed about the status, use Icon, Text, and Anchor (optional).
- If it’s in a Table and no additional information is needed, use a borderless Status Badge.
- Otherwise, use the default Status Badge.
Placement of the status in a Table should depend on the importance of the status to the given user flow and should be tested with users.
For statuses that are not as critical to a user’s workflow, use plain text statuses.
<><Heading as="h2" variant="heading20">Exports</Heading><Table><THead><Tr><Th>Status</Th><Th>Export name</Th></Tr></THead><TBody><Tr><Td><Box display="flex" flexDirection="column"><Box display="flex"><ProcessWarningIconcolor="colorTextIconWarning"decorative={false}title="warning" /><Text marginLeft="space20">Pre-registration needed</Text></Box><Box marginLeft="space60"><Anchor showExternal href="#" marginLeft="space20">Fill out the registration form here</Anchor></Box></Box></Td><Td><strong>Contacts who did not click</strong></Td></Tr><Tr><Td><Box display="inline-flex" columnGap="space20"><ProcessSuccessIconcolor="colorTextIconSuccess"decorative={false}title="success"/><Box><Text as="div">Successfully exported</Text><Text as="div" color="colorTextWeak">Tuesday, February 2, 2021</Text></Box></Box></Td><Td><strong>All contacts</strong></Td></Tr></TBody></Table><Box marginTop="space110"><Heading as="h2" variant="heading20">IDs</Heading></Box><Table><THead><Tr><Th>ID</Th><Th>Unique name</Th><Th>Region</Th><Th>Status</Th><Th>Order Date</Th></Tr></THead><TBody><Tr><Td>90294808908109537</Td><Td>WE902990c21gjioGasd</Td><Td>North America</Td><Td><StatusBadge variant="ProcessSuccess" size="borderless">Active</StatusBadge></Td><Td>2020-10-15</Td></Tr><Tr><Td>90294808908872345</Td><Td>WE928471c21gjioGasd</Td><Td>North America</Td><Td><StatusBadge variant="ProcessNeutral" size="borderless">Ready</StatusBadge></Td><Td>2020-10-15</Td></Tr></TBody></Table></>
<Stack orientation="vertical" spacing="space60"><Box width="60%"><Card><Boxas="span"display="flex"width="100%"alignItems="center"justifyContent="space-between"marginBottom="space70"><Heading as="h3" variant="heading40" marginBottom="space0">Business Profile</Heading><StatusBadge variant="ProcessSuccess">Approved</StatusBadge></Box><Paragraph marginBottom="space0">Information about your business</Paragraph></Card></Box></Stack>
Icon | Icon name | Token | Status Badge variant | Usage |
---|---|---|---|---|
ProcessErrorIcon | $color-text-icon-error | ProcessError | Indicates an error or that something went wrong. | |
ProcessWarningIcon | $color-text-icon-warning | ProcessWarning | Indicates a condition requiring corrective action. | |
ProcessSuccessIcon | $color-text-icon-success | ProcessSuccess | Indicates that something is stable, active, or successfully completed. | |
ProcessNeutralIcon | $color-text-icon-neutral | ProcessNeutral | Indicates a neutral / informative state. Can be used to fill any gaps that the more specific statuses don’t cover. | |
ProcessInProgressIcon | $color-text-icon-neutral | ProcessInProgress | Indicates that something is in progress, in review, or scheduled. | |
ProcessDisabledIcon | $color-text-icon | ProcessDisabled | Indicates that something is inactive, disabled, or paused. | |
ProcessDraftIcon | $color-text-icon | ProcessDraft | Indicates that something is a draft, unused, or not started. |
Not all object statuses need icons or shapes. In fact, giving every status an icon or a shape can make it difficult for a user to find and focus on the most critical information
If some statuses—such as successes or failures—are critical, use plain text for the other statuses that a user doesn’t need to identify as quickly.
<><Heading as="h2" variant="heading20">Agent queues</Heading><Table><THead><Tr><Th>Title</Th><Th>Media</Th><Th>Status</Th></Tr></THead><TBody><Tr><Td>Bewitched</Td><Td>Series</Td><Td><StatusBadge variant="ProcessWarning" size="borderless">Progress halted</StatusBadge></Td></Tr><Tr><Td>Mulan</Td><Td>Feature</Td><Td>Released</Td></Tr><Tr><Td>Little Women</Td><Td>Feature</Td><Td>Released</Td></Tr></TBody></Table></>
Connectivity statuses are used to show if a user, object, or system is online or offline. Connectivity statuses should always be paired with text.
<Box display="flex" rowGap="space100" flexWrap="wrap"><Box display="flex" columnGap="space50" rowGap="space60" flexWrap="wrap"><Box display="inherit"><ConnectivityAvailableIconcolor="colorTextIconAvailable"decorative={false}title="available"/>Available</Box><Box display="inherit"><ConnectivityBusyIconcolor="colorTextIconBusy"decorative={false}title="busy"/>Busy</Box><Box display="inherit"><ConnectivityUnavailableIconcolor="colorTextIconUnavailable"decorative={false}title="unavailable"/>Unavailable</Box><Box display="inherit"><ConnectivityNeutralIconcolor="colorTextIconNeutral"decorative={false}title="neutral"/>Neutral</Box><Box display="inherit"><ConnectivityOfflineIconcolor="colorTextIconOffline"decorative={false}title="offline"/>Offline</Box></Box><Box display="flex" columnGap="space50" rowGap="space60" flexWrap="wrap"><StatusBadge variant="ConnectivityAvailable">Available</StatusBadge><StatusBadge variant="ConnectivityUnavailable">Unavailable</StatusBadge><StatusBadge variant="ConnectivityBusy">Busy</StatusBadge><StatusBadge variant="ConnectivityNeutral">Neutral</StatusBadge><StatusBadge variant="ConnectivityOffline">Offline</StatusBadge></Box><Box display="flex" columnGap="space50" rowGap="space60" flexWrap="wrap"><StatusBadge size="borderless" variant="ConnectivityAvailable">Available</StatusBadge><StatusBadge size="borderless" variant="ConnectivityUnavailable">Unavailable</StatusBadge><StatusBadge size="borderless" variant="ConnectivityBusy">Busy</StatusBadge><StatusBadge size="borderless" variant="ConnectivityNeutral">Neutral</StatusBadge><StatusBadge size="borderless" variant="ConnectivityOffline">Offline</StatusBadge></Box></Box>
To determine how to show a connectivity status:
- If additional information is needed to explain the status, use Icon, Text, and Anchor.
- If it’s in a Table and no additional information is needed, use a borderless Status Badge.
- Otherwise, use the default Status Badge.
<><Heading as="h2" variant="heading20">Reboots</Heading><Table><THead><Tr><Th>Agents</Th><Th>Queues</Th></Tr></THead><TBody><Tr><Td><Box display="flex" columnGap="space20" alignItems="center"><Avatar name="Adaline Baxter" size="sizeIcon70" /><Box display="flex" flexDirection="column"><Text fontWeight="fontWeightMedium" marginLeft="space20">Adaline Baxter</Text><Box display="flex"><ConnectivityAvailableIconcolor="colorTextIconSuccess"decorative={false}title="success"/><DetailText marginTop="space0">Available | 12:43</DetailText></Box></Box></Box></Td><Td><Badge variant="decorative10">Queue name</Badge></Td></Tr><Tr><Td><Box display="flex" columnGap="space20" alignItems="center"><Avatar name="Jane Cooper" size="sizeIcon70" /><Box display="flex" flexDirection="column"><Text fontWeight="fontWeightMedium" marginLeft="space20">Jane Cooper</Text><Box display="flex"><ConnectivityBusyIconcolor="colorTextIconBusy"decorative={false}title="success"/><DetailText marginTop="space0">On break | 02:23</DetailText></Box></Box></Box></Td><Td><Badge variant="decorative10">Queue name</Badge></Td></Tr><Tr><Td><Box display="flex" columnGap="space20" alignItems="center"><Avatar name="Dan Reynolds" size="sizeIcon70" /><Box display="flex" flexDirection="column"><Text fontWeight="fontWeightMedium" marginLeft="space20">Dan Reynolds</Text><Box display="flex"><ConnectivityAvailableIconcolor="colorTextIconSuccess"decorative={false}title="success"/><DetailText marginTop="space0">Available | 10:21</DetailText></Box></Box></Box></Td><Td><Badge variant="decorative10">Queue name</Badge></Td></Tr></TBody></Table></>
const PageHeaderExample = () => {return (<Box maxWidth="size50" borderStyle="solid" padding="space50" borderWidth="borderWidth10" borderColor="colorBorderDecorative10Weaker" borderRadius="borderRadius20"><PageHeader size="compact"><PageHeaderDetails><PageHeaderPrefix><Avatar name="parker smith" size="sizeIcon100" icon={UserIcon} /></PageHeaderPrefix><PageHeaderHeading>Parker Smith</PageHeaderHeading><PageHeaderActions><ButtonGroup><Button variant="secondary" size="small">Edit</Button><Button variant="secondary" size="small"><MoreIcon decorative={false} title="more menu" /></Button></ButtonGroup></PageHeaderActions><PageHeaderMeta>Customer since June 11, 2009<StatusBadge variant="ConnectivityAvailable">Online</StatusBadge></PageHeaderMeta></PageHeaderDetails><PageHeaderInPageNavigation><InPageNavigation aria-label="get started"><InPageNavigationItem href="#" currentPage>Customer details</InPageNavigationItem><InPageNavigationItem href="#">Customer history</InPageNavigationItem></InPageNavigation></PageHeaderInPageNavigation></PageHeader></Box>);};render(<PageHeaderExample />)
Icon | Icon name | Token | Status Badge variant | Usage |
---|---|---|---|---|
ConnectivityAvailableIcon | $color-text-icon-available | ConnectivityAvailable | Indicates that a person or entity is available or online. | |
ConnectivityBusyIcon | $color-text-icon-busy | ConnectivityBusy | Indicates that a person or entity is busy or away. | |
ConnectivityUnavailableIcon | $color-text-icon-unavailable | ConnectivityUnavailable | Indicates that a person or entity is unavailable or at capacity. | |
ConnectivityNeutralIcon | $color-text-icon-neutral | ConnectivityNeutral | Indicates that a person or entity is neutral. | |
ConnectivityOfflineIcon | $color-text-icon-offline | ConnectivityOffline | Indicates that a person or entity is offline. |
Use a Status Menu to let users swap between statuses.
const ProcessStatusMenu = () => {const [process, setProcess] = React.useState(ProcessObject.Success);const menu = useStatusMenuState();const onClick = (status) => {setProcess(ProcessObject[status]);menu.hide();};return (<><StatusMenuBadge {...menu} i18nButtonLabel="Change account" variant={process.variant}>{process.children}</StatusMenuBadge><StatusMenu {...menu} aria-label="Preferences"><StatusMenuItemRadio{...menu}name="process"value="success"checked={process.children === ProcessObject.Success.children}onClick={() => onClick('Success')}variant="default"><StatusMenuItemChild variant="ProcessSuccess">{ProcessObject.Success.children}</StatusMenuItemChild></StatusMenuItemRadio><StatusMenuItemRadio{...menu}name="process"value="neutral"checked={process.children === ProcessObject.Neutral.children}onClick={() => onClick('Neutral')}variant="default"><StatusMenuItemChild variant="ProcessNeutral">{ProcessObject.Neutral.children}</StatusMenuItemChild></StatusMenuItemRadio><StatusMenuItemRadio{...menu}name="process"value="warning"checked={process.children === ProcessObject.Warning.children}onClick={() => onClick('Warning')}variant="default"><StatusMenuItemChild variant="ProcessWarning">{ProcessObject.Warning.children}</StatusMenuItemChild></StatusMenuItemRadio><StatusMenuItemRadio{...menu}name="process"value="error"checked={process.children === ProcessObject.Error.children}onClick={() => onClick('Error')}variant="default"><StatusMenuItemChild variant="ProcessError">{ProcessObject.Error.children}</StatusMenuItemChild></StatusMenuItemRadio><StatusMenuItemRadio{...menu}name="process"value="InProgress"checked={process.children === ProcessObject.InProgress.children}onClick={() => onClick('InProgress')}variant="default"><StatusMenuItemChild variant="ProcessInProgress">{ProcessObject.InProgress.children}</StatusMenuItemChild></StatusMenuItemRadio><StatusMenuItemRadio{...menu}name="process"value="disabled"checked={process.children === ProcessObject.Disabled.children}onClick={() => onClick('Disabled')}variant="default"><StatusMenuItemChild variant="ProcessDisabled">{ProcessObject.Disabled.children}</StatusMenuItemChild></StatusMenuItemRadio><StatusMenuItemRadio{...menu}name="process"value="draft"checked={process.children === ProcessObject.Draft.children}onClick={() => onClick('Draft')}variant="default"><StatusMenuItemChild variant="ProcessDraft">{ProcessObject.Draft.children}</StatusMenuItemChild></StatusMenuItemRadio></StatusMenu></>);};render(<ProcessStatusMenu />)
const ConnectivityStatusMenu = () => {const [availability, setConnectivity] = React.useState(ConnectivityObject.Available);const menu = useStatusMenuState();const onClick = (status) => {setConnectivity(ConnectivityObject[status]);menu.hide();};return (<><StatusMenuBadge {...menu} i18nButtonLabel="Change account" variant={availability.variant}>{availability.children}</StatusMenuBadge><StatusMenu {...menu} aria-label="Preferences"><StatusMenuItemRadioname="availability"checked={availability.children === 'Available'}value="available"{...menu}onClick={() => onClick('Available')}variant="default"><StatusMenuItemChild variant="ConnectivityAvailable">Available</StatusMenuItemChild></StatusMenuItemRadio><StatusMenuItemRadioname="availability"checked={availability.children === 'Busy'}value="busy"{...menu}onClick={() => onClick('Busy')}variant="default"><StatusMenuItemChild variant="ConnectivityBusy">Busy</StatusMenuItemChild></StatusMenuItemRadio><StatusMenuItemRadioname="availability"checked={availability.children === 'Unavailable'}value="unavailable"{...menu}onClick={() => onClick('Unavailable')}variant="default"><StatusMenuItemChild variant="ConnectivityUnavailable">Unavailable</StatusMenuItemChild></StatusMenuItemRadio><StatusMenuItemRadioname="availability"checked={availability.children === 'Neutral'}value="neutral"{...menu}onClick={() => onClick('Neutral')}variant="default"><StatusMenuItemChild variant="ConnectivityNeutral">Neutral</StatusMenuItemChild></StatusMenuItemRadio><StatusMenuItemRadioname="availability"checked={availability.children === 'Offline'}value="offline"{...menu}onClick={() => onClick('Offline')}variant="default"><StatusMenuItemChild variant="ConnectivityOffline">Offline</StatusMenuItemChild></StatusMenuItemRadio></Menu></>);};render(<ConnectivityStatusMenu />)
Status |
---|
Not Started |
Archived |
Error |
In-progress |
Success |
Do
Use status icons to draw attention to the most important statuses. Try to limit a given set of statuses to 3–4 icons, and use plain text statuses for the rest. This helps users skim a dense set of data for the information that is most critical.
Status |
---|
Not started |
Archived |
Error detected |
In-progress |
Success |
Don't
Don't put a status icon or shape on every status if some statuses are more important than others. If all statuses are of equal importance, they can all have icons.
- Adding text labels to status icons
- Showing error previews in a table
- Text color for success text and accessibility
- Bulk Action - Table component usage
- Visual and accessibility for Sender Id management section
- Status of different services and objects through out product's life-cycle
- Event Streams (Office Hours: Thu Dec 3)