-
-
Save gregveres/973e8d545ab40dc375b47ebc63f92846 to your computer and use it in GitHub Desktop.
import { Extension } from "@tiptap/core"; | |
import "@tiptap/extension-text-style"; | |
export type ColorOptions = { | |
types: string[]; | |
}; | |
declare module "@tiptap/core" { | |
interface Commands<ReturnType> { | |
backColor: { | |
/** | |
* Set the text color | |
*/ | |
setBackColor: (color: string) => ReturnType; | |
/** | |
* Unset the text color | |
*/ | |
unsetBackColor: () => ReturnType; | |
}; | |
} | |
} | |
export const BackColor = Extension.create<ColorOptions>({ | |
name: "backColor", | |
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 { | |
setBackColor: | |
(color) => | |
({ chain }) => { | |
return chain().setMark("textStyle", { backgroundColor: color }).run(); | |
}, | |
unsetBackColor: | |
() => | |
({ chain }) => { | |
return chain() | |
.setMark("textStyle", { backgroundColor: null }) | |
.removeEmptyTextStyle() | |
.run(); | |
}, | |
}; | |
}, | |
}); |
Thanks a lot, this gist saved my time ❤️
how use this code?
how use this code?
You use it like any other extension for TipTap. You import it and pass it to the editor with the list of extensions.
Then you create some UI that gets the colour and you do something like this on the button handler:
props.editor.chain().focus().setBackColor(newColor).run();
can you show example with vue 3 vite tiptap thank you!
I can not. I am still on Vue 2 and Vuetify. What UI toolkit are you using? Have you got the tiptap editor showing and editing text yet?
Yes. Can you in vue 2 or nuxt becouse I do not understant and I can not use this?
When setting up the editor, you first have to install this extension like this:
import { BackColor } from "./Extensions/back-color";
const editor = ref<Editor>(
new Editor({
content: content.value,
extensions: [
...
BackColor,
],
onUpdate: () => {
emit("input", editor.value.getHTML());
},
})
I have a button that I put on the toolbar that is implemented like this:
TextColorButton.vue
<script lang="ts">
import { defineComponent, ref, PropType } from 'vue';
import { Editor } from '@tiptap/vue-2';
import EditorMenuButton from './EditorMenuButton.vue';
import ColorPopover from '../utilities/ColorPopover.vue';
export default defineComponent({
name: 'TextColorButton',
components: { EditorMenuButton, ColorPopover },
props: {
editor: {
type: Object as PropType<Editor>,
required: true
},
background: {
type: Boolean,
default: false
},
tooltip: {
type: String,
required: false
}
},
setup(props) {
const selected = ref(props.editor.getAttributes('textStyle').color);
const popoverVisible = ref(false);
const confirmColor = (color: string | undefined): void => {
popoverVisible.value = false;
if (color) {
const newColor = color[0] === '#' ? color : `#${color}`;
if (props.background) {
props.editor.chain().focus().setBackColor(newColor).run();
} else {
props.editor.chain().focus().setColor(newColor).run();
}
} else {
if (props.background) {
props.editor.chain().focus().unsetBackColor().run();
} else {
props.editor.chain().focus().unsetColor().run();
}
}
};
const close = () => {
popoverVisible.value = false;
};
return { selected, popoverVisible, confirmColor, close };
}
});
</script>
<template>
<v-menu :close-on-content-click="false" bottom offset-y v-model="popoverVisible">
<template v-slot:activator="{ on, attrs }">
<EditorMenuButton
:icon="background ? '$fontBGColor' : '$fontColor'"
v-bind="attrs"
v-on="on"
:tooltip="tooltip"
/>
</template>
<ColorPopover :color="selected" @close="close" @selected="confirmColor" />
</v-menu>
</template>
And then in my toolbar I use the TextColorButton
like this:
<TextColorButton :editor="editor" tooltip="Set text foreground color" />
<TextColorButton :editor="editor" tooltip="Set text background color" background />
Uncaught Error: There is no mark type named 'textStyle'. Maybe you forgot to add the extension?
Thank you worked for me I do not import "@tiptap/extension-text-style";
Thanks, it's work. Save me a lot of time.
amazing
This is the background color I implemented like color, hope it is useful :))
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 background color
*/
setBackgroundColor: (color: string) => ReturnType
/**
* Unset the background color
*/
unsetBackgroundColor: () => ReturnType
}
}
}
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:
(color) =>
({ chain }) => {
return chain().setMark('textStyle', { backgroundColor: color }).run()
},
unsetBackgroundColor:
() =>
({ chain }) => {
return chain()
.setMark('textStyle', { backgroundColor: null })
.removeEmptyTextStyle()
.run()
}
}
}
})
This is the background color I implemented like color, hope it is useful :))
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 background color */ setBackgroundColor: (color: string) => ReturnType /** * Unset the background color */ unsetBackgroundColor: () => ReturnType } } } 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: (color) => ({ chain }) => { return chain().setMark('textStyle', { backgroundColor: color }).run() }, unsetBackgroundColor: () => ({ chain }) => { return chain() .setMark('textStyle', { backgroundColor: null }) .removeEmptyTextStyle() .run() } } } })
Very good code! But be aware that need to import @tiptap/extension-text-style
, otherwise you will get an error removeEmptyTextStyle
not found!
This is an extension for setting the background-color of text in a tiptap 2 editor.
The original code for this was taken from tiptap's color
The docs for using the extension are exactly the same as the color docs, just change "color" to "backColor" everywhere (match the case of the original).
I am hoping that once the authors of tiptap get to a point where they have less to do on tiptap, that they create their own version of backColor.