GrDivider

  • core
  • data
  • API · 8 props

Separates content with a line, optionally with a centered label.

import { GrDivider } from '@feugene/granularity/components/GrDivider'

Overview

When to take it

  • blocks have to be separated — the sections of a form, groups of menu items, parts of a card;
  • the separator has a label — “or”, “More”, a date in a feed of messages;
  • the separation is horizontal — a vertical line in a toolbar or an action bar;
  • native semantics is needed — without a label it renders as an <hr> with the implicit separator role.

When to take something else

NeedTake
The boundary is moved by the userGrSplitter
Sections with headings are being separatedGrFormSection
Menu items are being separatedGrDropdownMenu with dividers
The rows of a list are being separatedGrList with divided

Variants every tone and view, rendered by the real component

variant

  • solid
  • dashed
  • dotted

Playground controls come from the API, not from hand

Stage

Loading…

0 changed· state is in the URL

Examples 5 each with a live demo and its code

  • A word in the break

    label puts «or» between two ways to sign in and becomes the accessible name, so a screen reader hears «or, separator». spacing gives the line air on both sides without margins on the neighbours.

    Sign in to Acme

    Use your work account

  • Dates and the new-message mark

    The default slot takes markup — a date pill, a red «New». A separator hides its content from screen readers, so the slot gets aria-label. align="end" moves the word to the edge, and --gr-brd recolours the line.

    GW
    Grace Wu 17:42

    Retries are in. Five attempts with backoff, then the event goes to the dead-letter queue.

    LR
    Linus Ray 09:05

    Ran it against staging overnight: 1,284 events, zero lost.

    AL
    Ada Lin 09:31

    Approved. Let’s ship it after the 10:00 deploy.

  • Groups of tools in a row

    orientation="vertical" splits a toolbar into groups and stretches to the height of the flex row by itself. In the status bar the line is shorter than the row — length sets it, and outside a flex row it is the only way to give the line a height.

    Webhook retries

    Failed deliveries are retried five times with exponential backoff before the event moves to the dead-letter queue.

    Saved214 wordsMarkdown
  • Weight of the line carries meaning

    variant="dotted" between the rows of one list, dashed before adjustments that are not final, and a solid line of thickness="2" that closes the sum. Thickness goes to --gr-divider-thickness, so it can also come from a container.

    Order summary

    Team plan · 9 seats€432.00

    Extra storage · 180 GB€36.00

    Automation runs over quota€12.40

    Subtotal€480.40
    Annual discount-€48.00
    VAT 20 %€86.48

    Total due€518.88

API generated from the package · cannot drift

Props

PropTypedefaultDescription
lengthstring | number | undefinedundefinedThe length of the line: the height of a vertical separator, the width of a horizontal one. A vertical one needs it outside a flex parent — there it has nothing to stretch against.
variantGrDividerVariant | undefinedundefinedThe style of the line. Unset — it comes from `GrConfigProvider`, otherwise `solid`.
ariaLabelstring | undefinedundefinedThe name of the separator for a screen reader. A label from a slot cannot be expressed as a string, so the name is set separately; with `label` it is taken from it.
orientationGrDividerOrientation | undefined"horizontal"The direction of the line: between blocks or between items in a row. `horizontal` by default.
labelstring | undefinedundefinedA label in a gap of the line: "or", the name of a section. Horizontal only; it also gives the name.
alignGrDividerAlign | undefined"center"Where the label stands on the line: `start`, `center` or `end`. `center` by default.
spacingGrDividerSpacing | undefinedundefinedThe spacing around the separator. Unset — from `GrConfigProvider`, otherwise `none`.
thicknessstring | number | undefinedundefinedThe thickness of the line. A number is treated as pixels.

Slots

SlotTypeDescription
defaultanyA label inside the line: "or", the name of a section.

Types

Every exported type of the subpath, grouped by the file it lives in. Names, generics and bodies come from the package’s declaration files and cannot drift.

Import
import type { GrDividerOrientation, GrDividerAlign, GrDividerVariant } from '@feugene/granularity/components/GrDivider'

Filedist/types/components/GrDivider/grDividerStyles.d.ts

GrDividerOrientationtype
type GrDividerOrientation = 'horizontal' | 'vertical';
GrDividerAligntype
type GrDividerAlign = 'start' | 'center' | 'end';
GrDividerVarianttype
type GrDividerVariant = 'solid' | 'dashed' | 'dotted';
GrDividerSpacingtype
type GrDividerSpacing = 'none' | GrComponentSize;

Filedist/types/components/GrDivider/defaults.d.ts

GrDividerConfigurablePropsinterface
interface GrDividerConfigurableProps {
    variant: GrDividerVariant;
    spacing: GrDividerSpacing;
}

Filedist/types/components/GrDivider/config.d.ts

grDividerConfigconst
const grDividerConfig: import("@feugene/granum/contract").GranumComponentDescriptor<"GrDivider">;

Filedist/types/components/GrDivider/safelist.d.ts

grDividerSafelistconst
const grDividerSafelist: string[];

Filedist/types/components/GrDivider/GrDivider.vue.d.ts

GrDividerPropsinterface
interface GrDividerProps {
    orientation?: GrDividerOrientation;
    label?: string;
    align?: GrDividerAlign;
    variant?: GrDividerVariant;
    spacing?: GrDividerSpacing;
    thickness?: number | string;
    length?: number | string;
    ariaLabel?: string;
}

Usage from the library prose

Three render branches

Without a label — a native <hr>: it already has the implicit separator role, and duplicating it with an attribute is not allowed. With a label and in the vertical variant — a div with explicit role="separator" and aria-orientation.

The label and the name

role="separator" makes the content presentational: the text inside the role does not reach a screen reader. That is why the name of the separator is set with an attribute:

vue
<GrDivider label="or" />
<!-- aria-label="or" — a screen reader will announce "or, separator" -->

A label from a slot cannot be expressed as a string, so the name for it is set separately — ariaLabel; it also overrides label when the visible text and the announced name have to differ. A slot without ariaLabel stays nameless on purpose: a separator whose label cannot be expressed as a string is decorative.

align (start | center | end) decides on which side of the label the segments of the line are drawn.

Style, spacing, thickness
  • variant — solid (the default), dashed, dotted. The line is drawn with a border rather than with a background: a dash pattern cannot be expressed with a background, and two mechanisms for three variants of the same thing diverge at the very first edit;
  • spacing — none (the default) or the scale of the package xs | sm | md | lg: vertical padding for a horizontal separator, horizontal for a vertical one;
  • thickness — the thickness of the line, a number is treated as pixels. It travels into --gr-divider-thickness, so it can also be set from the outside, with the styles of the container.

variant and spacing are configured globally:

vue
<GrConfigProvider :component-defaults="{ GrDivider: { variant: 'dashed', spacing: 'md' } }">
A vertical separator and the flex context

A vertical separator stretches to the height of its flex parent (self-stretch). In a block context there is nothing to stretch against, and the line collapses into nothing — it looks like a component that vanished.

There are two ways out: put it into a flex container (the usual case — a toolbar) or set the length explicitly:

vue
<div class="flex items-center gap-3">
  <span>File</span>
  <GrDivider orientation="vertical" />
  <span>Edit</span>
</div>

<!-- outside a flex parent -->
<GrDivider orientation="vertical" :length="24" />

length sets the height of a vertical separator and the width of a horizontal one.