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

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.

@kingRayhan
Copy link

kingRayhan commented Aug 17, 2023

Thanks a lot, this gist saved my time ❤️

@Muhammetmyrat
Copy link

how use this code?

@gregveres
Copy link
Author

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();

@Muhammetmyrat
Copy link

can you show example with vue 3 vite tiptap thank you!

@gregveres
Copy link
Author

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?

@Muhammetmyrat
Copy link

Yes. Can you in vue 2 or nuxt becouse I do not understant and I can not use this?

@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