Stack
One-dimensional stacking with a consistent gap, plus the HStack and VStack presets.
Design review at 10:00
Ship the docs site
Water the plants
import { VStack, Box, Text } from "astralis-ui";
export function StackDemo() {
return (
<VStack gap="3" alignItems="stretch" w="full" maxW="sm">
{["Design review at 10:00", "Ship the docs site", "Water the plants"].map((task) => (
<Box key={task} bg="subtle" p="4" rounded="lg" border="normal" borderColor="base">
<Text size="sm">{task}</Text>
</Box>
))}
</VStack>
);
}direction
Layout & spacing
gap
alignItems
justifyContent
p
import { Box, Stack } from "astralis-ui";
<Stack>
<Box p="4" bg="subtle" rounded="md">One</Box>
<Box p="4" bg="subtle" rounded="md">Two</Box>
<Box p="4" bg="subtle" rounded="md">Three</Box>
</Stack>
Import#
import { Stack, HStack, VStack } from "astralis-ui";Usage#
Stack is the shorthand for the most common flex layout: children in one
direction with even spacing. VStack stacks vertically, HStack lays out
horizontally and centers its children on the cross axis, usually what
you want for rows of mixed-height content.
Orbit weekly
12 unread updates
import { HStack, Box, Text, Button } from "astralis-ui";
export function StackHorizontal() {
return (
/* HStack centers its children vertically by default. */
<HStack gap="4" bg="subtle" p="4" rounded="xl" border="normal" borderColor="base">
<Box size="12" bg="purple" rounded="full" />
<Box>
<Text size="sm" weight="semibold">Orbit weekly</Text>
<Text size="xs" color="muted">12 unread updates</Text>
</Box>
<Button size="sm" variant="subtle" colorScheme="purple">
Open
</Button>
</HStack>
);
}Direction#
The base Stack takes a direction prop if you'd rather not pick a preset.
It speaks in axes ("vertical" and "horizontal") rather than CSS's
column and row.
One
Two
One
Two
import { Stack, Box, Text, VStack } from "astralis-ui";
export function StackDirection() {
return (
<VStack gap="5" alignItems="stretch">
<VStack gap="1" alignItems="stretch">
<Text as="span" size="xs" color="muted">vertical (default)</Text>
<Stack gap="2">
<Box bg="cyan-subtle" px="4" py="2" rounded="md"><Text size="xs">One</Text></Box>
<Box bg="cyan-muted" px="4" py="2" rounded="md"><Text size="xs">Two</Text></Box>
</Stack>
</VStack>
<VStack gap="1" alignItems="stretch">
<Text as="span" size="xs" color="muted">horizontal</Text>
<Stack direction="horizontal" gap="2">
<Box bg="cyan-subtle" px="4" py="2" rounded="md"><Text size="xs">One</Text></Box>
<Box bg="cyan-muted" px="4" py="2" rounded="md"><Text size="xs">Two</Text></Box>
</Stack>
</VStack>
</VStack>
);
}direction is responsive like every other style prop, so the most common
layout of all (stacked on mobile, side by side on desktop) is one prop:
One
Two
Three
import { Stack, Box, Text } from "astralis-ui";
export function StackResponsive() {
return (
/* Resize the window: vertical below md, horizontal from md up. */
<Stack
direction={{ base: "vertical", md: "horizontal" }}
gap="3"
w="full"
maxW="md"
>
<Box bg="cyan-subtle" px="4" py="3" rounded="lg">
<Text size="xs">One</Text>
</Box>
<Box bg="cyan-muted" px="4" py="3" rounded="lg">
<Text size="xs">Two</Text>
</Box>
<Box bg="cyan-muted" px="4" py="3" rounded="lg">
<Text size="xs">Three</Text>
</Box>
</Stack>
);
}For two-dimensional layouts or per-child control, step up to Flex or Grid.
Props#
Stack extends Flex (and therefore Box).
| Prop | Type | Default | Description |
|---|---|---|---|
direction | "horizontal" | "vertical" | "vertical" | Stacking axis, responsive like every other style prop: direction={{ base: "vertical", md: "horizontal" }} is stack-on-mobile, row-on-desktop. HStack and VStack are presets with this fixed (HStack also centres on the cross axis). |
gap | "0" – "96" (spacing scale) | None | Space between children. |
alignItems · justifyContent · wrap … | Flex props | None | Stack is a Flex preset: every Flex and Box prop works. |