FontPicker
Font family picker component.
FontPicker renders a vertical list of available font families, each displayed in its own typeface for a visual preview. It is primarily used inside the FloatingToolbar but can also be used standalone within a Lexical editor context.
Import
import { FontPicker } from "@blokhaus/core";
import type { FontFamilyEntry } from "@blokhaus/core";Props
| Prop | Type | Default | Description |
|---|---|---|---|
fonts | FontFamilyEntry[] | DEFAULT_FONT_FAMILIES | Array of available font families. |
activeFont | string | null | required | The currently active font family CSS value, or null if using the default font. |
onClose | () => void | required | Callback invoked after a font is selected. Typically used to close the picker dropdown. |
Basic usage
The FontPicker is typically used inside the FloatingToolbar and does not need to be added separately. However, you can use it in a custom toolbar:
"use client";
import { useState } from "react";
import { FontPicker } from "@blokhaus/core";
function CustomFontControl() {
const [isOpen, setIsOpen] = useState(false);
return (
<div style={{ position: "relative" }}>
<button onClick={() => setIsOpen(!isOpen)}>Font</button>
{isOpen && (
<div style={{ position: "absolute", top: "100%", zIndex: 50 }}>
<FontPicker activeFont={null} onClose={() => setIsOpen(false)} />
</div>
)}
</div>
);
}The FontFamilyEntry interface
Each font option conforms to this interface:
interface FontFamilyEntry {
/** Human-readable label shown in the picker */
label: string;
/** CSS font-family value to apply. Empty string = remove / default. */
value: string;
/** Font stack used to render the preview text in the picker dropdown */
preview: string;
}Default font families
The default set includes four options:
| Label | CSS Value | Preview Font Stack |
|---|---|---|
| Default | (removes font override) | var(--blokhaus-font-sans) |
| Serif | var(--blokhaus-font-serif) | var(--blokhaus-font-serif) |
| Mono | var(--blokhaus-font-mono) | var(--blokhaus-font-mono) |
| Hand | var(--blokhaus-font-hand) | var(--blokhaus-font-hand) |
Custom font families
Override the defaults by passing a custom FontFamilyEntry[]:
import type { FontFamilyEntry } from "@blokhaus/core";
const customFonts: FontFamilyEntry[] = [
{ label: "Default", value: "", preview: "system-ui, sans-serif" },
{ label: "Georgia", value: "Georgia, serif", preview: "Georgia, serif" },
{
label: "Courier",
value: '"Courier New", monospace',
preview: '"Courier New", monospace',
},
{
label: "Comic Sans",
value: '"Comic Sans MS", cursive',
preview: '"Comic Sans MS", cursive',
},
];
<FontPicker fonts={customFonts} activeFont={null} onClose={() => {}} />;To add web fonts (e.g., Google Fonts), ensure the font is loaded in your application first, then reference it in the value and preview fields:
const googleFonts: FontFamilyEntry[] = [
{ label: "Default", value: "", preview: "system-ui, sans-serif" },
{
label: "Inter",
value: '"Inter", sans-serif',
preview: '"Inter", sans-serif',
},
{
label: "Playfair Display",
value: '"Playfair Display", serif',
preview: '"Playfair Display", serif',
},
{
label: "JetBrains Mono",
value: '"JetBrains Mono", monospace',
preview: '"JetBrains Mono", monospace',
},
];Command dispatched
When a font is selected, the FontPicker dispatches:
SET_FONT_FAMILY_COMMANDwith the CSS font-family value string
An empty string value ("") removes the font override, reverting to the editor's default font.
After dispatching the command, the picker calls editor.focus() to return focus to the editor and then invokes the onClose callback.
Visual indicators
- The active font is highlighted with a subtle background color (
--blokhaus-hover-bg). - A checkmark icon appears to the right of the active font label, colored with
--blokhaus-accent. - Each font label is rendered in its own
previewfont stack, giving users an immediate visual preview of what the font looks like.
Notes
FontPickeris a client component ('use client').- It must be rendered within a
LexicalComposercontext (i.e., insideEditorRoot). - The component uses
onMouseDownwithe.preventDefault()on the container to prevent the editor from losing focus when interacting with the picker. - Font values use CSS variable references by default (e.g.,
var(--blokhaus-font-serif)) so that the actual font stacks can be customized viatokens.csswithout modifying the picker. - The minimum width of the picker dropdown is 160px.
Related
- FloatingToolbar -- Parent component that hosts the font picker
- Theming guide -- Customizing font tokens in
tokens.css