Skip to content

Customisation

Community

Once you’ve chosen which editor a column uses (see Edit Components and the provided editors), ZenGrid lets you customise how that editor is presented and when it opens or commits — no custom component required:

  • Popup editors (Community). By default an editor is clamped to the cell box. Set editorPopup: true on the column to float it instead: it sizes to its own content and sits 'over' or 'under' the cell (editorPopupPosition) — ideal for editors bigger than the cell (pickers, panels, dialogs).
  • Lifecycle veto hooks (Community). A CellEditor can implement isCancelBeforeStart() to refuse opening for an ineligible cell, and isCancelAfterEnd() to reject its own final value on commit (the edit reverts as if Escape was pressed).
  • Popup dialog wrapper (Enterprise). popupEditor() wraps any editor in a polished dialog — a title header and a Save/Cancel footer, positioned over or under the cell — in one call.

A column opts into popup rendering declaratively:

const grid = new Zengrid(mount, {
columns: [
{ field: 'color', header: 'Color', editable: true,
editor: SwatchPicker, // any editor — built-in or custom
editorPopup: true, // float instead of clamping to the cell
editorPopupPosition: 'over' }, // 'over' (default) | 'under'
],
});
Option Type Purpose
editorPopup boolean Render the editor as a floating popup sized to its content instead of clamped to the cell.
editorPopupPosition 'over' | 'under' Where the popup sits relative to the cell (default 'over'). The grid flips it above the cell when 'under' would overflow the viewport.

An editor can also opt in itself by returning true from CellEditor.isPopup() (and a default side from getPopupPosition()); the declarative editorPopup flag wins when both are set.

Two optional CellEditor methods let the editor gate its own lifecycle:

Hook Called Return true to…
isCancelBeforeStart() Once, right after init Abort opening — the editor is destroyed and no edit:start fires.
isCancelAfterEnd() On commit, after validation Discard the edit and revert the cell (like Escape).

The Color column uses a custom swatch picker rendered as a popup (editorPopup: true) — it floats over the cell and sizes to its own content instead of being cropped. Double-click a Color cell and pick a swatch. Try removing editorPopup to see it clamp to the cell.

Enterprise

popupEditor() returns a ColumnDef that wraps any editor — a built-in class, a custom component, or a factory — in a polished popup dialog: an optional title header and a Save / Cancel footer, floated over or under the cell. You keep your editor; the dialog chrome, positioning, and commit/cancel wiring come for free.

import { popupEditor } from '@zengrid/enterprise';
const grid = new Zengrid(mount, {
columns: [
popupEditor({ field: 'notes', header: 'Notes', title: 'Edit notes',
width: 340, position: 'under', editor: NotesEditor }),
],
});

Everything on a normal ColumnDef (field/header/width/…) plus:

Option Type Purpose
editor CellEditor | class | () => CellEditor The editor to wrap in the dialog.
title string Heading shown at the top of the popup.
position 'over' | 'under' Where the dialog sits relative to the cell (default 'over').
width number Fixed popup width in px; omit to size to the editor’s content.
buttons boolean Show the Save/Cancel footer (default true).
saveLabel / cancelLabel string Footer button labels (default Save / Cancel).

The Save button commits the inner editor’s value (honouring its isValid() under editing.invalidEditMode); Cancel reverts.

popupEditor() wraps a plain textarea notes editor in a titled dialog with a Save/Cancel footer, 340px wide, floated over the cell. Double-click a Notes cell: type (Enter adds a newline), then click Save to commit or Cancel to revert.

  • Async Values — populate an editor from an asynchronous source.
  • ValidationinvalidEditMode and how a failing value is handled.