Font Family Combobox

Available in Start plan

A searchable font-family picker for Tiptap editors. The trigger shows the active font; opening it reveals a fuzzy search field and fonts grouped by category, each previewed in its own typeface. A “Default font” option unsets any inline font.

It is a richer, searchable counterpart to the font-family-dropdown-menu, and it pairs with the FontFamily mark from @tiptap/extension-text-style. The component is catalog-agnostic: pass your own fonts, categories, and defaultFont, or rely on the bundled web-safe defaults. All editor logic lives in the useFontFamilyCombobox hook.

Installation

Add the component via the Tiptap CLI:

npx @tiptap/cli@latest add font-family-combobox

Components

<FontFamilyCombobox />

A prebuilt searchable font picker built on Ariakit’s menu-with-combobox composite.

Usage

export default function MyEditor() {
  return (
    <FontFamilyCombobox
      editor={editor}
      hideWhenUnavailable={true}
      onOpenChange={(isOpen) => console.log('Picker', isOpen ? 'opened' : 'closed')}
    />
  )
}

To use your own catalog, supply fonts, categories, and defaultFont. Each option’s category is matched against a category id, and an option’s optional fallbackFor lets imported system fonts (e.g. "Arial") resolve to a bundled family.

const fonts = [
  { value: 'inter', label: 'Inter', family: 'Inter', hint: 'UI sans', category: 'sans-serif', default: true },
  { value: 'georgia', label: 'Georgia', family: 'Georgia, serif', hint: 'Serif', category: 'serif' },
]
const categories = [
  { id: 'sans-serif', label: 'Sans-serif' },
  { id: 'serif', label: 'Serif' },
]

<FontFamilyCombobox editor={editor} fonts={fonts} categories={categories} defaultFont={fonts[0]} />

Props

The component also forwards any extra Button props (except type) to the trigger.

NameTypeDefaultDescription
editorEditor | nullundefinedThe Tiptap editor instance.
fontsFontFamilyOption[]defaultFontFamilyOptionsThe fonts to offer in the picker.
defaultFontFontFamilyOptiondefaultFontFamilyOptionThe font the document falls back to when no inline font is applied.
categoriesFontFamilyCategory[]defaultFontFamilyCategoriesCategory groups to render, matched against each font’s category.
hideWhenUnavailablebooleanfalseHides the picker when font family cannot be applied.
onOpenChange(boolean) => voidundefinedCallback for when the picker opens or closes.

Types

interface FontFamilyOption {
  label: string // display name in the picker
  value: string // stable identifier
  family: string // CSS font-family applied to the document; previewed in this typeface
  hint?: string // short descriptor under the label, e.g. "Calibri-like"
  category: string // group id (matched against a FontFamilyCategory)
  default?: boolean // marks the default option (no inline font)
  fallbackFor?: string[] // system fonts this family stands in for on import
}

interface FontFamilyCategory {
  id: string
  label: string
}

Hooks

useFontFamilyCombobox()

A headless hook exposing the selection state and actions needed to build a custom font picker.

Usage

function MyFontPicker() {
  const { isVisible, triggerLabel, selectFont, selectDefault, filterFonts } = useFontFamilyCombobox(
    { editor, hideWhenUnavailable: true },
  )

  if (!isVisible) return null

  const results = filterFonts('geo') // ranked matches for a search query
  // …render your own UI using selectFont(font) / selectDefault()
}

Props

NameTypeDefaultDescription
editorEditor | nullundefinedThe Tiptap editor instance.
fontsFontFamilyOption[]defaultFontFamilyOptionsThe fonts to offer.
defaultFontFontFamilyOptiondefaultFontFamilyOptionThe document’s fallback font when nothing inline is set.
hideWhenUnavailablebooleanfalseHides the picker when font family is unavailable.

Return Values

NameTypeDescription
isVisiblebooleanWhether the picker should be rendered.
canTogglebooleanWhether font family can be applied in the current state.
isActivebooleanWhether an explicit inline font is active (not the default).
fontsFontFamilyOption[]The configured fonts.
defaultFontFontFamilyOptionThe configured default font.
selectionStateFontFamilySelectionStateThe selection’s font state (default / font / mixed).
activeFontFamilystringThe applied font-family for the selection (empty when default).
activeFontFontFamilyOption | undefinedThe resolved option for the active family, if any.
triggerLabelstringLabel for the trigger (active font, Mixed, or Default · …).
selectFont(font: FontFamilyOption) => voidApply a font family to the selection.
selectDefault() => voidUnset any inline font (use the document default).
filterFonts(query: string) => FontFamilyOption[]Rank the configured fonts against a search query.

Utilities

Default catalog

import {
  defaultFontFamilyOptions,
  defaultFontFamilyCategories,
  defaultFontFamilyOption,
} from '@/components/tiptap-ui/font-family-combobox'

A web-safe set (Arial, Verdana, Tahoma, Times New Roman, Georgia, Courier New) grouped into Sans-serif / Serif / Monospace, so the component is usable out of the box without loading any webfont.

Helpers

import {
  filterFontsByQuery,
  findFontByFamily,
  resolveFontFamily,
  getActiveFontOption,
  getFontFamilySelectionState,
  getFontFamilyTriggerLabel,
} from '@/components/tiptap-ui/font-family-combobox'

filterFontsByQuery(fonts, 'geo') // ranked matches (blank query → unchanged order)
findFontByFamily(fonts, 'Georgia') // the option whose family matches, or undefined
resolveFontFamily(fonts, 'Arial') // map a system font through each option's fallbackFor
getActiveFontOption(fonts, 'Inter') // resolve an applied family to an option
getFontFamilySelectionState(editor) // { kind: 'default' | 'font' | 'mixed', fontFamily }
getFontFamilyTriggerLabel(state, defaultFont, fonts) // the trigger label string

Requirements

Dependencies

  • @tiptap/react — Core Tiptap React integration
  • @tiptap/pm — ProseMirror model/state used to read the selection’s font marks
  • match-sorter — Fuzzy ranking for the search field
  • @tiptap/extension-text-style — Provides the FontFamily mark this picker applies

Referenced Components

  • use-tiptap-editor (hook)
  • use-composed-ref (hook)
  • font-family-dropdown-menu (component — shared editor helpers)
  • button (primitive)
  • combobox (primitive)
  • input (primitive)
  • menu (primitive)
  • check-icon (icon)
  • chevron-down-icon (icon)