jixoai-ui
the terminal design language
loading the style sheet…
Skip to content
docs · print medium: screen

registry:ui · General

empty — the no-data state, nothing more

The eight-state machine's no-data member (error/loading/404 are alert/result surfaces — ruled separate). Terminal illustration slot, title, description, actions. Zero JS.

install — empty

$npx jixoai-ui add empty

https://ui.jixoai.com/r/empty.json

zero JS illustration slot actions snippet owns the fix

overview

Overview

A figure with three optional parts and one required line: the no-data state of the eight-state machine, deliberately nothing more.

Empty renders one composition: a dashed muted figure holding the terminal-box illustration (the default is an empty directory listing — ls checks/, zero items), and a figcaption carrying the title, an optional description, and an optional actions snippet. Zero JS, zero state, zero transitions — the no-data state of the eight-state machine, and NOTHING more: the antd ruling keeps error/loading/404 in the alert and result surfaces.

Composition is consumer-side by law: the illustration is a slot (bring any glyph — it stays decorative, aria-hidden), and the actions snippet hosts the recovery controls (usually a press-button). No component composes Empty today (grep receipt) — pages own their no-data regions directly.

The eight axes resolve on the figure — density is the one axis that repaints (the named rung re-bases the rhythm channels), theme is the frozen pole (the paint reads no raw tokens, so an island changes nothing), and six stamp-and-supply. Per-axis below; the shared grammar lives on the universal props page.

usage

Usage

One required title; description and actions fill the caption; the illustration slot replaces the terminal default.

usage
<Empty title="no checks yet" description="add the first check">
  {#snippet actions()}<PressButton>add check</PressButton>{/snippet}
</Empty>

empty

empty — the no-data state, nothing more

no checks yet

Add the first check to start the audit pipeline.

empty-usage.svelte svelte
<Empty title="no checks yet" description="add the first check">
  {#snippet actions()}<PressButton>add check</PressButton>{/snippet}
</Empty>

examples

Composition

One required title and optional description, illustration and actions slots.

empty · composition

no artifacts

no checks

Add the first check.

empty-composition-demo.svelte svelte
<script lang="ts">
  import Empty from '@ui/empty.svelte';
  import PressButton from '@ui/press-button.svelte';
</script>

<div class="grid gap-4 md:grid-cols-2">
  <Empty title="no artifacts" />
  <Empty title="no checks" description="Add the first check.">
    {#snippet actions()}<PressButton>add check</PressButton>{/snippet}
  </Empty>
</div>

api

Props

The table renders from the GENERATED meta + curation; the eight axis rows split into the shared section beneath.

Properties

PropertyTypeDefaultDescription
title * string—The no-data heading — font-nav uppercase at the density channel's type voice.
description string—Optional supporting copy, clamped to a 36ch measure under the title.
illustration Snippet—Snippet replacing the default terminal listing (ls checks/ · 0 items) — bring any glyph; the art stays decorative (aria-hidden) either way.
actions Snippet—Recovery actions under the caption — usually a press-button; the row wraps at the density gap.
class string''Forwarded to the root figure, after the family atoms.

Universal props

PropertyTypeDefaultDescription
size'small' | 'medium' | 'large' | 'auto' | number'auto' · ambient scopethe base scale — root font-size; parts size in em
shape'round' | 'scoop' | 'bevel' | 'notch' | 'square' | 'squircle' | 'auto''auto' · ambient scopecorner geometry (CSS corner-shape; §14 degrade table)
radius'small' | 'medium' | 'large' | 'auto' | number'auto' · ambient scopecorner size; auto = the concentric broadcast (§3)
density'small' | 'medium' | 'large' | 'auto' | number'auto' · ambient scopespacing/leading scale over the kernel channels (§4)
color'primary' | 'secondary' | 'error' | 'warn' | 'success' | 'info' | 'auto' | number | string'auto' · ambient scopethe hue axis of the fixed oklch primary system (§5)
theme'light' | 'dark' | 'system' | 'auto''auto' · ambient scopelight/dark profile; system = the JS-mutable global (§6)
elevation'level-1' | 'level0' | 'level1' | 'level2' | 'level3' | 'level4' | 'level5' | 'auto' | number'auto' · ambient scopeofficial M3 levels over the surface ladder (§7)
motion'reduced' | 'subtle' | 'normal' | 'expressive' | 'auto' | number'auto' · ambient scopeintensity across the motion kernels (§8)

axes

The eight axes on empty

empty is the frozen pole of the axis surface (census batch D): all eight lanes resolve no-own on the figure, density repaints the composition through its named rung, and the other seven stamp-and-supply without touching the paint. theme is the measured absence — the declaring-selector grep finds zero raw-token reads, so a resolved dark stamps .dark and nothing flips. The carriers stamp the figure (the promoted root is self-carried), greppable in the raw SSR.

Reading the table: Property is the axis, Type is the real carrier or consumption it drives on THIS family, Default is the lane default — the named steps, number unit, and consumption are in each description.

PropertyTypeDefaultDescription
size 'small' | 'medium' | 'large' | 'auto' | number'auto'SUPPLY-ONLY — stamps --jx-size-effective; no family css reads it (grep receipt: zero readers in ui/empty/). The title and description read the fixed --jx-text/--jx-line channels and the art box is structural. Number unit: px.
shape 'round' | 'scoop' | 'bevel' | 'notch' | 'square' | 'squircle' | 'auto''auto'SUPPLY-ONLY — stamps --jx-shape-effective and --jx-radius-factor-effective; no family css reads them (grep receipt: zero readers). The figure and art frames are 1px hairline boxes with no corner law. Number unit: none.
radius 'small' | 'medium' | 'large' | 'auto' | number'auto'SUPPLY-ONLY — stamps --jx-radius-effective; no family css reads it (grep receipt: zero readers) — the family composes no radius, concentric or otherwise. Number unit: px.
density 'small' | 'medium' | 'large' | 'auto' | number (+ the five legacy spellings)'auto'CONSUMED — the axis that repaints this state. The named rung stamps data-density on the figure and the scope block re-bases every channel the atoms read: --jx-stack (the figure/caption/art gaps), --jx-inset ×2 (the figure's air), --jx-text/--jx-line (title and description type), --jx-gap (the actions row) — the whole no-data composition breathes together. The NUMBER lane is inert: the coefficient stamps on the figure, but the channels compose at :root and the rung scopes — substitution runs at the declaring element (the declaring-element law). Number unit: coefficient.
color 'primary' | 'secondary' | 'error' | 'warn' | 'success' | 'info' | 'auto' | number | string'auto'SUPPLY-ONLY — stamps --jx-color-effective; no family css reads it (grep receipt: zero readers). The '0 items' ink rides --jx-primary — the theme's primary, never the hue carrier; hue that paints comes from the theme or the jx-hue-* injection. Number unit: hue degrees.
theme 'light' | 'dark' | 'system' | 'auto''auto'THE FROZEN POLE, measured: a resolved dark stamps .dark on the figure and NOTHING flips — the declaring-selector grep finds zero raw-token reads in the family's paint (every voice is the stylex :root emission: --jx-border/--jx-muted/--jx-card/--jx-foreground/--jx-muted-foreground/--jx-primary/--jx-shadow-2xs, plus theme-free kernel channels). The no-data state keeps the page profile inside any island; consumers who want a dark empty state compose it inside their own dark scope. light and system stamp nothing — tree inheritance.
elevation 'level-1' | 'level0' | 'level1' | 'level2' | 'level3' | 'level4' | 'level5' | 'auto' | number'auto'SUPPLY-ONLY — stamps --jx-elevation-effective; no family css reads it. The art box's one shadow is --jx-shadow-2xs — a fixed recipe token, not the §7 consumption pair. Number unit: dp.
motion 'reduced' | 'subtle' | 'normal' | 'expressive' | 'auto' | number'auto'SUPPLY-ONLY — stamps --jx-motion-effective; no family css reads it. The component is zero-JS with zero transitions — nothing animates, so the axis has nothing to step. Number unit: coefficient.

Deviations, cited: the adoption is the census batch D row (the long tail — openspec/changes/explicit-props/research/migration-census.md); empty is a leaf (grep receipt: no component mounts it), so the supply feeds only consumer compositions. The §1 collision rule: the figure is a <figure> with no native attribute names at stake — every axis name is the family's own destructured lane.

the eight axes on empty
<!-- density: the named rung re-bases the figure's rhythm —
     the --jx-stack/--jx-inset/--jx-text/--jx-line channels the
     figure, art and caption read -->
<Empty title="compact (sm rung)" density="small" />
<Empty title="touch (lg rung)" density="lg" />

<!-- theme: the FROZEN pole — no raw-token voice exists in the
     family's paint, so a resolved dark stamps .dark and nothing
     flips; the state keeps the page profile -->
<Empty title="dark island — byte-identical" theme="dark" />

empty · the consumed lane and the frozen pole

density="small" — data-density="sm"; the air and type compact

compact (sm rung)

density="lg" — data-density="lg"; the touch-size figure

touch (lg rung)

light — the ambient profile

light figure

theme="dark" — .dark stamps; nothing flips (the frozen pole)

dark island — byte-identical

The two bottom figures render byte-identical paint in either profile — the theme row's documented absence, not a bug: every painted voice is the stylex :root emission, and a scoped .dark never re-substitutes it.

empty-axes.svelte svelte
<!-- density: the named rung re-bases the figure's rhythm —
     the --jx-stack/--jx-inset/--jx-text/--jx-line channels the
     figure, art and caption read -->
<Empty title="compact (sm rung)" density="small" />
<Empty title="touch (lg rung)" density="lg" />

<!-- theme: the FROZEN pole — no raw-token voice exists in the
     family's paint, so a resolved dark stamps .dark and nothing
     flips; the state keeps the page profile -->
<Empty title="dark island — byte-identical" theme="dark" />
one real query() case
<script lang="ts">
  import Empty from '@ui/empty.svelte';
  import { query } from '@lib/universal-props-query.svelte';
  import type { DensityLane } from '@lib/defaults.svelte';
</script>

<Empty
  title="responsive figure"
  density={query<{ sm: DensityLane }, DensityLane>({ sm: 'small' }, 'large')}
/>

empty · query()

responsive figure

Media keys are min-width: below 40rem the base applies — the large rung, the roomy figure; at 40rem and wider the sm case wins and the composition compacts. Resize across 40rem.

empty-query-demo.svelte svelte
<script lang="ts">
  import Empty from '@ui/empty.svelte';
  import { query } from '@lib/universal-props-query.svelte';
  import type { DensityLane } from '@lib/defaults.svelte';
</script>

<Empty
  title="responsive figure"
  density={query<{ sm: DensityLane }, DensityLane>({ sm: 'small' }, 'large')}
/>
TokenDefaultSource
--jx-stackrung scale × coefficientdensity
--jx-insetrung scale × coefficientdensity
--jx-text / --jx-line10 / 11 / 12 / 13 / 15px · 14 / 16 / 18 / 20 / 24px (2xs → lg)density
--jx-gaprung scale × coefficientdensity
--jx-shadow-2xsfixed recipestructural

a11y

Accessibility

ARIA

AttributeValueDescription
figureempty rootGroups the no-data message.
figcaptiontitle + descriptionKeeps the message discoverable.
aria-hiddenillustrationPrevents decorative art from interrupting the message.
jixoai-ui ui.jixoai.com the jixoai design language

Theme

Brand hue

0°

Auto cycle · 24h