Docs
EmptyStatePresentational

EmptyStatePresentational

An empty state for encouraging action.

Loading...
import { BucketPlus } from 'icons'
import { Plus } from 'lucide-react'
import { Button } from 'ui'
import { EmptyStatePresentational } from 'ui-patterns'
 
export function EmptyStatePresentationalIcon() {
  return (
    <EmptyStatePresentational
      icon={BucketPlus}
      title="Create a vector bucket"
      description="Store, index, and query your vector embeddings at scale."
    >
      <Button size="tiny" type="primary" icon={<Plus size={14} />}>
        Create bucket
      </Button>
    </EmptyStatePresentational>
  )
}

Expects a title, description, and optional action buttons or other children.

Props

Text

All text should be written using active language. The title should prompt the user to take an action, and the description should clearly explain the value of doing so.

Icon

Supports both Lucide icons and custom icons via the icons package. If neither are passed, EmptyStatePresentational falls back to Lucide’s SquarePlus.

Loading...
import { Plus } from 'lucide-react'
import { Button } from 'ui'
import { EmptyStatePresentational } from 'ui-patterns'
 
export function EmptyStatePresentationalIcon() {
  return (
    <EmptyStatePresentational
      title="Create an auth hook"
      description="Use Postgres functions or HTTP endpoints to customize your authentication flow."
    >
      <Button size="tiny" type="primary" icon={<Plus size={14} />}>
        Add hook
      </Button>
    </EmptyStatePresentational>
  )
}

See also Empty States.

Examples

It’s okay to repeat buttons inside of EmptyStatePresentational that are also available outside of it. The alternative is to conditionally determine button placement whilst polling for list length (to determine whether to show an empty state or not). This is problematic for two reasons:

  1. Rendering after client-side polling often leads to confusing layout shift. This layout shift becomes exacerbated when buttons are stacked against other objects.
  2. Consistent entry points outside of EmptyStatePresentational also teach a pattern that will continue to exist post initial object creation.

When repeating buttons, set the type to default so the original primary, button remains the only primary action on display.

Loading...
import { Plus } from 'lucide-react'
import { Button } from 'ui'
import { EmptyStatePresentational } from 'ui-patterns'
 
import {
  PageSection,
  PageSectionAside,
  PageSectionContent,
  PageSectionMeta,
  PageSectionSummary,
  PageSectionTitle,
} from 'ui-patterns/PageSection'
 
export function EmptyStatePresentationalIcon() {
  return (
    <div className="w-full">
      <PageSection>
        <PageSectionMeta>
          <PageSectionSummary>
            <PageSectionTitle>Providers</PageSectionTitle>
          </PageSectionSummary>
          <PageSectionAside>
            <Button size="tiny" type="primary" icon={<Plus size={14} />}>
              Add provider
            </Button>
          </PageSectionAside>
        </PageSectionMeta>
        <PageSectionContent>
          <EmptyStatePresentational
            title="Add a provider"
            description="Use third-party authentication systems to access your project."
          >
            <Button size="tiny" type="default" icon={<Plus size={14} />}>
              Add provider
            </Button>
          </EmptyStatePresentational>
        </PageSectionContent>
      </PageSection>
    </div>
  )
}