Separator

Visually or semantically separates content.

carbon
An opinionated React design system
Components on Base UI and StyleX, distributed by copy and paste.
import * as stylex from "@stylexjs/stylex"
import { Separator } from "@/components/ui/separator"
import { VStack } from "@/components/ui/stack"
import { color, leading, text } from "@/theme/tokens.stylex"

const styles = stylex.create({
  root: { width: "100%", maxWidth: "24rem", fontSize: text.sm, lineHeight: leading.sm },
  title: { fontWeight: 500, lineHeight: 1 },
  muted: { color: color.mutedForeground },
})

export default function SeparatorDemo() {
  return (
    <VStack gap={4} xstyle={styles.root}>
      <VStack gap={1.5}>
        <div {...stylex.props(styles.title)}>carbon</div>
        <div {...stylex.props(styles.muted)}>An opinionated React design system</div>
      </VStack>
      <Separator />
      <div>Components on Base UI and StyleX, distributed by copy and paste.</div>
    </VStack>
  )
}

Installation

Install the following dependencies:

pnpm add @base-ui/react @stylexjs/stylex clsx

Set up the token layer and the StyleX compiler, if you have not already. See Installation.

Copy and paste the following code into your project.

components/ui/separator.tsx
import { Separator as SeparatorPrimitive } from "@base-ui/react/separator"
import * as stylex from "@stylexjs/stylex"
import type { StyleXStyles } from "@stylexjs/stylex"
import { clsx } from "clsx"

import { color } from "@/theme/tokens.stylex"

const styles = stylex.create({
  base: {
    flexShrink: 0,
    backgroundColor: color.border,
  },
})

const orientations = stylex.create({
  horizontal: { width: "100%", height: 1 },
  vertical: { width: 1, alignSelf: "stretch" },
})

const separatorStyles = { base: styles.base, orientations }

type SeparatorOrientation = keyof typeof orientations

type SeparatorProps = Omit<SeparatorPrimitive.Props, "className"> & {
  xstyle?: StyleXStyles
  className?: string
}

function Separator({ orientation = "horizontal", xstyle, className, ...props }: SeparatorProps) {
  const sx = stylex.props(styles.base, orientations[orientation] ?? orientations.horizontal, xstyle)

  return (
    <SeparatorPrimitive
      data-slot="separator"
      orientation={orientation}
      {...sx}
      {...props}
      className={clsx(sx.className, className)}
    />
  )
}

export { Separator, separatorStyles, type SeparatorOrientation }

Update the import paths to match your project setup.

Usage

import { Separator } from "@/components/ui/separator"
<Separator />

Vertical

Use orientation="vertical" for a vertical separator. It stretches to the height of the flex row it sits in.

Blog
Docs
Source
import * as stylex from "@stylexjs/stylex"
import { Separator } from "@/components/ui/separator"
import { HStack } from "@/components/ui/stack"
import { leading, space, text } from "@/theme/tokens.stylex"

const styles = stylex.create({
  root: { height: space.s5, fontSize: text.sm, lineHeight: leading.sm },
})

export default function SeparatorVertical() {
  return (
    <HStack gap={4} align="center" xstyle={styles.root}>
      <div>Blog</div>
      <Separator orientation="vertical" />
      <div>Docs</div>
      <Separator orientation="vertical" />
      <div>Source</div>
    </HStack>
  )
}

A vertical separator has no height of its own. Outside a flex container, or in a row aligned by anything other than stretch, give it one through xstyle.

Use vertical separators between menu items with descriptions.

SettingsManage preferences
AccountProfile & security
HelpSupport & docs
import * as stylex from "@stylexjs/stylex"
import { Separator } from "@/components/ui/separator"
import { HStack, VStack } from "@/components/ui/stack"
import { color, leading, text } from "@/theme/tokens.stylex"

const styles = stylex.create({
  root: { fontSize: text.sm, lineHeight: leading.sm },
  title: { fontWeight: 500 },
  description: { fontSize: text.xs, lineHeight: leading.xs, color: color.mutedForeground },
})

export default function SeparatorMenu() {
  return (
    <HStack gap={4} align="center" xstyle={styles.root}>
      <VStack gap={1}>
        <span {...stylex.props(styles.title)}>Settings</span>
        <span {...stylex.props(styles.description)}>Manage preferences</span>
      </VStack>
      <Separator orientation="vertical" />
      <VStack gap={1}>
        <span {...stylex.props(styles.title)}>Account</span>
        <span {...stylex.props(styles.description)}>Profile & security</span>
      </VStack>
      <Separator orientation="vertical" />
      <VStack gap={1}>
        <span {...stylex.props(styles.title)}>Help</span>
        <span {...stylex.props(styles.description)}>Support & docs</span>
      </VStack>
    </HStack>
  )
}

List

Use horizontal separators between list items.

Item 1
Value 1
Item 2
Value 2
Item 3
Value 3
import * as stylex from "@stylexjs/stylex"
import { Separator } from "@/components/ui/separator"
import { HStack, VStack } from "@/components/ui/stack"
import { color, leading, text } from "@/theme/tokens.stylex"

const styles = stylex.create({
  root: { width: "100%", maxWidth: "24rem", fontSize: text.sm, lineHeight: leading.sm },
  value: { color: color.mutedForeground },
})

export default function SeparatorList() {
  return (
    <VStack gap={2} xstyle={styles.root}>
      <HStack render={<dl />} justify="between" align="center">
        <dt>Item 1</dt>
        <dd {...stylex.props(styles.value)}>Value 1</dd>
      </HStack>
      <Separator />
      <HStack render={<dl />} justify="between" align="center">
        <dt>Item 2</dt>
        <dd {...stylex.props(styles.value)}>Value 2</dd>
      </HStack>
      <Separator />
      <HStack render={<dl />} justify="between" align="center">
        <dt>Item 3</dt>
        <dd {...stylex.props(styles.value)}>Value 3</dd>
      </HStack>
    </VStack>
  )
}

API reference

Pass render to replace a part's element or compose it with another component.

Separator wraps the Base UI Separator and accepts its props. See the Base UI reference. It renders a <div role="separator"> with aria-orientation set from the prop.

Separator

PropTypeDefault
orientation"horizontal" | "vertical""horizontal"
xstyleStyleXStyles—
classNamestring—

separatorStyles

The style maps behind the component. Spread them onto any element.

KeyWhat it is
baseThe fill and flex-shrink: 0
orientationshorizontal and vertical: the 1px thickness and the length

Data attributes

AttributeOnEffect
data-slot="separator"the separatorTargets the rule from a parent
data-orientationthe separatorBase UI writes it from orientation