I\'m investigating the use of Quill for a project, and I need to know if it\'s possible to create a custom format/blot with more complexity than a single element and a single pa
So, I figured out how to do this in the end with minimal effort. It involves defining a new blot type for Quill 1.3 or greater, the same code should work on older versions however is untested.
See the code snippet for a working example. The crux is to extend the existing Embed blot 'blots/embed' and define your own toolbar handler to inject arbitrary DOM node instances.
// utility function used to inherit non prototypical methods/properties
function extend(target, base) {
for (var prop in base) {
target[prop] = base[prop];
}
}
// definition of a custom Blot.
(function(Embed) {
'use strict';
function Span() {
Object.getPrototypeOf(Embed).apply(this, arguments);
}
Span.prototype = Object.create(Embed && Embed.prototype);
Span.prototype.constructor = Span;
extend(Span, Embed);
Span.create = function create(value) {
return value; // expects a domNode as value
};
Span.value = function value(domNode) {
return domNode;
};
Span.blotName = 'span';
Span.tagName = 'SPAN';
Span.className = 'complex';
Quill.register(Span, true);
})(Quill.import('blots/embed')); // import the embed blot. This is important as this is being extended
// custom handler for the toolbar button
var handler = function() {
var complexSpan = document.getElementById('complextype').firstElementChild.cloneNode(true);
var selection = quill.getSelection();
quill.insertEmbed(selection.index, 'span', complexSpan);
}
// instantiate quill. Note that modules.toolbar.handlers has a 'span' handler. Quill parses this from // the class on the button in the toolbar markup: 'ql-span' this is 'ql-' + blotName
var quill = new Quill('#editor', {
modules: {
toolbar: {
container: '.toolbar',
handlers: {
'span': handler
}
}
},
theme: 'snow'
});
:root {
--complex-bgcolor: #767676;
--font-color: #FFFFFF;
}
html {
font-size: 10px;
}
button.ql-span {
width: 15rem !important;
}
.complex {
border-radius: 1rem;
border: 0.2rem solid black;
margin: 0.3rem;
}
.inner {
border-radius: 1rem;
background: var(--complex-bgcolor);
color: var(--font-color);
padding-left: 0.6rem;
padding-right: 0.6rem;
}
.formatting {
font-weight: bold;
font-style: italic;
text-decoration: underline;
}
.nested {
margin-left: 0.3rem;
margin-right: 0.3rem;
}
Lorem Ipsum
Format applied
More text
with formatting
dolor
sit amet