Skip to content

PlDivider

A rule between two things. With no children it is a hairline and a real role="separator"; with children the line breaks around a label set into it.

React
tsx
import { PlDivider } from 'plass-ui';

<PlDivider />;
<PlDivider>OR</PlDivider>;
<PlDivider orientation="vertical" />;
dart
import 'package:plass_ui/plass_ui.dart';

const PlDivider();
const PlDivider(child: Text('OR'));
const PlDivider(orientation: PlassOrientation.vertical);

Props

PropTypeDefaultDescription
orientationshared'horizontal' | 'vertical''horizontal'Which way the line runs. A vertical divider has no height of its own and stretches to its flex parent
colorshared'primary' | 'secondary' | 'success' | 'warning' | 'danger' | 'info'Semantic colour role. There is **no** default — left out, the rule is the neutral hairline, which is visible on every ground
sizeshared'xs' | 'sm' | 'md' | 'lg' | 'xl''md'Type scale of the label. Nothing else on a divider has a size
lengthnumber | stringHow far the rule runs. A number is pixels, a string is any CSS length. Left out, it fills its container
thicknessnumber | string1How thick the rule is. A number is pixels, a string is any CSS length
textAlignshared'start' | 'center' | 'end''center'Where the label sits. start and end leave a short stub on the near side, so the label still reads as set into the rule
childrenReactNodeA label set into the line — "OR" between two sign-in options
PropTypeDefaultDescription
orientationsharedPlassOrientationPlassOrientation.horizontalWhich way the line runs. A vertical divider has no height of its own and stretches to its flex parent
colorsharedPlassColor?nullSemantic colour role. There is **no** default — left out, the rule is the neutral hairline, which is visible on every ground
sizesharedPlassSizePlassSize.mdType scale of the label. Nothing else on a divider has a size
lengthdouble?How far the rule runs — the width of a horizontal divider, the height of a vertical one, in logical pixels. Left out, it runs as far as it is allowed to
thicknessdouble1How thick the rule is. A number is pixels, a string is any CSS length
textAlignsharedPlassAlignPlassAlign.centerWhere the label sits. start and end leave a short stub on the near side, so the label still reads as set into the rule
semanticLabelString?What a screen reader calls the divider. Without it the divider stays out of the semantics tree — a rule between two things is usually the layout speaking
childWidget?A label set into the line — "OR" between two sign-in options

Every native <div> attribute passes straight through. color and children are excluded from the pass-through because both are Plass props here.

color is a PlassColor? and defaults to null, which is how "no family, the neutral hairline" is spelled in a language with no undefined.

There is no variant and no elevation. A divider is not a surface: it is not made of glass, it catches no light and it casts no shadow.

What the shared axes (orientation color size textAlign) mean across the library is in prop conventions.

Examples

orientation

A vertical divider has no height of its own. It takes the height of whatever gives it one, which is what a rule between two toolbar groups should do. Give it a length when it has to be shorter than the row it is in.

"Whatever gives it one" is doing more work here than in CSS. A Row hands its children the height it was given, so a vertical divider inside one needs an IntrinsicHeight above it, or a length, before it has anything to stretch to. The demo below uses the first.

React

children and textAlign

center splits the line in half. start and end leave a short stub on the near side, so the label still reads as set into the rule rather than floating above it.

React

color

There is no default, which is the same choice PlTextLink makes. Left out, the rule is the neutral hairline, the one that is visible on every ground the library has: a page wash, a glass sheet, a card. The sheet's own white hairline is white light on a translucent pane and disappears the moment a divider is set on something opaque.

Passing a family tints the rule instead.

React

length and thickness

length rather than width, because a divider is the one component whose long axis turns with orientation.

A number is pixels; a string is any CSS length, so '50%' and '12rem' both work.

Both are doubles, logical pixels, which is what every other length in the package is. There is no percentage: a fraction of the parent is a FractionallySizedBox around the divider, and inventing a second spelling for it inside the component would be a second spelling.

length wins over a tight parent, which is not what a bare SizedBox would do. A divider very often sits in a Column with crossAxisAlignment: stretch, and there it would be handed a tight width and lose, so the box is wrapped in an Align, which passes loose constraints down.

React

size

size is the label's type scale and nothing else. A divider with no label has no size to set.

React

Accessibility

  • It renders Base UI's Separator, so it is a real role="separator" carrying the matching aria-orientation.
  • separator is not a name-from-content role, so a visible label does not become the accessible name on its own. A string label is copied into aria-label; a richer one is left alone, because only the caller knows which part of it is the name.
  • A divider that is purely decorative, a rule inside a card that is already separated by space, is better given role="presentation", which passes straight through.
  • The two stubs either side of a label are aria-hidden; the label is announced once, as the separator's name.
  • A divider says nothing unless it is given a semanticLabel, which is the honest default: a rule between two things is usually the layout speaking, not the content.
  • Naming one makes it a semantics node with that name. Pass it when the rule is carrying meaning. An "OR" between two sign-in routes is, a rule inside a card is not.
  • The label set into the line is still drawn as text, so it is read where it sits; semanticLabel is for the divider itself.

Differences from the React build

ReactFlutterWhy
role="separator" with aria-orientationa named semantics node, or nothingFlutter's semantics tree has no separator role. An unnamed rule is decoration, and stays out of the tree.
childrenchildFlutter's name.
a string label becomes aria-labelsemanticLabelNothing here can tell which part of a Widget is the name, so the name is asked for rather than guessed.
length/thickness as a CSS lengthdoubleLogical pixels, as everywhere else in the package. A fraction of the parent is a FractionallySizedBox.
className, styleThere is no class list and no style attribute to pass through.

Released under the MIT License