# Separator Guides

## Patterns

### Toolbar Divider

When to use:

- adjacent actions need a subtle visual boundary

Composition notes:

- use `orientation='vertical'`
- give the parent a real height

Trade-offs:

- low visual weight
- depends on parent sizing

```tsx
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)',
        padding: 'var(--spacing-2)',
        border: '1px solid var(--separator-opaque)',
        borderRadius: 'var(--radius-3)',
        background: 'var(--surface-primary)',
      }}
    >
      <IconButton aria-label='Bold' variant='secondary' appearance='transparent'>
        <Icon><Bold /></Icon>
      </IconButton>
      <IconButton aria-label='Italic' variant='secondary' appearance='transparent'>
        <Icon><Italic /></Icon>
      </IconButton>
      <IconButton aria-label='Insert link' variant='secondary' appearance='transparent'>
        <Icon><Link /></Icon>
      </IconButton>
      <Separator orientation='vertical' style={{ height: 'var(--spacing-10)', marginInline: 'var(--spacing-2)' }} />
      <IconButton aria-label='Bulleted list' variant='secondary' appearance='transparent'>
        <Icon><List /></Icon>
      </IconButton>
      <IconButton aria-label='Numbered list' variant='secondary' appearance='transparent'>
        <Icon><ListOrdered /></Icon>
      </IconButton>
      <Separator orientation='vertical' style={{ height: 'var(--spacing-10)', marginInline: 'var(--spacing-2)' }} />
      <IconButton aria-label='Align left' variant='secondary' appearance='transparent'>
        <Icon><AlignLeft /></Icon>
      </IconButton>
      <IconButton aria-label='Align center' variant='secondary' appearance='transparent'>
        <Icon><AlignCenter /></Icon>
      </IconButton>
    </div>
  );
}
```

### Section Break Inside A Panel

When to use:

- a panel has two related but distinct regions

Composition notes:

- keep the separator between already-labeled regions
- add spacing with layout, not with the separator itself

Trade-offs:

- keeps the surface clean
- does not explain the reason for the separation

```tsx
import { Card, Heading, Separator, Text } from '@vega-ui/react';

export default function SectionBreakInsideAPanel() {
  return (
    <Card style={{ display: 'grid', gap: 'var(--spacing-8)', width: '100%' }}>
      <section aria-labelledby='plan-usage-title' style={{ display: 'grid', gap: 'var(--spacing-2)' }}>
        <Heading as='h3' size={4} id='plan-usage-title'>Usage this month</Heading>
        <Text size={2} style={{ color: 'var(--label-secondary)', fontVariantNumeric: 'tabular-nums' }}>7,420 of 10,000 API requests used.</Text>
      </section>
      <Separator />
      <section aria-labelledby='plan-billing-title' style={{ display: 'grid', gap: 'var(--spacing-2)' }}>
        <Heading as='h3' size={4} id='plan-billing-title'>Next invoice</Heading>
        <Text size={2} style={{ color: 'var(--label-secondary)', fontVariantNumeric: 'tabular-nums' }}>$49.00 on April 1, charged to Visa ending in 4242.</Text>
      </section>
    </Card>
  );
}
```

### Dense Form Break

When to use:

- one form surface contains several short groups

Composition notes:

- use `Separator` together with explicit labels or legends
- avoid relying on the line alone

Trade-offs:

- keeps large forms readable
- still needs semantic section labeling nearby

```tsx
import {
  Button,
  Fieldset,
  FieldsetLegend,
  Label,
  Separator,
  Text,
  TextField,
  TextFieldInput,
} from '@vega-ui/react';
import { useState, type FormEvent } from 'react';

export default function DividerBetweenFieldGroups() {
  const [saved, setSaved] = useState('');

  const onSubmit = (event: FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    const data = new FormData(event.currentTarget);
    setSaved(`Saved ${data.get('fullName')} <${data.get('email')}>, ${data.get('company')}`);
  };

  return (
    <form
      onSubmit={onSubmit}
      onReset={() => setSaved('')}
      style={{ display: 'grid', gap: 'var(--spacing-12)', width: '100%' }}
    >
      <Fieldset style={{ display: 'grid', gap: 'var(--spacing-8)' }}>
        <FieldsetLegend style={{ marginBlockEnd: 'var(--spacing-8)' }}>Personal details</FieldsetLegend>
        <div style={{ display: 'grid', gap: 'var(--spacing-3)' }}>
          <Label htmlFor='billing-name'>Full name</Label>
          <TextField>
            <TextFieldInput id='billing-name' name='fullName' autoComplete='name' required />
          </TextField>
        </div>
        <div style={{ display: 'grid', gap: 'var(--spacing-3)' }}>
          <Label htmlFor='billing-email'>Email</Label>
          <TextField>
            <TextFieldInput id='billing-email' name='email' type='email' autoComplete='email' required />
          </TextField>
        </div>
      </Fieldset>
      <Separator />
      <Fieldset style={{ display: 'grid', gap: 'var(--spacing-8)' }}>
        <FieldsetLegend style={{ marginBlockEnd: 'var(--spacing-8)' }}>Company</FieldsetLegend>
        <div style={{ display: 'grid', gap: 'var(--spacing-3)' }}>
          <Label htmlFor='billing-company'>Company name</Label>
          <TextField>
            <TextFieldInput id='billing-company' name='company' autoComplete='organization' />
          </TextField>
        </div>
      </Fieldset>
      <div style={{ display: 'grid', gap: 'var(--spacing-6)' }}>
        <div style={{ display: 'flex', justifyContent: 'flex-end', gap: 'var(--spacing-4)' }}>
          <Button type='reset' variant='secondary' appearance='ghost'>Reset</Button>
          <Button type='submit'>Save</Button>
        </div>
        {saved && <Text size={2} role='status' style={{ color: 'var(--label-secondary)', overflowWrap: 'anywhere' }}>{saved}</Text>}
      </div>
    </form>
  );
}
```

## Comparison

### Quick Decision Rule

Use `Separator` for lightweight visual division. Use `Heading` or `Fieldset` when the UI needs named structure rather than only a line.

### `Separator` vs `Fieldset`

- Use `Separator` for visual division.
- Use `Fieldset` for grouped form semantics.

### `Separator` vs `Heading`

- Use `Separator` when no visible title is needed.
- Use `Heading` when the section needs a semantic label.

### `Separator` vs `Card`

- Use `Separator` inside an existing layout.
- Use `Card` when the whole section needs its own surface.

### Choose This Component When

- two adjacent regions need a subtle divider
- semantic grouping is already handled elsewhere

### Do Not Choose This Component When

- a section needs a label
- a set of controls needs native group semantics

## Troubleshooting

### The Vertical Divider Is Not Visible

#### Symptom

`orientation='vertical'` is set, but no divider is visible.

#### Likely Cause

The parent layout does not provide a height for the separator to fill.

#### How To Verify

- inspect the parent container height
- temporarily set an explicit height and check whether the divider appears

#### Fix

Give the parent a defined height or stretch context when using a vertical separator.

### The Divider Does Not Create Enough Space

#### Symptom

Content still feels cramped even though a separator is present.

#### Likely Cause

`Separator` only draws the line; it does not manage layout spacing.

#### How To Verify

- inspect surrounding gap, margin, or padding values

#### Fix

Add spacing in the parent layout and keep the separator responsible only for the visual division.

### The UI Has Dividers But Still Lacks Structure

#### Symptom

Sections are visually split, but users still cannot tell what each section means.

#### Likely Cause

Separators are being used where headings or form legends should carry the structure.

#### How To Verify

- remove the lines mentally and check whether section meaning remains clear

#### Fix

Add `Heading`, `Label`, or `FieldsetLegend` where semantic labeling is required.
