Edit in JSFiddle

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 based element changes
    onEvent({ elInput, component }) {
      // `elInput` is the result HTMLElement you get from `createInput`
      const inputType = elInput.querySelector('.href-next__type');
      let href = '';

      switch (inputType.value) {
        case 'url':
          const valUrl = elInput.querySelector('.href-next__url').value;
          href = valUrl;
          break;
        case 'email':
          const valEmail = elInput.querySelector('.href-next__email').value;
          const valSubj = elInput.querySelector('.href-next__email-subject').value;
					href = `mailto:${valEmail}${valSubj ? `?subject=${valSubj}` : ''}`;
          break;
      }

      component.addAttributes({ href });
    },

    onUpdate({ elInput, component }) {
      const href = component.getAttributes().href || '';
      const inputType = elInput.querySelector('.href-next__type');
      let type = 'url';

      if (href.indexOf('mailto:') === 0) {
        const inputEmail = elInput.querySelector('.href-next__email');
        const inputSubject = elInput.querySelector('.href-next__email-subject');
        const mailTo = href.replace('mailto:', '').split('?');
        const email = mailTo[0];
        const params = (mailTo[1] || '').split('&').reduce((acc, item) => {
          const items = item.split('=');
          acc[items[0]] = items[1];
          return acc;
        }, {});
        type = 'email';

        inputEmail.value = email || '';
        inputSubject.value = params.subject || '';
      } else {
        elInput.querySelector('.href-next__url').value = href;
      }

      inputType.value = type;
      inputType.dispatchEvent(new CustomEvent('change'));
    },
  });
};

const editor = grapesjs.init({
	container: '#gjs',
  height: '100%',
  fromElement: true,
  storageManager: false,
  plugins: [hrefNextTrait],
});
<div id="gjs">
  <a href="#">Link 1</a>
  <br/>
  <br/>
  <br/>
  <a href="#">Link 2</a>
</div>
body, html {
  margin: 0;
  height: 100%;
}