CodeMirror6 in Vaadin 14 & Lit

417 Views Asked by At

I created a simple LitElement with CodeMirror6 I can see the Editor, but when I call the same LitElement in Vaadin , the styling is completely gone.

I have tried both 14 and 23. Same issue.

CodeMirror6 Lit

import { LitElement, html } from 'lit';
import { EditorState, EditorView, basicSetup } from "@codemirror/basic-setup"
import { sql } from '@codemirror/lang-sql';
import { oneDark } from '@codemirror/theme-one-dark';

export class App extends LitElement {

    static get properties() {
        return {
            value: String,
        };
    }

    render() {
        return html`
        <div id="codeeditor"></div>`;
    }


    firstUpdated() {

        let editorState = EditorState.create({
            doc: this.value, extensions: [
                basicSetup,
                oneDark,
                sql(),
            ]
        });

        var element = document.getElementById('codeeditor');

        const editor = new EditorView(
            {
                state: editorState,
                parent: element
            }
        );

    }

    createRenderRoot() {
        return this;
    }
}
customElements.define('code-mirror', App);

LitElement Code Editor Image - https://i.stack.imgur.com/0MsjU.png

No issue here works perfectly, but When I call the above litelement into Vaadin . The formatting and styling is completely gone.

LitElement in Vaadin Image : https://i.stack.imgur.com/RP35C.png

Any suggestion or pointer for me to fix this issue.

1

There are 1 best solutions below

0
On

The problem is way on which vaadin renders child components in a Vertical|Horizontal layout (shadowRoot with slots). If you add your implementation to the ROOT content (first layout), the codemirror will work fine as the styles will be applied correctly.

I tried extending new module about @CssImport with codemirror styles. The module was displaying correctly but the codemirror events stopped working because of the vaadin structure ;/

The problem can be worked around as follows. I know it's not elegant, but it works.

  1. Create a new element in document.body
  2. Init codemirror in the new element
  3. Move codemirror from created element to element rendered by module

import {EditorState, EditorView, basicSetup} from "@codemirror/basic-setup"
import {sql} from "@codemirror/lang-sql"
import {html, LitElement} from "lit";
import { oneDark } from '@codemirror/theme-one-dark';

export class App extends LitElement {

    static get properties() {
        return {
            value: String,
        };
    }

    createRenderRoot() {
        return this;
    }

    render() {
        return html`<span id="codeeditor"></span>`;

    }


    firstUpdated() {
        var element = document.getElementById('codeeditor');
        var parent = document.createElement("div");
        document.body.append(parent);
        new EditorView({
            state: EditorState.create({
                extensions: [basicSetup, oneDark ,sql()]
            }),
            parent: parent
        })
        document.body.removeChild(parent);
        element.appendChild(parent);
    }


}
customElements.define('code-mirror', App);