Empty state
Introduction
Section titled “Introduction”EmptyState is a schema layout for “nothing here yet.” Use it inside a form or infolist when a repeater, relation, or custom slot has zero rows. Tables have their own empty chrome (.empty_state_heading / .empty_state_description on Table) that paints the same visual language on the index page.
Each variation below includes a short explanation, the fluent API, and a screenshot of the rendered control.
Basic empty state
Section titled “Basic empty state”Heading plus a short description. The default heading is Nothing here when you omit .heading() and .label().
from almasix.orbit.schemas import EmptyState
EmptyState.make() .heading("No drafts") .description("Create one when you are ready.")

.icon(...) renders a Heroicon above the heading so the slot reads as a destination, not an error.
EmptyState.make() .heading("No comments") .description("They will appear here after readers reply.") .icon("heroicon-o-chat-bubble-left-right")![]()
![]()
Actions
Section titled “Actions”.actions([...]) is a slot for Action buttons under the description — typically a Create that jumps to the resource create page.
from almasix.orbit.actions import CreateActionfrom almasix.orbit.schemas import EmptyState
EmptyState.make() .heading("No posts yet") .description("Write the first one.") .actions([CreateAction.make().url("/admin/posts/create")])

Nested schema
Section titled “Nested schema”Children passed to .schema([...]) render between the description and the action row. Use that for a short hint field or a secondary callout.
API cheat sheet
Section titled “API cheat sheet”| Method | Role |
|---|---|
.heading(text) |
Title (falls back to the component label, then “Nothing here”) |
.description(text) |
Paragraph under the heading |
.icon(name) |
Heroicon above the heading |
.actions([...]) |
Buttons under the copy |
.schema([...]) |
Nested components |
Tables: Rendering a table. Closures on .visible() still apply — see Form closures.