Flex
Composable flex container with VStack and HStack helpers
One
Two
Three
Left
Right
import { Flex, VStack } from '@/components/flex';
const Box = ({ children }: { children: React.ReactNode }) => (
<div className="rounded-md bg-background-secondary px-3 py-2 text-foreground-secondary text-sm">
{children}
</div>
);
export default function FlexPreview() {
return (
<VStack gap="lg">
<Flex gap="sm" align="center">
<Box>One</Box>
<Box>Two</Box>
<Box>Three</Box>
</Flex>
<Flex justify="between" align="center">
<Box>Left</Box>
<Box>Right</Box>
</Flex>
</VStack>
);
} Dependencies
Source Code
import type { VariantProps } from 'cva';
import { Slot } from '@/components/slot';
import { cn, cva } from '@/lib/utils/classnames';
const flexStyle = cva({
base: 'flex',
variants: {
direction: {
row: 'flex-row',
col: 'flex-col',
'row-reverse': 'flex-row-reverse',
'col-reverse': 'flex-col-reverse',
},
align: {
start: 'items-start',
center: 'items-center',
end: 'items-end',
stretch: 'items-stretch',
baseline: 'items-baseline',
},
justify: {
start: 'justify-start',
center: 'justify-center',
end: 'justify-end',
between: 'justify-between',
around: 'justify-around',
evenly: 'justify-evenly',
},
wrap: {
true: 'flex-wrap',
false: 'flex-nowrap',
},
gap: {
none: 'gap-0',
xs: 'gap-1',
sm: 'gap-2',
md: 'gap-4',
lg: 'gap-6',
xl: 'gap-8',
'2xl': 'gap-12',
},
},
defaultVariants: {
direction: 'row',
align: 'stretch',
justify: 'start',
gap: 'md',
},
});
interface FlexProps
extends React.ComponentPropsWithRef<'div'>,
VariantProps<typeof flexStyle> {
asChild?: boolean;
}
const Flex = ({
ref,
className,
direction,
align,
justify,
wrap,
gap,
asChild,
...rest
}: FlexProps) => {
const Comp = asChild ? Slot : 'div';
return (
<Comp
ref={ref}
className={cn(
flexStyle({ direction, align, justify, wrap, gap }),
className
)}
{...rest}
/>
);
};
const VStack = ({ ref, ...props }: Omit<FlexProps, 'direction'>) => (
<Flex ref={ref} direction="col" {...props} />
);
const HStack = ({ ref, ...props }: Omit<FlexProps, 'direction'>) => (
<Flex ref={ref} direction="row" {...props} />
);
export type { FlexProps };
export { Flex, flexStyle, HStack, VStack }; Server component. No
'use client'— flex layout primitive; no hooks or own handlers.
Flex is a thin, expressive wrapper around CSS flexbox. VStack and HStack
are convenience exports that lock the direction.
Anatomy
<Flex direction="row" gap="md" align="center" justify="between">
{children}
</Flex>
API Reference
Extends the div element.
| Prop | Default | Type |
|---|---|---|
direction | "row" | "row""col""row-reverse""col-reverse" |
align | "stretch" | "start""center""end""stretch""baseline" |
justify | "start" | "start""center""end""between""around""evenly" |
wrap | - | boolean |
gap | "md" | "none""xs""sm""md""lg""xl""2xl" |
asChild | - | boolean |
Examples
Default
One
Two
Three
Left
Right
import { Flex, VStack } from '@/components/flex';
const Box = ({ children }: { children: React.ReactNode }) => (
<div className="rounded-md bg-background-secondary px-3 py-2 text-foreground-secondary text-sm">
{children}
</div>
);
export default function FlexPreview() {
return (
<VStack gap="lg">
<Flex gap="sm" align="center">
<Box>One</Box>
<Box>Two</Box>
<Box>Three</Box>
</Flex>
<Flex justify="between" align="center">
<Box>Left</Box>
<Box>Right</Box>
</Flex>
</VStack>
);
} Previous
File Upload
Next
Grid