Enhancement of quill table module
[email protected] table module
- complete UI operation process
- insert/delete row/column/table; merge/split cells
- support all origin quill formats
- control cells width/height/border/background color
- 100 percent table width or fixed pixel width
- line break in cells
- redo and undo
- support whole table align left/center/right
-
<caption><th><thead><tfoot>support
npm install quill-table-upthe registe module name is used internal. so if you want to change it, place use the function
updateTableConstants
import Quill from 'quill';
import TableUp, { defaultCustomSelect, TableAlign, TableMenuContextmenu, TableResizeBox, TableResizeScale, TableSelection, TableVirtualScrollbar } from 'quill-table-up';
import 'quill/dist/quill.snow.css';
import 'quill-table-up/index.css';
// If using the default customSelect option. You need to import this css
import 'quill-table-up/table-creator.css';
Quill.register({ [`modules/${TableUp.moduleName}`]: TableUp }, true);
// or
// Quill.register({ 'modules/table-up': TableUp }, true);
const quill = new Quill('#editor', {
// ...
modules: {
// ...
toolbar: [
// ...
[ // use picker to enable the customSelect option
{ [TableUp.toolName]: [] }
],
],
[TableUp.moduleName]: {
customSelect: defaultCustomSelect,
modules: [
{ module: TableVirtualScrollbar },
{ module: TableAlign },
{ module: TableResizeLine },
{ module: TableResizeScale },
{ module: TableSelection },
{ module: TableMenuContextmenu, },
],
},
},
});Full options usage see demo
| Attribute | Description | Type | Default |
|---|---|---|---|
| full | if set true. width max will be 100% |
boolean |
false |
| fullSwitch | enable to choose insert a full width table | boolean |
true |
| texts | the text used to create the table | TableTextOptions |
defaultTexts |
| customSelect | display a custom select to custom row and column number add a table. module provides default selector defaultCustomSelect |
(tableModule: TableUp, picker: Picker) => Promise<HTMLElement> | HTMLElement |
- |
| customBtn | display a custom button to custom row and column number add a table. it only when use defaultCustomSelect will effect |
boolean |
false |
| icon | picker svg icon string. it will set with innerHTML |
string |
origin table icon |
| autoMergeCell | empty row or column will auto merge to one | boolean |
true |
| modules | the module plugin to help user control about table operate. see Export Internal Module |
[] |
{ module: Contstructor, options: any }[] |
I'm not suggest to use
TableVirtualScrollbarandTableResizeLineat same time, because it have a little conflict when user hover on it. Just like the first editor in demo
If you doesn't use
TableVirtualScrollbar, you may need to set css.ql-editor .ql-table-wrapper { scrollbar-width: auto; }to display the browser origin scrollbar.
default value
const defaultTexts = {
fullCheckboxText: 'Insert full width table',
customBtnText: 'Custom',
confirmText: 'Confirm',
cancelText: 'Cancel',
rowText: 'Row',
colText: 'Column',
notPositiveNumberError: 'Please enter a positive integer',
custom: 'Custom',
clear: 'Clear',
transparent: 'Transparent',
perWidthInsufficient: 'The percentage width is insufficient. To complete the operation, the table needs to be converted to a fixed width. Do you want to continue?',
InsertTop: 'Insert a row above',
InsertRight: 'Insert a column right',
InsertBottom: 'Insert a row below',
InsertLeft: 'Insert a column Left',
MergeCell: 'Merge Cell',
SplitCell: 'Split Cell',
DeleteRow: 'Delete Row',
DeleteColumn: 'Delete Column',
DeleteTable: 'Delete table',
BackgroundColor: 'Set background color',
BorderColor: 'Set border color',
SwitchWidth: 'Switch table width',
InsertCaption: 'Insert table caption',
ToggleTdBetweenTh: 'Toggle td between th',
};The table cell selection handler
| Attribute | Description | Type | Default |
|---|---|---|---|
| selectColor | selector border color | string |
#0589f3 |
The table cell resize handler
| Attribute | Description | Type | Default |
|---|---|---|---|
| size | bounding box size(px) | number |
12 |
| draggable | allow drag bounding box head to sort content cell | boolean |
true |
The table operate menu
This module needs to be used together with
TableSelection
| Attribute | Description | Type | Default |
|---|---|---|---|
| tipText | when tableMenuClass set TableUp.TableMenuSelect, display tip text when hover icon. when tableMenuClass set TableUp.TableMenuContextmenu, display tip text after icon |
boolean |
true |
| localstorageKey | used color save localstorage key | string |
__table-bg-used-color |
| tools | menu items | Tool[] |
defaultTools |
| defaultColorMap | color map | string[][] |
in source code |
types and default value
interface ToolOption {
name: string;
icon: string | ((tableModule: TableUp) => HTMLElement);
tip?: string;
isColorChoose?: boolean; // trigger a color picker first. need set `key`
key?: string; // the style name to set on td.
handle: (this: TableMenu, tableModule: TableUp, selectedTds: TableCellInnerFormat[], e: Event | string) => void;
}
interface ToolOptionBreak {
name: 'break';
}
type Tool = ToolOption | ToolOptionBreak;
const tableMenuTools: Record<string, Tool> = {
Break: {
name: 'break',
},
CopyCell: {
name: 'CopyCell',
tip: 'Copy cell',
icon: Copy,
handle: (tableModule, selectedTds) => {},
},
CutCell: {
name: 'CutCell',
tip: 'Cut cell',
icon: Cut,
handle: (tableModule, selectedTds) => {},
},
InsertTop: {
name: 'InsertTop',
icon: InsertTop,
tip: 'Insert row above',
handle: (tableModule, selectedTds) => {},
},
InsertRight: {
name: 'InsertRight',
icon: InsertRight,
tip: 'Insert column right',
handle: (tableModule, selectedTds) => {},
},
InsertBottom: {
name: 'InsertBottom',
icon: InsertBottom,
tip: 'Insert row below',
handle: (tableModule, selectedTds) => {},
},
InsertLeft: {
name: 'InsertLeft',
icon: InsertLeft,
tip: 'Insert column Left',
handle: (tableModule, selectedTds) => {},
},
MergeCell: {
name: 'MergeCell',
icon: MergeCell,
tip: 'Merge Cell',
handle: (tableModule, selectedTds) => {},
},
SplitCell: {
name: 'SplitCell',
icon: SplitCell,
tip: 'Split Cell',
handle: (tableModule, selectedTds) => {},
},
DeleteRow: {
name: 'DeleteRow',
icon: RemoveRow,
tip: 'Delete Row',
handle: (tableModule, selectedTds) => {},
},
DeleteColumn: {
name: 'DeleteColumn',
icon: RemoveColumn,
tip: 'Delete Column',
handle: (tableModule, selectedTds) => {},
},
DeleteTable: {
name: 'DeleteTable',
icon: RemoveTable,
tip: 'Delete table',
handle: (tableModule, selectedTds) => {},
},
BackgroundColor: {
name: 'BackgroundColor',
icon: Background,
isColorChoose: true,
tip: 'Set background color',
key: 'background-color',
handle: (tableModule, selectedTds, color) => {},
},
BorderColor: {
name: 'BorderColor',
icon: Border,
isColorChoose: true,
tip: 'Set border color',
key: 'border-color',
handle: (tableModule, selectedTds, color) => {},
},
SwitchWidth: {
name: 'SwitchWidth',
icon: AutoFull,
tip: 'Switch table width',
handle: (tableModule) => {},
},
InsertCaption: {
name: 'InsertCaption',
icon: TableHead,
tip: 'Insert table caption',
handle: (tableModule) => {},
},
ToggleTdBetweenTh: {
name: 'ToggleTdBetweenTh',
icon: ConvertCell,
tip: 'Toggle td between th',
handle: (tableModule, selectedTds) => {},
},
ConvertTothead: {
name: 'ConvertTothead',
icon: ConvertCell,
tip: 'Convert to thead',
handle: (tableModule, selectedTds) => {},
},
ConvertTotfoot: {
name: 'ConvertTotfoot',
icon: ConvertCell,
tip: 'Convert to tfoot',
handle: (tableModule, selectedTds) => {},
},
};
const defaultTools = [
tableMenuTools.InsertTop,
tableMenuTools.InsertRight,
tableMenuTools.InsertBottom,
tableMenuTools.InsertLeft,
tableMenuTools.Break,
tableMenuTools.MergeCell,
tableMenuTools.SplitCell,
tableMenuTools.Break,
tableMenuTools.DeleteRow,
tableMenuTools.DeleteColumn,
tableMenuTools.DeleteTable,
tableMenuTools.Break,
tableMenuTools.BackgroundColor,
tableMenuTools.BorderColor,
];Equal scale table cell handler
| Attribute | Description | Type | Default |
|---|---|---|---|
| blockSize | resize handle block size | number |
12 |
| offset | resize handle offset to table | number |
6 |
The table alignment tool
The table virtual scrollbar
In version 3.x, only changed the way options are passed in, the relevant additional modules are used in the modules option. e.g.
new Quill('#editor', {
theme: 'snow',
modules: {
toolbar: toolbarConfig,
[TableUp.moduleName]: {
customSelect: defaultCustomSelect,
customBtn: true,
modules: [
{ module: TableVirtualScrollbar },
{ module: TableAlign },
{ module: TableResizeLine },
{ module: TableResizeScale, options: { blockSize: 12, }, },
{ module: TableSelection, options: { selectColor: '#00ff8b4d', }, },
{
module: TableMenuContextmenu,
options: {
localstorageKey: 'used-color',
tipText: true,
tools: [],
defaultColorMap: [],
},
},
],
},
},
});You can use quill.getModule(TableUp.moduleName).getModule(TableSelection.moduleName) to get the TableSelection instance in the TableUp
- add new attributes
tagandwrap-tagintable-up-cell-innerwhich to represent parent label types
If you need to rewrite extends from quill Block or Scroll blot. you need to use Quill.import() after TableUp registed. beacuse module internal rewrite some functions, but those change only effect formats about table.
Header, List', Blockquote and CodeBlock have been overrides. If you need to rewrite them, you need to rewrite them before TableUp registed.
Please read source code to know those change.
import { BlockOverride, ScrollOverride, } from 'quill-table-up';
class ScrollBlot extends ScrollOverride {
// ...
}If it's not necessary, you should import constants variable from quill-table-up directly but not edit it.
import { blotName, tableUpEvent, tableUpInternal, tableUpSize, } from 'quill-table-up';You can change internal constants variable by importing updateTableConstants from quill-table-up and call it before TableUp registed.
It helps to migrate from other table modules with the same data structure.
If you change the TableWrapperFormat blot name, you also need to add new css style to make toolbar icon have correct style.
/* change 'table-up' to your new blot name */
.ql-toolbar .ql-picker:not(.ql-color-picker):not(.ql-icon-picker).ql-table-up {
width: 28px;
}
.ql-toolbar .ql-picker:not(.ql-color-picker):not(.ql-icon-picker).ql-table-up .ql-picker-label {
padding: 2px 4px;
}
.ql-toolbar .ql-picker:not(.ql-color-picker):not(.ql-icon-picker).ql-table-up .ql-picker-label svg {
position: static;
margin-top: 0;
}