Skip to content

Separator ​

A separator draws the line between two groups of content. It is a real role="separator" rather than a border, which is the point: a border says the box has an edge, a separator says these things are not the same things.

ts
import { Separator } from "ropav";
variant
orientation
template
<div
  style="display: flex; flex-direction: column; gap: calc(var(--rp-spacing) * 4); width: 100%; max-width: var(--rp-container-xs)"
>
  <Button variant="secondary">Undo</Button>
  <Separator />
  <Button>Publish</Button>
</div>

orientation decides the axis, and the box around the rule has to agree with it — which is why the snippet above carries one. Inside a Toolbar neither needs setting: a separator falls back to the toolbar's cross axis, because a rule between controls in a row has to run down the page. Set it explicitly anywhere else.

Between things in a row ​

The same component does both jobs: full width between stacked blocks, and a hairline between items on one line. A vertical separator sizes itself from its flex parent, so it needs a row with a height to stretch into.

Ropav

A component library for Vue.

Blog

Docs

Source

separator-inline.vue
vue
<script setup lang="ts">
import { Separator, Typography } from "ropav";

const links = ["Blog", "Docs", "Source"] as const;
</script>

<template>
  <div class="panel">
    <Typography type="h4">Ropav</Typography>
    <Typography class="note" type="body-sm">A component library for Vue.</Typography>

    <Separator class="rule" />

    <div class="row">
      <template v-for="(link, index) in links" :key="link">
        <Separator v-if="index > 0" orientation="vertical" />
        <Typography type="body-sm">{{ link }}</Typography>
      </template>
    </div>
  </div>
</template>

<style scoped>
.panel {
  width: 100%;
  max-width: var(--rp-container-md);
}

.panel .note {
  color: var(--rp-muted);
}

.panel .rule {
  margin-block: calc(var(--rp-spacing) * 4);
}

.row {
  display: flex;
  height: calc(var(--rp-spacing) * 5);
  align-items: center;
  gap: calc(var(--rp-spacing) * 4);
}
</style>

variant is the weight — default, secondary and tertiary in descending contrast. Under forced colours all three flatten to the same ink, because the mode has no second tier to give them; a separator that has to be distinguishable from another separator is asking colour to carry structure.

Accessibility ​

  • The rule is a real role="separator", so a reader moving through the document is told where one group ends rather than silently crossing into the next.
  • A separator inside a ButtonGroup or a ToggleButtonGroup is a different component and a decorative one — ButtonGroupSeparator is aria-hidden, because the group is already one control and a rule inside it divides nothing.
  • Do not reach for one where whitespace would do. A separator every few rows is structure; a separator between every row is noise a screen reader has to read through.

API ​

PropTypeDefaultDescription
orientation"horizontal" | "vertical""horizontal"Axis the separator divides along. Falls back to the cross axis of an enclosing Toolbar, which is where a rule between its controls has to run.
variant"default" | "secondary" | "tertiary""default"Visual weight.