-
-
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(); | |
}, | |
}; | |
}, | |
}); |
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!
can you show example with vue 3 vite tiptap thank you!