Overview
The Table plugin provides a complete solution for creating and managing tables. It includes features for cell selection, merging, splitting, and formatting tabular data.
Installation
npm install @yoopta/table
Basic Usage
import { Table } from '@yoopta/table' ;
const plugins = [
Table ,
// ... other plugins
];
< YooptaEditor
editor = { editor }
plugins = { plugins }
/>
Features
Flexible Tables : Create tables of any size
Cell Operations : Merge, split, insert, delete cells
Header Rows/Columns : Mark rows and columns as headers
Cell Alignment : Horizontal and vertical alignment
Column Resizing : Adjustable column widths
Cell Selection : Select multiple cells
Keyboard Shortcuts : Type table, ||, or 3x3 to insert
Structure
The Table plugin consists of nested elements:
table (props: headerRow, headerColumn, columnWidths)
└── table-row (multiple)
└── table-data-cell (props: align, verticalAlign, colSpan, rowSpan, asHeader)
Configuration
import { Table } from '@yoopta/table' ;
const plugins = [
Table ,
];
Options
Description shown in menus
shortcuts
string[]
default: "['table', '||', '3x3']"
Keyboard shortcuts to trigger the plugin
Element Props
table
Whether the first row should be treated as a header
Whether the first column should be treated as a header
columnWidths
number[]
default: "[200, 150, 250]"
Array of column widths in pixels
table-data-cell
Whether this cell should be rendered as a header (th)
align
'left' | 'center' | 'right'
default: "left"
Horizontal text alignment
verticalAlign
'top' | 'middle' | 'bottom'
default: "top"
Vertical text alignment
Number of columns this cell spans
Number of rows this cell spans
Commands
buildTableElements
Creates the initial table structure.
import { TableCommands } from '@yoopta/table' ;
TableCommands . buildTableElements ( editor , { rows: 3 , columns: 3 });
Number of columns to create
insertRow
Insert a new row at a specific position.
TableCommands . insertRow ( editor , blockId , {
at: rowIndex ,
position: 'after' , // or 'before'
});
insertColumn
Insert a new column at a specific position.
TableCommands . insertColumn ( editor , blockId , {
at: columnIndex ,
position: 'after' , // or 'before'
});
deleteRow
Delete a specific row.
TableCommands . deleteRow ( editor , blockId , rowIndex );
deleteColumn
Delete a specific column.
TableCommands . deleteColumn ( editor , blockId , columnIndex );
mergeCells
Merge selected cells into one.
TableCommands . mergeCells ( editor , blockId , {
startRow: 0 ,
startCol: 0 ,
endRow: 1 ,
endCol: 1 ,
});
splitCell
Split a merged cell.
TableCommands . splitCell ( editor , blockId , {
row: rowIndex ,
col: columnIndex ,
});
updateCellProps
Update cell properties.
TableCommands . updateCellProps ( editor , blockId , {
row: rowIndex ,
col: columnIndex ,
props: {
align: 'center' ,
backgroundColor: '#f3f4f6' ,
},
});
clearContents
Clear contents of selected cells.
import { clearContents } from '@yoopta/table' ;
clearContents ( editor , blockId , selectedCells );
Initial Structure
When created, the plugin initializes with a 3x3 table:
{
table : {
headerRow : false ,
headerColumn : false ,
columnWidths : [ 200 , 150 , 250 ],
},
rows : [
// 3 rows
{
cells: [
// 3 cells per row
{
align: 'left' ,
verticalAlign: 'top' ,
colSpan: 1 ,
rowSpan: 1 ,
},
],
},
],
}
Custom Rendering
import { Table } from '@yoopta/table' ;
const CustomTable = Table . extend ({
elements: {
table: {
render : ( props ) => {
const { headerRow , headerColumn , columnWidths } = props . element . props ;
return (
< div className = "table-wrapper" >
< table
className = "custom-table"
data-header-row = { headerRow }
data-header-col = { headerColumn }
{ ... props . attributes }
>
< tbody > { props . children } </ tbody >
</ table >
</ div >
);
},
},
'table-row' : {
render : ( props ) => (
< tr className = "table-row" { ... props . attributes } >
{ props . children }
</ tr >
),
},
'table-data-cell' : {
render : ( props ) => {
const {
asHeader ,
align ,
verticalAlign ,
colSpan ,
rowSpan ,
backgroundColor ,
} = props . element . props ;
const CellTag = asHeader ? 'th' : 'td' ;
return (
< CellTag
colSpan = { colSpan }
rowSpan = { rowSpan }
align = { align }
valign = { verticalAlign }
style = { { backgroundColor } }
{ ... props . attributes }
>
{ props . children }
</ CellTag >
);
},
},
},
});
Parsers
HTML Deserialization
The plugin automatically deserializes <table> tags:
< table >
< tbody >
< tr >
< td > Cell 1 </ td >
< td > Cell 2 </ td >
</ tr >
< tr >
< td > Cell 3 </ td >
< td > Cell 4 </ td >
</ tr >
</ tbody >
</ table >
HTML Serialization
< table >
< tbody >
< tr >
< td align = "left" valign = "top" > Cell content </ td >
</ tr >
</ tbody >
</ table >
Markdown Serialization
| Column 1 | Column 2 | Column 3 |
|----------|----------|----------|
| Cell 1 | Cell 2 | Cell 3 |
| Cell 4 | Cell 5 | Cell 6 |
Keyboard Behavior
The Table plugin has special keyboard handling:
Tab : Move to next cell
Shift+Tab : Move to previous cell
Arrow Keys : Navigate between cells
Enter : Move to cell below
Backspace : Delete cell content (not the cell)
Cell Selection
The plugin supports multi-cell selection:
// Access selected cells
import {
TABLE_CELLS_IN_SELECTION ,
TABLE_SLATE_TO_SELECTION_SET ,
} from '@yoopta/table' ;
const selectedCells = TABLE_CELLS_IN_SELECTION . get ( slate );
const selectionSet = TABLE_SLATE_TO_SELECTION_SET . get ( slate );
Use Cases
Data Tables Display structured data and statistics
Pricing Tables Compare pricing plans and features
Schedules Create timetables and schedules
Comparison Tables Compare products, services, or features
Best Practices
Avoid overly complex tables with too many merged cells
Consider mobile layouts for wide tables
Use consistent alignment patterns within columns
Provide table captions or descriptions for context
Styling Examples
Basic CSS
.table-wrapper {
overflow-x : auto ;
}
.custom-table {
width : 100 % ;
border-collapse : collapse ;
}
.custom-table th ,
.custom-table td {
padding : 0.75 rem ;
border : 1 px solid #e5e7eb ;
}
.custom-table th {
background : #f9fafb ;
font-weight : 600 ;
text-align : left ;
}
.custom-table tr :hover td {
background : #f9fafb ;
}
Striped Rows
.custom-table tbody tr :nth-child ( even ) {
background : #f9fafb ;
}
Bordered Style
.custom-table {
border : 2 px solid #e5e7eb ;
}
.custom-table th {
border-bottom : 2 px solid #e5e7eb ;
}
Advanced Patterns
With Cell Selection Highlight
const SelectableTable = Table . extend ({
elements: {
'table-data-cell' : {
render : ( props ) => {
const isSelected = checkIfSelected ( props . element );
return (
< td
className = { isSelected ? 'selected' : '' }
{ ... props . attributes }
>
{ props . children }
</ td >
);
},
},
},
});
With Sortable Columns
const SortableTable = Table . extend ({
elements: {
'table-data-cell' : {
render : ( props ) => {
if ( props . element . props . asHeader ) {
return (
< th { ... props . attributes } >
< button onClick = { () => sortColumn ( props . element ) } >
{ props . children }
< SortIcon />
</ button >
</ th >
);
}
return < td { ... props . attributes } > { props . children } </ td > ;
},
},
},
});