Custom Trait Type
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...