183 lines
7.4 KiB
Plaintext
183 lines
7.4 KiB
Plaintext
/**
|
|
* TextStylingTune — Block Tune for Editor.js
|
|
* Adds alignment, custom CSS class, custom CSS style, and HTML ID settings to blocks.
|
|
*/
|
|
class TextStylingTune {
|
|
constructor({ api, block, data }) {
|
|
this.api = api;
|
|
this.block = block;
|
|
this.data = data || {
|
|
alignment: '',
|
|
cssClass: '',
|
|
customStyle: '',
|
|
elementId: '',
|
|
customAttrs: ''
|
|
};
|
|
}
|
|
|
|
static get isTune() {
|
|
return true;
|
|
}
|
|
|
|
render() {
|
|
const wrapper = document.createElement('div');
|
|
wrapper.className = 'cdx-settings-text-styling p-2 border-top';
|
|
wrapper.style.fontFamily = 'inherit';
|
|
|
|
const title = document.createElement('div');
|
|
title.className = 'small font-weight-bold text-primary mb-2';
|
|
title.innerHTML = '<i class="fas fa-palette"></i> Style & Alignment';
|
|
wrapper.appendChild(title);
|
|
|
|
// Alignment row
|
|
const alignWrapper = document.createElement('div');
|
|
alignWrapper.className = 'd-flex mb-2 align-items-center justify-content-start';
|
|
|
|
const alignments = [
|
|
{ name: 'left', icon: '<i class="fas fa-align-left"></i>', title: 'Align Left' },
|
|
{ name: 'center', icon: '<i class="fas fa-align-center"></i>', title: 'Align Center' },
|
|
{ name: 'right', icon: '<i class="fas fa-align-right"></i>', title: 'Align Right' },
|
|
{ name: 'justify', icon: '<i class="fas fa-align-justify"></i>', title: 'Align Justify' }
|
|
];
|
|
|
|
alignments.forEach(align => {
|
|
const btn = document.createElement('button');
|
|
btn.type = 'button';
|
|
btn.className = 'btn btn-xs btn-light mr-1 border';
|
|
btn.style.width = '30px';
|
|
btn.style.height = '30px';
|
|
btn.style.padding = '0';
|
|
btn.title = align.title;
|
|
if (this.data.alignment === align.name) {
|
|
btn.className = 'btn btn-xs btn-info mr-1 border';
|
|
}
|
|
btn.innerHTML = align.icon;
|
|
btn.addEventListener('click', () => {
|
|
this.data.alignment = this.data.alignment === align.name ? '' : align.name;
|
|
alignWrapper.querySelectorAll('button').forEach((b, idx) => {
|
|
b.className = (this.data.alignment === alignments[idx].name) ? 'btn btn-xs btn-info mr-1 border' : 'btn btn-xs btn-light mr-1 border';
|
|
});
|
|
this.applyTuneToBlock();
|
|
});
|
|
alignWrapper.appendChild(btn);
|
|
});
|
|
wrapper.appendChild(alignWrapper);
|
|
|
|
// CSS Class Group
|
|
const classGroup = document.createElement('div');
|
|
classGroup.className = 'form-group mb-1';
|
|
const classLabel = document.createElement('label');
|
|
classLabel.className = 'small font-weight-bold text-secondary mb-0 d-block';
|
|
classLabel.innerText = 'CSS Class';
|
|
const classInput = document.createElement('input');
|
|
classInput.type = 'text';
|
|
classInput.className = 'form-control form-control-sm py-0';
|
|
classInput.style.height = '24px';
|
|
classInput.placeholder = 'e.g. lead text-primary font-weight-bold';
|
|
classInput.value = this.data.cssClass || '';
|
|
classInput.addEventListener('input', (e) => {
|
|
this.data.cssClass = e.target.value.trim();
|
|
this.applyTuneToBlock();
|
|
});
|
|
classGroup.appendChild(classLabel);
|
|
classGroup.appendChild(classInput);
|
|
wrapper.appendChild(classGroup);
|
|
|
|
// Custom CSS Style Group
|
|
const styleGroup = document.createElement('div');
|
|
styleGroup.className = 'form-group mb-1';
|
|
const styleLabel = document.createElement('label');
|
|
styleLabel.className = 'small font-weight-bold text-secondary mb-0 d-block';
|
|
styleLabel.innerText = 'CSS Style';
|
|
const styleInput = document.createElement('input');
|
|
styleInput.type = 'text';
|
|
styleInput.className = 'form-control form-control-sm py-0';
|
|
styleInput.style.height = '24px';
|
|
styleInput.placeholder = 'e.g. color: #dc3545; font-size: 1.5rem;';
|
|
styleInput.value = this.data.customStyle || '';
|
|
styleInput.addEventListener('input', (e) => {
|
|
this.data.customStyle = e.target.value.trim();
|
|
this.applyTuneToBlock();
|
|
});
|
|
styleGroup.appendChild(styleLabel);
|
|
styleGroup.appendChild(styleInput);
|
|
wrapper.appendChild(styleGroup);
|
|
|
|
// HTML ID Group
|
|
const idGroup = document.createElement('div');
|
|
idGroup.className = 'form-group mb-1';
|
|
const idLabel = document.createElement('label');
|
|
idLabel.className = 'small font-weight-bold text-secondary mb-0 d-block';
|
|
idLabel.innerText = 'Element ID';
|
|
const idInput = document.createElement('input');
|
|
idInput.type = 'text';
|
|
idInput.className = 'form-control form-control-sm py-0';
|
|
idInput.style.height = '24px';
|
|
idInput.placeholder = 'e.g. section-main-title';
|
|
idInput.value = this.data.elementId || '';
|
|
idInput.addEventListener('input', (e) => {
|
|
this.data.elementId = e.target.value.trim();
|
|
this.applyTuneToBlock();
|
|
});
|
|
idGroup.appendChild(idLabel);
|
|
idGroup.appendChild(idInput);
|
|
wrapper.appendChild(idGroup);
|
|
|
|
// Custom HTML Attributes Group
|
|
const attrsGroup = document.createElement('div');
|
|
attrsGroup.className = 'form-group mb-0';
|
|
const attrsLabel = document.createElement('label');
|
|
attrsLabel.className = 'small font-weight-bold text-secondary mb-0 d-block';
|
|
attrsLabel.innerText = 'Custom Attributes';
|
|
const attrsInput = document.createElement('input');
|
|
attrsInput.type = 'text';
|
|
attrsInput.className = 'form-control form-control-sm py-0';
|
|
attrsInput.style.height = '24px';
|
|
attrsInput.placeholder = 'e.g. data-aos="fade-up" target="_blank"';
|
|
attrsInput.value = this.data.customAttrs || '';
|
|
attrsInput.addEventListener('input', (e) => {
|
|
this.data.customAttrs = e.target.value.trim();
|
|
});
|
|
attrsGroup.appendChild(attrsLabel);
|
|
attrsGroup.appendChild(attrsInput);
|
|
wrapper.appendChild(attrsGroup);
|
|
|
|
return wrapper;
|
|
}
|
|
|
|
applyTuneToBlock() {
|
|
if (!this.block || !this.block.holder) return;
|
|
const blockContent = this.block.holder.querySelector('.ce-block__content');
|
|
if (blockContent) {
|
|
// Live alignment preview
|
|
blockContent.style.textAlign = this.data.alignment || '';
|
|
// Live styling preview
|
|
const currentElement = blockContent.firstElementChild;
|
|
if (currentElement) {
|
|
// Apply custom inline styles on top of defaults
|
|
currentElement.style.cssText = this.data.customStyle || '';
|
|
}
|
|
}
|
|
}
|
|
|
|
save() {
|
|
return this.data;
|
|
}
|
|
|
|
wrap(blockContent) {
|
|
// Applies styling during initial render / loading
|
|
if (this.data.alignment) {
|
|
blockContent.style.textAlign = this.data.alignment;
|
|
}
|
|
const currentElement = blockContent.firstElementChild;
|
|
if (currentElement && this.data.customStyle) {
|
|
currentElement.style.cssText = this.data.customStyle;
|
|
}
|
|
return blockContent;
|
|
}
|
|
}
|
|
|
|
// Register globally
|
|
window.SISEditorPlugins = window.SISEditorPlugins || {};
|
|
window.SISEditorPlugins['textStyling'] = { class: TextStylingTune };
|