EmDivider
A rule between things — horizontal or vertical, with an optional center label. The component picks the element and the ARIA for each shape so you never have to.
Usage
EmDivider has one prop and one slot. orientation turns the line vertical; the default slot, when you fill it, becomes a small centered label with the line running out to both sides of it.
An empty horizontal divider renders a native hr, so the common case is the semantic one for free. The vertical and labeled shapes swap to div-based rendering because the platform element cannot express them — the details are under Composed on v0.
Anatomy
<script setup lang="ts">
import { EmDivider } from '@paper/emerald'
</script>
<template>
<EmDivider />
</template>Composed on v0
EmDivider renders a single Atom — v0’s polymorphic foundation element — and the whole component is really a decision about what to ask that Atom to be:
No label, horizontal — the Atom renders as
hr. The platform supplies the separator semantics; Emerald supplies only the stroke.No label, vertical —
hris unavoidably horizontal, so the Atom renders as adivcarryingrole="separator"andaria-orientation="vertical", restating by hand what the native element would have said.Labeled — the Atom renders as a
divwith no separator role at all. That is deliberate:role="separator"treats its children as presentational, so putting it on the wrapper would strip the label’s text from the accessibility tree. Instead the two flanking line spans arearia-hiddenand the label reads as ordinary content.
The anatomy is fixed — as and renderless are not part of the prop surface, because the element choice above is the component’s job. Styling hangs entirely off the attributes the template writes: data-orientation for direction and data-labeled for the labeled shape; there are no state classes.
Examples
Props
| Prop | Type | Default | Description |
|---|---|---|---|
orientation | 'horizontal' | 'vertical' | 'horizontal' | Direction of the rule. Also decides the rendered element and ARIA — see Composed on v0 |
The default slot is the optional label; filling it switches the component to its labeled shape. There are no named slots and no events.
Accessibility
Each of the three shapes says something different to assistive technology, and each is the correct statement for that shape:
| Shape | Rendered as | Semantics |
|---|---|---|
| Horizontal, no label | hr | Implicit separator role from the platform |
| Vertical, no label | div | Explicit role="separator" with aria-orientation="vertical" |
| Labeled | div | No role. Lines are aria-hidden; the label reads as plain text |
The labeled shape carrying no role is the part worth understanding rather than “fixing”. A separator is children-presentational — assistive technology discards everything inside it — so a labeled divider marked as a separator would announce as an anonymous rule and swallow its own words. Emerald keeps the words and gives up the role, which is the better half of that trade: the lines are decoration, the label is content.
The divider is never focusable and has no keyboard behavior in any shape. ARIA’s focusable-separator variant is a window splitter — a control that moves — and a divider that only draws a line must not take a tab stop. If you need a draggable divider between panes, that is Splitter, not this component.