Font Picker
Font::make('default_font') renders a searchable typography picker compiled to FilamentCraft's FontPickerField — far more than a <select>. It is the control you use for every typography setting in a theme. Uses the instant live() update mode.
use FilamentCraft\Settings\Types\Font;
Font::make('default_font')
->cssVar('--font-default')
->default('inter');| Method | Effect |
|---|---|
onlyCategory(array|string $categories) | Restrict the picker to one or more categories. |

What the picker does
- Live catalog from
https://fonts.bunny.net/list— fetched once and cached server-side for 24 hours, with system stacks added locally. - Popular tab pinned first — Inter, Roboto, Open Sans, Lato, Poppins, Manrope, DM Sans, Merriweather, Playfair Display, JetBrains Mono, and more, ahead of the alphabetical roster.
- Per-row preview in the option's own font — lazy-loaded via IntersectionObserver as you scroll.
- Eager-load of the active font plus the top 25 popular fonts on mount, so opening the popover is instant.
- Searchable with debounced 150 ms input.
- Category chips: Popular · All · System · Sans · Serif · Display · Mono · Handwriting.
- Keyboard navigation: arrow up/down to highlight, Enter to commit, Escape to close.
- Live preview: pick a font → the setting persists → the iframe
<head>re-syncs (Bunny<link>injected,<style id="fc-tokens">updated) within ~1.5 s.
Restricting categories
Font::make('heading_font')
->cssVar('--font-heading')
->onlyCategory(['display', 'serif']) // hides sans / mono / handwriting
->default('playfair-display');onlyCategory() accepts a single string or an array. Valid categories mirror the chips: system, sans, serif, display, mono, handwriting.
What gets stored and rendered
The picker stores the font slug (e.g. 'inter', 'merriweather', 'system-sans'). At render time Font::resolveFamily($slug) expands it to the full CSS font stack via the cached FontCatalog — so the CSS variable receives something like "Inter", ui-sans-serif, sans-serif.
Free-form values pass through unchanged, so a theme author can ship a literal stack and skip the catalog entirely:
Font::make('brand')->default('"Acme Sans", sans-serif');System stacks (system-sans, system-serif, system-mono) resolve entirely to platform fonts and emit no Bunny <link> tag. Any other family auto-injects:
<link rel="stylesheet"
href="https://fonts.bunny.net/css?family={slug}:400,500,600,700&display=swap">Catalog extension points
| Hook | Purpose |
|---|---|
\FilamentCraft\Support\FontCatalog | The catalog service singleton — bind your own implementation to swap the data source (e.g. self-host the list). |
FontCatalog::flush() | Clear the 24-hour cache to force a fresh fetch. |
