GrapesJS questioning need for `extend`

Grapesjs example - showing that specifying either extend or tagname is enough to define custom link. See discussion at https://github.com/artf/grapesjs/issues/3135

by Andy Bulka

HTML

<script src="https://unpkg.com/grapesjs"></script>
<link rel="stylesheet" href="https://unpkg.com/grapesjs/dist/css/grapes.min.css">
<script src="https://unpkg.com/grapesjs-blocks-basic"></script>
    <div style="background-color: bisque;">
        <p>This custom link component has been created without the use of 'extend' and seems to show that:</p>
        <ul>
            <li>Specifying <i>either</i>
                <ul>
                    <li><code>extend: "link"</code></li>
                    <li><code>model.defaults.tagname: 'a'</code></li>
                </ul>
                is enough to define a custom link component properly. You seemingly don't <i>need</i> to use <code>extend</code>.
            </li>
            <li>All link component traits like <code>target</code> etc. are available even if you don't specify
                <code>extend: "link"</code> (even the 'target' dropdown trait UI).</li>
        </ul>
        <p>So respectfully, what is 'extend' really good for, when you can define a custom link component without using it?</p>
    </div>

    <div id="gjs">
        <p>Here is the custom link component. Click on its settings and see that has all the link traits plus an
            additional custom attribute. View the exported code and see the correct link tag is generated. 
            Note <code>extend: "link"</code> has not been used in defining this component.</p>
    </div>

CSS

body, html {
  margin: 0;
  height: 100%;
}

Babel + JSX

function customLinkPlugin(editor) {

    editor.DomComponents.addType("customLink", {
        // extend: "link", // alone fixes the canvas <a> rendering and correct export of <a> - but can use tagName instead
        model: {
            defaults: {
                tagName: 'a', // alone fixes the canvas <a> rendering and correct export of <a>
                traits: [
                    "id",
                    "title",
                    "href",  
                    "target",  // drop down UI link traits available even without use of 'extend' !!
                    "data-info1"  // custom attribute
                ],
            },
        },
    });
}


const editor = grapesjs.init({
    container: '#gjs',
    fromElement: 1,
    height: '100%',
    storageManager: { type: 0 },
    plugins: ['customLinkPlugin']
});


// create some initial components
editor.addComponents(
    {
        type: 'customLink',
        classes: ['cls'],
        content: 'my custom hyperlink',
        attributes: { href: "somewhere", 'data-info1': "whatever" }
    },
);

// auto select our demo component
editor.on('load', () => {
    editor.select(editor.getWrapper().find('[data-gjs-type="customLink"]')[0])
});

// make settings panel the default
editor.Panels.getButton('views', 'open-tm').set('active', true)