Skip to content

Instantly share code, notes, and snippets.

@gregveres
Created May 3, 2022 23:26
Show Gist options
  • Save gregveres/973e8d545ab40dc375b47ebc63f92846 to your computer and use it in GitHub Desktop.
Save gregveres/973e8d545ab40dc375b47ebc63f92846 to your computer and use it in GitHub Desktop.
background-color for tiptap 2
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();
},
};
},
});
@gregveres
Copy link
Author

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 />

@Muhammetmyrat
Copy link

Uncaught Error: There is no mark type named 'textStyle'. Maybe you forgot to add the extension?

@Muhammetmyrat
Copy link

Muhammetmyrat commented Sep 11, 2023

Thank you worked for me I do not import "@tiptap/extension-text-style";

@namlh023
Copy link

namlh023 commented Feb 2, 2024

Thanks, it's work. Save me a lot of time.

@realmxu
Copy link

realmxu commented Jun 24, 2024

amazing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment