Display

Labelled Separator

A separator with a centred label: the line is a three-column grid, so it works on any background.

  • separator
  • divider
  • layout
  • a11y

Preview

1440pxHost theme

Use it with AI

  1. 1. Copy the link.
  2. 2. Write to your agent in your own words and drop the link into the sentence.
  3. 3. The agent opens the link and installs the component from the registry.

put this in the header: https://vibeui.ru/c/separator-001?lang=en

or
Show the full instructions

What the link says, spelled out. Use it when your agent cannot open links — paste this text instead.

# Install and place "separator-001" (Labelled Separator) from VibeUI

## 1. Install first — do not skip, do not recreate
Run this exact command before writing any code:
npx shadcn@latest add https://vibeui.ru/r/separator-001.json

Registry item: https://vibeui.ru/r/separator-001.json
Installs to: components/vibeui/separator-001.tsx (the exact path follows this project's components.json aliases).
npm dependencies: none.
Registry dependencies: none.

Install it from the registry. Do not recreate it from the description,
do not substitute a similar component from another library, and do not
rewrite it to match the project's existing style.

## 2. What it is
A separator with a centred label: the line is a three-column grid, so it works on any background.

A separator: horizontal with a centred label, or vertical without one. Zero dependencies, one file, no client JS.

## 3. How to use it
import { Separator001 } from "@/components/vibeui/separator-001"

<Separator001 label="or" />

Read the installed file for the full prop list.

## 4. Where to place it
This is a small inline component. Put it exactly where the user asked,
inside the existing markup. Do not create a new page, section or
wrapper for it. If a similar control already sits in that spot,
replace it instead of adding a second one.

Placement: ___
(The user fills this line in. If it is still blank, ask where to put it
instead of guessing.)

## 5. Keep exactly as installed
- the local --vibeui-separator-001-* palette — do not swap it for your theme tokens
- the grid instead of a background behind the text: the label then works on any surface
- role="separator" with aria-orientation
- the vertical variant stretching to its neighbours rather than setting their height
- the small caps label: it is auxiliary and must not compete with the surrounding text
- the one-pixel thickness — a separator divides, it does not draw a frame

## 6. You may change
- label — the caption or none
- orientation — horizontal or vertical
- the line colour
- the surrounding spacing

## 7. Rules
- An unlabelled separator needs no name: aria-label is added only when there is text.
- The vertical variant needs height from its parent: in a height-less block it collapses.
- Do not use a separator instead of spacing: if the groups already read apart, the line is noise.
- Do not lift the CSS variables into globals.css: the component has to stay a single file.

## 8. Verify
- it renders with no console errors;
- it looks like the preview on the VibeUI page you copied this from;
- if it does not, you changed something listed in section 5 — put it back.

For developers

npx shadcn@latest add https://vibeui.ru/r/separator-001.json
https://vibeui.ru/r/separator-001.json

Компонент самодостаточен: один файл, без зависимостей, собственная палитра в локальных переменных --vibeui-separator-001-*. Серверный: хуков нет. Линия с подписью — грид из трёх колонок, поэтому не нужен приём с фоном под текстом и разделитель работает на любой подложке. Вертикальный вариант тянется по высоте соседей. Роль separator объявлена с aria-orientation.

Component source

The same file your agent installs. Here in case you would rather copy it by hand.

import type { ComponentPropsWithoutRef, CSSProperties } from "react"

export type Separator001Props = Omit<
  ComponentPropsWithoutRef<"div">,
  "children"
> & {
  label?: string
  orientation?: "horizontal" | "vertical"
}

// Идея компонента: разделитель, который умеет держать подпись. Линия с
// текстом посередине набирается сеткой из трёх колонок, а не двумя блоками с
// фоном: тогда она работает на любой подложке. Пустой разделитель помечен
// role="separator" и aria-hidden не получает — его слышно как границу.
const STYLES = `
:where([data-vibeui-block="separator-001"]){
--vibeui-separator-001-line:oklch(0.9 0.006 265);
--vibeui-separator-001-muted:oklch(0.56 0.014 265);
--vibeui-separator-001-font:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
}
[data-vibeui-block="separator-001"]{
display:grid;align-items:center;gap:0.75rem;
width:100%;box-sizing:border-box;
font-family:var(--vibeui-separator-001-font);
}
/* Три колонки: линия — текст — линия. Так подпись живёт на любом фоне. */
[data-vibeui-block="separator-001"][data-with-label="true"]{grid-template-columns:1fr auto 1fr}
[data-vibeui-block="separator-001"] [data-part="line"]{height:1px;background:var(--vibeui-separator-001-line)}
[data-vibeui-block="separator-001"] [data-part="label"]{
font-size:0.75rem;font-weight:600;letter-spacing:0.04em;text-transform:uppercase;
color:var(--vibeui-separator-001-muted);
}
/* Вертикальный вариант тянется по высоте соседей, а не задаёт её. */
[data-vibeui-block="separator-001"][data-orientation="vertical"]{
display:block;width:1px;min-height:1.5rem;height:100%;
background:var(--vibeui-separator-001-line);
}
@media (prefers-reduced-motion:reduce){[data-vibeui-block="separator-001"] *{animation:none!important;transition:none!important}}
`

/**
 * Разделитель с подписью посередине и вертикальный вариант.
 * Один файл, ноль зависимостей, собственная палитра.
 */
export function Separator001({
  label = "или",
  orientation = "horizontal",
  className,
  style,
  ...props
}: Separator001Props) {
  const vertical = orientation === "vertical"

  return (
    <>
      <style href="vibeui-separator-001" precedence="medium">
        {STYLES}
      </style>
      <div
        {...props}
        data-vibeui-block="separator-001"
        data-orientation={orientation}
        data-with-label={Boolean(label) && !vertical}
        role="separator"
        aria-orientation={orientation}
        aria-label={label && !vertical ? label : undefined}
        className={className}
        style={style as CSSProperties}
      >
        {vertical ? null : (
          <>
            <span data-part="line" />
            {label ? <span data-part="label">{label}</span> : null}
            {label ? <span data-part="line" /> : null}
          </>
        )}
      </div>
    </>
  )
}