Browse docs
Browse docs
A visual line that says "things on one side, different things on the other". Two modes: a plain line, or a labeled separator with the line on both sides of the label (<Divider>OR</Divider> — the universal sign-in pattern).
import { Divider, Typography } from '@dashforge/tw';
{/* Plain line */}
<Divider />
{/* Labeled — "OR" pattern */}
<Divider>
<Typography variant="overline">OR</Typography>
</Divider>{/* Between sections */}
<Typography variant="h2">Profile</Typography>
<Divider sx="my-6" />
<Typography variant="h2">Notifications</Typography>
{/* OR pattern in sign-in */}
<Button color="primary" fullWidth>Continue with Google</Button>
<Divider sx="my-4">OR</Divider>
<TextField name="email" label="Email" />
{/* Vertical inside a Stack row */}
<Stack direction="row" align="center" gap={3}>
<Typography>Item A</Typography>
<Divider orientation="vertical" sx="h-6" />
<Typography>Item B</Typography>
</Stack>divider propBoth insert visual separators between things. Use which one:
| Scenario | Use |
|---|---|
| You want a separator BETWEEN every pair of children in a list | <Stack divider={<Divider />}> — the prop handles N-1 insertion |
| You want ONE separator at a specific place | <Divider /> standalone |
| You need an "OR" label between two pieces of content | <Divider>OR</Divider> (Stack's divider is meant for repeating separators, not labels) |
| You want vertical separator between flex row items | Either — Stack's divider works for repeating, standalone Divider for one-off |
Section A — first paragraph
Section B — after solid divider
Section C — after dashed divider
import { Divider, Stack, Typography } from '@dashforge/tw';
<Stack gap={3}>
<Typography variant="body2">Section A — first paragraph</Typography>
<Divider />
<Typography variant="body2">Section B — after solid divider</Typography>
<Divider variant="dashed" />
<Typography variant="body2">Section C — after dashed divider</Typography>
</Stack><Divider /> {/* solid (default) */}
<Divider variant="dashed" />
<Divider variant="dotted" />Solid for the canonical separator. Dashed/dotted for "draft state", "less authoritative", or simply visual variety.
<Divider /> {/* neutral */}
<Divider color="primary" />
<Divider color="success" />
<Divider color="warning" />
<Divider color="danger" />Colored dividers are useful when the divider IS the message: a red one above an "Irreversible action" section, a green one between "Old plan" and "New plan" in an upgrade flow.
<Divider>OR</Divider>
<Divider><Typography variant="overline">OR</Typography></Divider>
<Divider>Continue with</Divider>
<Divider><strong>Section title</strong></Divider>Any node works as the label — string, Typography element, custom JSX. Recommended: <Typography variant="overline"> for short uppercase labels (matches the meta-text rhythm of section kickers).
The implementation renders two flex line segments either side of the label, with a small horizontal padding around the label so it doesn't kiss the lines.
<Divider align="start"> Title hugs left</Divider>
<Divider align="center">Title centered (default)</Divider>
<Divider align="end"> Title hugs right</Divider>start/end leave a short ~32px stub on the squashed side (rather than collapsing to zero) so the divider visually exists on both sides regardless of alignment.
{/* Between row items */}
<Stack direction="row" align="center" gap={3}>
<Typography variant="body2">Logged in</Typography>
<Divider orientation="vertical" sx="h-4" />
<Typography variant="body2" color="muted">2 minutes ago</Typography>
</Stack>
{/* As a column splitter */}
<Box fullHeight>
<Stack direction="row" fullHeight>
<NavSidebar />
<Divider orientation="vertical" />
<MainContent />
</Stack>
</Box>Vertical dividers need a height context — they take the height of their parent flex row via self-stretch. When that doesn't work (no flex parent), set sx="h-N" explicitly.
<Box variant="outlined" rounded="xl" p={6}>
<Typography variant="h3">Profile</Typography>
<Stack gap={3} sx="mt-4">
<TextField name="name" label="Display name" />
<TextField name="email" label="Email" />
</Stack>
<Divider sx="my-6" />
<Typography variant="h3">Security</Typography>
<Stack gap={3} sx="mt-4">
<Switch label="Two-factor authentication" />
</Stack>
</Box>import { Divider, Stack, Button, Typography } from '@dashforge/tw';
<Stack gap={4}>
<Button color="primary" fullWidth>Sign in with Google</Button>
<Divider>
<Typography variant="overline" color="muted">OR</Typography>
</Divider>
<Button variant="outline" fullWidth>Continue with email</Button>
</Stack><Stack gap={4}>
<Button color="primary" fullWidth>Continue with Google</Button>
<Button variant="outlined" fullWidth>Continue with GitHub</Button>
<Divider>
<Typography variant="overline" color="muted">or</Typography>
</Divider>
<Stack gap={3}>
<TextField name="email" type="email" label="Email" />
<TextField name="password" type="password" label="Password" />
<Button color="primary" fullWidth>Sign in</Button>
</Stack>
</Stack>| Prop | Type | Default | Description |
|---|---|---|---|
orientation | 'horizontal' | 'vertical' | 'horizontal' | Line direction. |
variant | 'solid' | 'dashed' | 'dotted' | 'solid' | Border-style. |
color | 'neutral' | 'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'info' | 'neutral' | Border-color intent. |
align | 'start' | 'center' | 'end' | 'center' | Label position (labeled mode only). |
children | ReactNode | — | When present → labeled mode (3 elements). Absent → line-only mode (1 element). |
flexItem | boolean | false | Forward-compat hook for MUI parity (currently a no-op — self-stretch is on by default for vertical). |
sx | string | — | Utility-class override, merged via tailwind-merge. |
| ...rest | HTMLAttributes | — | Native attributes pass through. |
| Mode | Triggered when | Renders |
|---|---|---|
| Line-only | children is absent/null | <hr> (horizontal) or <div role="separator"> (vertical) with line classes |
| Labeled | children is provided | <div role="separator"> wrapping 2 <span aria-hidden> line segments + 1 <span> label |
role="separator" (implicit on <hr>, explicit on <div>)aria-orientation: "horizontal" or "vertical" always setaria-hidden (the separator role lives on the root; duplicating on children would confuse AT)import { dividerVariants, dividerLineVariants } from '@dashforge/tw';
// dividerVariants({ orientation: 'horizontal', align: 'center' }) → root className
// dividerLineVariants({ orientation: 'horizontal', variant: 'solid', color: 'primary', segment: 'grow' }) → line classNameTwo TV recipes (root + line) because labeled mode renders 3 elements while line-only mode renders 1 — splitting keeps each catalogue small.
<hr> for horizontal line-only: gives implicit role="separator" for screen readers without an extra attribute. We zero out the UA default border via border-0 and re-apply ours.<div> because <hr> can't be vertical cross-browser-consistently. Same role="separator" is set explicitly.align="start" / "end" uses a 32px stub on the squashed side rather than collapsing to zero — keeps the divider visually present on both sides.flexItem is a no-op for now: self-stretch is already on the vertical line by default. Kept in the API for MUI Divider parity and as a forward-compat hook.<Stack divider={<Divider />}> instead of intermingling <Divider /> between every child. The Stack divider prop handles N-1 insertion cleanly.<Box sx="mt-12"> (more vertical space) communicates the section break without an explicit line.