github.com/ngocphuongnb/tetua@v0.0.7-alpha/packages/editor/src/menu/items/table.ts (about) 1 import { TetuaEditor } from "../.."; 2 import { MenuItem } from "../menu-item"; 3 4 interface MenuItemConfig { 5 handler: string; 6 check: string; 7 text: string; 8 } 9 10 const menuItems: MenuItemConfig[] = [ 11 { 12 handler: 'addColumnBefore', 13 check: 'addColumnBefore', 14 text: 'Add column before', 15 }, 16 { 17 handler: 'addColumnAfter', 18 check: 'addColumnAfter', 19 text: 'Add column after', 20 }, 21 { 22 handler: 'deleteColumn', 23 check: 'deleteColumn', 24 text: 'Delete column', 25 }, 26 { 27 handler: 'addRowBefore', 28 check: 'addRowBefore', 29 text: 'Add row before', 30 }, 31 { 32 handler: 'addRowAfter', 33 check: 'addRowAfter', 34 text: 'Add row after', 35 }, 36 { 37 handler: 'deleteRow', 38 check: 'deleteRow', 39 text: 'Delete row', 40 }, 41 { 42 handler: 'deleteTable', 43 check: 'deleteTable', 44 text: 'Delete table', 45 }, 46 { 47 handler: 'mergeCells', 48 check: 'mergeCells', 49 text: 'Merge cells', 50 }, 51 { 52 handler: 'splitCell', 53 check: 'splitCell', 54 text: 'Split cell', 55 }, 56 { 57 handler: 'toggleHeaderColumn', 58 check: 'toggleHeaderColumn', 59 text: 'Toggle header column', 60 }, 61 { 62 handler: 'toggleHeaderRow', 63 check: 'toggleHeaderRow', 64 text: 'Toggle header row', 65 }, 66 { 67 handler: 'toggleHeaderCell', 68 check: 'toggleHeaderCell', 69 text: 'Toggle header cell', 70 }, 71 { 72 handler: 'mergeOrSplit', 73 check: 'mergeOrSplit', 74 text: 'Merge or split', 75 }, 76 // { 77 // handler: 'fixTables', 78 // check: 'fixTables', 79 // text: 'fixTables', 80 // }, 81 // { 82 // handler: 'goToNextCell', 83 // check: 'goToNextCell', 84 // text: 'goToNextCell', 85 // }, 86 // { 87 // handler: 'goToPreviousCell', 88 // check: 'goToPreviousCell', 89 // text: 'goToPreviousCell', 90 // }, 91 ]; 92 93 export class MenuTable extends MenuItem { 94 protected command = 'table'; 95 protected label = 'Table'; 96 protected isActive = false; 97 protected icon = `<svg viewBox="0 0 24 24"><path fill="currentColor" d="M5,4H19A2,2 0 0,1 21,6V18A2,2 0 0,1 19,20H5A2,2 0 0,1 3,18V6A2,2 0 0,1 5,4M5,8V12H11V8H5M13,8V12H19V8H13M5,14V18H11V14H5M13,14V18H19V14H13Z" /></svg>`; 98 // protected icon = `<svg fill="currentColor" viewBox="0 0 24 24"><g><path fill="none" d="M0 0h24v24H0z"></path><path d="M4 8h16V5H4v3zm10 11v-9h-4v9h4zm2 0h4v-9h-4v9zm-8 0v-9H4v9h4zM3 3h18a1 1 0 0 1 1 1v16a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1z"></path></g></svg>`; 99 100 constructor(editor: TetuaEditor) { 101 super(editor); 102 menuItems.forEach(item => { 103 const menuItem = this.createTableButton(item); 104 this.subMenuitems.push(menuItem); 105 }); 106 } 107 108 protected handler(e: MouseEvent) { 109 e.preventDefault(); 110 this.editor.tiptapEditor.chain().focus().insertTable({ rows: 3, cols: 3, withHeaderRow: true }).run(); 111 } 112 113 private createTableButton(config: MenuItemConfig) { 114 const can = this.editor.tiptapEditor.can() as any; 115 const container = document.createElement('div'); 116 const button = document.createElement('button'); 117 button.type = 'button'; 118 button.innerText = config.text 119 button.disabled = !can[config.check](); 120 button.dataset.check = config.check; 121 button.addEventListener('click', (e: MouseEvent) => { 122 const chain = this.editor.tiptapEditor.chain().focus() as any; 123 e.preventDefault(); 124 e.stopImmediatePropagation(); 125 chain[config.handler]().run(); 126 }); 127 container.append(button); 128 return container; 129 } 130 131 public update() { 132 super.update(); 133 this.subMenuitems.forEach((item: HTMLButtonElement) => { 134 const button = item.querySelector('button'); 135 const checkFn = button.dataset.check; 136 const can = this.editor.tiptapEditor.can() as any; 137 button.disabled = !can[checkFn](); 138 }); 139 } 140 }