GrapesJS Custom Style 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">
<script src="https://unpkg.com/grapesjs-blocks-basic"></script>
<div id="gjs">
<div style="padding: 25px">Custom Style Type</div>
<div style="font-size: 50px">Value 50</div>
</div>
CSS
body, html {
margin: 0;
height: 100%;
}
.selectors-wrp {
padding: 10px 5px;
}
.selectors-head {
display: flex;
align-items: center;
}
.selectors-title {
flex-grow: 1;
text-align: left;
}
.selectors {
display: flex;
flex-wrap: wrap;
background-color: rgb(0 0 0 / 15%);
padding: 3px 5px;
border-radius: 3px;
margin: 10px 0;
gap: 5px;
}
.selector, .selector-add {
display: flex;
gap: 3px;
background-color: #8f4a79;
color: white;
padding: 2px 5px 3px;
border-radius: 3px;
align-items: center;
white-space: nowrap;
}
.selector-add {
font-size: 1rem;
padding: 2px 8px 3px;
background-color: rgb(255 255 255 / 25%);
cursor: pointer;
}
.selector-rm {
font-size: 1rem;
cursor: pointer;
}
.selectors-targets {
text-align: left;
}
Babel + JSX
const customType = (editor) => {
editor.StyleManager.addType('my-custom-prop', {
// Create UI
create({ props, change }) {
const el = document.createElement('div');
el.innerHTML = `<input type="range" class="my-input" min="${props.min}" max="${props.max}"/>`;
const inputEl = el.querySelector('.my-input');
inputEl.addEventListener('change', event => change({ event })); // `change` will trigger the emit
inputEl.addEventListener('input', event => change({ event, partial: true }));
return el;
},
// Propagate UI changes up to the targets
emit({ props, updateStyle }, { event, partial }) {
const { value } = event.target;
updateStyle(`${value}px`, { partial });
},
// Update UI (eg. when the target is changed)
update({ value, el }) {
el.querySelector('.my-input').value = parseInt(value, 10);
},
// Clean the memory from side effects if necessary (eg. global event listeners, etc.)
destroy() {
},
});
};
const editor = grapesjs.init({
container: '#gjs',
fromElement: true,
height: '100%',
storageManager: false,
noticeOnUnload: false,
plugins: [customType],
styleManager: {
sectors: [
{
name: 'My sector',
properties: [
{
type: 'my-custom-prop',
property: 'font-size',
default: '15',
min: 10,
max: 70,
},
],
},
],
},
});