mirror of
https://github.com/ueberdosis/tiptap.git
synced 2025-06-07 17:43:49 +08:00
feat(text-style): merge all pkgs into text-style, add background-color
and line-height
(#6001)
This commit is contained in:
parent
6a53bb2699
commit
0b4981c832
5
.changeset/orange-spoons-rescue.md
Normal file
5
.changeset/orange-spoons-rescue.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
'@tiptap/extension-text-style': minor
|
||||
---
|
||||
|
||||
Add `toggleTextStyle` command and add typings for the commands parameters based on the installed extensions that include `textStyle`
|
5
.changeset/smart-turtles-happen.md
Normal file
5
.changeset/smart-turtles-happen.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
'@tiptap/extension-background-color': patch
|
||||
---
|
||||
|
||||
Adds a new extension, `extension-background-color` which can color the background of `textStyle`s
|
5
.changeset/twelve-paws-work.md
Normal file
5
.changeset/twelve-paws-work.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
'@tiptap/extension-line-height': patch
|
||||
---
|
||||
|
||||
This adds the `extension-line-height` package which controls the line-height of text like `font-size`, `font-family`, etc.
|
@ -1,8 +1,7 @@
|
||||
import './styles.scss'
|
||||
|
||||
import { Color } from '@tiptap/extension-color'
|
||||
import ListItem from '@tiptap/extension-list-item'
|
||||
import TextStyle from '@tiptap/extension-text-style'
|
||||
import { Color, TextStyle } from '@tiptap/extension-text-style'
|
||||
import { EditorContent, useEditor } from '@tiptap/react'
|
||||
import StarterKit from '@tiptap/starter-kit'
|
||||
import React, { useCallback } from 'react'
|
||||
|
@ -1,10 +1,9 @@
|
||||
import './styles.scss'
|
||||
|
||||
import { Color } from '@tiptap/extension-color'
|
||||
import { Image } from '@tiptap/extension-image'
|
||||
import Link from '@tiptap/extension-link'
|
||||
import ListItem from '@tiptap/extension-list-item'
|
||||
import TextStyle from '@tiptap/extension-text-style'
|
||||
import { Color, TextStyle } from '@tiptap/extension-text-style'
|
||||
import { EditorProvider, useCurrentEditor } from '@tiptap/react'
|
||||
import StarterKit from '@tiptap/starter-kit'
|
||||
import React, { useCallback } from 'react'
|
||||
|
@ -1,9 +1,8 @@
|
||||
import './styles.scss'
|
||||
|
||||
import { Color } from '@tiptap/extension-color'
|
||||
import ListItem from '@tiptap/extension-list-item'
|
||||
import Mentions from '@tiptap/extension-mention'
|
||||
import TextStyle from '@tiptap/extension-text-style'
|
||||
import { Color , TextStyle } from '@tiptap/extension-text-style'
|
||||
import { EditorProvider } from '@tiptap/react'
|
||||
import StarterKit from '@tiptap/starter-kit'
|
||||
import React from 'react'
|
||||
|
@ -1,8 +1,7 @@
|
||||
import './styles.scss'
|
||||
|
||||
import { Color } from '@tiptap/extension-color'
|
||||
import ListItem from '@tiptap/extension-list-item'
|
||||
import TextStyle from '@tiptap/extension-text-style'
|
||||
import { Color , TextStyle } from '@tiptap/extension-text-style'
|
||||
import { EditorProvider, useCurrentEditor, useEditorState } from '@tiptap/react'
|
||||
import StarterKit from '@tiptap/starter-kit'
|
||||
import React from 'react'
|
||||
|
@ -1,9 +1,9 @@
|
||||
<script>
|
||||
import "./styles.scss";
|
||||
|
||||
import { Color } from '@tiptap/extension-color'
|
||||
import { Color } from '@tiptap/extension-text-style'
|
||||
import ListItem from '@tiptap/extension-list-item'
|
||||
import TextStyle from '@tiptap/extension-text-style'
|
||||
import { TextStyle } from '@tiptap/extension-text-style'
|
||||
import StarterKit from "@tiptap/starter-kit";
|
||||
import { Editor } from "@tiptap/core";
|
||||
import { onMount } from "svelte";
|
||||
|
@ -119,9 +119,8 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Color } from '@tiptap/extension-color'
|
||||
import ListItem from '@tiptap/extension-list-item'
|
||||
import TextStyle from '@tiptap/extension-text-style'
|
||||
import { Color, TextStyle } from '@tiptap/extension-text-style'
|
||||
import StarterKit from '@tiptap/starter-kit'
|
||||
import { Editor, EditorContent } from '@tiptap/vue-3'
|
||||
|
||||
|
@ -1,8 +1,7 @@
|
||||
import './styles.scss'
|
||||
|
||||
import { Color } from '@tiptap/extension-color'
|
||||
import ListItem from '@tiptap/extension-list-item'
|
||||
import TextStyle from '@tiptap/extension-text-style'
|
||||
import { Color, TextStyle } from '@tiptap/extension-text-style'
|
||||
import { EditorProvider, JSONContent, useCurrentEditor, useEditorState } from '@tiptap/react'
|
||||
import StarterKit from '@tiptap/starter-kit'
|
||||
import { renderToHTMLString, renderToMarkdown, renderToReactElement } from '@tiptap/static-renderer'
|
||||
|
@ -104,7 +104,6 @@ import Bold from '@tiptap/extension-bold'
|
||||
import BulletList from '@tiptap/extension-bullet-list'
|
||||
import Code from '@tiptap/extension-code'
|
||||
import CodeBlockLowlight from '@tiptap/extension-code-block-lowlight'
|
||||
import Color from '@tiptap/extension-color'
|
||||
import Document from '@tiptap/extension-document'
|
||||
import Dropcursor from '@tiptap/extension-dropcursor'
|
||||
import Gapcursor from '@tiptap/extension-gapcursor'
|
||||
@ -129,7 +128,7 @@ import TaskItem from '@tiptap/extension-task-item'
|
||||
import TaskList from '@tiptap/extension-task-list'
|
||||
import Text from '@tiptap/extension-text'
|
||||
import TextAlign from '@tiptap/extension-text-align'
|
||||
import TextStyle from '@tiptap/extension-text-style'
|
||||
import { Color, TextStyle } from '@tiptap/extension-text-style'
|
||||
import Underline from '@tiptap/extension-underline'
|
||||
import { Editor, EditorContent } from '@tiptap/vue-3'
|
||||
import { all, createLowlight } from 'lowlight'
|
||||
|
@ -1,8 +1,7 @@
|
||||
import './styles.scss'
|
||||
|
||||
import { Color } from '@tiptap/extension-color'
|
||||
import ListItem from '@tiptap/extension-list-item'
|
||||
import TextStyle from '@tiptap/extension-text-style'
|
||||
import { Color, TextStyle } from '@tiptap/extension-text-style'
|
||||
import { EditorContent, Node, useEditor } from '@tiptap/react'
|
||||
import StarterKit from '@tiptap/starter-kit'
|
||||
import React from 'react'
|
||||
|
56
demos/src/Extensions/BackgroundColor/React/index.spec.js
Normal file
56
demos/src/Extensions/BackgroundColor/React/index.spec.js
Normal file
@ -0,0 +1,56 @@
|
||||
context('/src/Extensions/BackgroundColor/React/', () => {
|
||||
before(() => {
|
||||
cy.visit('/src/Extensions/BackgroundColor/React/')
|
||||
})
|
||||
|
||||
beforeEach(() => {
|
||||
cy.get('.tiptap').then(([{ editor }]) => {
|
||||
editor.commands.setContent('<p>Example Text</p>')
|
||||
})
|
||||
cy.get('.tiptap').type('{selectall}')
|
||||
})
|
||||
|
||||
it('should set the background color of the selected text', () => {
|
||||
cy.get('[data-testid="setPurple"]').should('not.have.class', 'is-active').click().should('have.class', 'is-active')
|
||||
|
||||
cy.get('.tiptap').find('span').should('have.attr', 'style', 'background-color: #958DF1')
|
||||
})
|
||||
|
||||
it('should remove the background color of the selected text', () => {
|
||||
cy.get('[data-testid="setPurple"]').click()
|
||||
|
||||
cy.get('.tiptap span').should('exist')
|
||||
|
||||
cy.get('[data-testid="unsetBackgroundColor"]').click()
|
||||
|
||||
cy.get('.tiptap span').should('not.exist')
|
||||
})
|
||||
|
||||
it('should change background color with color picker', () => {
|
||||
cy.get('input[type=color]').invoke('val', '#ff0000').trigger('input')
|
||||
|
||||
cy.get('.tiptap').find('span').should('have.attr', 'style', 'background-color: #ff0000')
|
||||
})
|
||||
|
||||
it('should match background color and color picker color values', () => {
|
||||
cy.get('[data-testid="setPurple"]').click()
|
||||
|
||||
cy.get('input[type=color]').should('have.value', '#958df1')
|
||||
})
|
||||
|
||||
it('should preserve background color on new lines', () => {
|
||||
cy.get('[data-testid="setPurple"]').click()
|
||||
cy.get('.ProseMirror').type('Example Text{enter}')
|
||||
|
||||
cy.get('[data-testid="setPurple"]').should('have.class', 'is-active')
|
||||
})
|
||||
|
||||
it('should unset background color on new lines after unset clicked', () => {
|
||||
cy.get('[data-testid="setPurple"]').click()
|
||||
cy.get('.ProseMirror').type('Example Text{enter}')
|
||||
cy.get('[data-testid="unsetBackgroundColor"]').click()
|
||||
cy.get('.ProseMirror').type('Example Text')
|
||||
|
||||
cy.get('[data-testid="setPurple"]').should('not.have.class', 'is-active')
|
||||
})
|
||||
})
|
109
demos/src/Extensions/BackgroundColor/React/index.tsx
Normal file
109
demos/src/Extensions/BackgroundColor/React/index.tsx
Normal file
@ -0,0 +1,109 @@
|
||||
import './styles.scss'
|
||||
|
||||
import Document from '@tiptap/extension-document'
|
||||
import Paragraph from '@tiptap/extension-paragraph'
|
||||
import Text from '@tiptap/extension-text'
|
||||
import { BackgroundColor, TextStyle } from '@tiptap/extension-text-style'
|
||||
import { EditorContent, useEditor, useEditorState } from '@tiptap/react'
|
||||
import React from 'react'
|
||||
|
||||
export default () => {
|
||||
const editor = useEditor({
|
||||
extensions: [Document, Paragraph, Text, TextStyle, BackgroundColor],
|
||||
content: `
|
||||
<p><span style="background-color: #958DF1">Oh, for some reason that’s purple.</span></p>
|
||||
`,
|
||||
})
|
||||
|
||||
const editorState = useEditorState({
|
||||
editor,
|
||||
selector: ctx => {
|
||||
return {
|
||||
color: ctx.editor.getAttributes('textStyle').backgroundColor,
|
||||
isPurple: ctx.editor.isActive('textStyle', { backgroundColor: '#958DF1' }),
|
||||
isRed: ctx.editor.isActive('textStyle', { backgroundColor: '#F98181' }),
|
||||
isOrange: ctx.editor.isActive('textStyle', { backgroundColor: '#FBBC88' }),
|
||||
isYellow: ctx.editor.isActive('textStyle', { backgroundColor: '#FAF594' }),
|
||||
isBlue: ctx.editor.isActive('textStyle', { backgroundColor: '#70CFF8' }),
|
||||
isTeal: ctx.editor.isActive('textStyle', { backgroundColor: '#94FADB' }),
|
||||
isGreen: ctx.editor.isActive('textStyle', { backgroundColor: '#B9F18D' }),
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
if (!editor) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="control-group">
|
||||
<div className="button-group">
|
||||
<input
|
||||
type="color"
|
||||
onInput={event => editor.chain().focus().setBackgroundColor(event.currentTarget.value).run()}
|
||||
value={editorState.color}
|
||||
data-testid="setBackgroundColor"
|
||||
/>
|
||||
<button
|
||||
onClick={() => editor.chain().focus().setBackgroundColor('#958DF1').run()}
|
||||
className={editorState.isPurple ? 'is-active' : ''}
|
||||
data-testid="setPurple"
|
||||
>
|
||||
Purple
|
||||
</button>
|
||||
<button
|
||||
onClick={() => editor.chain().focus().setBackgroundColor('#F98181').run()}
|
||||
className={editorState.isRed ? 'is-active' : ''}
|
||||
data-testid="setRed"
|
||||
>
|
||||
Red
|
||||
</button>
|
||||
<button
|
||||
onClick={() => editor.chain().focus().setBackgroundColor('#FBBC88').run()}
|
||||
className={editorState.isOrange ? 'is-active' : ''}
|
||||
data-testid="setOrange"
|
||||
>
|
||||
Orange
|
||||
</button>
|
||||
<button
|
||||
onClick={() => editor.chain().focus().setBackgroundColor('#FAF594').run()}
|
||||
className={editorState.isYellow ? 'is-active' : ''}
|
||||
data-testid="setYellow"
|
||||
>
|
||||
Yellow
|
||||
</button>
|
||||
<button
|
||||
onClick={() => editor.chain().focus().setBackgroundColor('#70CFF8').run()}
|
||||
className={editorState.isBlue ? 'is-active' : ''}
|
||||
data-testid="setBlue"
|
||||
>
|
||||
Blue
|
||||
</button>
|
||||
<button
|
||||
onClick={() => editor.chain().focus().setBackgroundColor('#94FADB').run()}
|
||||
className={editorState.isTeal ? 'is-active' : ''}
|
||||
data-testid="setTeal"
|
||||
>
|
||||
Teal
|
||||
</button>
|
||||
<button
|
||||
onClick={() => editor.chain().focus().setBackgroundColor('#B9F18D').run()}
|
||||
className={editorState.isGreen ? 'is-active' : ''}
|
||||
data-testid="setGreen"
|
||||
>
|
||||
Green
|
||||
</button>
|
||||
<button
|
||||
onClick={() => editor.chain().focus().unsetBackgroundColor().run()}
|
||||
data-testid="unsetBackgroundColor"
|
||||
>
|
||||
Unset color
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<EditorContent editor={editor} />
|
||||
</>
|
||||
)
|
||||
}
|
6
demos/src/Extensions/BackgroundColor/React/styles.scss
Normal file
6
demos/src/Extensions/BackgroundColor/React/styles.scss
Normal file
@ -0,0 +1,6 @@
|
||||
/* Basic editor styles */
|
||||
.tiptap {
|
||||
:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
0
demos/src/Extensions/BackgroundColor/Vue/index.html
Normal file
0
demos/src/Extensions/BackgroundColor/Vue/index.html
Normal file
56
demos/src/Extensions/BackgroundColor/Vue/index.spec.js
Normal file
56
demos/src/Extensions/BackgroundColor/Vue/index.spec.js
Normal file
@ -0,0 +1,56 @@
|
||||
context('/src/Extensions/BackgroundColor/Vue/', () => {
|
||||
before(() => {
|
||||
cy.visit('/src/Extensions/BackgroundColor/Vue/')
|
||||
})
|
||||
|
||||
beforeEach(() => {
|
||||
cy.get('.tiptap').then(([{ editor }]) => {
|
||||
editor.commands.setContent('<p>Example Text</p>')
|
||||
})
|
||||
cy.get('.tiptap').type('{selectall}')
|
||||
})
|
||||
|
||||
it('should set the background color of the selected text', () => {
|
||||
cy.get('[data-testid="setPurple"]').should('not.have.class', 'is-active').click().should('have.class', 'is-active')
|
||||
|
||||
cy.get('.tiptap').find('span').should('have.attr', 'style', 'background-color: #958DF1')
|
||||
})
|
||||
|
||||
it('should remove the background color of the selected text', () => {
|
||||
cy.get('[data-testid="setPurple"]').click()
|
||||
|
||||
cy.get('.tiptap span').should('exist')
|
||||
|
||||
cy.get('[data-testid="unsetBackgroundColor"]').click()
|
||||
|
||||
cy.get('.tiptap span').should('not.exist')
|
||||
})
|
||||
|
||||
it('should change background color with color picker', () => {
|
||||
cy.get('input[type=color]').invoke('val', '#ff0000').trigger('input')
|
||||
|
||||
cy.get('.tiptap').find('span').should('have.attr', 'style', 'background-color: #ff0000')
|
||||
})
|
||||
|
||||
it('should match background color and color picker color values', () => {
|
||||
cy.get('[data-testid="setPurple"]').click()
|
||||
|
||||
cy.get('input[type=color]').should('have.value', '#958df1')
|
||||
})
|
||||
|
||||
it('should preserve background color on new lines', () => {
|
||||
cy.get('[data-testid="setPurple"]').click()
|
||||
cy.get('.ProseMirror').type('Example Text{enter}')
|
||||
|
||||
cy.get('[data-testid="setPurple"]').should('have.class', 'is-active')
|
||||
})
|
||||
|
||||
it('should unset background color on new lines after unset clicked', () => {
|
||||
cy.get('[data-testid="setPurple"]').click()
|
||||
cy.get('.ProseMirror').type('Example Text{enter}')
|
||||
cy.get('[data-testid="unsetBackgroundColor"]').click()
|
||||
cy.get('.ProseMirror').type('Example Text')
|
||||
|
||||
cy.get('[data-testid="setPurple"]').should('not.have.class', 'is-active')
|
||||
})
|
||||
})
|
109
demos/src/Extensions/BackgroundColor/Vue/index.vue
Normal file
109
demos/src/Extensions/BackgroundColor/Vue/index.vue
Normal file
@ -0,0 +1,109 @@
|
||||
<template>
|
||||
<div v-if="editor" class="container">
|
||||
<div class="control-group">
|
||||
<div class="button-group">
|
||||
<input
|
||||
type="color"
|
||||
@input="editor.chain().focus().setBackgroundColor($event.target.value).run()"
|
||||
:value="editor.getAttributes('textStyle').backgroundColor"
|
||||
data-testid="setBackgroundColor"
|
||||
/>
|
||||
<button
|
||||
@click="editor.chain().focus().setBackgroundColor('#958DF1').run()"
|
||||
:class="{ 'is-active': editor.isActive('textStyle', { backgroundColor: '#958DF1' }) }"
|
||||
data-testid="setPurple"
|
||||
>
|
||||
Purple
|
||||
</button>
|
||||
<button
|
||||
@click="editor.chain().focus().setBackgroundColor('#F98181').run()"
|
||||
:class="{ 'is-active': editor.isActive('textStyle', { backgroundColor: '#F98181' }) }"
|
||||
data-testid="setRed"
|
||||
>
|
||||
Red
|
||||
</button>
|
||||
<button
|
||||
@click="editor.chain().focus().setBackgroundColor('#FBBC88').run()"
|
||||
:class="{ 'is-active': editor.isActive('textStyle', { backgroundColor: '#FBBC88' }) }"
|
||||
data-testid="setOrange"
|
||||
>
|
||||
Orange
|
||||
</button>
|
||||
<button
|
||||
@click="editor.chain().focus().setBackgroundColor('#FAF594').run()"
|
||||
:class="{ 'is-active': editor.isActive('textStyle', { backgroundColor: '#FAF594' }) }"
|
||||
data-testid="setYellow"
|
||||
>
|
||||
Yellow
|
||||
</button>
|
||||
<button
|
||||
@click="editor.chain().focus().setBackgroundColor('#70CFF8').run()"
|
||||
:class="{ 'is-active': editor.isActive('textStyle', { backgroundColor: '#70CFF8' }) }"
|
||||
data-testid="setBlue"
|
||||
>
|
||||
Blue
|
||||
</button>
|
||||
<button
|
||||
@click="editor.chain().focus().setBackgroundColor('#94FADB').run()"
|
||||
:class="{ 'is-active': editor.isActive('textStyle', { backgroundColor: '#94FADB' }) }"
|
||||
data-testid="setTeal"
|
||||
>
|
||||
Teal
|
||||
</button>
|
||||
<button
|
||||
@click="editor.chain().focus().setBackgroundColor('#B9F18D').run()"
|
||||
:class="{ 'is-active': editor.isActive('textStyle', { backgroundColor: '#B9F18D' }) }"
|
||||
data-testid="setGreen"
|
||||
>
|
||||
Green
|
||||
</button>
|
||||
<button @click="editor.chain().focus().unsetBackgroundColor().run()" data-testid="unsetBackgroundColor">
|
||||
Unset color
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<editor-content :editor="editor" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Document from '@tiptap/extension-document'
|
||||
import Paragraph from '@tiptap/extension-paragraph'
|
||||
import Text from '@tiptap/extension-text'
|
||||
import { BackgroundColor , TextStyle } from '@tiptap/extension-text-style'
|
||||
import { Editor, EditorContent } from '@tiptap/vue-3'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
EditorContent,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
editor: null,
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.editor = new Editor({
|
||||
extensions: [Document, Paragraph, Text, TextStyle, BackgroundColor],
|
||||
content: `
|
||||
<p><span style="background-color: #958DF1">Oh, for some reason that's purple.</span></p>
|
||||
`,
|
||||
})
|
||||
},
|
||||
|
||||
beforeUnmount() {
|
||||
this.editor.destroy()
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
/* Basic editor styles */
|
||||
.tiptap {
|
||||
:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,10 +1,9 @@
|
||||
import './styles.scss'
|
||||
|
||||
import { Color } from '@tiptap/extension-color'
|
||||
import Document from '@tiptap/extension-document'
|
||||
import Paragraph from '@tiptap/extension-paragraph'
|
||||
import Text from '@tiptap/extension-text'
|
||||
import TextStyle from '@tiptap/extension-text-style'
|
||||
import { Color, TextStyle } from '@tiptap/extension-text-style'
|
||||
import { EditorContent, useEditor, useEditorState } from '@tiptap/react'
|
||||
import React from 'react'
|
||||
|
||||
@ -42,7 +41,7 @@ export default () => {
|
||||
<div className="button-group">
|
||||
<input
|
||||
type="color"
|
||||
onInput={event => editor.chain().focus().setColor(event.target.value).run()}
|
||||
onInput={event => editor.chain().focus().setColor(event.currentTarget.value).run()}
|
||||
value={editorState.color}
|
||||
data-testid="setColor"
|
||||
/>
|
@ -57,11 +57,10 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Color } from '@tiptap/extension-color'
|
||||
import Document from '@tiptap/extension-document'
|
||||
import Paragraph from '@tiptap/extension-paragraph'
|
||||
import Text from '@tiptap/extension-text'
|
||||
import TextStyle from '@tiptap/extension-text-style'
|
||||
import { Color, TextStyle } from '@tiptap/extension-text-style'
|
||||
import { Editor, EditorContent } from '@tiptap/vue-3'
|
||||
|
||||
export default {
|
||||
|
@ -1,10 +1,9 @@
|
||||
import './styles.scss'
|
||||
|
||||
import Document from '@tiptap/extension-document'
|
||||
import FontFamily from '@tiptap/extension-font-family'
|
||||
import Paragraph from '@tiptap/extension-paragraph'
|
||||
import Text from '@tiptap/extension-text'
|
||||
import TextStyle from '@tiptap/extension-text-style'
|
||||
import { FontFamily , TextStyle } from '@tiptap/extension-text-style'
|
||||
import { EditorContent, useEditor, useEditorState } from '@tiptap/react'
|
||||
import React from 'react'
|
||||
|
||||
|
@ -41,10 +41,9 @@
|
||||
|
||||
<script>
|
||||
import Document from '@tiptap/extension-document'
|
||||
import FontFamily from '@tiptap/extension-font-family'
|
||||
import Paragraph from '@tiptap/extension-paragraph'
|
||||
import Text from '@tiptap/extension-text'
|
||||
import TextStyle from '@tiptap/extension-text-style'
|
||||
import { FontFamily , TextStyle } from '@tiptap/extension-text-style'
|
||||
import { Editor, EditorContent } from '@tiptap/vue-3'
|
||||
|
||||
export default {
|
||||
|
@ -1,5 +1,4 @@
|
||||
import FontSize from '@tiptap/extension-font-size'
|
||||
import TextStyle from '@tiptap/extension-text-style'
|
||||
import { FontSize , TextStyle } from '@tiptap/extension-text-style'
|
||||
import { EditorContent, useEditor } from '@tiptap/react'
|
||||
import StarterKit from '@tiptap/starter-kit'
|
||||
|
||||
|
@ -26,8 +26,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import FontSize from '@tiptap/extension-font-size'
|
||||
import TextStyle from '@tiptap/extension-text-style'
|
||||
import { FontSize , TextStyle } from '@tiptap/extension-text-style'
|
||||
import StarterKit from '@tiptap/starter-kit'
|
||||
import { Editor, EditorContent } from '@tiptap/vue-3'
|
||||
|
||||
|
0
demos/src/Extensions/LineHeight/React/index.html
Normal file
0
demos/src/Extensions/LineHeight/React/index.html
Normal file
38
demos/src/Extensions/LineHeight/React/index.spec.js
Normal file
38
demos/src/Extensions/LineHeight/React/index.spec.js
Normal file
@ -0,0 +1,38 @@
|
||||
context('/src/Extensions/LineHeight/React/', () => {
|
||||
before(() => {
|
||||
cy.visit('/src/Extensions/LineHeight/React/')
|
||||
})
|
||||
|
||||
beforeEach(() => {
|
||||
cy.get('.tiptap').then(([{ editor }]) => {
|
||||
editor.commands.setContent('<p>Example Text</p>')
|
||||
})
|
||||
cy.get('.tiptap').type('{selectall}')
|
||||
})
|
||||
|
||||
it('should set line-height 1.5 for the selected text', () => {
|
||||
cy.get('[data-test-id="1.5"]').should('not.have.class', 'is-active').click().should('have.class', 'is-active')
|
||||
|
||||
cy.get('.tiptap').find('span').should('have.attr', 'style', 'line-height: 1.5')
|
||||
})
|
||||
|
||||
it('should set line-height 2.0 for the selected text', () => {
|
||||
cy.get('[data-test-id="2.0"]').should('not.have.class', 'is-active').click().should('have.class', 'is-active')
|
||||
|
||||
cy.get('.tiptap').find('span').should('have.attr', 'style', 'line-height: 2.0')
|
||||
})
|
||||
|
||||
it('should set line-height 4.0 for the selected text', () => {
|
||||
cy.get('[data-test-id="4.0"]').should('not.have.class', 'is-active').click().should('have.class', 'is-active')
|
||||
|
||||
cy.get('.tiptap').find('span').should('have.attr', 'style', 'line-height: 4.0')
|
||||
})
|
||||
|
||||
it('should remove the line-height of the selected text', () => {
|
||||
cy.get('[data-test-id="1.5"]').click()
|
||||
cy.get('.tiptap').find('span').should('have.attr', 'style', 'line-height: 1.5')
|
||||
|
||||
cy.get('[data-test-id="unsetLineHeight"]').click()
|
||||
cy.get('.tiptap span').should('not.exist')
|
||||
})
|
||||
})
|
66
demos/src/Extensions/LineHeight/React/index.tsx
Normal file
66
demos/src/Extensions/LineHeight/React/index.tsx
Normal file
@ -0,0 +1,66 @@
|
||||
import './styles.scss'
|
||||
|
||||
import { LineHeight, TextStyle } from '@tiptap/extension-text-style'
|
||||
import { EditorContent, useEditor, useEditorState } from '@tiptap/react'
|
||||
import StarterKit from '@tiptap/starter-kit'
|
||||
import React from 'react'
|
||||
|
||||
export default () => {
|
||||
const editor = useEditor({
|
||||
extensions: [StarterKit, TextStyle, LineHeight],
|
||||
content: `
|
||||
<p>Adjusting line heights can greatly affect the readability of your text, making it easier for users to engage with your content.</p>
|
||||
<p>Line height is the vertical distance between lines of text in a paragraph. It's also known as leading, which comes from the days of metal type, when strips of lead were placed between lines of type to add space.</p>
|
||||
<p>Line height is expressed as a ratio, meaning the default line height is 1.0. A line height of 1.5 would be 1.5 times the height of the font, while a line height of 2.0 would be twice the height of the font.</p>
|
||||
<p>It's important to choose a line height that's appropriate for your font size and line length. A line height that's too small can make text feel cramped, while a line height that's too large can make text feel disconnected.</p>
|
||||
<p><span style="line-height: 1.5">This paragraph has a line height of 1.5.</span></p>
|
||||
<p>This paragraph has the default line height of 1.0.</p>
|
||||
<p><span style="line-height: 4.0">This paragraph has a line height of 4.0.</span></p>
|
||||
`,
|
||||
})
|
||||
const { isLarge, isSmall, isExtraLarge } = useEditorState({
|
||||
editor,
|
||||
selector: ctx => {
|
||||
return {
|
||||
isSmall: ctx.editor.isActive('textStyle', { lineHeight: '1.5' }),
|
||||
isLarge: ctx.editor.isActive('textStyle', { lineHeight: '2.0' }),
|
||||
isExtraLarge: ctx.editor.isActive('textStyle', { lineHeight: '4.0' }),
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="control-group">
|
||||
<div className="button-group">
|
||||
<button
|
||||
onClick={() => editor.chain().focus().toggleTextStyle({ lineHeight: '1.5' }).run()}
|
||||
className={isSmall ? 'is-active' : ''}
|
||||
data-test-id="1.5"
|
||||
>
|
||||
Line height 1.5
|
||||
</button>
|
||||
<button
|
||||
onClick={() => editor.chain().focus().toggleTextStyle({ lineHeight: '2.0' }).run()}
|
||||
className={isLarge ? 'is-active' : ''}
|
||||
data-test-id="2.0"
|
||||
>
|
||||
Line height 2.0
|
||||
</button>
|
||||
<button
|
||||
onClick={() => editor.chain().focus().toggleTextStyle({ lineHeight: '4.0' }).run()}
|
||||
className={isExtraLarge ? 'is-active' : ''}
|
||||
data-test-id="4.0"
|
||||
>
|
||||
Line height 4.0
|
||||
</button>
|
||||
<button onClick={() => editor.chain().focus().unsetLineHeight().run()} data-test-id="unsetLineHeight">
|
||||
Unset line height
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<EditorContent editor={editor} />
|
||||
</>
|
||||
)
|
||||
}
|
18
demos/src/Extensions/LineHeight/React/styles.scss
Normal file
18
demos/src/Extensions/LineHeight/React/styles.scss
Normal file
@ -0,0 +1,18 @@
|
||||
/* Basic editor styles */
|
||||
.tiptap {
|
||||
line-height: 1.0;
|
||||
:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
img {
|
||||
display: block;
|
||||
height: auto;
|
||||
margin: 1.5rem 0;
|
||||
max-width: 100%;
|
||||
|
||||
&.ProseMirror-selectednode {
|
||||
outline: 3px solid var(--purple);
|
||||
}
|
||||
}
|
||||
}
|
0
demos/src/Extensions/LineHeight/Vue/index.html
Normal file
0
demos/src/Extensions/LineHeight/Vue/index.html
Normal file
38
demos/src/Extensions/LineHeight/Vue/index.spec.js
Normal file
38
demos/src/Extensions/LineHeight/Vue/index.spec.js
Normal file
@ -0,0 +1,38 @@
|
||||
context('/src/Extensions/LineHeight/Vue/', () => {
|
||||
before(() => {
|
||||
cy.visit('/src/Extensions/LineHeight/Vue/')
|
||||
})
|
||||
|
||||
beforeEach(() => {
|
||||
cy.get('.tiptap').then(([{ editor }]) => {
|
||||
editor.commands.setContent('<p>Example Text</p>')
|
||||
})
|
||||
cy.get('.tiptap').type('{selectall}')
|
||||
})
|
||||
|
||||
it('should set line-height 1.5 for the selected text', () => {
|
||||
cy.get('[data-test-id="1.5"]').should('not.have.class', 'is-active').click().should('have.class', 'is-active')
|
||||
|
||||
cy.get('.tiptap').find('span').should('have.attr', 'style', 'line-height: 1.5')
|
||||
})
|
||||
|
||||
it('should set line-height 2.0 for the selected text', () => {
|
||||
cy.get('[data-test-id="2.0"]').should('not.have.class', 'is-active').click().should('have.class', 'is-active')
|
||||
|
||||
cy.get('.tiptap').find('span').should('have.attr', 'style', 'line-height: 2.0')
|
||||
})
|
||||
|
||||
it('should set line-height 4.0 for the selected text', () => {
|
||||
cy.get('[data-test-id="4.0"]').should('not.have.class', 'is-active').click().should('have.class', 'is-active')
|
||||
|
||||
cy.get('.tiptap').find('span').should('have.attr', 'style', 'line-height: 4.0')
|
||||
})
|
||||
|
||||
it('should remove the line-height of the selected text', () => {
|
||||
cy.get('[data-test-id="1.5"]').click()
|
||||
cy.get('.tiptap').find('span').should('have.attr', 'style', 'line-height: 1.5')
|
||||
|
||||
cy.get('[data-test-id="unsetLineHeight"]').click()
|
||||
cy.get('.tiptap span').should('not.exist')
|
||||
})
|
||||
})
|
72
demos/src/Extensions/LineHeight/Vue/index.vue
Normal file
72
demos/src/Extensions/LineHeight/Vue/index.vue
Normal file
@ -0,0 +1,72 @@
|
||||
<template>
|
||||
<div v-if="editor" class="container">
|
||||
<div class="control-group">
|
||||
<div class="button-group">
|
||||
<button
|
||||
@click="editor.chain().focus().toggleTextStyle({ lineHeight: '1.5' }).run()"
|
||||
:class="{ 'is-active': editor.isActive('textStyle', { lineHeight: '1.5' }) }"
|
||||
data-test-id="1.5"
|
||||
>
|
||||
Line height 1.5
|
||||
</button>
|
||||
<button
|
||||
@click="editor.chain().focus().toggleTextStyle({ lineHeight: '2.0' }).run()"
|
||||
:class="{ 'is-active': editor.isActive('textStyle', { lineHeight: '2.0' }) }"
|
||||
data-test-id="2.0"
|
||||
>
|
||||
Line height 2.0
|
||||
</button>
|
||||
<button
|
||||
@click="editor.chain().focus().toggleTextStyle({ lineHeight: '4.0' }).run()"
|
||||
:class="{ 'is-active': editor.isActive('textStyle', { lineHeight: '4.0' }) }"
|
||||
data-test-id="4.0"
|
||||
>
|
||||
Line height 4.0
|
||||
</button>
|
||||
<button @click="editor.chain().focus().unsetLineHeight().run()" data-test-id="unsetLineHeight">
|
||||
Unset line height
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<editor-content :editor="editor" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import './styles.scss'
|
||||
|
||||
import { LineHeight, 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, LineHeight],
|
||||
content: `
|
||||
<p>Adjusting line heights can greatly affect the readability of your text, making it easier for users to engage with your content.</p>
|
||||
<p>Line height is the vertical distance between lines of text in a paragraph. It's also known as leading, which comes from the days of metal type, when strips of lead were placed between lines of type to add space.</p>
|
||||
<p>Line height is expressed as a ratio, meaning the default line height is 1.0. A line height of 1.5 would be 1.5 times the height of the font, while a line height of 2.0 would be twice the height of the font.</p>
|
||||
<p>It's important to choose a line height that's appropriate for your font size and line length. A line height that's too small can make text feel cramped, while a line height that's too large can make text feel disconnected.</p>
|
||||
<p><span style="line-height: 1.5">This paragraph has a line height of 1.5.</span></p>
|
||||
<p>This paragraph has the default line height of 1.0.</p>
|
||||
<p><span style="line-height: 4.0">This paragraph has a line height of 4.0.</span></p>
|
||||
`,
|
||||
})
|
||||
},
|
||||
|
||||
beforeUnmount() {
|
||||
this.editor.destroy()
|
||||
},
|
||||
}
|
||||
</script>
|
18
demos/src/Extensions/LineHeight/Vue/styles.scss
Normal file
18
demos/src/Extensions/LineHeight/Vue/styles.scss
Normal file
@ -0,0 +1,18 @@
|
||||
/* Basic editor styles */
|
||||
.tiptap {
|
||||
line-height: 1.0;
|
||||
:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
img {
|
||||
display: block;
|
||||
height: auto;
|
||||
margin: 1.5rem 0;
|
||||
max-width: 100%;
|
||||
|
||||
&.ProseMirror-selectednode {
|
||||
outline: 3px solid var(--purple);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,12 +1,10 @@
|
||||
import './styles.scss'
|
||||
|
||||
import Bold from '@tiptap/extension-bold'
|
||||
import { Color } from '@tiptap/extension-color'
|
||||
import Document from '@tiptap/extension-document'
|
||||
import { FontFamily } from '@tiptap/extension-font-family'
|
||||
import Paragraph from '@tiptap/extension-paragraph'
|
||||
import Text from '@tiptap/extension-text'
|
||||
import TextStyle from '@tiptap/extension-text-style'
|
||||
import { Color , FontFamily , TextStyle } from '@tiptap/extension-text-style'
|
||||
import { EditorContent, useEditor } from '@tiptap/react'
|
||||
import React from 'react'
|
||||
|
||||
|
@ -6,12 +6,10 @@
|
||||
|
||||
<script>
|
||||
import Bold from '@tiptap/extension-bold'
|
||||
import { Color } from '@tiptap/extension-color'
|
||||
import Document from '@tiptap/extension-document'
|
||||
import { FontFamily } from '@tiptap/extension-font-family'
|
||||
import Paragraph from '@tiptap/extension-paragraph'
|
||||
import Text from '@tiptap/extension-text'
|
||||
import TextStyle from '@tiptap/extension-text-style'
|
||||
import { Color, FontFamily , TextStyle } from '@tiptap/extension-text-style'
|
||||
import { Editor, EditorContent } from '@tiptap/vue-3'
|
||||
|
||||
export default {
|
||||
|
@ -22,6 +22,16 @@ const getPackageDependencies = () => {
|
||||
replacement: resolve(`../packages/${name}/${subPkgName}/index.ts`),
|
||||
})
|
||||
})
|
||||
} else if (name === 'extension-text-style') {
|
||||
fg.sync(`../packages/${name}/src/*`, { onlyDirectories: true }).forEach(subName => {
|
||||
const subPkgName = subName.replace(`../packages/${name}/src/`, '')
|
||||
|
||||
paths.push({
|
||||
find: `@tiptap/${name}/${subPkgName}`,
|
||||
replacement: resolve(`../packages/${name}/src/${subPkgName}/index.ts`),
|
||||
})
|
||||
})
|
||||
paths.push({ find: `@tiptap/${name}`, replacement: resolve(`../packages/${name}/src/index.ts`) })
|
||||
} else {
|
||||
paths.push({ find: `@tiptap/${name}`, replacement: resolve(`../packages/${name}/src/index.ts`) })
|
||||
}
|
||||
|
@ -31,11 +31,9 @@
|
||||
"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.1",
|
||||
"@tiptap/extension-text-style": "^3.0.0-next.1"
|
||||
},
|
||||
"repository": {
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { Color } from './color.js'
|
||||
// @ts-ignore
|
||||
import { Color, ColorOptions } from '@tiptap/extension-text-style/color'
|
||||
|
||||
export * from './color.js'
|
||||
export { Color, ColorOptions }
|
||||
|
||||
export default Color
|
||||
|
@ -31,12 +31,10 @@
|
||||
"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.1",
|
||||
"@tiptap/extension-text-style": "^3.0.0-next.1"
|
||||
"@tiptap/extension-text-style": "^3.0.0-next.3"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { FontFamily } from './font-family.js'
|
||||
// @ts-ignore
|
||||
import { FontFamily, FontFamilyOptions } from '@tiptap/extension-text-style/font-family'
|
||||
|
||||
export * from './font-family.js'
|
||||
export { FontFamily, FontFamilyOptions }
|
||||
|
||||
export default FontFamily
|
||||
|
@ -1,3 +0,0 @@
|
||||
# Change Log
|
||||
|
||||
## 2.10.2
|
@ -1,18 +0,0 @@
|
||||
# @tiptap/extension-font-size
|
||||
|
||||
[](https://www.npmjs.com/package/@tiptap/extension-font-size)
|
||||
[](https://npmcharts.com/compare/tiptap?minimal=true)
|
||||
[](https://www.npmjs.com/package/@tiptap/extension-font-size)
|
||||
[](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).
|
@ -1,50 +0,0 @@
|
||||
{
|
||||
"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": {
|
||||
"import": "./dist/index.d.ts",
|
||||
"require": "./dist/index.d.cts"
|
||||
},
|
||||
"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",
|
||||
"lint": "prettier ./src/ --check && eslint --cache --quiet --no-error-on-unmatched-pattern ./src/"
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
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'],
|
||||
})
|
@ -21,6 +21,62 @@
|
||||
},
|
||||
"import": "./dist/index.js",
|
||||
"require": "./dist/index.cjs"
|
||||
},
|
||||
"./background-color": {
|
||||
"types": {
|
||||
"import": "./dist/background-color/index.d.ts",
|
||||
"require": "./dist/background-color/index.d.cts"
|
||||
},
|
||||
"import": "./dist/background-color/index.js",
|
||||
"require": "./dist/background-color/index.cjs"
|
||||
},
|
||||
"./color": {
|
||||
"types": {
|
||||
"import": "./dist/color/index.d.ts",
|
||||
"require": "./dist/color/index.d.cts"
|
||||
},
|
||||
"import": "./dist/color/index.js",
|
||||
"require": "./dist/color/index.cjs"
|
||||
},
|
||||
"./font-family": {
|
||||
"types": {
|
||||
"import": "./dist/font-family/index.d.ts",
|
||||
"require": "./dist/font-family/index.d.cts"
|
||||
},
|
||||
"import": "./dist/font-family/index.js",
|
||||
"require": "./dist/font-family/index.cjs"
|
||||
},
|
||||
"./font-size": {
|
||||
"types": {
|
||||
"import": "./dist/font-size/index.d.ts",
|
||||
"require": "./dist/font-size/index.d.cts"
|
||||
},
|
||||
"import": "./dist/font-size/index.js",
|
||||
"require": "./dist/font-size/index.cjs"
|
||||
},
|
||||
"./line-height": {
|
||||
"types": {
|
||||
"import": "./dist/line-height/index.d.ts",
|
||||
"require": "./dist/line-height/index.d.cts"
|
||||
},
|
||||
"import": "./dist/line-height/index.js",
|
||||
"require": "./dist/line-height/index.cjs"
|
||||
},
|
||||
"./text-style": {
|
||||
"types": {
|
||||
"import": "./dist/text-style/index.d.ts",
|
||||
"require": "./dist/text-style/index.d.cts"
|
||||
},
|
||||
"import": "./dist/text-style/index.js",
|
||||
"require": "./dist/text-style/index.cjs"
|
||||
},
|
||||
"./text-style-kit": {
|
||||
"types": {
|
||||
"import": "./dist/text-style-kit/index.d.ts",
|
||||
"require": "./dist/text-style-kit/index.d.cts"
|
||||
},
|
||||
"import": "./dist/text-style-kit/index.js",
|
||||
"require": "./dist/text-style-kit/index.cjs"
|
||||
}
|
||||
},
|
||||
"main": "dist/index.cjs",
|
||||
|
@ -0,0 +1,90 @@
|
||||
import '../text-style/index.js'
|
||||
|
||||
import { Extension } from '@tiptap/core'
|
||||
|
||||
export type BackgroundColorOptions = {
|
||||
/**
|
||||
* The types where the color can be applied
|
||||
* @default ['textStyle']
|
||||
* @example ['heading', 'paragraph']
|
||||
*/
|
||||
types: string[]
|
||||
}
|
||||
|
||||
declare module '@tiptap/core' {
|
||||
interface Commands<ReturnType> {
|
||||
backgroundColor: {
|
||||
/**
|
||||
* Set the text color
|
||||
* @param backgroundColor The color to set
|
||||
* @example editor.commands.setColor('red')
|
||||
*/
|
||||
setBackgroundColor: (backgroundColor: string) => ReturnType
|
||||
|
||||
/**
|
||||
* Unset the text backgroundColor
|
||||
* @example editor.commands.unsetBackgroundColor()
|
||||
*/
|
||||
unsetBackgroundColor: () => ReturnType
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// @ts-ignore because the module is not found during dts build
|
||||
declare module '@tiptap/extension-text-style' {
|
||||
interface TextStyleAttributes {
|
||||
backgroundColor?: string | null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This extension allows you to color your text.
|
||||
* @see https://tiptap.dev/api/extensions/background-color
|
||||
*/
|
||||
export const BackgroundColor = Extension.create<BackgroundColorOptions>({
|
||||
name: 'backgroundColor',
|
||||
|
||||
addOptions() {
|
||||
return {
|
||||
types: ['textStyle'],
|
||||
}
|
||||
},
|
||||
|
||||
addGlobalAttributes() {
|
||||
return [
|
||||
{
|
||||
types: this.options.types,
|
||||
attributes: {
|
||||
backgroundColor: {
|
||||
default: null,
|
||||
parseHTML: element => element.style.backgroundColor?.replace(/['"]+/g, ''),
|
||||
renderHTML: attributes => {
|
||||
if (!attributes.backgroundColor) {
|
||||
return {}
|
||||
}
|
||||
|
||||
return {
|
||||
style: `background-color: ${attributes.backgroundColor}`,
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
]
|
||||
},
|
||||
|
||||
addCommands() {
|
||||
return {
|
||||
setBackgroundColor:
|
||||
backgroundColor =>
|
||||
({ chain }) => {
|
||||
return chain().setMark('textStyle', { backgroundColor }).run()
|
||||
},
|
||||
unsetBackgroundColor:
|
||||
() =>
|
||||
({ chain }) => {
|
||||
return chain().setMark('textStyle', { backgroundColor: null }).removeEmptyTextStyle().run()
|
||||
},
|
||||
}
|
||||
},
|
||||
})
|
@ -0,0 +1,5 @@
|
||||
import { BackgroundColor } from './background-color.js'
|
||||
|
||||
export * from './background-color.js'
|
||||
|
||||
export default BackgroundColor
|
@ -1,4 +1,4 @@
|
||||
import '@tiptap/extension-text-style'
|
||||
import '../text-style/index.js'
|
||||
|
||||
import { Extension } from '@tiptap/core'
|
||||
|
||||
@ -30,6 +30,13 @@ declare module '@tiptap/core' {
|
||||
}
|
||||
}
|
||||
|
||||
// @ts-ignore because the module is not found during dts build
|
||||
declare module '@tiptap/extension-text-style' {
|
||||
interface TextStyleAttributes {
|
||||
color?: string | null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This extension allows you to color your text.
|
||||
* @see https://tiptap.dev/api/extensions/color
|
5
packages/extension-text-style/src/color/index.ts
Normal file
5
packages/extension-text-style/src/color/index.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import { Color } from './color.js'
|
||||
|
||||
export * from './color.js'
|
||||
|
||||
export default Color
|
@ -1,4 +1,4 @@
|
||||
import '@tiptap/extension-text-style'
|
||||
import '../text-style/index.js'
|
||||
|
||||
import { Extension } from '@tiptap/core'
|
||||
|
||||
@ -29,6 +29,13 @@ declare module '@tiptap/core' {
|
||||
}
|
||||
}
|
||||
|
||||
// @ts-ignore because the module is not found during dts build
|
||||
declare module '@tiptap/extension-text-style' {
|
||||
interface TextStyleAttributes {
|
||||
fontFamily?: string | null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This extension allows you to set a font family for text.
|
||||
* @see https://www.tiptap.dev/api/extensions/font-family
|
5
packages/extension-text-style/src/font-family/index.ts
Normal file
5
packages/extension-text-style/src/font-family/index.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import { FontFamily } from './font-family.js'
|
||||
|
||||
export * from './font-family.js'
|
||||
|
||||
export default FontFamily
|
@ -1,4 +1,4 @@
|
||||
import '@tiptap/extension-text-style'
|
||||
import '../text-style/index.js'
|
||||
|
||||
import { Extension } from '@tiptap/core'
|
||||
|
||||
@ -29,6 +29,13 @@ declare module '@tiptap/core' {
|
||||
}
|
||||
}
|
||||
|
||||
// @ts-ignore because the module is not found during dts build
|
||||
declare module '@tiptap/extension-text-style' {
|
||||
interface TextStyleAttributes {
|
||||
fontSize?: string | null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This extension allows you to set a font size for text.
|
||||
* @see https://www.tiptap.dev/api/extensions/font-size
|
@ -1,5 +1,14 @@
|
||||
import { TextStyle } from './text-style.js'
|
||||
/* eslint-disable @typescript-eslint/no-empty-object-type */
|
||||
|
||||
export * from './text-style.js'
|
||||
export * from './background-color/index.js'
|
||||
export * from './color/index.js'
|
||||
export * from './font-family/index.js'
|
||||
export * from './font-size/index.js'
|
||||
export * from './line-height/index.js'
|
||||
export * from './text-style/index.js'
|
||||
export * from './text-style-kit/index.js'
|
||||
|
||||
export default TextStyle
|
||||
/**
|
||||
* The available text style attributes.
|
||||
*/
|
||||
export interface TextStyleAttributes extends Record<string, any> {}
|
||||
|
5
packages/extension-text-style/src/line-height/index.ts
Normal file
5
packages/extension-text-style/src/line-height/index.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import { LineHeight } from './line-height.js'
|
||||
|
||||
export * from './line-height.js'
|
||||
|
||||
export default LineHeight
|
89
packages/extension-text-style/src/line-height/line-height.ts
Normal file
89
packages/extension-text-style/src/line-height/line-height.ts
Normal file
@ -0,0 +1,89 @@
|
||||
import '../text-style/index.js'
|
||||
|
||||
import { Extension } from '@tiptap/core'
|
||||
|
||||
export type LineHeightOptions = {
|
||||
/**
|
||||
* A list of node names where the line height can be applied.
|
||||
* @default ['textStyle']
|
||||
* @example ['heading', 'paragraph']
|
||||
*/
|
||||
types: string[]
|
||||
}
|
||||
|
||||
declare module '@tiptap/core' {
|
||||
interface Commands<ReturnType> {
|
||||
lineHeight: {
|
||||
/**
|
||||
* Set the line height
|
||||
* @param lineHeight The line height
|
||||
* @example editor.commands.setLineHeight('1.5')
|
||||
*/
|
||||
setLineHeight: (lineHeight: string) => ReturnType
|
||||
/**
|
||||
* Unset the line height
|
||||
* @example editor.commands.unsetLineHeight()
|
||||
*/
|
||||
unsetLineHeight: () => ReturnType
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// @ts-ignore because the module is not found during dts build
|
||||
declare module '@tiptap/extension-text-style' {
|
||||
interface TextStyleAttributes {
|
||||
lineHeight?: string | null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This extension allows you to set the line-height for text.
|
||||
* @see https://www.tiptap.dev/api/extensions/line-height
|
||||
*/
|
||||
export const LineHeight = Extension.create<LineHeightOptions>({
|
||||
name: 'lineHeight',
|
||||
|
||||
addOptions() {
|
||||
return {
|
||||
types: ['textStyle'],
|
||||
}
|
||||
},
|
||||
|
||||
addGlobalAttributes() {
|
||||
return [
|
||||
{
|
||||
types: this.options.types,
|
||||
attributes: {
|
||||
lineHeight: {
|
||||
default: null,
|
||||
parseHTML: element => element.style.lineHeight,
|
||||
renderHTML: attributes => {
|
||||
if (!attributes.lineHeight) {
|
||||
return {}
|
||||
}
|
||||
|
||||
return {
|
||||
style: `line-height: ${attributes.lineHeight}`,
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
]
|
||||
},
|
||||
|
||||
addCommands() {
|
||||
return {
|
||||
setLineHeight:
|
||||
lineHeight =>
|
||||
({ chain }) => {
|
||||
return chain().setMark('textStyle', { lineHeight }).run()
|
||||
},
|
||||
unsetLineHeight:
|
||||
() =>
|
||||
({ chain }) => {
|
||||
return chain().setMark('textStyle', { lineHeight: null }).removeEmptyTextStyle().run()
|
||||
},
|
||||
}
|
||||
},
|
||||
})
|
80
packages/extension-text-style/src/text-style-kit/index.ts
Normal file
80
packages/extension-text-style/src/text-style-kit/index.ts
Normal file
@ -0,0 +1,80 @@
|
||||
import { Extension } from '@tiptap/core'
|
||||
|
||||
import { BackgroundColor, BackgroundColorOptions } from '../background-color/index.js'
|
||||
import { Color, ColorOptions } from '../color/index.js'
|
||||
import { FontFamily, FontFamilyOptions } from '../font-family/index.js'
|
||||
import { FontSize, FontSizeOptions } from '../font-size/index.js'
|
||||
import { LineHeight, LineHeightOptions } from '../line-height/index.js'
|
||||
import { TextStyle, TextStyleOptions } from '../text-style/index.js'
|
||||
|
||||
export interface TextStyleKitOptions {
|
||||
/**
|
||||
* If set to false, the background color extension will not be registered
|
||||
* @example backgroundColor: false
|
||||
*/
|
||||
backgroundColor: Partial<BackgroundColorOptions> | false
|
||||
/**
|
||||
* If set to false, the color extension will not be registered
|
||||
* @example color: false
|
||||
*/
|
||||
color: Partial<ColorOptions> | false
|
||||
/**
|
||||
* If set to false, the font family extension will not be registered
|
||||
* @example fontFamily: false
|
||||
*/
|
||||
fontFamily: Partial<FontFamilyOptions> | false
|
||||
/**
|
||||
* If set to false, the font size extension will not be registered
|
||||
* @example fontSize: false
|
||||
*/
|
||||
fontSize: Partial<FontSizeOptions> | false
|
||||
/**
|
||||
* If set to false, the line height extension will not be registered
|
||||
* @example lineHeight: false
|
||||
*/
|
||||
lineHeight: Partial<LineHeightOptions> | false
|
||||
/**
|
||||
* If set to false, the text style extension will not be registered (required for other text style extensions)
|
||||
* @example textStyle: false
|
||||
*/
|
||||
textStyle: Partial<TextStyleOptions> | false
|
||||
}
|
||||
|
||||
/**
|
||||
* The table kit is a collection of table editor extensions.
|
||||
*
|
||||
* It’s a good starting point for building your own table in Tiptap.
|
||||
*/
|
||||
export const TextStyleKit = Extension.create<TextStyleKitOptions>({
|
||||
name: 'textStyleKit',
|
||||
|
||||
addExtensions() {
|
||||
const extensions = []
|
||||
|
||||
if (this.options.backgroundColor !== false) {
|
||||
extensions.push(BackgroundColor.configure(this.options.backgroundColor))
|
||||
}
|
||||
|
||||
if (this.options.color !== false) {
|
||||
extensions.push(Color.configure(this.options.color))
|
||||
}
|
||||
|
||||
if (this.options.fontFamily !== false) {
|
||||
extensions.push(FontFamily.configure(this.options.fontFamily))
|
||||
}
|
||||
|
||||
if (this.options.fontSize !== false) {
|
||||
extensions.push(FontSize.configure(this.options.fontSize))
|
||||
}
|
||||
|
||||
if (this.options.lineHeight !== false) {
|
||||
extensions.push(LineHeight.configure(this.options.lineHeight))
|
||||
}
|
||||
|
||||
if (this.options.textStyle !== false) {
|
||||
extensions.push(TextStyle.configure(this.options.textStyle))
|
||||
}
|
||||
|
||||
return extensions
|
||||
},
|
||||
})
|
@ -1,5 +1,7 @@
|
||||
import { Mark, mergeAttributes } from '@tiptap/core'
|
||||
|
||||
import type { TextStyleAttributes } from '../index.js'
|
||||
|
||||
export interface TextStyleOptions {
|
||||
/**
|
||||
* HTML attributes to add to the span element.
|
||||
@ -25,6 +27,12 @@ declare module '@tiptap/core' {
|
||||
* @example editor.commands.removeEmptyTextStyle()
|
||||
*/
|
||||
removeEmptyTextStyle: () => ReturnType
|
||||
/**
|
||||
* Toggle a text style
|
||||
* @param attributes The text style attributes
|
||||
* @example editor.commands.toggleTextStyle({ fontWeight: 'bold' })
|
||||
*/
|
||||
toggleTextStyle: (attributes?: TextStyleAttributes) => ReturnType
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -49,7 +57,7 @@ const mergeNestedSpanStyles = (element: HTMLElement) => {
|
||||
|
||||
/**
|
||||
* This extension allows you to create text styles. It is required by default
|
||||
* for the `textColor` and `backgroundColor` extensions.
|
||||
* for the `text-color` and `font-family` extensions.
|
||||
* @see https://www.tiptap.dev/api/marks/text-style
|
||||
*/
|
||||
export const TextStyle = Mark.create<TextStyleOptions>({
|
||||
@ -92,6 +100,11 @@ export const TextStyle = Mark.create<TextStyleOptions>({
|
||||
|
||||
addCommands() {
|
||||
return {
|
||||
toggleTextStyle:
|
||||
attributes =>
|
||||
({ commands }) => {
|
||||
return commands.toggleMark(this.name, attributes)
|
||||
},
|
||||
removeEmptyTextStyle:
|
||||
() =>
|
||||
({ tr }) => {
|
@ -1,11 +1,22 @@
|
||||
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'],
|
||||
})
|
||||
export default defineConfig(
|
||||
[
|
||||
'src/background-color/index.ts',
|
||||
'src/color/index.ts',
|
||||
'src/font-family/index.ts',
|
||||
'src/font-size/index.ts',
|
||||
'src/line-height/index.ts',
|
||||
'src/text-style/index.ts',
|
||||
'src/text-style-kit/index.ts',
|
||||
'src/index.ts',
|
||||
].map(entry => ({
|
||||
entry: [entry],
|
||||
tsconfig: '../../tsconfig.build.json',
|
||||
outDir: `dist${entry.replace('src', '').split('/').slice(0, -1).join('/')}`,
|
||||
dts: true,
|
||||
sourcemap: true,
|
||||
format: ['esm', 'cjs'],
|
||||
external: [/^[^./]/],
|
||||
})),
|
||||
)
|
||||
|
@ -345,9 +345,6 @@ importers:
|
||||
|
||||
packages/extension-color:
|
||||
devDependencies:
|
||||
'@tiptap/core':
|
||||
specifier: ^3.0.0-next.3
|
||||
version: link:../core
|
||||
'@tiptap/extension-text-style':
|
||||
specifier: ^3.0.0-next.3
|
||||
version: link:../extension-text-style
|
||||
@ -384,18 +381,6 @@ importers:
|
||||
|
||||
packages/extension-font-family:
|
||||
devDependencies:
|
||||
'@tiptap/core':
|
||||
specifier: ^3.0.0-next.3
|
||||
version: link:../core
|
||||
'@tiptap/extension-text-style':
|
||||
specifier: ^3.0.0-next.3
|
||||
version: link:../extension-text-style
|
||||
|
||||
packages/extension-font-size:
|
||||
devDependencies:
|
||||
'@tiptap/core':
|
||||
specifier: ^3.0.0-next.3
|
||||
version: link:../core
|
||||
'@tiptap/extension-text-style':
|
||||
specifier: ^3.0.0-next.3
|
||||
version: link:../extension-text-style
|
||||
@ -454,6 +439,15 @@ importers:
|
||||
specifier: ^3.0.0-next.3
|
||||
version: link:../core
|
||||
|
||||
packages/extension-line-height:
|
||||
devDependencies:
|
||||
'@tiptap/core':
|
||||
specifier: ^3.0.0-next.3
|
||||
version: link:../core
|
||||
'@tiptap/extension-text-style':
|
||||
specifier: ^3.0.0-next.3
|
||||
version: link:../extension-text-style
|
||||
|
||||
packages/extension-link:
|
||||
dependencies:
|
||||
linkifyjs:
|
||||
|
@ -1,12 +1,10 @@
|
||||
/// <reference types="cypress" />
|
||||
|
||||
import { Editor } from '@tiptap/core'
|
||||
import Color from '@tiptap/extension-color'
|
||||
import Document from '@tiptap/extension-document'
|
||||
import FontFamily from '@tiptap/extension-font-family'
|
||||
import Paragraph from '@tiptap/extension-paragraph'
|
||||
import Text from '@tiptap/extension-text'
|
||||
import TextStyle from '@tiptap/extension-text-style'
|
||||
import { Color, FontFamily , TextStyle } from '@tiptap/extension-text-style'
|
||||
|
||||
describe('isActive', () => {
|
||||
it('should check the current node', () => {
|
||||
|
Loading…
Reference in New Issue
Block a user