'two tiptap2 custom extensions that extend TextStyle

In tiptap2, I have two custom extensions that add a class versus a style because I am utilizing tailwindcss, which leverages classes exclusively, not inline styles.

So, the first one adds 'class="text-green-500"' (or whatever) and likewise, 'class="bg-green-500"'. I extend TextStyle in both custom extensions to allow for class versus span. I believe the answer lies in extending textstyle once, but I'm not sure how to go about that and catch both outcomes.

I can't combine the two by having a highlight span and a color span together.

If I take the following: enter image description here

and then try and say make the "w" a different color, I get: enter image description here

What I want to achieve is "Howdy" with complete cyan while still able to apply individual font colors within the outer span (or vice-versa).

import { TextStyle } from '@tiptap/extension-text-style';

export const HighlightColorStyle = TextStyle.extend({
    parseHTML() {
        return [
            {
                tag: 'span',
                getAttrs: (node) => /text|bg-[\w]*-[1-9]00/.test(node.className)
            }
        ];
    }
});

export const HighlightColor = Extension.create({
    name: 'highlightColor',

    addGlobalAttributes() {
        return [
            {
                types: ['textStyle'],
                attributes: {
                    class: {
                        default: ''
                    }
                }
            }
        ];
    },
    addCommands() {
        return {
            setHighlightColor:
                (color) =>
                ({ chain }) => {
                    console.log('hoadodoadfaf', color);
                    return chain().setMark('textStyle', { class: color });
                },
            toggleHighlightColor:
                () =>
                ({ chain }) => {
                    return chain().toggleMark('textStyle');
                },
            unsetHighlightColor:
                () =>
                ({ chain }) => {
                    return chain().setMark('textStyle', { class: null }).removeEmptyTextStyle();
                }
        };
    }
});

and

import { Extension } from '@tiptap/core';
import { TextStyle } from '@tiptap/extension-text-style';

export const TextColorStyle = TextStyle.extend({
    parseHTML() {
        return [
            {
                tag: 'span',
                getAttrs: node => /text-[\w]*-[1-9]00/.test(node.className) 
            }
        ];
    }
});

export const TextColor = Extension.create({
    name: 'textColor',

    addGlobalAttributes() {
        return [
            {
                types: ['textStyle'],
                attributes: {
                    class: {
                        default: ''
                    }               }
            }
        ];
    },
    addCommands() {
        return {
            setTextColor:
                color =>
                ({ chain }) => {
                    console.log('hoadodoadfaf', color)
                    return chain().setMark('textStyle', { class: color });
                },
            toggleTextColor:
                () =>
                ({ chain }) => {
                    return chain().toggleMark('textStyle');
                },
            unsetTextColor:
                () =>
                ({ chain }) => {
                    return chain().setMark('textStyle', { class: null }).removeEmptyTextStyle();
                }
        };
    }
});


Solution 1:[1]

You should treat class as object not string, so the multi class can combine, then add a ClassExtension to apply the class to a tag.

The ClassExtension is works like textStyle, except it will apply the class, textStyle dose not apply styles, because styles is an object, applied by individual Extension.


Write a simple classNames extension based on a modified testStyle extension.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1