feat(editor): Add wysiwyg editor
This commit is contained in:
69
ts_web/elements/wysiwyg/wysiwyg.shortcuts.ts
Normal file
69
ts_web/elements/wysiwyg/wysiwyg.shortcuts.ts
Normal file
@@ -0,0 +1,69 @@
|
||||
import { type IBlock, type IShortcutPattern, type ISlashMenuItem } from './wysiwyg.types.js';
|
||||
|
||||
export class WysiwygShortcuts {
|
||||
static readonly HEADING_PATTERNS: IShortcutPattern[] = [
|
||||
{ pattern: /^#[\s\u00A0]$/, type: 'heading-1' },
|
||||
{ pattern: /^##[\s\u00A0]$/, type: 'heading-2' },
|
||||
{ pattern: /^###[\s\u00A0]$/, type: 'heading-3' }
|
||||
];
|
||||
|
||||
static readonly LIST_PATTERNS: IShortcutPattern[] = [
|
||||
{ pattern: /^[*-][\s\u00A0]$/, type: 'bullet' },
|
||||
{ pattern: /^(\d+)\.[\s\u00A0]$/, type: 'ordered' },
|
||||
{ pattern: /^(\d+)\)[\s\u00A0]$/, type: 'ordered' }
|
||||
];
|
||||
|
||||
static readonly QUOTE_PATTERN = /^>[\s\u00A0]$/;
|
||||
static readonly CODE_PATTERN = /^```$/;
|
||||
static readonly DIVIDER_PATTERNS = ['---', '***', '___'];
|
||||
|
||||
static checkHeadingShortcut(content: string): { type: IBlock['type'] } | null {
|
||||
for (const { pattern, type } of this.HEADING_PATTERNS) {
|
||||
if (pattern.test(content)) {
|
||||
return { type: type as IBlock['type'] };
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static checkListShortcut(content: string): { type: 'list', listType: 'bullet' | 'ordered' } | null {
|
||||
for (const { pattern, type } of this.LIST_PATTERNS) {
|
||||
if (pattern.test(content)) {
|
||||
return { type: 'list', listType: type as 'bullet' | 'ordered' };
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static checkQuoteShortcut(content: string): boolean {
|
||||
return this.QUOTE_PATTERN.test(content);
|
||||
}
|
||||
|
||||
static checkCodeShortcut(content: string): boolean {
|
||||
return this.CODE_PATTERN.test(content);
|
||||
}
|
||||
|
||||
static checkDividerShortcut(content: string): boolean {
|
||||
return this.DIVIDER_PATTERNS.includes(content);
|
||||
}
|
||||
|
||||
static getSlashMenuItems(): ISlashMenuItem[] {
|
||||
return [
|
||||
{ type: 'paragraph', label: 'Paragraph', icon: '¶' },
|
||||
{ type: 'heading-1', label: 'Heading 1', icon: 'H₁' },
|
||||
{ type: 'heading-2', label: 'Heading 2', icon: 'H₂' },
|
||||
{ type: 'heading-3', label: 'Heading 3', icon: 'H₃' },
|
||||
{ type: 'quote', label: 'Quote', icon: '"' },
|
||||
{ type: 'code', label: 'Code', icon: '<>' },
|
||||
{ type: 'list', label: 'List', icon: '•' },
|
||||
{ type: 'divider', label: 'Divider', icon: '—' },
|
||||
];
|
||||
}
|
||||
|
||||
static generateBlockId(): string {
|
||||
return `block-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
|
||||
}
|
||||
}
|
||||
|
||||
// Re-export the type that is used in this module
|
||||
export type { ISlashMenuItem } from './wysiwyg.types.js';
|
Reference in New Issue
Block a user