Skip to content

Commit

Permalink
feat(font-size): add font size extension (#5894)
Browse files Browse the repository at this point in the history
  • Loading branch information
kart-c authored Dec 31, 2024
1 parent 20f68f6 commit 3b4e06c
Show file tree
Hide file tree
Showing 15 changed files with 354 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/red-rivers-exist.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@tiptap/extension-font-size": patch
---

This adds the new @tiptap/extension-font-size extension for changing the font-size of text based on the textStyle extension
1 change: 1 addition & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
"extension/floating-menu",
"extension/focus",
"extension/font-family",
"extension/font-size",
"extension/gapcursor",
"extension/hard-break",
"extension/heading",
Expand Down
Empty file.
51 changes: 51 additions & 0 deletions demos/src/Extensions/FontSize/React/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import FontSize from '@tiptap/extension-font-size'
import TextStyle from '@tiptap/extension-text-style'
import { EditorContent, useEditor } from '@tiptap/react'
import StarterKit from '@tiptap/starter-kit'

export default () => {
const editor = useEditor({
shouldRerenderOnTransaction: true,
extensions: [StarterKit, TextStyle, FontSize],
content: `
<p>Adjusting font sizes can greatly affect the readability of your text, making it easier for users to engage with your content.</p>
<p>When designing a website, it's crucial to balance large headings and smaller body text for a clean, organized layout.</p>
<p>When setting font sizes, it's important to consider accessibility, ensuring that text is readable for users with different visual impairments.</p>
<p><span style="font-size: 10px">Too small</span> a font size can strain the eyes, while <span style="font-size: 40px">too large</span> can disrupt the flow of the design.</p>
<p>When designing for mobile, font sizes should be adjusted to maintain readability on smaller screens.</p>
`,
})

if (!editor) {
return null
}

return <>
<div className="control-group">
<div className="button-group">
<button
onClick={() => editor.chain().focus().setFontSize('28px').run()}
className={editor.isActive('textStyle', { fontSize: '28px' }) ? 'is-active' : ''}
data-test-id="28px"
>
Font size 28px
</button>
<button
onClick={() => editor.chain().focus().setFontSize('32px').run()}
className={editor.isActive('textStyle', { fontSize: '32px' }) ? 'is-active' : ''}
data-test-id="32px"
>
Font size 32px
</button>
<button
onClick={() => editor.chain().focus().unsetFontSize().run()}
data-test-id="unsetFontSize"
>
Unset font size
</button>
</div>
</div>

<EditorContent editor={editor} />
</>
}
28 changes: 28 additions & 0 deletions demos/src/Extensions/FontSize/React/index.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
context('/src/Extensions/FontSize/React/', () => {
before(() => {
cy.visit('/src/Extensions/FontSize/React/')
})

beforeEach(() => {
cy.get('.tiptap').then(([{ editor }]) => {
editor.commands.setContent('<p>Example Text</p>')
})
cy.get('.tiptap').type('{selectall}')
})

it('should set the font-size of the selected text', () => {
cy.get('[data-test-id="28px"]')
.should('not.have.class', 'is-active')
.click()
.should('have.class', 'is-active')

cy.get('.tiptap').find('span').should('have.attr', 'style', 'font-size: 28px')
})

it('should remove the font-size of the selected text', () => {
cy.get('[data-test-id="28px"]').click()
cy.get('.tiptap').find('span').should('have.attr', 'style', 'font-size: 28px')
cy.get('[data-test-id="unsetFontSize"]').click()
cy.get('.tiptap').get('span').should('not.exist')
})
})
Empty file.
28 changes: 28 additions & 0 deletions demos/src/Extensions/FontSize/Vue/index.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
context('/src/Extensions/FontSize/Vue/', () => {
before(() => {
cy.visit('/src/Extensions/FontSize/Vue/')
})

beforeEach(() => {
cy.get('.tiptap').then(([{ editor }]) => {
editor.commands.setContent('<p>Example Text</p>')
})
cy.get('.tiptap').type('{selectall}')
})

it('should set the font-size of the selected text', () => {
cy.get('[data-test-id="28px"]')
.should('not.have.class', 'is-active')
.click()
.should('have.class', 'is-active')

cy.get('.tiptap').find('span').should('have.attr', 'style', 'font-size: 28px')
})

it('should remove the font-size of the selected text', () => {
cy.get('[data-test-id="28px"]').click()
cy.get('.tiptap').find('span').should('have.attr', 'style', 'font-size: 28px')
cy.get('[data-test-id="unsetFontSize"]').click()
cy.get('.tiptap').get('span').should('not.exist')
})
})
58 changes: 58 additions & 0 deletions demos/src/Extensions/FontSize/Vue/index.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<template>
<div v-if="editor" class="container">
<div class="control-group">
<div class="button-group">
<button @click="editor.chain().focus().setFontSize('28px').run()" :class="{ 'is-active': editor.isActive('textStyle', { fontSize: '28px' }) }" data-test-id="28px">
Font size 28px
</button>
<button @click="editor.chain().focus().setFontSize('32px').run()" :class="{ 'is-active': editor.isActive('textStyle', { fontSize: '32px' }) }" data-test-id="32px">
Font size 32px
</button>
<button @click="editor.chain().focus().unsetFontSize().run()" data-test-id="unsetFontSize">
Unset font size
</button>
</div>
</div>
<editor-content :editor="editor" />
</div>
</template>

<script>
import FontSize from '@tiptap/extension-font-size'
import TextStyle from '@tiptap/extension-text-style'
import StarterKit from '@tiptap/starter-kit'
import { Editor, EditorContent } from '@tiptap/vue-3'
export default {
components: {
EditorContent,
},
data() {
return {
editor: null,
}
},
mounted() {
this.editor = new Editor({
extensions: [
StarterKit,
TextStyle,
FontSize,
],
content: `
<p>Adjusting font sizes can greatly affect the readability of your text, making it easier for users to engage with your content.</p>
<p>When designing a website, it's crucial to balance large headings and smaller body text for a clean, organized layout.</p>
<p>When setting font sizes, it's important to consider accessibility, ensuring that text is readable for users with different visual impairments.</p>
<p><span style="font-size: 10px">Too small</span> a font size can strain the eyes, while <span style="font-size: 40px">too large</span> can disrupt the flow of the design.</p>
<p>When designing for mobile, font sizes should be adjusted to maintain readability on smaller screens.</p>
`,
})
},
beforeUnmount() {
this.editor.destroy()
},
}
</script>
21 changes: 21 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions packages/extension-font-size/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Change Log

## 2.10.2
14 changes: 14 additions & 0 deletions packages/extension-font-size/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# @tiptap/extension-font-size
[![Version](https://img.shields.io/npm/v/@tiptap/extension-font-size.svg?label=version)](https://www.npmjs.com/package/@tiptap/extension-font-size)
[![Downloads](https://img.shields.io/npm/dm/@tiptap/extension-font-size.svg)](https://npmcharts.com/compare/tiptap?minimal=true)
[![License](https://img.shields.io/npm/l/@tiptap/extension-font-size.svg)](https://www.npmjs.com/package/@tiptap/extension-font-size)
[![Sponsor](https://img.shields.io/static/v1?label=Sponsor&message=%E2%9D%A4&logo=GitHub)](https://github.com/sponsors/ueberdosis)

## Introduction
Tiptap is a headless wrapper around [ProseMirror](https://ProseMirror.net) – a toolkit for building rich text WYSIWYG editors, which is already in use at many well-known companies such as *New York Times*, *The Guardian* or *Atlassian*.

## Official Documentation
Documentation can be found on the [Tiptap website](https://tiptap.dev).

## License
Tiptap is open sourced software licensed under the [MIT license](https://github.com/ueberdosis/tiptap/blob/main/LICENSE.md).
46 changes: 46 additions & 0 deletions packages/extension-font-size/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"name": "@tiptap/extension-font-size",
"description": "font size extension for tiptap",
"version": "3.0.0-next.3",
"homepage": "https://tiptap.dev",
"keywords": [
"tiptap",
"tiptap extension"
],
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/ueberdosis"
},
"type": "module",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js",
"require": "./dist/index.cjs"
}
},
"main": "dist/index.cjs",
"module": "dist/index.js",
"types": "dist/index.d.ts",
"files": [
"src",
"dist"
],
"devDependencies": {
"@tiptap/core": "^3.0.0-next.3",
"@tiptap/extension-text-style": "^3.0.0-next.3"
},
"peerDependencies": {
"@tiptap/core": "^3.0.0-next.3",
"@tiptap/extension-text-style": "^3.0.0-next.3"
},
"repository": {
"type": "git",
"url": "https://github.com/ueberdosis/tiptap",
"directory": "packages/extension-font-size"
},
"scripts": {
"build": "tsup"
}
}
80 changes: 80 additions & 0 deletions packages/extension-font-size/src/font-size.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import '@tiptap/extension-text-style'

import { Extension } from '@tiptap/core'

export type FontSizeOptions = {
/**
* A list of node names where the font size can be applied.
* @default ['textStyle']
* @example ['heading', 'paragraph']
*/
types: string[];
};

declare module '@tiptap/core' {
interface Commands<ReturnType> {
fontSize: {
/**
* Set the font size
* @param fontSize The font size
* @example editor.commands.setFontSize('Arial')
*/
setFontSize: (fontSize: string) => ReturnType;
/**
* Unset the font size
* @example editor.commands.unsetFontSize()
*/
unsetFontSize: () => ReturnType;
};
}
}

/**
* This extension allows you to set a font size for text.
* @see https://www.tiptap.dev/api/extensions/font-size
*/
export const FontSize = Extension.create<FontSizeOptions>({
name: 'fontSize',

addOptions() {
return {
types: ['textStyle'],
}
},

addGlobalAttributes() {
return [
{
types: this.options.types,
attributes: {
fontSize: {
default: null,
parseHTML: element => element.style.fontSize,
renderHTML: attributes => {
if (!attributes.fontSize) {
return {}
}

return {
style: `font-size: ${attributes.fontSize}`,
}
},
},
},
},
]
},

addCommands() {
return {
setFontSize:
fontSize => ({ chain }) => {
return chain().setMark('textStyle', { fontSize }).run()
},
unsetFontSize:
() => ({ chain }) => {
return chain().setMark('textStyle', { fontSize: null }).removeEmptyTextStyle().run()
},
}
},
})
5 changes: 5 additions & 0 deletions packages/extension-font-size/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { FontSize } from './font-size.js'

export * from './font-size.js'

export default FontSize
14 changes: 14 additions & 0 deletions packages/extension-font-size/tsup.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { defineConfig } from 'tsup'

export default defineConfig({
entry: ['src/index.ts'],
tsconfig: '../../tsconfig.build.json',
outDir: 'dist',
dts: true,
clean: true,
sourcemap: true,
format: [
'esm',
'cjs',
],
})

0 comments on commit 3b4e06c

Please sign in to comment.