Files
dees-catalog/readme.plan.md
Juergen Kunz 987ae70e7a feat: add DeesInputFileupload and DeesInputRichtext components
- Implemented DeesInputFileupload component with file upload functionality, including drag-and-drop support, file previews, and clear all option.
- Developed DeesInputRichtext component featuring a rich text editor with a formatting toolbar, link management, and word count display.
- Created demo for DeesInputRichtext showcasing various use cases including basic editing, placeholder text, different heights, and disabled state.
- Added styles for both components to ensure a consistent and user-friendly interface.
- Introduced types for toolbar buttons in the rich text editor for better type safety and maintainability.
2025-09-19 15:26:21 +00:00

377 lines
12 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# WYSIWYG Editor Refactoring Plan
## 2025-?? - Component Subfolder Refactor
- [x] Inventory large single-file components and dependencies
- [x] Refactor dees-input-datepicker into subfolder structure
- [x] Refactor dees-input-fileupload into subfolder structure
- [x] Refactor dees-input-richtext into subfolder structure
- [x] Refactor dees-chart-area into subfolder structure
- [x] Refactor dees-appui-appbar into subfolder structure
- [x] Update exports/imports and verify build
## Current Status
The `dees-wysiwyg-block.ts` file has grown to over 2100 lines and contains:
- Main component logic
- CSS styles for all block types
- Rendering logic for each block type
- Setup methods for each block type
- Helper methods for various functionality
This makes the file difficult to maintain and extend.
## Refactoring Goals
1. **Modularity**: Each block type should be self-contained
2. **Extensibility**: Adding new block types should be straightforward
3. **Maintainability**: Code should be organized by responsibility
4. **Type Safety**: Strong interfaces to ensure consistent implementation
5. **Performance**: Enable potential lazy loading of block types
## Proposed File Structure
```
ts_web/elements/wysiwyg/
 dees-wysiwyg-block.ts (main component - simplified)
 blocks/
  index.ts (exports all block types)
  block.base.ts (base class/interface)
  block.registry.ts (block type registry)
  block.styles.ts (common block styles)
 
  text/
   paragraph.block.ts
   heading.block.ts
   quote.block.ts
   code.block.ts
   list.block.ts
 
  media/
   image.block.ts
   youtube.block.ts
   attachment.block.ts
 
  content/
   markdown.block.ts
   html.block.ts
   divider.block.ts
 
  utils/
  file.utils.ts
  media.utils.ts
  markdown.utils.ts
```
## Implementation Details
### 1. Block Handler Interface
```typescript
// block.base.ts
export interface IBlockHandler {
type: string;
render(block: IBlock, isSelected: boolean): string;
setup(element: HTMLElement, block: IBlock, handlers: IBlockEventHandlers): void;
getStyles(): string;
getPlaceholder?(): string;
}
export interface IBlockEventHandlers {
onInput: (e: InputEvent) => void;
onKeyDown: (e: KeyboardEvent) => void;
onFocus: () => void;
onBlur: () => void;
onCompositionStart: () => void;
onCompositionEnd: () => void;
onMouseUp?: (e: MouseEvent) => void;
}
export abstract class BaseBlockHandler implements IBlockHandler {
abstract type: string;
abstract render(block: IBlock, isSelected: boolean): string;
// Default implementation for common setup
setup(element: HTMLElement, block: IBlock, handlers: IBlockEventHandlers): void {
// Common setup logic
}
// Common styles can be defined here
getStyles(): string {
return '';
}
}
```
### 2. Block Registry Pattern
```typescript
// block.registry.ts
export class BlockRegistry {
private static handlers = new Map<string, IBlockHandler>();
static register(type: string, handler: IBlockHandler): void {
this.handlers.set(type, handler);
}
static getHandler(type: string): IBlockHandler | undefined {
return this.handlers.get(type);
}
static getAllTypes(): string[] {
return Array.from(this.handlers.keys());
}
}
```
### 3. Example Block Implementation
```typescript
// media/image.block.ts
export class ImageBlockHandler extends BaseBlockHandler {
type = 'image';
render(block: IBlock, isSelected: boolean): string {
const selectedClass = isSelected ? ' selected' : '';
const imageUrl = block.metadata?.url || '';
const isLoading = block.metadata?.loading || false;
return `
<div class="block image${selectedClass}" data-block-id="${block.id}" data-block-type="${block.type}" tabindex="0">
${isLoading ? `<div class="image-loading">Uploading image...</div>` : ''}
${imageUrl ? this.renderImage(imageUrl, block.content) : this.renderPlaceholder()}
</div>
`;
}
private renderImage(url: string, alt: string): string {
return `
<div class="image-container">
<img src="${url}" alt="${alt || 'Uploaded image'}" />
</div>
`;
}
private renderPlaceholder(): string {
return `
<div class="image-upload-placeholder">
<div class="upload-icon">=<3D></div>
<div class="upload-text">Click to upload an image</div>
<div class="upload-hint">or drag and drop</div>
</div>
<input type="file" accept="image/*" style="display: none;" />
`;
}
setup(element: HTMLElement, block: IBlock, handlers: IBlockEventHandlers): void {
const imageBlock = element.querySelector('.block.image') as HTMLDivElement;
if (!imageBlock) return;
// Setup click handlers
imageBlock.addEventListener('click', (e) => {
if ((e.target as HTMLElement).tagName !== 'INPUT') {
e.stopPropagation();
imageBlock.focus();
handlers.onFocus();
}
});
// Setup file upload
this.setupFileUpload(imageBlock, block, handlers);
// Setup drag and drop
this.setupDragDrop(imageBlock, block, handlers);
// Setup keyboard events
this.setupKeyboardEvents(imageBlock, handlers);
}
getStyles(): string {
return `
.block.image {
min-height: 200px;
padding: 0;
margin: 16px 0;
border-radius: 8px;
overflow: hidden;
position: relative;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: all 0.15s ease;
}
.block.image:focus {
outline: none;
}
.block.image.selected {
box-shadow: 0 0 0 3px rgba(0, 102, 204, 0.3);
}
/* ... rest of image-specific styles ... */
`;
}
}
```
## Migration Strategy
### Phase 1: Infrastructure (Week 1)
- [x] Create `blocks/` directory structure
- [x] Implement `IBlockHandler` interface and `BaseBlockHandler` class
- [x] Implement `BlockRegistry` with registration mechanism
- [x] Create `block.styles.ts` for common styles
- [x] Set up exports in `blocks/index.ts`
### Phase 2: Proof of Concept (Week 1) ✅
- [x] Migrate `divider` block as the simplest example
- [x] Update main component to use registry for divider blocks
- [x] Test that divider blocks work identically to before
- [x] Document any issues or adjustments needed
### Phase 3: Text Blocks Migration (Week 2) ✅
- [x] Migrate `paragraph` block
- [x] Migrate `heading` blocks (h1, h2, h3)
- [x] Migrate `quote` block
- [x] Migrate `code` block
- [x] Migrate `list` block
- [x] Extract common text formatting utilities
### Phase 4: Media Blocks Migration (Week 2)
- [ ] Migrate `image` block
- [ ] Migrate `youtube` block
- [ ] Migrate `attachment` block
- [ ] Extract file handling utilities to `utils/file.utils.ts`
- [ ] Extract media utilities to `utils/media.utils.ts`
### Phase 5: Content Blocks Migration (Week 3)
- [ ] Migrate `markdown` block
- [ ] Migrate `html` block
- [ ] Extract markdown utilities to `utils/markdown.utils.ts`
### Phase 6: Cleanup (Week 3)
- [ ] Remove old code from main component
- [ ] Optimize imports and exports
- [ ] Update documentation
- [ ] Performance testing
- [ ] Bundle size analysis
## Technical Considerations
### 1. Backwards Compatibility
- Ensure all existing functionality remains intact
- No breaking changes to the public API
- Maintain existing event handling patterns
### 2. Performance
- Monitor bundle size impact
- Consider dynamic imports for heavy block types:
```typescript
// Lazy load markdown handler
const { MarkdownBlockHandler } = await import('./content/markdown.block.js');
```
### 3. Type Safety
- All block handlers must implement `IBlockHandler`
- Proper typing for block metadata
- Type guards for block-specific operations
### 4. Testing Strategy
- Unit tests for each block handler
- Integration tests for the registry
- E2E tests to ensure no regressions
### 5. Style Management
- Common styles in `block.styles.ts`
- Block-specific styles returned by `getStyles()`
- Theme variables properly utilized
## Success Criteria
1. **Code Organization**: Each file under 300 lines
2. **Single Responsibility**: Each class handles one block type
3. **No Regressions**: All existing functionality works identically
4. **Improved Developer Experience**: Adding new blocks is straightforward
5. **Performance**: No significant increase in bundle size or runtime overhead
## Future Enhancements
1. **Plugin System**: Allow external block types to be registered
2. **Lazy Loading**: Dynamic imports for rarely used block types
3. **Block Templates**: Predefined configurations for common use cases
4. **Block Transformations**: Convert between compatible block types
5. **Custom Block API**: Allow users to define their own block types
## Notes
- This refactoring should be done incrementally to minimize risk
- Each phase should be fully tested before moving to the next
- Regular code reviews to ensure consistency
- Documentation should be updated as we go
---
## 2025-?? - Dashboard Grid Drag & Drop Improvements
- [x] Review current drag/drop flow and outline live preview approach
- [x] Implement preview state with live displacement for drag/resize
- [x] Run `pnpm build`; passes after syncing lifecycle overrides and media query listener handling
## 2025-?? - Dashboard Grid Overlap Fix
- [x] Capture regression in automated test for overlapping placeholder swap
- [x] Adjust swap handling in `resolveWidgetPlacement` to avoid overlaps
- [x] Verify via `pnpm run build` and focused test run
## 2025-?? - dees-editor Monaco Version Handling
- [x] Generate version module from installed monaco-editor via postinstall script
- [x] Move `dees-editor` implementation into dedicated subfolder and update exports
- [x] Use generated version constant for jsDelivr URLs and verify build
## 2025-?? - dees-stepper Modern Styling
- [x] Review existing dees-stepper layout and identify shadcn-inspired refinements
- [x] Update layout/CSS for dees-stepper to deliver modern cards & progress rail
- [x] Verify build after styling changes
## 2025-?? - dees-stepper Card Polish
- [x] Refresh step card styling while keeping outer layout intact
- [x] Extend demo to showcase eight consecutive steps
- [x] Run `pnpm run build`
## 2025-?? - dees-stepper File Organization
- [x] Move `dees-stepper` implementation into its own folder
- [x] Update exports/imports to match new location
- [x] Verify build with `pnpm run build`
## 2025-?? - Element Subfolder Entry Points
- [x] Add `index.ts` entry points to all subfolders under `ts_web/elements`
- [x] Adjust exports/imports to use new entry files
- [x] Run `pnpm run build`
## 2025-?? - dees-input-wysiwyg Folder Refactor
- [x] Move `dees-input-wysiwyg` implementation into dedicated subfolder
- [x] Consolidate related helper modules and update imports/exports
- [x] Verify build with `pnpm run build`
## 2025-?? - dees-stepper Demo Extraction
- [x] Move inline demo definition into dedicated `dees-stepper.demo.ts`
- [x] Wire component to import demo from new file
- [x] Run `pnpm run build`
## 2025-?? - WYSIWYG Output Formats Demo Review
- [x] Inspect "Output Formats" section in `dees-input-wysiwyg.demo.ts`
- [x] Ensure markdown/HTML outputs render as intended
- [x] Document findings and add preview controls
## 2025-?? - dees-toast Demo Fix
- [x] Ensure demo function returns TemplateResult instead of Promise
- [x] Verify toast demo renders correctly
- [x] Run `pnpm run build`
## 2025-?? - Documentation Consolidation
- [x] Review existing contributor guidance in `codex.md` and `CLAUDE.md`
- [x] Cross-check commands and workflows against `package.json` and repo scripts
- [x] Draft merged outline for `readme.info.md`
- [x] Author `readme.info.md` with consolidated, accurate content
- [x] Remove superseded files (`codex.md`, `CLAUDE.md`)
- [x] Search and update any references to the old documents