Skip to content

Divider

A horizontal rule with an optional centered label, spacing steps and a line-less mode.

A horizontal rule with an optional centered label, spacing steps and a line-less mode. Compose it from the exported registry parts so local content and behaviour stay in the application while the visual contract stays token-driven.

Root class newt-divider
import { Divider } from "@/registry/bases/newt/ui/divider"

export default function DividerDemo() {
  return (
    <div className="w-full max-w-sm">
      <Divider>SECTION LABEL</Divider>
      <Divider spacing="sm" />
      <Divider spacing="lg" line={false}>
        SPACING ONLY
      </Divider>
    </div>
  )
}
<script setup lang="ts">
import { Divider } from "~~/registry/bases/newt/ui/divider"
</script>

<template>
  <div class="w-full max-w-sm">
    <Divider>SECTION LABEL</Divider>
    <Divider spacing="sm" />
    <Divider spacing="lg" :line="false">SPACING ONLY</Divider>
  </div>
</template>

Installation

pnpm dlx newtui@latest add divider
npx newtui@latest add divider
yarn dlx newtui@latest add divider
bunx newtui@latest add divider

Install the dependencies

pnpm dlx --yes class-variance-authority
npx --yes class-variance-authority
yarn dlx --yes class-variance-authority
bunx --yes class-variance-authority

Copy the source into your project

import { cva, type VariantProps } from "class-variance-authority"
import * as React from "react"

import { cn } from "@/lib/utils"

const dividerVariants = cva(
  "flex items-center gap-3 text-xs font-semibold text-newt-text-muted",
  {
    variants: {
      /* Spacing steps, for stacking dividers inside dense containers. */
      spacing: {
        sm: "my-1",
        md: "my-4",
        lg: "my-6",
      },
      /* Pure spacing: keeps the gap, drops the rules around the label. */
      line: {
        true: "before:h-px before:flex-1 before:bg-newt-border before:content-[''] after:h-px after:flex-1 after:bg-newt-border after:content-['']",
        false: "",
      },
    },
    defaultVariants: {
      spacing: "md",
      line: true,
    },
  }
)

export interface DividerProps
  extends
    React.HTMLAttributes<HTMLDivElement>,
    VariantProps<typeof dividerVariants> {}

const Divider = React.forwardRef<HTMLDivElement, DividerProps>(
  ({ className, spacing, line, children, ...props }, ref) => (
    <div
      ref={ref}
      role="separator"
      className={cn(dividerVariants({ spacing, line }), className)}
      {...props}
    >
      {children}
    </div>
  )
)
Divider.displayName = "Divider"

export { Divider, dividerVariants }
<script setup lang="ts">
import type { HTMLAttributes } from "vue"

import { cn } from "@/lib/utils"

import { dividerVariants, type DividerVariants } from "."

const props = withDefaults(
  defineProps<{
    class?: HTMLAttributes["class"]
    spacing?: DividerVariants["spacing"]
    line?: boolean
  }>(),
  { line: true }
)
</script>

<template>
  <div
    role="separator"
    :class="
      cn(
        dividerVariants({ spacing: props.spacing, line: props.line }),
        props.class
      )
    "
  >
    <slot />
  </div>
</template>
import { cva, type VariantProps } from "class-variance-authority"

export { default as Divider } from "./Divider.vue"

export const dividerVariants = cva(
  "flex items-center gap-3 text-xs font-semibold text-newt-text-muted",
  {
    variants: {
      /* Spacing steps, for stacking dividers inside dense containers. */
      spacing: {
        sm: "my-1",
        md: "my-4",
        lg: "my-6",
      },
      /* Pure spacing: keeps the gap, drops the rules around the label. */
      line: {
        true: "before:h-px before:flex-1 before:bg-newt-border before:content-[''] after:h-px after:flex-1 after:bg-newt-border after:content-['']",
        false: "",
      },
    },
    defaultVariants: {
      spacing: "md",
      line: true,
    },
  }
)

export type DividerVariants = VariantProps<typeof dividerVariants>

Update the import paths

The files import @/lib/utils and sibling components through the aliases in your components.json. Point them at wherever those live in your project.

Usage

import { Divider } from "@/components/ui/divider"

export function Example() {
  return <Divider />
}
<script setup lang="ts">
import { Divider } from "@/components/ui/divider"
</script>

<template>
  <Divider />
</template>

API reference

Divider

PropType
children / default slot?React.ReactNode / Vue slot

Content rendered inside the component.

TypeReact.ReactNode / Vue slot
className / class?string

Additional classes merged with the component defaults.

Typestring

The registry exports Divider. Parts without a table accept the native attributes for the element they render; React uses className, while Vue uses class and fallthrough attributes.

Accessibility

Preserve the native semantics of the rendered elements and pass through ARIA attributes when the surrounding context needs a label or description. Any interactive child needs a visible focus indicator, and meaning must not rely on colour alone.

Tokens

Divider reads its colours, radii and motion from the --newt-* tokens installed with the library. Override a token and every component that reads it follows, including this one — see the token layer. In the plain HTML and CSS distribution the same component is newt-divider.