Vaadin 14 Component based on Node Module

Hello everyone,

I am trying to build a Java Vaadin 14 Component which wraps the Monaco Editor: https://microsoft.github.io/monaco-editor/ . What are the steps I need to take to make it work? Unfortunately, I can not find helpful information in your documentation.

Thanks in advance,
Eric

Hello we build a base project to do add ons [my-element]
(https://sourceforge.net/p/kuwaiba/code/HEAD/tree/prototype/my-element-vaadin14/) You may find inspiration to integrate the monaco-editor. The project contains what I believe is the most basic component you can build using Polymer 3 and Vaadin 14

Hello Johny,

thanks for your reply. I will try your approach. It indeed looks very basic and convenient.

Regards,
Eric

Eric Franke:
Hello everyone,

I am trying to build a Java Vaadin 14 Component which wraps the Monaco Editor: https://microsoft.github.io/monaco-editor/ . What are the steps I need to take to make it work? Unfortunately, I can not find helpful information in your documentation.

Thanks in advance,
Eric

Hey Eric, do you have any progress on that?

Hi Oksana,

there is progress, but i’m still not satisfied with my solution. My only working attempt looks like this:

@JavaScript("https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.18.1/min/vs/loader.js")
public class MonacoSQLEditor extends Div {

    private static final AtomicLong NEXT_ID = new AtomicLong();
    private final long ID = NEXT_ID.getAndIncrement();
    private final String INIT_EDITOR = ""
          + "    require.config({ paths: { 'vs': 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.18.1/min/vs' }});\n"
          + "    require(['vs/editor/editor.main']
, function() {\n"
          + "        window.editor" + ID + " = monaco.editor.create(document.getElementById('monaco-editor-div-" + ID + "'), {\n"
          + "            language: 'pgsql'\n"
          + "        });\n"
          + "    });";

    public MonacoSQLEditor() {
        setId("monaco-editor-div-" + ID);
        setSizeFull();
        getElement().executeJs(INIT_EDITOR);
    }

    /*
    As of right now, there is no way to do this synchronously.
    https://vaadin.com/forum/thread/18007474/pendingjavascriptresult-tocompletablefuture-does-not-terminate
     */
    public void getText(SerializableConsumer<JsonValue> consumer) {
        getElement().executeJs("editor" + ID + ".getValue()").then(consumer);
    }

    public void setText(String text) {
        getElement().executeJs("editor" + ID + ".setValue($0)", text);
    }
}

The exact same code fails, if I add the @NodeModule annotation and import the .js files from the local node_modules. I was also not able to use the LitElement interface - same problem. Hence, I was forced to use the cdn. I settled on using a promising editor from Sergio Alberto Hilero: https://vaadin.com/directory/component/ace-widget1 . It’s still in beta, but already looks pretty good.

Hi!

I integrated in a similar way - see above code - following JS libs.

MathJax,
Highlight.js
and the AceEditor - before Sergio Alberto Hilero released a new version of his AceEditor which is Vaadin 14 compatible.

Direct JS integration was easy after finding the needed information - finding the information was NOT so easy. On the other hand it would be nice for other user to provide such JS lib integration as a module. But my personal problem - I am a Java developer - JS, node js, polymer isn’t my world.

My actual sandbox for testing JS/CSS/etc integration inside Vaadin 14
https://iot-blog.at/

Eric Franke:
Hi Oksana,

there is progress, but i’m still not satisfied with my solution. My only working attempt looks like this:

@JavaScript("https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.18.1/min/vs/loader.js")
public class MonacoSQLEditor extends Div {

    private static final AtomicLong NEXT_ID = new AtomicLong();
    private final long ID = NEXT_ID.getAndIncrement();
    private final String INIT_EDITOR = ""
          + "    require.config({ paths: { 'vs': 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.18.1/min/vs' }});\n"
          + "    require(['vs/editor/editor.main']

, function() {\n"

      + "        window.editor" + ID + " = monaco.editor.create(document.getElementById('monaco-editor-div'), {\n"
      + "            language: 'pgsql'\n"
      + "        });\n"
      + "    });";

public MonacoSQLEditor() {
    setId("monaco-editor-div-" + ID);
    setSizeFull();
    getElement().executeJs(INIT_EDITOR);
}

/*
As of right now, there is no way to do this synchronously.
https://vaadin.com/forum/thread/18007474/pendingjavascriptresult-tocompletablefuture-does-not-terminate
 */
public void getText(SerializableConsumer<JsonValue> consumer) {
    getElement().executeJs("editor" + ID + ".getValue()").then(consumer);
}

public void setText(String text) {
    getElement().executeJs("editor" + ID + ".setValue($0)", text);
}

}


The exact same code fails, if I add the @NodeModule annotation and import the .js files from the local node_modules. I was also not able to use the LitElement interface - same problem. Hence, I was forced to use the cdn. I settled on using a promising editor from Sergio Alberto Hilero: https://vaadin.com/directory/component/ace-widget1 . It's still in beta, but already looks pretty good.

@Eric Thanks for quick reply! Oh wow, I am glad to finally see something working… its been weeks! :slight_smile: Have you tried implementing it by Extending PolymerElement/HTMLElement?

I think you can get your code to work without cdn by putting the files into the resources folder, and referencing it from there.