How to remove a decoration mark from state

I have followed the example from here to create a simple decoration. Now I want to remove the decoration, how do I do that?

    applyStyling (view, selections, styling) {
      const addUnderline = StateEffect.define({from: 0, to: 0})
      const underlineMark = Decoration.mark({class: styling})

      const underlineField = StateField.define({
        create() {
          return Decoration.none
        },
        update(underlines, tr) {
          underlines = underlines.map(tr.changes)
          for (const e of tr.effects)  {
            if (e.is(addUnderline)) {
              underlines = underlines.update({
                add: [underlineMark.range(e.value.from, e.value.to)]
              })
            }
          }
          return underlines
        },
        provide: f => EditorView.decorations.from(f)
      })

      const themes = EditorView.baseTheme({
        ...
      })

      const effects = selections.map(({from, to}) => addUnderline.of({from, to}))
      if (!view.state.field(underlineField, false)) {
        effects.push(StateEffect.appendConfig.of([underlineField,
                                                        themes]))
      }
      view.dispatch({effects})
}

Many thanks

The RangeSet class’ update method also allows you to pass a filter to remove decorations from the set. So you could define another effect and, when that shows up in a transaction, filter out some decorations.

Thank you, I did what you said:

Here is a snippet of my code.

    highlightField () {
      return StateField.define({
        create: () => {
          return Decoration.none
        },
        update: (underlines, tr) => {
          underlines = underlines.map(tr.changes)
          for (const e of tr.effects)  {
            try {
              if (e.is(this.effectTypes.addUnderline)) {
                // underlines : RangeSet
                underlines = underlines.update({
                  add: [this.decorationMarks[e.value.mark].range(e.value.from, e.value.to)],
                })
              } else if (e.is(this.effectTypes.removeUnderline)) {
                underlines = underlines.update({
                  filter: (f, t, value) => value.class === "XYZ"
                })
              }
            } catch (err) {
              console.log(err)
            }
          }
          return underlines
        },
        provide: f => EditorView.decorations.from(f)
      })
    },

This raised another problem:

How do I get the sentences Decoration.mark to encapsulate other Decoration marks?

Nesting is determined by extension precedence—decorations with lower precedence wrap decorations with higher precedence.

1 Like

Yes I read that in the documentation, but is a StateField considered an extension? At the moment I have my decoration marks in the same StateField. How do I then alter the precedence of each decoration give my case?

You’ll have to separate them to give them different precedences.

1 Like