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.

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=&quot;{value}&quot;</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> ); }
Scan to open this page on your phoneplocks.dev/ui/Flex