Files
dees-catalog/ts_web/elements/wysiwyg/wysiwyg.blocks.ts
2025-06-23 21:15:04 +00:00

106 lines
3.3 KiB
TypeScript

import { html, type TemplateResult } from '@design.estate/dees-element';
import { type IBlock } from './wysiwyg.types.js';
import { WysiwygConverters } from './wysiwyg.converters.js';
export class WysiwygBlocks {
static renderListContent(content: string, metadata?: any): string {
const items = content.split('\n').filter(item => item.trim());
if (items.length === 0) return '';
const listTag = metadata?.listType === 'ordered' ? 'ol' : 'ul';
return `<${listTag}>${items.map(item => `<li>${WysiwygConverters.escapeHtml(item)}</li>`).join('')}</${listTag}>`;
}
static renderBlock(
block: IBlock,
isSelected: boolean,
handlers: {
onInput: (e: InputEvent) => void;
onKeyDown: (e: KeyboardEvent) => void;
onFocus: () => void;
onBlur: () => void;
onCompositionStart: () => void;
onCompositionEnd: () => void;
onMouseUp?: (e: MouseEvent) => void;
}
): TemplateResult {
if (block.type === 'divider') {
return html`
<div
class="block divider"
data-block-id="${block.id}"
>
<hr>
</div>
`;
}
if (block.type === 'list') {
return html`
<div
class="block list ${isSelected ? 'selected' : ''}"
data-block-id="${block.id}"
contenteditable="true"
@input="${handlers.onInput}"
@keydown="${handlers.onKeyDown}"
@focus="${handlers.onFocus}"
@blur="${handlers.onBlur}"
@compositionstart="${handlers.onCompositionStart}"
@compositionend="${handlers.onCompositionEnd}"
@mouseup="${(e: MouseEvent) => {
console.log('Block mouseup event fired');
if (handlers.onMouseUp) handlers.onMouseUp(e);
}}"
.innerHTML="${this.renderListContent(block.content, block.metadata)}"
></div>
`;
}
return html`
<div
class="block ${block.type} ${isSelected ? 'selected' : ''}"
contenteditable="true"
@input="${handlers.onInput}"
@keydown="${handlers.onKeyDown}"
@focus="${handlers.onFocus}"
@blur="${handlers.onBlur}"
@compositionstart="${handlers.onCompositionStart}"
@compositionend="${handlers.onCompositionEnd}"
@mouseup="${(e: MouseEvent) => {
console.log('Block mouseup event fired');
if (handlers.onMouseUp) handlers.onMouseUp(e);
}}"
></div>
`;
}
static setCursorToEnd(element: HTMLElement): void {
const range = document.createRange();
const sel = window.getSelection();
range.selectNodeContents(element);
range.collapse(false);
sel!.removeAllRanges();
sel!.addRange(range);
}
static setCursorToStart(element: HTMLElement): void {
const range = document.createRange();
const sel = window.getSelection();
range.selectNodeContents(element);
range.collapse(true);
sel!.removeAllRanges();
sel!.addRange(range);
}
static focusListItem(listElement: HTMLElement): void {
const firstLi = listElement.querySelector('li');
if (firstLi) {
firstLi.focus();
const range = document.createRange();
const sel = window.getSelection();
range.selectNodeContents(firstLi);
range.collapse(true);
sel!.removeAllRanges();
sel!.addRange(range);
}
}
}