Features
- Enables creation and editing of tables with advanced behaviors.
- Arrow navigation (up/down).
- Grid cell selection.
- Cell selection expansion with
Shift+Arrow
keys. - Copying and pasting cells.
- Row drag-and-drop reordering
- Row selection via drag handle
Kit Usage
Installation
The fastest way to add table functionality is with the TableKit
, which includes pre-configured TablePlugin
, TableRowPlugin
, TableCellPlugin
, and TableCellHeaderPlugin
with their Plate UI components.
TableElement
: Renders table containers.TableRowElement
: Renders table rows.TableCellElement
: Renders table cells.TableCellHeaderElement
: Renders table header cells.
Add Kit
Add the kit to your plugins:
import { createPlateEditor } from 'platejs/react';
import { TableKit } from '@/components/editor/plugins/table-kit';
const editor = createPlateEditor({
plugins: [
// ...otherPlugins,
...TableKit,
],
});
Manual Usage
Installation
pnpm add @platejs/table
Add Plugin
Include TablePlugin
in your Plate plugins array when creating the editor.
import { TablePlugin } from '@platejs/table/react';
import { createPlateEditor } from 'platejs/react';
const editor = createPlateEditor({
plugins: [
// ...otherPlugins,
TablePlugin,
],
});
Configure Plugins
Configure the table plugins with custom components and options.
import {
TableCellHeaderPlugin,
TableCellPlugin,
TablePlugin,
TableRowPlugin,
} from '@platejs/table/react';
import { createPlateEditor } from 'platejs/react';
import {
TableCellElement,
TableCellHeaderElement,
TableElement,
TableRowElement,
} from '@/components/ui/table-node';
const editor = createPlateEditor({
plugins: [
// ...otherPlugins,
TablePlugin.configure({
node: { component: TableElement },
options: {
initialTableWidth: 600,
disableMerge: false,
minColumnWidth: 48,
},
}),
TableRowPlugin.withComponent(TableRowElement),
TableCellPlugin.withComponent(TableCellElement),
TableCellHeaderPlugin.withComponent(TableCellHeaderElement),
],
});
node.component
: AssignsTableElement
to render table containers.withComponent
: Assigns components for table rows, cells, and header cells.options.initialTableWidth
: Sets the initial width for new tables.options.disableMerge
: Disables cell merging functionality.options.minColumnWidth
: Sets the minimum width for table columns.
Add Toolbar Button
You can add TableToolbarButton
to your Toolbar to insert tables.
Insert Toolbar Button
You can add this item to the Insert Toolbar Button to insert table elements:
{
icon: <TableIcon />,
label: 'Table',
value: KEYS.table,
}
Disable Merging Example
Plugins
TablePlugin
disableMerge optional boolean
Disables the merging behavior of cells.
disableExpandOnInsert optional boolean
Disables the expansion of the table when inserting cells.
disableMarginLeft optional boolean
Disables the left resizer of the first column in the table.
enableUnsetSingleColSize optional boolean
Disables unsetting the width of the first column when the table has only one column. Set this to
true
if you want to resize the table width when there's only one column. Leave itfalse
if you have a full-width table.initialTableWidth optional number
If defined, a normalizer will set each undefined table
colSizes
to this value divided by the number of columns. Note that merged cells are not yet supported.minColumnWidth optional number
The minimum width of a column in the table.
- Default:
48
- Default:
TableRowPlugin
Plugin for table rows.
TableCellPlugin
Plugin for table cells.
TableCellHeaderPlugin
Plugin for table header cells.
API
editor.api.create.table
editor.api.create.tableCell
Creates an empty cell node for a table.
header optional boolean
Specify
true
if the cell is a header cell.row optional TTableRowElement
The row element. If
header
is not specified, it will determine if the cell is a header cell based on the row's children.children optional Descendant[]
The children of the new cell node.
- Default:
[editor.api.create.block()]
- Default:
editor.api.create.tableRow
Creates an empty row node with the specified number of columns.
editor.api.table.getCellBorders
Gets the border styles for a table cell, handling special cases for first row and first column cells.
editor.api.table.getCellChildren
Gets the children of a table cell.
editor.api.table.getCellSize
Gets the width and minimum height of a table cell, taking into account column spans and column sizes.
editor.api.table.getColSpan
Gets the column span of a table cell.
editor.api.table.getRowSpan
Gets the row span of a table cell.
getCellType
Get the plugin cell types.
getNextTableCell
Gets the next cell in the table.
getPreviousTableCell
Gets the previous cell in the table.
getTableColumnCount
Gets the number of columns in a table.
getTableColumnIndex
Gets the column index of a cell node within a table.
getTableEntries
Gets the table, row, and cell node entries based on the current selection or a specified location.
getTableGridAbove
Gets the sub table above the anchor and focus positions based on the specified format (tables or cells).
getTableGridByRange
Gets the sub table between two cell paths within a given range.
getTableRowIndex
Gets the row index of a cell node within a table.
getTopTableCell
Gets the cell above the current cell in the table.
isTableBorderHidden
Checks if the border of a table cell or the table itself is hidden based on the specified border direction.
Transforms
tf.insert.table
Inserts a table at the current selection if there is no existing table in the editor. Selects the start of the inserted table.
tf.insert.tableColumn
Inserts a column into the table at the current selection or a specified cell path.
at optional Path
The exact path of the cell to insert the column at. This overrules the
fromCell
option.before optional boolean
If true, insert the column before the current column instead of after.
fromCell optional Path
The path of the cell to insert the column from.
header optional boolean
If true, the inserted column will be treated as a header column.
select optional boolean
If true, the inserted column will be selected after insertion.
tf.insert.tableRow
Inserts a row into the table at the current selection or a specified row path.
at optional Path
Exact path of the row to insert the column at. Pass the table path to insert at the end of the table. Will overrule
fromRow
.before optional boolean
If true, insert the row before the current row instead of after.
fromRow optional Path
The path of the row to insert the new row from.
header optional boolean
If true, the inserted row will be treated as a header row.
select optional boolean
If true, the inserted row will be selected after insertion.
tf.remove.tableColumn
Deletes the column containing the selected cell in a table.
tf.remove.tableRow
Deletes the row containing the selected cell in a table.
tf.remove.table
Deletes the entire table.
tf.table.merge
Merges multiple selected cells into one.
The merged cell will:
- Have a colSpan equal to the number of columns spanned by the selected cells
- Have a rowSpan equal to the number of rows spanned by the selected cells
- Contain the combined content of all merged cells (non-empty cells only)
- Inherit the header status from the first selected cell
tf.table.split
Splits a merged cell back into individual cells.
The split operation will:
- Create new cells for each column and row that was spanned
- Copy the header status from the original merged cell
- Place the original cell's content in the first cell
- Create empty cells for the remaining spaces
tf.moveSelectionFromCell
Moves the selection by cell unit within a table.
at optional Location
The location to move the selection from.
reverse optional boolean
Set to
true
to move the selection to the cell above,false
to move the selection to the cell below.edge optional 'top' | 'left' | 'right' | 'bottom'
The edge to expand the cell selection to.
fromOneCell optional boolean
Set to
true
to move the selection from only one selected cell.
tf.setBorderSize
Sets the size of the specified border in a table cell.
tf.setTableColSize
Sets the width of a specific column in a table.
tf.setTableMarginLeft
Sets the margin left of a table.
tf.setTableRowSize
Sets the size (height) of a table row.
Plugin Extensions
onKeyDownTable
Handles the keyboard events for tables.
withDeleteTable
Prevents the deletion of cells in tables.
withGetFragmentTable
If the selection is inside a table, it retrieves the subtable above the selection as the fragment. This is useful when copying and pasting table cells.
withInsertFragmentTable
If inserting a table:
- If the block above the anchor of the selection is a table, replace each cell above with the inserted table until out of bounds. Select the inserted cells.
- If there is no table above the anchor, check if the selection is inside a table. If it is, find the cell at the anchor position and replace its children with the inserted fragment.
withInsertTextTable
If the selection is expanded:
- Check if the selection is inside a table. If it is, collapse the selection to the focus edge.
withNormalizeTable
Normalize table structure by performing the following actions:
- Wrap cell children in a paragraph if they are texts.
- Unwrap nodes that are not valid table elements.
- Set initial column sizes for tables if specified.
withSelectionTable
Handle table selections by performing the following actions:
- Adjust the focus of the selection when the anchor is inside a table and the focus is in a block before or after the table.
- Adjust the focus of the selection when the focus is inside a table and the anchor is in a block before or after the table.
- Override the selection from a cell if the previous and new selections are in different cells.
withSetFragmentDataTable
Handle setting data to the clipboard when copying or cutting table data by performing the following actions:
- Check if a table entry and selected cell entries exist.
- Handle single-cell copy or cut operations by copying the cell content instead of the table structure.
- Create a table structure with the selected cells' content.
- Set the text, HTML, CSV, TSV, and Slate fragment data to the clipboard.
withTable
Enhance the editor instance with table-related functionality by applying the following higher-order functions:
withNormalizeTable
: Normalize table structure and content.withDeleteTable
: Prevent cell deletion within a table.withGetFragmentTable
: Handle getting the fragment data when copying or cutting table cells.withInsertFragmentTable
: Handle inserting table fragments.withInsertTextTable
: Handle inserting text within a table.withSelectionTable
: Handle adjusting the selection within a table.withSetFragmentDataTable
: Handle setting the fragment data when copying or cutting table data.
Hooks
useTableCellElementResizable
A hook that provides resizing functionality for table cell elements.
colIndex number
The index of the column.
colSpan number
The number of columns this cell spans.
rowIndex number
The index of the row.
step optional number
Resize by step instead of by pixel.
stepX optional number
Step size for horizontal resizing.
stepY optional number
Step size for vertical resizing.
- Default:
step
- Default:
bottomProps ResizeHandleProps
Props for the bottom resize handle, including resize direction and handler.
hiddenLeft boolean
Whether the left resize handle should be hidden. True if not the first column or margin left is disabled.
leftProps ResizeHandleProps
Props for the left resize handle, including resize direction and handler.
rightProps ResizeHandleProps
Props for the right resize handle, including resize direction, initial size, and handler.
useTableStore
The table store stores the state of the table plugin.
useIsCellSelected
Custom hook that checks if a table cell is selected.
useSelectedCells
A hook that manages the selection of cells in a table.
It keeps track of the currently selected cells and updates them based on changes in editor selection.
useTableBordersDropdownMenuContentState
A state hook for the table borders dropdown menu content.
hasBottomBorder boolean
Indicates whether the selected table cells have a bottom border.
hasTopBorder boolean
Indicates whether the selected table cells have a top border.
hasLeftBorder boolean
Indicates whether the selected table cells have a left border.
hasRightBorder boolean
Indicates whether the selected table cells have a right border.
hasNoBorders boolean
Indicates whether the selected table cells have no borders.
hasOuterBorders boolean
Indicates whether the selected table cells have outer borders (i.e., borders on all sides).
getOnSelectTableBorder function
A factory function that returns the
onSelectTableBorder
handler for a specific border type.- The
onSelectTableBorder
handler is responsible for setting the border style for the selected table cells.
- The
An object with the following properties:
useTableColSizes
Custom hook that returns the column sizes of a table with overrides applied. If the colCount
of the table updates to 1 and the enableUnsetSingleColSize
option is enabled, it unsets the colSizes
node.
useTableElement
A hook for a table element that handles cell selection and margin left calculations.
useTableCellElement
A hook for a table cell element that provides state and functionality for table cells.
borders BorderStylesDefault
The border styles of the table cell.
colIndex number
The ending column index (considering colSpan).
colSpan number
The number of columns this cell spans.
isSelectingCell boolean
Whether cells are currently being selected.
minHeight number | undefined
The minimum height of the cell.
rowIndex number
The ending row index (considering rowSpan).
selected boolean
Whether this cell is currently selected.
width number | string
The width of the cell.
useTableCellBorders
A hook that returns the border styles for a table cell.
useTableCellSize
A hook that returns the size (width and minimum height) of a table cell.
On This Page
FeaturesKit UsageInstallationAdd KitManual UsageInstallationAdd PluginConfigure PluginsAdd Toolbar ButtonInsert Toolbar ButtonDisable Merging ExamplePluginsTablePluginTableRowPluginTableCellPluginTableCellHeaderPluginAPIeditor.api.create.tableeditor.api.create.tableCelleditor.api.create.tableRoweditor.api.table.getCellBorderseditor.api.table.getCellChildreneditor.api.table.getCellSizeeditor.api.table.getColSpaneditor.api.table.getRowSpangetCellTypegetNextTableCellgetPreviousTableCellgetTableColumnCountgetTableColumnIndexgetTableEntriesgetTableGridAbovegetTableGridByRangegetTableRowIndexgetTopTableCellisTableBorderHiddenTransformstf.insert.table
tf.insert.tableColumn
tf.insert.tableRow
tf.remove.tableColumn
tf.remove.tableRow
tf.remove.table
tf.table.merge
tf.table.split
tf.moveSelectionFromCell
tf.setBorderSize
tf.setTableColSize
tf.setTableMarginLeft
tf.setTableRowSize
Plugin ExtensionsonKeyDownTable
withDeleteTable
withGetFragmentTable
withInsertFragmentTable
withInsertTextTable
withNormalizeTable
withSelectionTable
withSetFragmentDataTable
withTable
HooksuseTableCellElementResizable
useTableStore
useIsCellSelected
useSelectedCells
useTableBordersDropdownMenuContentState
useTableColSizes
useTableElement
useTableCellElement
useTableCellBorders
useTableCellSize