UnflowUI
Components

StateMessage

A centered state message for empty, not-found, loading, and success scenarios. Includes preset icons and a call-to-action button.

Overview

StateMessage displays a centered empty-state pattern with a decorative icon, title, description, and an optional button. It ships with six semantic presets (empty, notFound, success, error, warning, connectionError) that set the default icon and color, plus an isLoading flag that swaps the icon for a spinner. Every part is overridable via slots and slotProps.

Use it inside panels, modals, pages, or any area that needs to communicate status to the user.

Import

import { StateMessage } from '@unflow.io/ui/components/StateMessage';

Props

PropTypeDefaultDescription
type'empty' | 'notFound' | 'success' | 'error' | 'warning' | 'connectionError''empty'Semantic preset that selects the default icon
titlestringPrimary heading
descriptionstringSecondary body text
ctaStateMessageCTACall-to-action button configuration. Preset defaults: secondary for most states, destructiveSecondary for error. All Button props can still be overridden.
isLoadingbooleanfalseSwaps the preset icon for a spinner
disableRingsbooleanfalseHides the decorative rings behind the icon

StateMessageCTA is the same shape as IButton:

export type StateMessageCTA = IButton;

Presets

Empty

Empty message title text here

This is a subtitle text for the empty message. Keep it simple, but show the user what it needs to see some content here.

<StateMessage
  type="empty"
  title="Empty message title text here"
  description="This is a subtitle text for the empty message."
  cta={{ label: 'Button label', size: 'sm' }}
/>

Not found

Not found message title text here

This is a subtitle text for the not found message. Keep it simple, but show the user what it needs to see some content here.

<StateMessage
  type="notFound"
  title="Not found message title text here"
  description="This is a subtitle text for the not found message."
  cta={{ label: 'Button label', size: 'sm' }}
/>

Loading

Loading message title text here

This is a subtitle text for the loading message. Keep it simple, but show the user what it needs to see some content here.

<StateMessage
  type="empty"
  isLoading
  title="Loading message title text here"
  description="This is a subtitle text for the loading message."
/>

Success

Success message title text here

This is a subtitle text for the success message. Keep it simple, but show the user what it needs to see some content here.

<StateMessage
  type="success"
  title="Success message title text here"
  description="This is a subtitle text for the success message."
  cta={{ label: 'Button label', size: 'sm' }}
/>

Error

Error message title text here

This is a subtitle text for the error message. Keep it simple, but show the user what it needs to see some content here.

<StateMessage
  type="error"
  title="Error message title text here"
  description="This is a subtitle text for the error message."
  cta={{ label: 'Button label', size: 'sm' }}
/>

Warning

Warning message title text here

This is a subtitle text for the warning message. Keep it simple, but show the user what it needs to see some content here.

<StateMessage
  type="warning"
  title="Warning message title text here"
  description="This is a subtitle text for the warning message."
  cta={{ label: 'Button label', size: 'sm' }}
/>

Connection error

Connection error message title text here

This is a subtitle text for the connection error message. Keep it simple, but show the user what it needs to see some content here.

<StateMessage
  type="connectionError"
  title="Connection error message title text here"
  description="This is a subtitle text for the connection error message."
  cta={{ label: 'Button label', size: 'sm' }}
/>

Full-width button

Set cta.fullWidth when the message lives in a narrow container, such as a drawer or a card.

Empty message title text here

Use cta.fullWidth when the state message sits inside a narrow container.

<StateMessage
  type="empty"
  title="Empty message title text here"
  description="Use cta.fullWidth when the state message sits inside a narrow container."
  cta={{ label: 'Button label', size: 'sm', fullWidth: true }}
/>

Customization (slots)

Replace the preset icon with any React node:

Custom icon

You can override the preset icon with any React node using slots.icon.

import { Cloud } from '@unflow-ui/icons/system-devices/cloud';

<StateMessage
  type="empty"
  title="Custom icon"
  description="You can override the preset icon with any React node using slots.icon."
  slots={{ icon: <Cloud /> }}
/>

Customization (slotProps)

SlotPropsDescription
iconBaseHTMLProps<HTMLDivElement>Icon wrapper, including the decorative rings
loadingIconBaseHTMLProps<HTMLDivElement> & Pick<ISpinner, 'size' &#124; 'thickness'>Loading indicator wrapper and spinner sizing props
titleBaseHTMLProps<HTMLHeadingElement>Heading element
descriptionBaseHTMLProps<HTMLParagraphElement>Body text element
ctaIButtonCTA button props

Accessibility

  • The root is a <div> with centered text. Use inside a region or landmark when it is the main content of a page.
  • Preset icons are decorative and not focusable.
  • The loading state uses the existing Spinner component, which renders role="status". Override it via slots.loadingIcon or tweak its size/thickness through slotProps.loadingIcon.
  • Provide meaningful title and description text so the message is understandable without the icon.
  • When cta is supplied, the button is a standard Button and inherits its keyboard and focus behavior.