GrapesJS Starter

by artur_arseniev

HTML

<script src="https://unpkg.com/grapesjs"></script>
<link rel="stylesheet" href="https://unpkg.com/grapesjs/dist/css/grapes.min.css">
<div id="gjs">
  <a href="#">Link 1</a>
  <br/>
  <br/>
  <br/>
  <a href="#">Link 2</a>
</div>

CSS

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

Babel + JSX

const hrefNextTrait = (editor) => {
	// Update default link component
	editor.DomComponents.addType('link', {
    model: {
      defaults: {
        traits: [
          {
            type: 'href-next',
            name: 'href',
            label: 'New href',
          },
        ]
      }
    }
  });

  editor.TraitManager.addType('href-next', {
    noLabel: true,

    // Return a simple HTML string or an HTML element
    createInput({ trait }) {
      // Here we can decide to use properties from the trait
      const traitOpts = trait.get('options') || [];
      const options = traitOpts.lenght ? traitOpts : [
        { id: 'url', name: 'URL' },
        { id: 'email', name: 'Email' },
      ];

      // Create a new element container add some content
      const el = document.createElement('div');
      el.innerHTML = `
      <select class="href-next__type">
        ${options.map(opt => 
        	`<option value="${opt.id}">${opt.name}</option>`)
          .join('')}
      </select>
      <div class="href-next__url-inputs">
        <input class="href-next__url" placeholder="Insert URL"/>
      </div>
      <div class="href-next__email-inputs">
        <input class="href-next__email" placeholder="Insert email"/>
        <input class="href-next__email-subject" placeholder="Insert subject"/>
      </div>
    `;

      // Let's make our content alive
      const inputsUrl = el.querySelector('.href-next__url-inputs');
      const inputsEmail = el.querySelector('.href-next__email-inputs');
      const inputType = el.querySelector('.href-next__type');
      inputType.addEventListener('change', ev => {
        switch (ev.target.value) {
          case 'url':
            inputsUrl.style.display = '';
            inputsEmail.style.display = 'none';
            break;
          case 'email':
            inputsUrl.style.display = 'none';
            inputsEmail.style.display = '';
            break;
        }
      });

      return el;
    },

    // Update the component...