State
A State represents a meaningful variation, condition, or status variant of a screen surface.
Definition & Purpose
A State describes a distinct, observable condition of a screen. While a screen defines where a user is, a state defines what condition that surface is currently displaying (e.g. default, empty, loading, error, past_due).
Compact vs Expanded Format
UXDL supports two syntax formats for declaring states:
# Compact Format (String description):states: default: Ready for user input payment_failed: Gateway declined card# Expanded Format (Object with metadata):states: payment_failed: name: Payment Declined metadata: analytics_id: "evt_pay_failed" error_code: "card_declined"Address Syntax & Examples
State addresses append .states.state_id to the owning screen address:
Address format:screen_id.states.state_idReal-world domain address examples:- checkout.states.payment_failed- billing.states.past_due- sign_in.states.invalid_credentials- dashboard.states.empty_workspaceFlowchart Node Presentation
In Canvas view, states render as variant tags inside their parent screen card. When targeted by a relation arrow, the edge connects directly to the specific target state tag.
Complete Valid Example
Here is a screen with 4 distinct states representing a payment lifecycle:
screens: checkout: name: Checkout Surface type: page states: default: Ready for credit card input processing: Submitting payment transaction payment_failed: Gateway declined card (grace period active) session_expired: Security token timed outWhat a State Does NOT Mean
A UXDL State is NOT component local state (React useState), NOT a Redux/Zustand store object, and NOT a database row column value. It describes an observable user-facing surface variation.
Connected Primitives & Best Practices
- Screen — Every state MUST belong to exactly one parent screen.
- Relation — Relations target specific states using 'to: screen_id' and 'state: state_id'.
- Contextual Linter — The linter flags screens missing error or empty state coverage.