Skip to main content

Component Catalog

All components are imported from @espcompose/ui. They accept theme-driven design tokens and compile to LVGL widget trees.

Layout Components​

Screen​

Top-level page wrapper. Each <Screen> compiles to an <lvgl-page>.

PropTypeDefaultDescription
paddingSpacingToken—Inner padding
skipbooleanfalseExclude from LVGL page cycling (useful for boot screens)
<Screen padding="lg">
{/* Page content */}
</Screen>

Space / VStack / HStack​

Flexible layout container that arranges children with direction and gap. VStack and HStack are convenience wrappers.

PropTypeDefaultDescription
direction'horizontal' | 'vertical''vertical'Layout direction
gapSpacingToken—Gap between children
paddingSpacingToken—Inner padding
alignFlexAlign—Main-axis alignment ('start', 'center', 'end', 'spaceBetween', 'spaceAround', 'spaceEvenly')
crossAlignCrossAlign—Cross-axis alignment ('start', 'center', 'end', 'stretch')
wrapboolean—Allow wrapping
<VStack gap="md" align="center">
<Text text="Item 1" />
<Text text="Item 2" />
</VStack>

<HStack align="spaceBetween" crossAlign="center">
<Text text="Label" />
<Switch />
</HStack>

Row / Col​

Grid-like horizontal layout inspired by Ant Design. Row wraps by default; Col uses proportional width via flexGrow.

Row PropsTypeDefaultDescription
gutterSpacingToken | [SpacingToken, SpacingToken]—Gap between columns (single or [horizontal, vertical])
justifyFlexAlign'start'Horizontal alignment
alignCrossAlign'start'Vertical alignment
wrapbooleantrueAllow wrapping
Col PropsTypeDefaultDescription
spannumber1Proportional width (flexGrow)
<Row gutter="md">
<Col span={1}>
<Text text="Left" />
</Col>
<Col span={2}>
<Text text="Right (wider)" />
</Col>
</Row>

Grid / GridItem​

Native CSS Grid layout with explicit columns and rows.

Grid PropsTypeDefaultDescription
columnsTrackSize[]requiredColumn definitions: 'fr(n)', 'content', or pixel number
rowsTrackSize[]requiredRow definitions
columnGapSpacingToken—Gap between columns
rowGapSpacingToken—Gap between rows
gapSpacingToken—Shorthand for both gaps
GridItem PropsTypeDefaultDescription
colnumberrequiredColumn position (0-based)
rownumberrequiredRow position (0-based)
colSpannumber1Number of columns to span
rowSpannumber1Number of rows to span
<Grid columns={['fr(1)', 'fr(1)']} rows={['content', 'content']} gap="sm">
<GridItem col={0} row={0}><Text text="Top Left" /></GridItem>
<GridItem col={1} row={0}><Text text="Top Right" /></GridItem>
<GridItem col={0} row={1} colSpan={2}><Text text="Full Width" /></GridItem>
</Grid>

Card​

Styled container with rounded corners and themed background.

PropTypeDefaultDescription
paddingSpacingToken'md'Inner padding
radiusRadiusToken'md'Border radius
gapSpacingToken—Gap between children
<Card padding="lg" radius="lg">
<Text variant="subtitle" text="Settings" />
<Slider min={0} max={100} />
</Card>

Control Components​

Button​

Interactive button with optional label. Supports solid and outline variants with semantic status colors.

PropTypeDefaultDescription
textstring—Button label text
statusStatusToken'primary'Color scheme: 'primary', 'secondary', 'success', 'warning', 'danger'
sizeSizeToken'md'Size preset: 'xs', 'sm', 'md', 'lg', 'xl'
variant'solid' | 'outline''solid'Visual style
onPressTriggerHandler—Press event handler
<Button text="Save" status="success" size="lg" onPress={() => { /* save */ }} />
<Button text="Delete" status="danger" variant="outline" onPress={() => { /* delete */ }} />

Slider​

Horizontal slider control with themed track, indicator, and knob.

PropTypeDefaultDescription
valuenumber—Current value (reactive)
minnumber0Minimum value
maxnumber100Maximum value
onChangeTriggerHandler<{ x: number }>—Value change handler
<Slider min={0} max={255} onChange={({ x }) => { brightness.set(x); }} />

Switch​

Toggle switch control with themed rail and knob.

PropTypeDefaultDescription
valueboolean—Current state (reactive)
onChangeTriggerHandler<{ x: boolean }>—State change handler
<HStack align="spaceBetween" crossAlign="center">
<Text text="Night Mode" />
<Switch value={nightMode.value} onChange={({ x }) => { nightMode.set(x); }} />
</HStack>

Dropdown selection control.

PropTypeDefaultDescription
optionsstringrequiredNewline-separated list of options
valueunknown—Selected value (reactive)
onChangeTriggerHandler<{ x: number }>—Selection change handler (index)
<Dropdown
options={"Option A\nOption B\nOption C"}
onChange={({ x }) => { selection.set(x); }}
/>

Display Components​

Text​

Semantic text display with theme-driven typography.

PropTypeDefaultDescription
textstring—Text content (reactive)
variantTextVariant'body'Typography scale: 'title', 'subtitle', 'body', 'caption'
align'left' | 'center' | 'right' | 'auto'—Text alignment
colorStatusToken—Override text color with a status color
longMode'WRAP' | 'DOT' | 'SCROLL' | 'SCROLL_CIRCULAR' | 'CLIP'—Long text behavior
<Text variant="title" text="Dashboard" />
<Text variant="caption" text="Last updated: 5m ago" color="secondary" />

SensorText​

Text display automatically driven by a Home Assistant entity binding's stateText.

PropTypeDefaultDescription
bindingSensorBinding | BinarySensorBinding | LightBindingrequiredEntity binding from useHAEntity()
textstring—Optional static prefix/label
variantTextVariant—Typography scale
colorStatusToken—Override text color
const temp = useHAEntity('sensor.temperature');
<SensorText binding={temp} variant="title" />

Image​

Image display widget with size presets and optional border radius.

PropTypeDefaultDescription
srcRef<ImageRef>requiredImage ref from useImage()
sizeSizeToken—Size preset
radiusRadiusToken—Border radius
anglenumber—Rotation angle in degrees
zoomnumber—Zoom factor
antialiasboolean—Enable anti-aliasing
const logo = useImage({ file: './assets/logo.png', type: 'RGB' });
<Image src={logo} size="lg" radius="md" />

Spinner​

Loading spinner with theme-driven colors.

PropTypeDefaultDescription
statusStatusToken'primary'Color scheme
sizeSizeToken'md'Size preset
arcLengthnumber60Arc length in degrees
durationnumber1000Animation duration in milliseconds
<Spinner status="primary" size="lg" />

Design Token Types​

These token types are shared across all components:

TokenValues
SpacingToken'none', 'xs', 'sm', 'md', 'lg', 'xl'
SizeToken'xs', 'sm', 'md', 'lg', 'xl'
RadiusToken'none', 'sm', 'md', 'lg', 'full'
StatusToken'primary', 'secondary', 'success', 'warning', 'danger'
TextVariant'title', 'subtitle', 'body', 'caption'

See Theming for how these tokens map to actual pixel values and colors.