Text Editor - Table

Insert and manage tables with column, row, and cell options.

#Usage

import { TextEditor } from '@primeui/vue-texteditor';
<TextEditor.Root v-model="value">
    <TextEditor.Content />
    <TextEditor.TableControls>
        <TableControls />
    </TextEditor.TableControls>
</TextEditor.Root>

Use tables to insert a grid at the cursor and manage its columns, rows, and cells through four floating sub-parts. commands.table(rows?, cols?) inserts a table at the cursor. TextEditor.TableControls is the floating add-row / add-column surface pinned to the active table; its widget reads useTableControlsContext() for the anchor position and the addRow / addColumn commands.

Table support is composed from four sub-parts. Alongside <TextEditor.TableControls>, the action popovers <TextEditor.TableColumnMenu>, <TextEditor.TableRowMenu>, and <TextEditor.TableCellMenu> open from the column, row, and cell triggers. Each has a matching <TextEditor.*Submenu> sibling, and both halves share the same submenu controller through the parent menu's context, keeping the popovers in lock-step.

Column sizing is configured on <TextEditor.Root> via minTableColumnWidth (default 40) and defaultTableColumnWidth (default 120). Set them in pixels when the design needs denser or wider columns.

Interactive column resizing (drag handles) is disabled in right-to-left (RTL) documents — the underlying resize behavior drags from the wrong edge under RTL. Column widths set programmatically or imported from HTML still render correctly; only the drag-to-resize affordance is unavailable in RTL.

Header cells (<th>) carry a scope attribute (col by default, or row when imported) so screen readers can associate data cells with their headers.

<TextEditor.TableControls>
    <TableControls />
</TextEditor.TableControls>
<TextEditor.TableColumnMenu>
    <TableColumnOptions />
    <TextEditor.TableColumnSubmenu>
        <TableColumnOptionsSubmenu />
    </TextEditor.TableColumnSubmenu>
</TextEditor.TableColumnMenu>

#Table controls

useTableControlsContext() exposes position (a TableOverlayRect or null when no table is active) and commands: { addRow, addColumn }. The widget renders nothing while position is null.

<!-- TableControls.vue -->
<script setup lang="ts">
import { useTableControlsContext } from '@primeui/vue-texteditor';

const { position, commands } = useTableControlsContext();
</script>

<template>
    <div v-if="position" :style="{ left: position.left + 'px', top: position.top + 'px' }">
        <button @click="commands.addColumn">+ column</button>
        <button @click="commands.addRow">+ row</button>
    </div>
</template>

#Column, row, and cell menus

Widgets inside each menu read their own context. useTableColumnMenuContext() exposes colIndex, colCount, commands (typed TextEditorTableColumnCommands), the shared submenu controller, and dismiss(). useTableRowMenuContext() mirrors it with rowIndex / rowCount. useTableCellMenuContext() exposes isMultiCellSelected, isCellMerged, plus the same commands / submenu / dismiss triad.

<!-- TableColumnOptions.vue -->
<script setup lang="ts">
import { useTableColumnMenuContext } from '@primeui/vue-texteditor';

const { commands, submenu, dismiss } = useTableColumnMenuContext();

function run(action: () => void) {
    action();
    dismiss();
}
</script>

<template>
    <button role="menuitem" @click="run(commands.insertBefore)">Insert left</button>
    <button role="menuitem" @click="run(commands.insertAfter)">Insert right</button>
    <button role="menuitem" @click="submenu.open('align')">Align…</button>
    <button role="menuitem" @click="run(commands.delete)">Delete column</button>
</template>

The matching submenu widget reads the same context. TableColumnSubmenu calls useTableColumnMenuContext() and branches on submenu.active. The submenu controller is exposed on every menu context so the popovers stay in lock-step.

#Example

Loading Demo...

#API

commands.table(rows?, cols?) inserts a table, while useTableControlsContext(), useTableColumnMenuContext(), useTableRowMenuContext(), and useTableCellMenuContext() drive the floating controls and menus. Slots and Contexts lays out how the four outlets nest; API documents each context shape.