Flex
Flex provides a powerful and intuitive way to create flexible layouts using CSS Flexbox principles. It handles spacing, alignment, and direction with a clean API that works consistently across platforms.
Source
LLM docs
Package
Examples
4
Properties
41
Align Items
Item alignment options along the cross axis (flex-start, center, stretch, etc.).
Loading demo…
import { Block, Card, Flex, Text, useTheme } from '@plocks/ui';
const ALIGNMENTS = ['flex-start', 'center', 'flex-end', 'stretch', 'baseline'] as const;
export function Demo() {
const theme = useTheme();
// Baseline is only legible if each Text has a visible box; pull the fill from
// the theme so it reads in both light and dark.
const chip = { backgroundColor: theme.backgrounds.elevated, paddingHorizontal: 8 };
return (
// wrap="wrap" — five fixed-width examples in a row would overflow on narrow
// viewports, since flex children don't shrink by default here.
<Flex wrap="wrap" align="flex-start" gap="lg" fullWidth>
{ALIGNMENTS.map((value) => (
<Block key={value} gap="xs">
<Text variant="span" size="sm" c="muted">align="{value}"</Text>
<Card variant="subtle" p="sm">
{value === 'baseline' ? (
<Flex direction="row" align="baseline" gap="sm" h={80}>
{/* Text of varying sizes — their baselines line up, not their boxes */}
<Text variant="span" size={24} style={chip}>Aa</Text>
<Text variant="span" size={16} style={chip}>Bb</Text>
<Text variant="span" size={12} style={chip}>Cc</Text>
</Flex>
) : value === 'stretch' ? (
<Flex direction="row" align={value} gap="sm" h={80}>
{/* No fixed heights so children stretch to the container's cross-size */}
<Card p="xs" style={{ minWidth: 32 }}><Text variant="small">1</Text></Card>
<Card p="xs" style={{ minWidth: 32 }}><Text variant="small">2</Text></Card>
<Card p="xs" style={{ minWidth: 32 }}><Text variant="small">3</Text></Card>
</Flex>
) : (
<Flex direction="row" align={value} gap="sm" h={80}>
{/* Different heights to showcase flex-start/center/flex-end */}
<Card p="xs" h={40}><Text variant="small">A</Text></Card>
<Card p="xs" h={60}><Text variant="small">B</Text></Card>
<Card p="xs" h={30}><Text variant="small">C</Text></Card>
</Flex>
)}
</Card>
</Block>
))}
</Flex>
);
}Basics
Simple flex container with three items and gap spacing.
Loading demo…
import { Card, Flex, Text } from '@plocks/ui';
export function Demo() {
return (
<Flex gap="md" fullWidth>
<Card p="sm">
<Text>Item 1</Text>
</Card>
<Card p="sm">
<Text>Item 2</Text>
</Card>
<Card p="sm">
<Text>Item 3</Text>
</Card>
</Flex>
);
}Flex Direction
Row and column direction layouts for different item arrangements.
Loading demo…
import { Block, Card, Flex, Text } from '@plocks/ui';
export function Demo() {
return (
<Block fullWidth>
<Block>
<Text variant="span" size="sm" c="muted">direction="row"</Text>
<Flex direction="row" gap="md">
<Card p="sm"><Text>Item 1</Text></Card>
<Card p="sm"><Text>Item 2</Text></Card>
<Card p="sm"><Text>Item 3</Text></Card>
</Flex>
</Block>
<Block>
<Text variant="span" size="sm" c="muted">direction="column"</Text>
<Flex direction="column" gap="md">
<Card p="sm"><Text>Item 1</Text></Card>
<Card p="sm"><Text>Item 2</Text></Card>
<Card p="sm"><Text>Item 3</Text></Card>
</Flex>
</Block>
</Block>
);
}Justify Content
Content justification options along the main axis (flex-start, center, space-between, etc.).
Loading demo…
import { Block, Card, Flex, Text, useTheme, type FlexProps } from '@plocks/ui';
const JUSTIFY_OPTIONS: Array<{ label: string; value: NonNullable<FlexProps['justify']> }> = [
{ label: 'Start', value: 'flex-start' },
{ label: 'Center', value: 'center' },
{ label: 'End', value: 'flex-end' },
{ label: 'Between', value: 'space-between' },
{ label: 'Around', value: 'space-around' },
{ label: 'Evenly', value: 'space-evenly' },
];
export function Demo() {
const theme = useTheme();
return (
<Block align="stretch">
{JUSTIFY_OPTIONS.map(({ value }) => (
<Block key={value} align="stretch">
<Text variant="span" size="sm" c="muted">justify="{value}"</Text>
<Flex
direction="row"
justify={value}
mih={60}
style={{
// Give the row a large track to clearly expose free space
width: 600,
maxWidth: '100%',
borderWidth: 1,
borderStyle: 'dashed' as const,
// Without an explicit color the dashed track falls back to black
// in both themes.
borderColor: theme.backgrounds.border,
borderRadius: 4
}}
>
{/* Small fixed squares with no shrink so free space is obvious */}
<Card padding={0} style={{ width: 40, height: 40, flexShrink: 0, alignItems: 'center', justifyContent: 'center' }}>
<Text variant="small">A</Text>
</Card>
<Card padding={0} style={{ width: 40, height: 40, flexShrink: 0, alignItems: 'center', justifyContent: 'center' }}>
<Text variant="small">B</Text>
</Card>
<Card padding={0} style={{ width: 40, height: 40, flexShrink: 0, alignItems: 'center', justifyContent: 'center' }}>
<Text variant="small">C</Text>
</Card>
</Flex>
</Block>
))}
</Block>
);
}React Native design for iOS, Android, and Web.
Quick Links
Resources