ComponentsLayout

Separator

A thin line that divides related content. It can be horizontal or vertical, carry a centered label, fade toward a transcript label, or become a quiet timeline note.

Orientations

Horizontal splits stacked regions. Vertical splits items in a row and stretches to the row height.

Project details

Meadow is a shared workspace for the spring planting plan.

MeadowUpdated today3 members

Button groups

tone="input" matches control borders. The separator runs across the group, so it is vertical in a row and horizontal in a column.

Page 1 of 3

Page 1 of 3

Form sections

Separator with children centers short text on the line. Children that render nothing keep the same spacing.

or

Chosen: None yet

Preferences
Notification preferences for every shared workspace

Item lists

Separators go between rows only, so loading and empty lists never show a stray line.

List state

Planting schedule.pdf

Updated today by Maya

Seed order.csv

Updated yesterday by Leo

Greenhouse watering rotation and volunteer handbook.docx

Updated last week by Priya

Sidebar

SidebarSeparator insets the line to the menu edges.

Profile

Settings page preview

Usage

Separator usageTSX
import { Separator } from "@tulipfarm/sprout/separator";

<p>Project details</p>
<Separator />

<div className="flex items-center gap-3">
  <span>Meadow</span>
  <Separator orientation="vertical" />
  <span>Updated today</span>
</div>

<div role="group" aria-label="Pages" className="flex">
  <Button variant="ghost">Previous</Button>
  <Separator tone="input" orientation="vertical" />
  <Button variant="ghost">Next</Button>
</div>

<Separator>or</Separator>

orientation is "horizontal" (default) or "vertical". A horizontal line fills the width. A vertical line stretches to the height of its flex row. tone is "default", which uses --sprout-line, or "input", which uses --sprout-input to match control borders inside button groups. In a column of buttons, use a horizontal separator.

Separator has no margin. Add spacing with className, for example my-2 between list rows. className may be a function of { orientation }, and the Base UI render prop swaps the element.

Variants

variant and children pick the shape. The root always gets data-slot="separator" and a data-variant.

  • "line" (default) draws a bare 1px rule in either orientation.
  • A line with children centers short content such as "or". Itsdata-variant is "label".
  • "fade" fades the line toward a centered text label. Use it to mark a point in a transcript.
  • "marker" is a quiet, full-width timeline note with an icon and text.
  • "marker-border" adds a line under the marker row. Use it to head a group of events.

Labeled separator

Pass children to center short text such as "or" or a section name on a horizontal line. The labeled row takes div props. Children that render nothing, such as false, keep the same 20px height, so form spacing stays even. Long text stays on one line and ends with an ellipsis.

Put a SeparatorIcon before the text for an icon and label between two lines. Use this to split a timeline by day.

Fade

Fade usageTSX
<Separator variant="fade">Auto compacted</Separator>
<Separator variant="fade">Compacted</Separator>

With variant="fade", children is a required string. It is shown between the lines and also names the separator. The fade fills the width of its container and has no margin, so add spacing with the parent's gap or with className. Otherdiv props and the Base UI render prop pass through.

The lines fade in from the edges toward the label. On hover, a soft highlight sweeps across the lines and label once. Long labels stay on one line and end with an ellipsis.

Fade labels

Faded lines with a centered label. These are the two labels the chat uses after a compaction.

Chat compaction

A finished compaction collapses to a fade separator between messages. While the handoff is still being written, the chat shows a status row instead.

Summarise the spring planting plan for the Meadow beds.

Tulips go in the north beds first, then the allium border once the soil drops below 12°C.

Which beds still need compost?

Narrow columns

The lines shrink first. If a label still does not fit, it stays on one line and ends with an ellipsis.

Marker

Marker usageTSX
import {
  Separator,
  SeparatorContent,
  SeparatorIcon,
} from "@tulipfarm/sprout/separator";
import { BookOpen } from "reicon-react/icons/BookOpen";
import { Calendar } from "reicon-react/icons/Calendar";
import { History } from "reicon-react/icons/History";

<Separator variant="marker">
  <SeparatorIcon><BookOpen size={16} /></SeparatorIcon>
  <SeparatorContent>Used skill Weekly report · 3f9a2c1b</SeparatorContent>
</Separator>

<Separator>
  <SeparatorIcon><Calendar /></SeparatorIcon>
  Today
</Separator>

<Separator variant="marker-border">
  <SeparatorIcon><History /></SeparatorIcon>
  <SeparatorContent>Yesterday · 4 events</SeparatorContent>
</Separator>

A marker renders a div with 14px muted text and 8px between its parts. "marker-border" adds a 1px line and 8px of space under the row. There is one size.

SeparatorIcon is a 16px slot. An svg inside it is 16px unless you give it a size class. SeparatorContentholds the marker text. Long words wrap, so the row never overflows its column.

Marker variants

One 14px text size with a 16px icon. Pick the row by how strongly the note should split the timeline.

variant="marker"Icon and text on one quiet row. Chat uses it for skill use.
Used skill Weekly report · 3f9a2c1b
<Separator>An icon and text centered between two lines. Use it to split a timeline by day.
Today
variant="marker-border"A line under the row. Use it as a heading over a group of events.
Yesterday · 4 events

Chat skill use

Sample chat parts. A skill-use part renders a marker with a book icon, the skill name, and an 8-character revision. A day part renders a labeled Separator.

Today

Draft this week's greenhouse update for the team.

Used skill Weekly report · 3f9a2c1b
Used skill Plain language · a71e09c4

Here is the update. Seedlings in bay 2 are ready to move, and the new drip lines are in.

Timeline marker variants

The internal playground row. Each row has a check icon and its name with “Today”.

marker · Today
label · Today
marker-border · Today

Links

Links inside SeparatorContent, or a whole marker rendered as a link, are underlined and darken on hover and focus.

Long content

In narrow columns marker text wraps. A labeled row stays on one line and ends with an ellipsis.

Used skill Quarterly greenhouse operations summary · 9c04be7f
Used skill Quarterly greenhouse operations summary · 9c04be7f
Used skill Quarterly greenhouse operations summary · 9c04be7f

Marker links

Links in a markerTSX
<Separator variant="marker">
  <SeparatorContent>
    Robin edited the brief · <a href="/changes">View changes</a>
  </SeparatorContent>
</Separator>

<Separator variant="marker" render={<a href="/skills/weekly-report" />}>
  <SeparatorIcon><BookOpen size={16} /></SeparatorIcon>
  <SeparatorContent>Open skill Weekly report</SeparatorContent>
</Separator>

A link directly inside SeparatorContent is underlined. So is a marker rendered as a link with render. Both turn to the text color on hover and keyboard focus and get a focus ring.

Sidebar

SidebarSeparator usageTSX
import { SidebarSeparator } from "@tulipfarm/sprout/sidebar";

<SidebarGroup>…</SidebarGroup>
<SidebarSeparator />
<SidebarGroup>…</SidebarGroup>

SidebarSeparator is a Separator inset 8px from each edge, withdata-sidebar="separator". SidebarHeader and SidebarFooter already draw their own border, so use it between groups.

Accessibility

A line renders role="separator" with aria-orientation. It is not focusable and does not stop keyboard movement between the controls around it. If a line is only decoration, pass role="none".

The text in a labeled separator is read as normal text. The second line is hidden from screen readers. SeparatorIcon is aria-hidden, so put the meaning in words.

A fade separator uses its label as its aria-label. The highlight copy is hidden from screen readers. The hover sweep only runs on devices that can hover, and never when reduced motion is requested.

A marker has no role and does not take focus. Screen readers read its content as plain text. In forced colors mode the marker border uses the system text color.

Line and link colors change in 120ms and do not animate when reduced motion is requested.

Theme tokens

Lines use --sprout-line, and tone="input" uses--sprout-input. Labels and marker text use --sprout-muted. Fade labels are --sprout-text-xs, and the hover highlight uses --sprout-text. Hovered and focused marker links use--sprout-text, and the focus ring uses --sprout-focus. Override them in light and dark modes like any other Sprõut token.