hyperlinkmonaco-editorformatted-text

How do I insert a link in the editor?


I'd like to add a hyperlink in a editor, like vscode does:

enter image description here

I'd like to add this formatted document and when you click into it, some operation happens, open a file dialog, for example.

I have no code to show yet because I didn't find anything like that yet, only for regular text that goes like this:

const line = editor.getPosition();
if(!line) {
  throw new Error('line is null');
}
const range = new monaco.Range(line.lineNumber, 1, 
                               line.lineNumber, 1);
const text = "empty tab";
const op: monaco.editor.IIdentifiedSingleEditOperation = {
    range: range, 
    text: text, 
    forceMoveMarkers: true
};
editor.executeEdits('my-source', [op]);

but I didn't see how add a format it.


Solution

  • You can use an overlay element and define the placeholder content in HTML, with links that will perform actions (e.g. change the editor theme, change the language etc).

    The HTML for the placeholder would look something like this:

    <div class="monaco-placeholder">
        This is a test placeholder that will disappear when you click into the editor.
        Click 
        <a href="#" class="change-language">here</a>
        first if you want to change the editor language from HTML to JavaScript, or click
        <a href="#" class="change-theme">here</a>
        if you want to change the editor theme
    </div>
    
    

    Along with the following CSS:

    .monaco-placeholder {
      color: darkturquoise;
      display: none;
      position: absolute;
      top: 0;
      left: 65px;
      pointer-events: all;
      z-index: 1;
      opacity: 0.7;
    }
    

    You can then wire this up in JavaScript as follows:

    Functions to hide and show the placeholder:

    function showPlaceholder() {
      document.querySelector(".monaco-placeholder").style.display = "initial";
    }
    
    function hidePlaceholder() {
      document.querySelector(".monaco-placeholder").style.display = "none";
    }
    

    Create the editor and show the placeholder:

    const instance = monaco.editor.create(document.getElementById('container'), {
        value: "",
        language: 'html'
    });
    
    showPlaceholder();
    

    Add event handlers for any links in the placeholder that you want to perform actions when clicked:

    document.getElementsByClassName('change-language')[0].addEventListener('click', (e) => {
        e.stopPropagation();
        var model = instance.getModel();
        monaco.editor.setModelLanguage(model, "javascript")
        console.log('language successfully changed to JavaScript')
    });
    
    
    document.getElementsByClassName('change-theme')[0].addEventListener('click', (e) => {
        e.stopPropagation();
        monaco.editor.setTheme('vs-dark')
        console.log('theme successfully changed')
    });
    

    Event handler to clear the placeholder and focus into the editor when the user clicks on any part of the placeholder apart from the links:

    document.getElementsByClassName('monaco-placeholder')[0].addEventListener('click', () => {
        hidePlaceholder();
        instance.focus();
    });
    

    If you copy the HTML, CSS and JavaScript below into the Monaco Playground, you will see this working:

    HTML

    <div id="container" style="height: 100%"></div>
    <div class="monaco-placeholder">
        This is a test placeholder that will disappear when you click into the editor.
        Click 
        <a href="#"  class="change-language">here</a>
        first if you want to change the editor language from HTML to JavaScript, or click
        <a href="#"  class="change-theme">here</a>
        if you want to change the editor theme
    </div>
    
    

    CSS

    .monaco-placeholder {
      color: darkturquoise;
      display: none;
      position: absolute;
      top: 0;
      left: 65px;
      pointer-events: all;
      z-index: 1;
      opacity: 0.7;
    }
    

    JavaScript

    const instance = monaco.editor.create(document.getElementById('container'), {
        value: "",
        language: 'html'
    });
    
    showPlaceholder();
    
    function showPlaceholder() {
      document.querySelector(".monaco-placeholder").style.display = "initial";
    }
    
    function hidePlaceholder() {
      document.querySelector(".monaco-placeholder").style.display = "none";
    }
    
    document.getElementsByClassName('monaco-placeholder')[0].addEventListener('click', () => {
        hidePlaceholder();
        instance.focus();
    });
    
    document.getElementsByClassName('change-language')[0].addEventListener('click', (e) => {
        e.stopPropagation();
        var model = instance.getModel();
        monaco.editor.setModelLanguage(model, "javascript")
        console.log('language successfully changed to JavaScript')
    });
    
    
    document.getElementsByClassName('change-theme')[0].addEventListener('click', (e) => {
        e.stopPropagation();
        monaco.editor.setTheme('vs-dark')
        console.log('theme successfully changed')
    });