Inline widget

Hello!

How to realize inline Widget in Codemirror6?
To show readonly error message.

In codemirror 5, I could do this like:

editor.addLineWidget({line: newLine, ch: 0}, cmWidget, {readOnly: true});

I found how to use widget by this example zebra example,
but there it recommend put it like extension, and I don’t find way to make line readonly and update widget on trigger. For example: after sending request I want to show error line.

Also tried another way to insert empty line with dispatch.
But line is also available to changes, line without background styles, and after dispatch there appearing a number on a new line.

dispatch({
    changes: {
      from:   codeFrom,
      to: codeTo      ,
      insert: `\nX ${errorMessage}`
    }
  });

It looks like you’re looking for block widgets, which are widget decorations with a block: true option, which causes them to appear between the lines, rather than inside of them.

Cool, thanks for response!

I found how to initiate widget in extension:

  const startState = EditorState.create({
    doc: code,
    extensions: [
      midpointWidgetStateField
    ],
  });

const midpointWidgetStateField = StateField.define<DecorationSet>({
    create(state: EditorState) {
      const midpoint = Math.floor(state.doc.length / 2);
      return getMidpointWidgetDecorationSet(midpoint);
    },
    update(currentDecorations, transaction) {
      if (transaction.docChanged) {
        const midpoint = Math.floor(transaction.newDoc.length / 2);
  
        return getMidpointWidgetDecorationSet(midpoint);
      }
  
      return currentDecorations;
    },
    provide: (f) => EditorView.decorations.from(f),
  });

function getMidpointWidgetDecorationSet(midpoint: number) {
    const widget = new MidpointWidget();
  
    return Decoration.set([
      Decoration.widget({
        widget,
        block: true,
      }).range(midpoint),
    ]);
  }

 class MidpointWidget extends WidgetType {
    toDOM(view: EditorView) {
      const midpoint = Math.floor(view.state.doc.length / 2);
      const span = document.createElement('span')
      span.textContent = `${midpoint}`;
      span.className = 'zebraStripe';
  
      return span;
    }
  }

Now I see widget on first initiate codemirror. Cause midpointWidgetStateField has create and update functions.

Now I 'm searching how to show widget on trigger like

dispatch({
effects: EditorView.decoration.of(getMidpointWidgetDecorationSet)
})

function getMidpointWidgetDecorationSet() {
  const widget = new MidpointWidget();
  const midpoint = 3;

  return Decoration.set([
    Decoration.widget({
      widget,
      block: true,
    }).range(midpoint),
  ]);
}

class MidpointWidget extends WidgetType {
  toDOM(view: EditorView) {
    const midpoint = Math.floor(view.state.doc.length / 2);
    const span = document.createElement('span')
    span.textContent = `${midpoint}`;
    span.className = 'zebraStripe';

    return span;
  }
}

This is not work, so I’m still watching solution. Have any ideas?

So, I found solution for realize Inline block Widget in CodeMirror6 like in CodeMirror5.

  1. Initiated widget with { block: true }, like extension with Compartment. In default widget is hide.
    2.In html I have button. onClick I make editorView.dispatch({ effects: compartmentVariable.reconfigure(showWidgetState) })
  2. It works. Will prepare codesandbox.

But solution looks ugly. When writing extension I have to provide

StateField.define<DecorationSet>({
  create(){}
  update(currentDecorations, transaction){
    /**
      And here is ugly peace. 
      Because I have to write handle on codemirror update and 
      check where updates, in which line and how to combine 
      changes with widget. Maybe I can simulate Codemirror5 
      block widget by easier solution? 
    */

  }
  provide(){}
})