feat(editor): Add wysiwyg editor

This commit is contained in:
Juergen Kunz
2025-06-23 21:18:03 +00:00
parent cdcd4f79c8
commit 302777feff

View File

@ -401,58 +401,101 @@ export class DeesInputWysiwyg extends DeesInputBase<string> {
} }
} }
if (e.key === 'Enter' && !e.shiftKey) { if (e.key === 'Enter') {
if (block.type === 'list') { // Handle code blocks specially
// Handle Enter in lists differently if (block.type === 'code') {
const target = e.target as HTMLDivElement; if (e.shiftKey) {
const selection = window.getSelection(); // Shift+Enter in code blocks creates a new block
if (selection && selection.rangeCount > 0) { e.preventDefault();
const range = selection.getRangeAt(0);
const currentLi = range.startContainer.parentElement?.closest('li');
if (currentLi && currentLi.textContent === '') { const blockIndex = this.blocks.findIndex(b => b.id === block.id);
// Empty list item - exit list mode const newBlock: IBlock = {
e.preventDefault(); id: WysiwygShortcuts.generateBlockId(),
const blockIndex = this.blocks.findIndex(b => b.id === block.id); type: 'paragraph',
const newBlock: IBlock = { content: '',
id: WysiwygShortcuts.generateBlockId(), };
type: 'paragraph',
content: '',
};
this.blocks = [...this.blocks.slice(0, blockIndex + 1), newBlock, ...this.blocks.slice(blockIndex + 1)]; this.blocks = [...this.blocks.slice(0, blockIndex + 1), newBlock, ...this.blocks.slice(blockIndex + 1)];
setTimeout(() => { this.updateValue();
const newBlockElement = this.shadowRoot!.querySelector(`[data-block-id="${newBlock.id}"]`) as HTMLDivElement;
if (newBlockElement) { setTimeout(() => {
newBlockElement.focus(); const wrapperElement = this.shadowRoot!.querySelector(`[data-block-id="${newBlock.id}"]`);
if (wrapperElement) {
const blockElement = wrapperElement.querySelector('.block') as HTMLDivElement;
if (blockElement) {
blockElement.focus();
WysiwygBlocks.setCursorToStart(blockElement);
} }
}); }
} });
// Otherwise, let the browser handle creating new list items
} }
// For normal Enter in code blocks, let the browser handle it (creates new line)
return; return;
} }
e.preventDefault(); // For other block types, handle Enter normally (without shift)
if (!e.shiftKey) {
if (block.type === 'list') {
// Handle Enter in lists differently
const target = e.target as HTMLDivElement;
const selection = window.getSelection();
if (selection && selection.rangeCount > 0) {
const range = selection.getRangeAt(0);
const currentLi = range.startContainer.parentElement?.closest('li');
const blockIndex = this.blocks.findIndex(b => b.id === block.id); if (currentLi && currentLi.textContent === '') {
const newBlock: IBlock = { // Empty list item - exit list mode
id: WysiwygShortcuts.generateBlockId(), e.preventDefault();
type: 'paragraph', const blockIndex = this.blocks.findIndex(b => b.id === block.id);
content: '', const newBlock: IBlock = {
}; id: WysiwygShortcuts.generateBlockId(),
type: 'paragraph',
content: '',
};
this.blocks = [...this.blocks.slice(0, blockIndex + 1), newBlock, ...this.blocks.slice(blockIndex + 1)]; this.blocks = [...this.blocks.slice(0, blockIndex + 1), newBlock, ...this.blocks.slice(blockIndex + 1)];
this.updateValue(); setTimeout(() => {
const wrapperElement = this.shadowRoot!.querySelector(`[data-block-id="${newBlock.id}"]`);
setTimeout(() => { if (wrapperElement) {
const newBlockElement = this.shadowRoot!.querySelector(`[data-block-id="${newBlock.id}"]`) as HTMLDivElement; const blockElement = wrapperElement.querySelector('.block') as HTMLDivElement;
if (newBlockElement) { if (blockElement) {
newBlockElement.focus(); blockElement.focus();
WysiwygBlocks.setCursorToStart(blockElement);
}
}
});
}
// Otherwise, let the browser handle creating new list items
}
return;
} }
});
e.preventDefault();
const blockIndex = this.blocks.findIndex(b => b.id === block.id);
const newBlock: IBlock = {
id: WysiwygShortcuts.generateBlockId(),
type: 'paragraph',
content: '',
};
this.blocks = [...this.blocks.slice(0, blockIndex + 1), newBlock, ...this.blocks.slice(blockIndex + 1)];
this.updateValue();
setTimeout(() => {
const wrapperElement = this.shadowRoot!.querySelector(`[data-block-id="${newBlock.id}"]`);
if (wrapperElement) {
const blockElement = wrapperElement.querySelector('.block') as HTMLDivElement;
if (blockElement) {
blockElement.focus();
WysiwygBlocks.setCursorToStart(blockElement);
}
}
});
}
} else if (e.key === 'Backspace' && block.content === '' && this.blocks.length > 1) { } else if (e.key === 'Backspace' && block.content === '' && this.blocks.length > 1) {
e.preventDefault(); e.preventDefault();
const blockIndex = this.blocks.findIndex(b => b.id === block.id); const blockIndex = this.blocks.findIndex(b => b.id === block.id);