Choose a typeface from a curated catalog of 59 Google Fonts families — searchable, grouped by category, every row previewed in its own face — or one of 16 type pairings. Ships with a deduped Google Fonts loader and a provider that applies a pairing to a page or a single section.
59 Google Fonts families, all with Turkish characters.
Installation
The whole kit as one package — get updates by bumping the version. Add the styles to globals.css: @import "@vamos-ui/react/styles.css";
Usage
import { FontPicker, FontPairingPicker, FontProvider } from "@vamos-ui/react/fonts";
<Field label="Heading font">
<FontPicker value={family} onValueChange={setFamily} />
</Field>Privacy: loading from fonts.googleapis.com sends the visitor's IP address to Google. For GDPR / KVKK-sensitive sites, self-host the files (see /docs/fonts) and pass loadPreviews={false} / load={false}.
Every catalog family supports latin-ext, so Turkish ğ ş ı İ ç ö ü render in the chosen face.
Previews download glyph subsets (only the characters of the family names and the sample line), and only for rows that scroll into view.
Examples
Restrict categories
categories narrows the list — mono for code and invoice numbers, serif for article text. The chips only show categories that remain.
Empty, invalid and disabled
Inside a Field the trigger picks up the label, hint, error and disabled state.
Nothing chosen yet.
Choose a font that supports Greek for the Athens site.
Locked by the brand kit.
Inline list
FontPickerList is the panel without the popover, for settings pages. Type to filter; ↑/↓ and PageUp/PageDown move, Enter selects. The specimen strip shows the active row large.
Selected: Bricolage Grotesque
Pairing picker
Sixteen curated heading + body + mono pairings, each with its own display weight, tracking, <em> style and scale. A radio group: arrows move and select.
CMS brand settings
Three pickers build a custom pairing with createFontPairing; FontProvider applies it to the preview only, so the panel around it keeps the admin fonts.
Slow-cooked lamb, wood-fired bread and Aegean wines
Ağaç fırında pişen ekmek, şef İlkay Şahin’in mevsim menüsü ve Bozcaada bağlarından seçilmiş şaraplar.
- Tue–Sun
- 18:00–23:30
- Tasting menu
- ₺2.450
- Seats
- 48
Scoped provider
useFontPairing() reads and sets the pairing of the nearest FontProvider. scope="document" applies it to <html> instead.
How we cut onboarding from nine days to two
Our HR team rebuilt the first week around one checklist, three owners and a shared calendar. Here is what changed.
Set in Newsroom
API
FontPicker
| Prop | Type | Default |
|---|---|---|
valueSelected family name (controlled). null = nothing selected. | string | null | — |
defaultValueInitial family (uncontrolled). | string | null | — |
onValueChangeCalled on selection; the popover then closes and focus returns to the trigger. | (family: string, font: GoogleFont) => void | — |
fontsFamilies to offer. Default: the 59-family catalog. | GoogleFont[] | googleFonts |
categories"sans" | "serif" | "display" | "rounded" | "condensed" | "mono" | "handwriting". | FontCategory[] | — |
previewTextSample line under each family. | string | "Hamburgefonstiv — Ağaç işçiliği" |
loadPreviewsLoad glyph-subset previews (a few KB per visible family) from Google Fonts. Turn off when you self-host. | boolean | true |
specimenLarge specimen of the active row at the bottom of the panel. | boolean | true |
listHeightMax height of the scrolling list. | string | "18rem" |
sizeTrigger height; md follows --control-h. | "sm" | "md" | "lg" | "md" |
placeholderTrigger text when empty. | string | "Choose a font" |
showCategoryShow the group ("Serif · Display") beside the family in the trigger. | boolean | true |
open / defaultOpen / onOpenChangePopover state, controlled or not. | boolean / boolean / (open) => void | — |
alignPopover alignment against the trigger. | "start" | "center" | "end" | "start" |
name / requiredAdds a hidden input for native form posts. | string / boolean | — |
disabledAlso read from the surrounding Field. | boolean | false |
contentClassNameClass for the popover panel. | string | — |
labelsBuilt-in strings (namespace fontPicker): placeholder, search, searchPlaceholder, categories, all, list, empty, results, variable, italic, weights. | Partial<FontPickerLabels> | — |
FontPickerList
| Prop | Type | Default |
|---|---|---|
value / defaultValue / onValueChangeSame as FontPicker. | string | null / string | null / (family, font) => void | — |
fonts · categories · previewText · loadPreviews · specimen · listHeight · labelsSame as FontPicker. | — | — |
autoFocusFocus the search field on mount. | boolean | false |
FontPairingPicker
| Prop | Type | Default |
|---|---|---|
value / defaultValueSelected pairing id. | string | null | — |
onValueChangeCalled when a pairing is chosen (click, arrows, Home/End). | (id: string, pairing: FontPairing) => void | — |
pairingsThe 16 built-ins, or your own. | FontPairing[] | fontPairings |
layoutSpecimen cards, or compact rows for popovers. | "grid" | "list" | "grid" |
showDescriptionShow the one-line description. | boolean | grid: true · list: false |
loadPreviewsLoad preview glyphs from Google Fonts. | boolean | true |
disabledDisables every option. | boolean | false |
labelsNamespace fontPairingPicker: label. | Partial<FontPairingPickerLabels> | — |
FontProvider
| Prop | Type | Default |
|---|---|---|
pairing / defaultPairingPairing object or preset id. | FontPairing | string | "editorial" |
onPairingChangeCalled by useFontPairing().setPairing. | (pairing: FontPairing) => void | — |
scopeelement: wraps children in a <div> carrying the tokens. document: applies to <html>, restored on unmount. | "element" | "document" | "element" |
loadLoad the families from Google Fonts. | boolean | true |
pairingsPresets resolvable by id. | FontPairing[] | fontPairings |
classNameClass of the wrapper (element scope). | string | — |
Helpers
| Prop | Type | Default |
|---|---|---|
loadGoogleFonts(families, options?)Injects one <link rel=stylesheet> (plus preconnect) for the families not loaded yet. Options: display (default "swap"), text, opticalSize, renderBlocking, document. | Promise<void> | — |
googleFontsUrl(families, options?)The css2 URL — use it in a server-rendered <link>. | string | — |
applyFontPairing(el, pairing, options?)Sets data-font, --font-ui / --font-heading / --font-code and the four --display-* tokens; loads the fonts. | Promise<void> | — |
createFontPairing({ heading, body, mono })Custom pairing; display tokens follow the heading family. | FontPairing | — |
serializeFontPairing / parseFontPairingStore a pairing (with its URL and tokens) in localStorage or a cookie. | StoredFontPairing ⇄ FontPairing | — |
fontBootScript(storageKey?, field?)Inline <head> script that applies a stored pairing before first paint. | string | — |