fix(dees-modal): theming

This commit is contained in:
2025-06-24 10:45:06 +00:00
parent c82c407350
commit 8b02c5aea3
18 changed files with 2283 additions and 600 deletions

View File

@@ -42,20 +42,41 @@ export class WysiwygInputHandler {
* Updates block content based on its type
*/
private updateBlockContent(block: IBlock, target: HTMLDivElement): void {
if (block.type === 'list') {
const listItems = target.querySelectorAll('li');
block.content = Array.from(listItems).map(li => li.textContent || '').join('\n');
// Get the block component for proper content extraction
const wrapperElement = target.closest('.block-wrapper');
const blockComponent = wrapperElement?.querySelector('dees-wysiwyg-block') as any;
if (blockComponent) {
// Use the block component's getContent method for consistency
block.content = blockComponent.getContent();
const listElement = target.querySelector('ol, ul');
if (listElement) {
block.metadata = {
listType: listElement.tagName.toLowerCase() === 'ol' ? 'ordered' : 'bullet'
};
// Update list metadata if needed
if (block.type === 'list') {
const listElement = target.querySelector('ol, ul');
if (listElement) {
block.metadata = {
listType: listElement.tagName.toLowerCase() === 'ol' ? 'ordered' : 'bullet'
};
}
}
} else if (block.type === 'code') {
block.content = target.textContent || '';
} else {
block.content = target.innerHTML || '';
// Fallback if block component not found
if (block.type === 'list') {
const listItems = target.querySelectorAll('li');
// Use innerHTML to preserve formatting
block.content = Array.from(listItems).map(li => li.innerHTML || '').join('\n');
const listElement = target.querySelector('ol, ul');
if (listElement) {
block.metadata = {
listType: listElement.tagName.toLowerCase() === 'ol' ? 'ordered' : 'bullet'
};
}
} else if (block.type === 'code') {
block.content = target.textContent || '';
} else {
block.content = target.innerHTML || '';
}
}
}
@@ -151,24 +172,54 @@ export class WysiwygInputHandler {
* Handles slash command detection and menu display
*/
private handleSlashCommand(textContent: string, target: HTMLDivElement): void {
if (textContent === '/' || (textContent.startsWith('/') && this.component.showSlashMenu)) {
if (!this.component.showSlashMenu && textContent === '/') {
this.component.showSlashMenu = true;
this.component.slashMenuSelectedIndex = 0;
const slashMenu = this.component.slashMenu;
const isSlashMenuVisible = slashMenu && slashMenu.visible;
if (textContent === '/' || (textContent.startsWith('/') && isSlashMenuVisible)) {
if (!isSlashMenuVisible && textContent === '/') {
// Get position for menu based on cursor location
const rect = this.getCaretCoordinates(target);
const rect = target.getBoundingClientRect();
const containerRect = this.component.shadowRoot!.querySelector('.wysiwyg-container')!.getBoundingClientRect();
// Show the slash menu at the cursor position
slashMenu.show(
{ x: rect.left, y: rect.bottom + 4 },
(type: string) => {
this.component.insertBlock(type);
}
);
this.component.slashMenuPosition = {
x: rect.left - containerRect.left,
y: rect.bottom - containerRect.top + 4
};
// Ensure the block maintains focus
requestAnimationFrame(() => {
if (document.activeElement !== target) {
target.focus();
}
});
}
// Update filter
if (slashMenu) {
slashMenu.updateFilter(textContent.slice(1));
}
this.component.slashMenuFilter = textContent.slice(1);
} else if (!textContent.startsWith('/')) {
this.component.closeSlashMenu();
}
}
/**
* Gets the coordinates of the caret/cursor
*/
private getCaretCoordinates(element: HTMLElement): DOMRect {
const selection = window.getSelection();
if (selection && selection.rangeCount > 0) {
const range = selection.getRangeAt(0);
const rect = range.getBoundingClientRect();
if (rect.width > 0 || rect.height > 0) {
return rect;
}
}
// Fallback to element position
return element.getBoundingClientRect();
}
/**
* Schedules auto-save after a delay
@@ -177,6 +228,10 @@ export class WysiwygInputHandler {
if (this.saveTimeout) {
clearTimeout(this.saveTimeout);
}
// Don't auto-save if slash menu is open
if (this.component.slashMenu && this.component.slashMenu.visible) {
return;
}
this.saveTimeout = setTimeout(() => {
this.component.updateValue();
}, 1000);