🎁 100 free AI Toolkit licenses – apply by August 15.Learn more

Integrate a button in your Editor

Available for free

A clickable element that performs an action when activated.

Install

You can add the primitive via Tiptap CLI

npx @tiptap/cli@latest add button

Usage

import { Button } from '@/components/tiptap-ui-primitive/button'
import { BoldIcon } from '@/components/tiptap-icons/bold-icon'

export default function MyComponent() {
  return (
    <Button
      data-style="ghost"
      data-active-state="on"
      tooltip="Bold"
      shortcutKeys="Ctrl+B"
      onClick={() => console.log('Bold clicked')}
    >
      <BoldIcon className="tiptap-button-icon" />
      <span className="tiptap-button-text">Bold</span>
    </Button>
  )
}

Props

Button

NameTypeDefaultDescription
variant'ghost' | 'primary' | 'check'undefinedVisual style, or the check feature variant
size'small' | 'default' | 'large'undefinedButton size
tooltipReactNodeundefinedContent displayed in the tooltip
shortcutKeysstringundefinedKeyboard shortcut displayed in tooltip
showTooltipbooleantrueRenders the tooltip wrapper when tooltip is set
data-stylestringundefinedButton style, set from variant when it is provided
data-active-state'on' | 'off'undefinedButton active state
data-sizestringundefinedButton size, set from size when it is provided
data-appearancestringundefinedButton appearance
data-disabledbooleanundefinedVisual disabled state

The button forwards every other ButtonHTMLAttributes<HTMLButtonElement> to the underlying element.

Check variant

variant="check" renders a checkbox-style toggle: a full-width row with the label on the left and a check indicator on the right. It defaults to the ghost style at small size, provides role="checkbox", and renders its own indicator, so you supply only the label and the state.

Drive it with aria-checked, which defaults to false and also accepts "mixed":

import { useState } from 'react'
import { Button } from '@/components/tiptap-ui-primitive/button'
import { CaseSensitiveIcon } from '@/components/tiptap-icons/case-sensitive-icon'

export default function MatchCaseOption() {
  const [matchCase, setMatchCase] = useState(false)

  return (
    <Button
      variant="check"
      aria-checked={matchCase}
      onClick={() => setMatchCase((current) => !current)}
    >
      <CaseSensitiveIcon className="tiptap-button-icon" />
      <span className="tiptap-button-text">Match case</span>
    </Button>
  )
}

The variant sets data-variant="check" on the element and renders the indicator as .tiptap-button-check, so both are available for styling. Its colors come from the --tt-button-check-* custom properties in button-colors.scss, and it installs the check-icon component.