- Implemented WysiwygModalManager for managing modals related to code blocks and block settings. - Created WysiwygSelection for handling text selection across Shadow DOM boundaries. - Introduced WysiwygShortcuts for managing keyboard shortcuts and slash menu items. - Developed wysiwygStyles for consistent styling of the WYSIWYG editor. - Defined types for blocks, slash menu items, and shortcut patterns in wysiwyg.types.ts.
		
			
				
	
	
		
			80 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			80 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| import { BaseBlockHandler, type IBlockEventHandlers } from '../block.base.js';
 | |
| import type { IBlock } from '../../wysiwyg.types.js';
 | |
| import { cssManager } from '@design.estate/dees-element';
 | |
| 
 | |
| export class DividerBlockHandler extends BaseBlockHandler {
 | |
|   type = 'divider';
 | |
|   
 | |
|   render(block: IBlock, isSelected: boolean): string {
 | |
|     const selectedClass = isSelected ? ' selected' : '';
 | |
|     return `
 | |
|       <div class="block divider${selectedClass}" data-block-id="${block.id}" data-block-type="${block.type}" tabindex="0">
 | |
|         <hr>
 | |
|       </div>
 | |
|     `;
 | |
|   }
 | |
|   
 | |
|   setup(element: HTMLElement, block: IBlock, handlers: IBlockEventHandlers): void {
 | |
|     const dividerBlock = element.querySelector('.block.divider') as HTMLDivElement;
 | |
|     if (!dividerBlock) return;
 | |
|     
 | |
|     // Handle click to select
 | |
|     dividerBlock.addEventListener('click', (e) => {
 | |
|       e.stopPropagation();
 | |
|       // Focus will trigger the selection
 | |
|       dividerBlock.focus();
 | |
|       // Ensure focus handler is called immediately
 | |
|       handlers.onFocus?.();
 | |
|     });
 | |
|     
 | |
|     // Handle focus/blur
 | |
|     dividerBlock.addEventListener('focus', () => {
 | |
|       handlers.onFocus?.();
 | |
|     });
 | |
|     
 | |
|     dividerBlock.addEventListener('blur', () => {
 | |
|       handlers.onBlur?.();
 | |
|     });
 | |
|     
 | |
|     // Handle keyboard events
 | |
|     dividerBlock.addEventListener('keydown', (e) => {
 | |
|       if (e.key === 'Backspace' || e.key === 'Delete') {
 | |
|         e.preventDefault();
 | |
|         // Let the keyboard handler in the parent component handle the deletion
 | |
|         handlers.onKeyDown?.(e);
 | |
|       } else {
 | |
|         // Handle navigation keys
 | |
|         handlers.onKeyDown?.(e);
 | |
|       }
 | |
|     });
 | |
|   }
 | |
|   
 | |
|   getStyles(): string {
 | |
|     return `
 | |
|       .block.divider {
 | |
|         padding: 8px 0;
 | |
|         margin: 16px 0;
 | |
|         cursor: pointer;
 | |
|         position: relative;
 | |
|         border-radius: 4px;
 | |
|         transition: all 0.15s ease;
 | |
|       }
 | |
| 
 | |
|       .block.divider:focus {
 | |
|         outline: none;
 | |
|       }
 | |
| 
 | |
|       .block.divider.selected {
 | |
|         background: ${cssManager.bdTheme('rgba(0, 102, 204, 0.05)', 'rgba(77, 148, 255, 0.08)')};
 | |
|         box-shadow: inset 0 0 0 2px ${cssManager.bdTheme('rgba(0, 102, 204, 0.2)', 'rgba(77, 148, 255, 0.2)')};
 | |
|       }
 | |
| 
 | |
|       .block.divider hr {
 | |
|         border: none;
 | |
|         border-top: 1px solid ${cssManager.bdTheme('#e0e0e0', '#333')};
 | |
|         margin: 0;
 | |
|         pointer-events: none;
 | |
|       }
 | |
|     `;
 | |
|   }
 | |
| } |