import { Separator, Text } from '@vega-ui/react';
<div>
<Text size={3}>Profile</Text>
<Separator />
<Text size={3}>Billing</Text>
<Separator />
<Text size={3}>Security</Text>
</div>- Browser support
- Widely available
- Chrome 111
- Edge 111
- Firefox 113
- Safari 15.4
- Safari on iOS 15.4
- Bundle size
- Oklab and OkLCh — comes from the design tokens
- :where()
Summary
Separator is the visual division primitive for horizontal and vertical boundaries between adjacent UI regions.
Imports
import { Separator, type SeparatorProps } from '@vega-ui/react';Exported Types
SeparatorProps
Basic Usage
import { Heading, Separator, Text } from '@vega-ui/react';
export default function BasicUsage() {
return (
<div style={{ display: 'grid', gap: 'var(--spacing-8)', width: '100%' }}>
<div style={{ display: 'grid', gap: 'var(--spacing-2)' }}>
<Heading as='h3' size={4}>Notifications</Heading>
<Text size={2} style={{ color: 'var(--label-secondary)' }}>Email me when someone mentions me or assigns me a task.</Text>
</div>
<Separator />
<div style={{ display: 'grid', gap: 'var(--spacing-2)' }}>
<Heading as='h3' size={4}>Privacy</Heading>Variants
- Orientation:
horizontalorvertical - Layout: full-width horizontal rule or full-height vertical divider
Edge Cases
- Vertical separators need an explicit height from the parent layout.
- The component is visual; surrounding layout still determines spacing.
- Decorative separators should not replace real headings or fieldset grouping.
Common Mistakes
- Rendering a vertical separator without a defined parent height.
- Using separators where semantic grouping is actually needed.
- Expecting
Separatorto provide layout spacing on its own.
Examples
Basic
Basic: order summary divider
A horizontal Separator stretches to the width of its container and sets the total apart from the line items. Spacing comes from the parent gap, not from the separator.
import { Separator, Text } from '@vega-ui/react';
const items = [
{ name: 'Wireless keyboard', price: '$89.00' },
{ name: 'USB-C hub, 7 ports', price: '$45.00' },
{ name: 'Shipping', price: '$6.50' },
];
export default function HorizontalSectionDivider() {
return (
<div style={{ display: 'grid', gap: 'var(--spacing-6)', width: '100%' }}>
{items.map((item) => (Controlled/Stateful
Controlled/Stateful: dividers between visible groups only
Separators are rendered between groups and never before the first one, so filtering a group out cannot leave a doubled or dangling line. Each group stays a section labelled by its heading, so the structure does not rely on the line.
import { Button, Heading, Separator, Text } from '@vega-ui/react';
import { Fragment, useState } from 'react';
const projects = [
{ name: 'Website redesign', status: 'active' },
{ name: 'Mobile onboarding', status: 'active' },
{ name: 'Q3 pricing test', status: 'paused' },
{ name: 'Legacy API migration', status: 'archived' },
{ name: 'Holiday campaign', status: 'archived' },
];
const groups = [Form/Integration
Form/Integration: divider between field groups
Two Fieldset groups with their own legends, separated by a line. The separator is only visual: the legends give the groups their accessible names, and the submit reads both groups with FormData.
import {
Button,
Fieldset,
FieldsetLegend,
Label,
Separator,
Text,
TextField,
TextFieldInput,
} from '@vega-ui/react';
import { useState, type FormEvent } from 'react';
Layout/Overlay
Layout/Overlay: vertical dividers in a toolbar
Vertical separators split a role='toolbar' into formatting, list and alignment groups. A vertical separator takes height: 100%, so the toolbar has an explicit height; every icon button gets its own aria-label.
import { Icon, IconButton, Separator } from '@vega-ui/react';
import { AlignCenter, AlignLeft, Bold, Italic, Link, List, ListOrdered } from '@vega-ui/icons';
export default function VerticalDividerInToolbar() {
return (
<div
role='toolbar'
aria-label='Text formatting'
style={{
display: 'flex',
alignItems: 'center',
gap: 'var(--spacing-2)',Error
Error: divider before the danger zone
The separator sets the destructive form apart from regular settings. The confirmation is checked on submit: a mismatch marks the field invalid and links the HelperText with aria-describedby, and typing clears the error.
import {
Button,
Heading,
HelperText,
Label,
Separator,
Text,
TextField,
TextFieldInput,
} from '@vega-ui/react';
import { useState, type CSSProperties, type FormEvent } from 'react';
Disabled
Disabled: separator in a disabled fieldset
Separator has no disabled state: it sits inside a Fieldset that is disabled as a whole, and the explanation is linked to the fieldset with aria-describedby. The toggle shows the same layout in both states.
import {
Button,
Fieldset,
FieldsetLegend,
Label,
Separator,
Text,
TextField,
TextFieldInput,
} from '@vega-ui/react';
import { useState } from 'react';
Edge
Edge: vertical divider without a fixed height
height: 100% collapses to zero when the parent has no definite height. In a row whose height comes from its content, override it with height: 'auto' and alignSelf: 'stretch' so the line takes the height of the row.
import { Separator, Text } from '@vega-ui/react';
const stats = [
{ label: 'Revenue', value: '$12.4k' },
{ label: 'Orders', value: '318' },
{ label: 'Refunds', value: '4' },
];
export default function ConstrainedVerticalDivider() {
return (
<div style={{ display: 'flex', gap: 'var(--spacing-10)' }}>
{stats.map((stat, index) => (Edge: decorative divider
Inside a list every role='separator' is announced between the items. When the line is purely decorative, pass aria-hidden so screen readers hear only the list items.
import { Separator, Text } from '@vega-ui/react';
const posts = [
{ title: 'Release notes 3.2', date: 'Mar 12' },
{ title: 'Dark mode for charts', date: 'Mar 5' },
{ title: 'Faster CSV exports', date: 'Feb 26' },
];
export default function DecorativeDivider() {
return (
<ul style={{ display: 'grid', gap: 'var(--spacing-6)', width: '100%', margin: 0, padding: 0, listStyle: 'none' }}>
{posts.map((post, index) => (Anatomy
Overview
Separator is a single-part primitive that renders a thin dividing line with role='separator'.
Required Parts
Separator
Required. Owns both the semantic divider role and the visual line.
Optional Parts
There are no exported child parts.
Composition Order
Separator
Valid Composition Patterns
A horizontal separator between the content and the footer, and a vertical one between the footer actions. The footer row has an explicit height because a vertical separator takes height: 100% of its parent.
import { Button, Card, Heading, Separator, Text } from '@vega-ui/react';
export default function ValidCompositionPatterns() {
return (
<Card style={{ display: 'grid', gap: 'var(--spacing-8)', width: '100%' }}>
<div style={{ display: 'grid', gap: 'var(--spacing-2)' }}>
<Heading as='h3' size={4}>Quarterly report</Heading>
<Text size={2} style={{ color: 'var(--label-secondary)' }}>Revenue grew 12% compared to the previous quarter.</Text>
</div>
<Separator />
<div style={{ display: 'flex', alignItems: 'center', gap: 'var(--spacing-4)', height: 'var(--spacing-16)' }}>
<Button size='sm' variant='secondary' appearance='ghost'>Download PDF</Button>Invalid Composition Patterns
Vertical separator without parent height
The divider collapses because it has no height context.
Separator used as the only section structure
This creates visual division without semantic labeling.