JSFiddle - React, Tailwind, and code Playground
by Digvijay Naruka
HTML
<script src="//cdn.quilljs.com/1.3.6/quill.js"></script>
<link rel="stylesheet" href="//cdn.quilljs.com/1.3.6/quill.snow.css">
<div id="toolbar">
<button id='btn-separator' class='ql-button'>
Hierarchy separator
</button>
</div>
<div id="editor-container">
</div>
SCSS
#editor-container {
height: 375px;
}
.toolbar .ql-button {
background: rgb(231, 237, 245) !important;
border-color: rgb(158, 176, 199) !important;
padding: 4px 6px !important;
width: max-content !important;
margin: 0 3px 0 3px !important;
}
div#editor-container .ql-editor {
height: 100px;
font-size: 16px !important;
& * {
font-size: 14px !important;
}
.ql-sep::before {
background: lightgrey;
padding: 2px 4px;
display: inline-block;
content: ',';
}
s {
text-decoration: line-through !important;
}
em {
filter: blur(0.05em);
}
em:hover {
filter: blur(0);
}
.hidden-preview, .excluded-search ,.hierarchy-separator {
position: relative;
opacity: 0.5;
color: gray;
font-style: italic;
}
.hidden-preview:hover, .excluded-search:hover ,.hierarchy-separator:hover {
opacity: 1;
color: black;
}
.hidden-preview {
border: 2px dashed red;
background-color: rgba(255, 0, 0, 0.1);
}
.excluded-search {
border: 2px dashed blue;
background-color: rgba(0, 0, 255, 0.1);
}
.hidden-preview::before {
content: 'Hidden';
position: absolute;
top: 100%;
right: 0;
background-color: red;
color: white;
padding: 2px 5px;
font-size: 10px;
}
.excluded-search::before {
content: 'Not Searchable';
position: absolute;
top: 100%;
background-color: blue;
color: white;
padding: 2px 5px;
font-size: 10px;
}
.hierarchy-separator {
color: red ;
font-weight: bold;
position: relative;
display: inline-block;
padding-bottom: 10px;
}
...
JavaScript
const Parchment = Quill.imports.parchment;
const Delta = Quill.imports.delta;
class Label extends Parchment.Embed {
static create(value) {
const node = super.create(value);
node.innerText = value;
node.contentEditable = 'false';
//this._addRemovalButton(node);
return node;
}
static value(node) {
return node.childNodes[0].textContent;
}
static _addRemovalButton(node) {
const button = document.createElement('button');
button.innerText = 'x';
button.onclick = () => node.remove();
button.contentEditable = 'false';
node.appendChild(button);
// Extra span forces the cursor to the end of the label, otherwise it appears inside the removal button
const span = document.createElement('span');
span.innerText = ' ';
node.appendChild(span);
}
}
Label.blotName = 'sep';
Label.tagName = 'SPAN';
Label.className = 'hierarchy-separator';
Quill.register(Label);
var quill = new Quill('#editor-container', {
modules: {
toolbar: '#toolbar'
},
placeholder: 'Compose an epic...',
theme: 'snow' // or 'bubble'
});
const customButton = document.querySelector('#btn-separator');
customButton.addEventListener('click', function() {
let selection = quill.getSelection();
var caretPosition = quill.getSelection(true);
/* quill.insert(caretPosition, {sep:',' } );*/
console.log(caretPosition)
quill.updateContents(new Delta()
.retain(caretPosition.index)
.insert({sep: ','})
);
quill.setSelection(caretPosition.index + 1);
});
quill.updateContents(new Delta().insert('foo').insert({
sep: ','
}));