Example: font-family
Change the font family of text.
Install this example with
shadcn: npx shadcn@latest add @prosekit/react-example-font-familynpx shadcn@latest add @prosekit/preact-example-font-familynpx shadcn@latest add @prosekit/solid-example-font-familynpx shadcn@latest add @prosekit/svelte-example-font-familynpx shadcn@latest add @prosekit/vue-example-font-family'use client'
import 'prosekit/basic/style.css'
import 'prosekit/basic/typography.css'
import { createEditor, type NodeJSON } from 'prosekit/core'
import { ProseKit } from 'prosekit/react'
import { useMemo } from 'react'
import { sampleContent } from '../../sample/sample-doc-font-family'
import { defineExtension } from './extension'
import Toolbar from './toolbar'
interface EditorProps {
initialContent?: NodeJSON
}
export default function Editor(props: EditorProps) {
const defaultContent = props.initialContent ?? sampleContent
const editor = useMemo(() => {
const extension = defineExtension()
return createEditor({ extension, defaultContent })
}, [defaultContent])
return (
<ProseKit editor={editor}>
<div className="box-border h-full w-full min-h-36 overflow-y-hidden overflow-x-hidden rounded-md border border-solid border-gray-200 dark:border-gray-700 shadow-sm flex flex-col bg-[canvas] text-black dark:text-white">
<Toolbar />
<div className="relative w-full flex-1 box-border overflow-y-auto">
<div ref={editor.mount} className="ProseMirror box-border min-h-full px-[max(4rem,calc(50%-20rem))] py-8 outline-hidden outline-0 [&_span[data-mention=user]]:text-blue-500 [&_span[data-mention=tag]]:text-violet-500"></div>
</div>
</div>
</ProseKit>
)
}import { defineBasicExtension } from 'prosekit/basic'
import { union } from 'prosekit/core'
import { defineFontFamily } from 'prosekit/extensions/font-family'
export function defineExtension() {
return union(defineBasicExtension(), defineFontFamily())
}
export type EditorExtension = ReturnType<typeof defineExtension>export { default as ExampleEditor } from './editor''use client'
import type { Editor } from 'prosekit/core'
import { useEditorDerivedValue } from 'prosekit/react'
import { useEffect } from 'react'
import type { EditorExtension } from './extension'
const fonts = [
{ label: 'Arial', family: 'Arial, sans-serif' },
{ label: 'Times New Roman', family: 'Times New Roman, serif' },
{ label: 'Courier New', family: 'Courier New, monospace' },
{ label: 'Georgia', family: 'Georgia, serif' },
{ label: 'Verdana', family: 'Verdana, sans-serif' },
{ label: 'Comic Sans MS', family: 'Comic Sans MS, cursive' },
{ label: 'Impact', family: 'Impact, sans-serif' },
{ label: 'Inter', family: 'Inter, sans-serif', google: true },
{ label: 'Playfair Display', family: 'Playfair Display, serif', google: true },
{ label: 'Merriweather', family: 'Merriweather, serif', google: true },
]
function loadGoogleFonts() {
const linkId = 'prosekit-google-fonts'
if (document.getElementById(linkId)) return
const link = document.createElement('link')
link.id = linkId
link.rel = 'stylesheet'
link.href =
'https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700&family=Merriweather:wght@400;700&family=Playfair+Display:wght@400;700&display=swap'
document.head.appendChild(link)
}
function getToolbarState(editor: Editor<EditorExtension>) {
let activeFont = ''
for (const font of fonts) {
if (editor.marks.fontFamily.isActive({ family: font.family })) {
activeFont = font.family
break
}
}
const handleChange = (value: string) => {
if (!value) {
editor.commands.removeFontFamily()
return
}
const font = fonts.find((f) => f.family === value)
if (font?.google) {
loadGoogleFonts()
}
editor.commands.addFontFamily({ family: value })
}
return { activeFont, handleChange }
}
export default function Toolbar() {
const state = useEditorDerivedValue(getToolbarState)
useEffect(() => {
loadGoogleFonts()
}, [])
return (
<div className="z-2 box-border border-gray-200 dark:border-gray-800 border-solid border-l-0 border-r-0 border-t-0 border-b flex flex-wrap gap-1 p-2 items-center">
<select
value={state.activeFont}
onChange={(e) => state.handleChange(e.target.value)}
className="px-2 py-1 rounded border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 text-sm"
>
<option value="">Default Font</option>
{fonts.map((font) => (
<option key={font.family} value={font.family} style={{ fontFamily: font.family }}>
{font.label}
</option>
))}
</select>
</div>
)
}import type { NodeJSON } from 'prosekit/core'
export const sampleContent: NodeJSON = {
type: 'doc',
content: [
{
type: 'paragraph',
content: [
{
type: 'text',
text: 'Select text and choose a font from the inline menu. ',
},
{
type: 'text',
marks: [
{
type: 'fontFamily',
attrs: {
family: 'Georgia, serif',
},
},
],
text: 'Georgia',
},
{
type: 'text',
text: ', ',
},
{
type: 'text',
marks: [
{
type: 'fontFamily',
attrs: {
family: 'Courier New, monospace',
},
},
],
text: 'Courier New',
},
{
type: 'text',
text: ', ',
},
{
type: 'text',
marks: [
{
type: 'fontFamily',
attrs: {
family: 'Impact, sans-serif',
},
},
],
text: 'Impact',
},
{
type: 'text',
text: ', ',
},
{
type: 'text',
marks: [
{
type: 'fontFamily',
attrs: {
family: 'Comic Sans MS, cursive',
},
},
],
text: 'Comic Sans',
},
{
type: 'text',
text: '.',
},
],
},
],
}import 'prosekit/basic/style.css'
import 'prosekit/basic/typography.css'
import { useMemo } from 'preact/hooks'
import { createEditor, type NodeJSON } from 'prosekit/core'
import { ProseKit } from 'prosekit/preact'
import { sampleContent } from '../../sample/sample-doc-font-family'
import { defineExtension } from './extension'
import Toolbar from './toolbar'
interface EditorProps {
initialContent?: NodeJSON
}
export default function Editor(props: EditorProps) {
const defaultContent = props.initialContent ?? sampleContent
const editor = useMemo(() => {
const extension = defineExtension()
return createEditor({ extension, defaultContent })
}, [defaultContent])
return (
<ProseKit editor={editor}>
<div className="box-border h-full w-full min-h-36 overflow-y-hidden overflow-x-hidden rounded-md border border-solid border-gray-200 dark:border-gray-700 shadow-sm flex flex-col bg-[canvas] text-black dark:text-white">
<Toolbar />
<div className="relative w-full flex-1 box-border overflow-y-auto">
<div ref={editor.mount} className="ProseMirror box-border min-h-full px-[max(4rem,calc(50%-20rem))] py-8 outline-hidden outline-0 [&_span[data-mention=user]]:text-blue-500 [&_span[data-mention=tag]]:text-violet-500"></div>
</div>
</div>
</ProseKit>
)
}import { defineBasicExtension } from 'prosekit/basic'
import { union } from 'prosekit/core'
import { defineFontFamily } from 'prosekit/extensions/font-family'
export function defineExtension() {
return union(defineBasicExtension(), defineFontFamily())
}
export type EditorExtension = ReturnType<typeof defineExtension>export { default as ExampleEditor } from './editor'import { useEffect } from 'preact/hooks'
import type { Editor } from 'prosekit/core'
import { useEditorDerivedValue } from 'prosekit/preact'
import type { EditorExtension } from './extension'
const fonts = [
{ label: 'Arial', family: 'Arial, sans-serif' },
{ label: 'Times New Roman', family: 'Times New Roman, serif' },
{ label: 'Courier New', family: 'Courier New, monospace' },
{ label: 'Georgia', family: 'Georgia, serif' },
{ label: 'Verdana', family: 'Verdana, sans-serif' },
{ label: 'Comic Sans MS', family: 'Comic Sans MS, cursive' },
{ label: 'Impact', family: 'Impact, sans-serif' },
{ label: 'Inter', family: 'Inter, sans-serif', google: true },
{ label: 'Playfair Display', family: 'Playfair Display, serif', google: true },
{ label: 'Merriweather', family: 'Merriweather, serif', google: true },
]
function loadGoogleFonts() {
const linkId = 'prosekit-google-fonts'
if (document.getElementById(linkId)) return
const link = document.createElement('link')
link.id = linkId
link.rel = 'stylesheet'
link.href =
'https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700&family=Merriweather:wght@400;700&family=Playfair+Display:wght@400;700&display=swap'
document.head.appendChild(link)
}
function getToolbarState(editor: Editor<EditorExtension>) {
let activeFont = ''
for (const font of fonts) {
if (editor.marks.fontFamily.isActive({ family: font.family })) {
activeFont = font.family
break
}
}
const handleChange = (value: string) => {
if (!value) {
editor.commands.removeFontFamily()
return
}
const font = fonts.find((f) => f.family === value)
if (font?.google) {
loadGoogleFonts()
}
editor.commands.addFontFamily({ family: value })
}
return { activeFont, handleChange }
}
export default function Toolbar() {
const state = useEditorDerivedValue(getToolbarState)
useEffect(() => {
loadGoogleFonts()
}, [])
return (
<div className="z-2 box-border border-gray-200 dark:border-gray-800 border-solid border-l-0 border-r-0 border-t-0 border-b flex flex-wrap gap-1 p-2 items-center">
<select
value={state.activeFont}
onChange={(e) => state.handleChange((e.target as HTMLSelectElement).value)}
className="px-2 py-1 rounded border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 text-sm"
>
<option value="">Default Font</option>
{fonts.map((font) => (
<option key={font.family} value={font.family} style={{ fontFamily: font.family }}>
{font.label}
</option>
))}
</select>
</div>
)
}import type { NodeJSON } from 'prosekit/core'
export const sampleContent: NodeJSON = {
type: 'doc',
content: [
{
type: 'paragraph',
content: [
{
type: 'text',
text: 'Select text and choose a font from the inline menu. ',
},
{
type: 'text',
marks: [
{
type: 'fontFamily',
attrs: {
family: 'Georgia, serif',
},
},
],
text: 'Georgia',
},
{
type: 'text',
text: ', ',
},
{
type: 'text',
marks: [
{
type: 'fontFamily',
attrs: {
family: 'Courier New, monospace',
},
},
],
text: 'Courier New',
},
{
type: 'text',
text: ', ',
},
{
type: 'text',
marks: [
{
type: 'fontFamily',
attrs: {
family: 'Impact, sans-serif',
},
},
],
text: 'Impact',
},
{
type: 'text',
text: ', ',
},
{
type: 'text',
marks: [
{
type: 'fontFamily',
attrs: {
family: 'Comic Sans MS, cursive',
},
},
],
text: 'Comic Sans',
},
{
type: 'text',
text: '.',
},
],
},
],
}import 'prosekit/basic/style.css'
import 'prosekit/basic/typography.css'
import { createEditor, type NodeJSON } from 'prosekit/core'
import { ProseKit } from 'prosekit/solid'
import type { JSX } from 'solid-js'
import { sampleContent } from '../../sample/sample-doc-font-family'
import { defineExtension } from './extension'
import Toolbar from './toolbar'
interface EditorProps {
initialContent?: NodeJSON
}
export default function Editor(props: EditorProps): JSX.Element {
const defaultContent = props.initialContent ?? sampleContent
const extension = defineExtension()
const editor = createEditor({ extension, defaultContent })
return (
<ProseKit editor={editor}>
<div class="box-border h-full w-full min-h-36 overflow-y-hidden overflow-x-hidden rounded-md border border-solid border-gray-200 dark:border-gray-700 shadow-sm flex flex-col bg-[canvas] text-black dark:text-white">
<Toolbar />
<div class="relative w-full flex-1 box-border overflow-y-auto">
<div ref={editor.mount} class="ProseMirror box-border min-h-full px-[max(4rem,calc(50%-20rem))] py-8 outline-hidden outline-0 [&_span[data-mention=user]]:text-blue-500 [&_span[data-mention=tag]]:text-violet-500"></div>
</div>
</div>
</ProseKit>
)
}import { defineBasicExtension } from 'prosekit/basic'
import { union } from 'prosekit/core'
import { defineFontFamily } from 'prosekit/extensions/font-family'
export function defineExtension() {
return union(defineBasicExtension(), defineFontFamily())
}
export type EditorExtension = ReturnType<typeof defineExtension>export { default as ExampleEditor } from './editor'import type { Editor } from 'prosekit/core'
import { useEditorDerivedValue } from 'prosekit/solid'
import { onMount, type JSX } from 'solid-js'
import type { EditorExtension } from './extension'
const fonts = [
{ label: 'Arial', family: 'Arial, sans-serif' },
{ label: 'Times New Roman', family: 'Times New Roman, serif' },
{ label: 'Courier New', family: 'Courier New, monospace' },
{ label: 'Georgia', family: 'Georgia, serif' },
{ label: 'Verdana', family: 'Verdana, sans-serif' },
{ label: 'Comic Sans MS', family: 'Comic Sans MS, cursive' },
{ label: 'Impact', family: 'Impact, sans-serif' },
{ label: 'Inter', family: 'Inter, sans-serif', google: true },
{ label: 'Playfair Display', family: 'Playfair Display, serif', google: true },
{ label: 'Merriweather', family: 'Merriweather, serif', google: true },
]
function loadGoogleFonts() {
const linkId = 'prosekit-google-fonts'
if (document.getElementById(linkId)) return
const link = document.createElement('link')
link.id = linkId
link.rel = 'stylesheet'
link.href =
'https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700&family=Merriweather:wght@400;700&family=Playfair+Display:wght@400;700&display=swap'
document.head.appendChild(link)
}
function getToolbarState(editor: Editor<EditorExtension>) {
let activeFont = ''
for (const font of fonts) {
if (editor.marks.fontFamily.isActive({ family: font.family })) {
activeFont = font.family
break
}
}
const handleChange = (value: string) => {
if (!value) {
editor.commands.removeFontFamily()
return
}
const font = fonts.find((f) => f.family === value)
if (font?.google) {
loadGoogleFonts()
}
editor.commands.addFontFamily({ family: value })
}
return { activeFont, handleChange }
}
export default function Toolbar(): JSX.Element {
const state = useEditorDerivedValue(getToolbarState)
onMount(() => {
loadGoogleFonts()
})
return (
<div class="z-2 box-border border-gray-200 dark:border-gray-800 border-solid border-l-0 border-r-0 border-t-0 border-b flex flex-wrap gap-1 p-2 items-center">
<select
value={state().activeFont}
onChange={(e) => state().handleChange(e.target.value)}
class="px-2 py-1 rounded border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 text-sm"
>
<option value="">Default Font</option>
{fonts.map((font) => (
<option value={font.family} style={{ 'font-family': font.family }}>
{font.label}
</option>
))}
</select>
</div>
)
}import type { NodeJSON } from 'prosekit/core'
export const sampleContent: NodeJSON = {
type: 'doc',
content: [
{
type: 'paragraph',
content: [
{
type: 'text',
text: 'Select text and choose a font from the inline menu. ',
},
{
type: 'text',
marks: [
{
type: 'fontFamily',
attrs: {
family: 'Georgia, serif',
},
},
],
text: 'Georgia',
},
{
type: 'text',
text: ', ',
},
{
type: 'text',
marks: [
{
type: 'fontFamily',
attrs: {
family: 'Courier New, monospace',
},
},
],
text: 'Courier New',
},
{
type: 'text',
text: ', ',
},
{
type: 'text',
marks: [
{
type: 'fontFamily',
attrs: {
family: 'Impact, sans-serif',
},
},
],
text: 'Impact',
},
{
type: 'text',
text: ', ',
},
{
type: 'text',
marks: [
{
type: 'fontFamily',
attrs: {
family: 'Comic Sans MS, cursive',
},
},
],
text: 'Comic Sans',
},
{
type: 'text',
text: '.',
},
],
},
],
}<script lang="ts">
import 'prosekit/basic/style.css'
import 'prosekit/basic/typography.css'
import { createEditor, type NodeJSON } from 'prosekit/core'
import { ProseKit } from 'prosekit/svelte'
import { untrack } from 'svelte'
import { sampleContent } from '../../sample/sample-doc-font-family'
import { defineExtension } from './extension'
import Toolbar from './toolbar.svelte'
const props: {
initialContent?: NodeJSON
} = $props()
const extension = defineExtension()
const defaultContent = untrack(() => props.initialContent ?? sampleContent)
const editor = createEditor({ extension, defaultContent })
</script>
<ProseKit {editor}>
<div class="box-border h-full w-full min-h-36 overflow-y-hidden overflow-x-hidden rounded-md border border-solid border-gray-200 dark:border-gray-700 shadow-sm flex flex-col bg-[canvas] text-black dark:text-white">
<Toolbar />
<div class="relative w-full flex-1 box-border overflow-y-auto">
<div {@attach editor.mount} class="ProseMirror box-border min-h-full px-[max(4rem,calc(50%-20rem))] py-8 outline-hidden outline-0 [&_span[data-mention=user]]:text-blue-500 [&_span[data-mention=tag]]:text-violet-500"></div>
</div>
</div>
</ProseKit>import { defineBasicExtension } from 'prosekit/basic'
import { union } from 'prosekit/core'
import { defineFontFamily } from 'prosekit/extensions/font-family'
export function defineExtension() {
return union(defineBasicExtension(), defineFontFamily())
}
export type EditorExtension = ReturnType<typeof defineExtension>export { default as ExampleEditor } from './editor.svelte'<script lang="ts">
import type { Editor } from 'prosekit/core'
import { useEditorDerivedValue } from 'prosekit/svelte'
import type { EditorExtension } from './extension'
const fonts = [
{ label: 'Arial', family: 'Arial, sans-serif' },
{ label: 'Times New Roman', family: 'Times New Roman, serif' },
{ label: 'Courier New', family: 'Courier New, monospace' },
{ label: 'Georgia', family: 'Georgia, serif' },
{ label: 'Verdana', family: 'Verdana, sans-serif' },
{ label: 'Comic Sans MS', family: 'Comic Sans MS, cursive' },
{ label: 'Impact', family: 'Impact, sans-serif' },
{ label: 'Inter', family: 'Inter, sans-serif', google: true },
{ label: 'Playfair Display', family: 'Playfair Display, serif', google: true },
{ label: 'Merriweather', family: 'Merriweather, serif', google: true },
]
function loadGoogleFonts() {
const linkId = 'prosekit-google-fonts'
if (document.getElementById(linkId)) return
const link = document.createElement('link')
link.id = linkId
link.rel = 'stylesheet'
link.href =
'https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700&family=Merriweather:wght@400;700&family=Playfair+Display:wght@400;700&display=swap'
document.head.appendChild(link)
}
function getToolbarState(editor: Editor<EditorExtension>) {
let activeFont = ''
for (const font of fonts) {
if (editor.marks.fontFamily.isActive({ family: font.family })) {
activeFont = font.family
break
}
}
const handleChange = (value: string) => {
if (!value) {
editor.commands.removeFontFamily()
return
}
const font = fonts.find((f) => f.family === value)
if (font?.google) {
loadGoogleFonts()
}
editor.commands.addFontFamily({ family: value })
}
return { activeFont, handleChange }
}
const state = useEditorDerivedValue(getToolbarState)
$effect(() => {
loadGoogleFonts()
})
</script>
<div class="z-2 box-border border-gray-200 dark:border-gray-800 border-solid border-l-0 border-r-0 border-t-0 border-b flex flex-wrap gap-1 p-2 items-center">
<select
value={$state.activeFont}
onchange={(e) => $state.handleChange((e.target as HTMLSelectElement).value)}
class="px-2 py-1 rounded border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 text-sm"
>
<option value="">Default Font</option>
{#each fonts as font (font.family)}
<option value={font.family} style:font-family={font.family}>
{font.label}
</option>
{/each}
</select>
</div>import type { NodeJSON } from 'prosekit/core'
export const sampleContent: NodeJSON = {
type: 'doc',
content: [
{
type: 'paragraph',
content: [
{
type: 'text',
text: 'Select text and choose a font from the inline menu. ',
},
{
type: 'text',
marks: [
{
type: 'fontFamily',
attrs: {
family: 'Georgia, serif',
},
},
],
text: 'Georgia',
},
{
type: 'text',
text: ', ',
},
{
type: 'text',
marks: [
{
type: 'fontFamily',
attrs: {
family: 'Courier New, monospace',
},
},
],
text: 'Courier New',
},
{
type: 'text',
text: ', ',
},
{
type: 'text',
marks: [
{
type: 'fontFamily',
attrs: {
family: 'Impact, sans-serif',
},
},
],
text: 'Impact',
},
{
type: 'text',
text: ', ',
},
{
type: 'text',
marks: [
{
type: 'fontFamily',
attrs: {
family: 'Comic Sans MS, cursive',
},
},
],
text: 'Comic Sans',
},
{
type: 'text',
text: '.',
},
],
},
],
}<script setup lang="ts">
import 'prosekit/basic/style.css'
import 'prosekit/basic/typography.css'
import { createEditor, type NodeJSON } from 'prosekit/core'
import { ProseKit } from 'prosekit/vue'
import { sampleContent } from '../../sample/sample-doc-font-family'
import { defineExtension } from './extension'
import Toolbar from './toolbar.vue'
const props = defineProps<{
initialContent?: NodeJSON
}>()
const extension = defineExtension()
const defaultContent = props.initialContent ?? sampleContent
const editor = createEditor({ extension, defaultContent })
</script>
<template>
<ProseKit :editor="editor">
<div class="box-border h-full w-full min-h-36 overflow-y-hidden overflow-x-hidden rounded-md border border-solid border-gray-200 dark:border-gray-700 shadow-sm flex flex-col bg-[canvas] text-black dark:text-white">
<Toolbar />
<div class="relative w-full flex-1 box-border overflow-y-auto">
<div :ref="(el) => editor.mount(el as HTMLElement | null)" class="ProseMirror box-border min-h-full px-[max(4rem,calc(50%-20rem))] py-8 outline-hidden outline-0 [&_span[data-mention=user]]:text-blue-500 [&_span[data-mention=tag]]:text-violet-500" />
</div>
</div>
</ProseKit>
</template>import { defineBasicExtension } from 'prosekit/basic'
import { union } from 'prosekit/core'
import { defineFontFamily } from 'prosekit/extensions/font-family'
export function defineExtension() {
return union(defineBasicExtension(), defineFontFamily())
}
export type EditorExtension = ReturnType<typeof defineExtension>export { default as ExampleEditor } from './editor.vue'<script setup lang="ts">
import type { Editor } from 'prosekit/core'
import { useEditorDerivedValue } from 'prosekit/vue'
import { onMounted } from 'vue'
import type { EditorExtension } from './extension'
const fonts = [
{ label: 'Arial', family: 'Arial, sans-serif' },
{ label: 'Times New Roman', family: 'Times New Roman, serif' },
{ label: 'Courier New', family: 'Courier New, monospace' },
{ label: 'Georgia', family: 'Georgia, serif' },
{ label: 'Verdana', family: 'Verdana, sans-serif' },
{ label: 'Comic Sans MS', family: 'Comic Sans MS, cursive' },
{ label: 'Impact', family: 'Impact, sans-serif' },
{ label: 'Inter', family: 'Inter, sans-serif', google: true },
{ label: 'Playfair Display', family: 'Playfair Display, serif', google: true },
{ label: 'Merriweather', family: 'Merriweather, serif', google: true },
]
function loadGoogleFonts() {
const linkId = 'prosekit-google-fonts'
if (document.getElementById(linkId)) return
const link = document.createElement('link')
link.id = linkId
link.rel = 'stylesheet'
link.href =
'https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700&family=Merriweather:wght@400;700&family=Playfair+Display:wght@400;700&display=swap'
document.head.appendChild(link)
}
function getToolbarState(editor: Editor<EditorExtension>) {
let activeFont = ''
for (const font of fonts) {
if (editor.marks.fontFamily.isActive({ family: font.family })) {
activeFont = font.family
break
}
}
const handleChange = (value: string) => {
if (!value) {
editor.commands.removeFontFamily()
return
}
const font = fonts.find((f) => f.family === value)
if (font?.google) {
loadGoogleFonts()
}
editor.commands.addFontFamily({ family: value })
}
return { activeFont, handleChange }
}
const state = useEditorDerivedValue(getToolbarState)
onMounted(() => {
loadGoogleFonts()
})
</script>
<template>
<div class="z-2 box-border border-gray-200 dark:border-gray-800 border-solid border-l-0 border-r-0 border-t-0 border-b flex flex-wrap gap-1 p-2 items-center">
<select
:value="state.activeFont"
class="px-2 py-1 rounded border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 text-sm"
@change="state.handleChange(($event.target as HTMLSelectElement).value)"
>
<option value="">
Default Font
</option>
<option
v-for="font in fonts"
:key="font.family"
:value="font.family"
:style="{ fontFamily: font.family }"
>
{{ font.label }}
</option>
</select>
</div>
</template>import type { NodeJSON } from 'prosekit/core'
export const sampleContent: NodeJSON = {
type: 'doc',
content: [
{
type: 'paragraph',
content: [
{
type: 'text',
text: 'Select text and choose a font from the inline menu. ',
},
{
type: 'text',
marks: [
{
type: 'fontFamily',
attrs: {
family: 'Georgia, serif',
},
},
],
text: 'Georgia',
},
{
type: 'text',
text: ', ',
},
{
type: 'text',
marks: [
{
type: 'fontFamily',
attrs: {
family: 'Courier New, monospace',
},
},
],
text: 'Courier New',
},
{
type: 'text',
text: ', ',
},
{
type: 'text',
marks: [
{
type: 'fontFamily',
attrs: {
family: 'Impact, sans-serif',
},
},
],
text: 'Impact',
},
{
type: 'text',
text: ', ',
},
{
type: 'text',
marks: [
{
type: 'fontFamily',
attrs: {
family: 'Comic Sans MS, cursive',
},
},
],
text: 'Comic Sans',
},
{
type: 'text',
text: '.',
},
],
},
],
}