Is there any built-in functions I can update mark attributes?

Assume I have the mark type font in my schema, if I use toggleMark to toggle the font mark, I will have to provide all three attributes, and it will override all attributes if the marks already exist in the selection.

marks: {
    font: {
        attrs: {
            fontFamily: { default: 'Helvetica, sans-serif' },
            color: { default: 'black' },
            fontSize: { default: '12pt' }
        toDOM(node) {
            return ['span', { style: `font-family: ${node.attrs.fontFamily}; font-size: ${node.attrs.fontSize}; color: ${node.attrs.color};` }, 0];
        parseDOM: [
                tag: 'span',
                getAttrs(dom) {
                return {

What I want is a way to just update the attributes that I want to update, for instance, if there’s a font mark in my current selection with attributes:

fontSize = '36pt', color = 'red', fontFamily = 'blahblah, sans-serif' 

if I toggle it with font mark with color = ‘green’, that mark will be updated to

fontSize = '36pt', color = 'green', fontFamily = 'blahblah, sans-serif'

and the rest of the selection will be toggled with a mark with the given color attribute and attrubutes with default values

fontSize = '12pt', color = 'green', fontFamily = 'Helvetica, sans-serif'

I’ve browsed the forum and Googled it for few days, but didn’t see any issue related to this, so I’m here for some advice, thanks!

FYI, what I’m currently doing is have 3 different marks fontSize, fontFamily, fontColor, but it will be excellent if I can combine three of them with just font, which can make my template much cleaner.

1 Like

No, there’s no built-in function that does this (toggleMark will generally be a bad fit for marks like this). You’ll have to write that logic yourself. Or split the mark into separate fontFamily/color/fontSize marks.

For tiptap 2 we added a textStyle mark and custom commands for setMark and toggleMark which behave exactly like this.

Cool thanks @philippkuehn! I will have a look how it was implemented