Overview
The <web-grid> web component provides a high-performance data grid with editing, sorting, pagination, and Excel-like navigation.
Core Properties
| Property | Type | Default | Description |
|---|---|---|---|
items | T[] | [] | Array of data objects to display |
columns | Column<T>[] | [] | Column definitions (see Columns API) |
mode | 'read-only' | 'excel' | 'input-matrix' | 'excel' | Grid mode - sets sensible defaults for common use cases |
Display Properties
| Property | Type | Default | Description |
|---|---|---|---|
isStriped | boolean | true | Alternating row background colors |
isHoverable | boolean | true | Highlight rows on hover |
isRowNumbersVisible | boolean | false | Show row number column on the left |
isFilterable | boolean | false | Show filter inputs below column headers |
class | string | - | Custom CSS class(es) on host element |
style | string | - | Inline styles on host element |
Resizable Columns Properties
Excel-like column resizing by dragging header edges.
| Property | Type | Default | Description |
|---|---|---|---|
gridName | string | - | Unique name for localStorage persistence |
shouldPersistColumnWidths | boolean | false | Save column widths to localStorage |
oncolumnresize | function | - | Callback after column resize: (detail) => void |
Column Properties
| Property | Type | Description |
|---|---|---|
isResizable | boolean | Per-column opt-out (default: true) |
minWidth | string | Minimum width constraint (e.g., '50px') |
maxWidth | string | Maximum width constraint (e.g., '300px') |
Methods
| Method | Description |
|---|---|
setColumnWidth(field, width) | Set width of a specific column |
setColumnWidths(widths) | Set widths of multiple columns |
getColumnWidthsState() | Get current widths of all columns |
Reorderable Columns Properties
Drag column headers to rearrange columns.
| Property | Type | Default | Description |
|---|---|---|---|
isColumnReorderAllowed | boolean | false | Enable column drag-to-reorder |
shouldPersistColumnOrder | boolean | false | Save column order to localStorage (requires gridName) |
oncolumnreorder | function | - | Callback after reorder: (detail) => void |
Methods
| Method | Description |
|---|---|
setColumnOrder(order) | Set column order by field names array |
getColumnOrderState() | Get current column order |
moveColumn(field, toIndex) | Move a column to a specific index (internal - available on WebGrid, not directly on the web component element) |
Fill Handle Properties
Excel-like drag-to-fill for copying values to adjacent cells.
| Property | Type | Default | Description |
|---|---|---|---|
fillDirection | 'vertical' | 'all' | 'vertical' | Allowed fill directions (grid-level default) |
fillDragCallback | function | - | Callback before fill: return false to cancel |
Column Properties
| Property | Type | Description |
|---|---|---|
fillDirection | 'vertical' | 'all' | Per-column override for fill direction |
- Number columns: Only numeric values accepted
- Select/Combobox: Only values from options accepted
- Date columns: Only valid dates accepted
- Text/Autocomplete: Any value (use fillDragCallback for custom validation)
Freeze Panes Properties
Excel-like frozen columns that stay visible while scrolling horizontally.
| Property | Type | Default | Description |
|---|---|---|---|
isStickyRowNumbers | boolean | false | Make row number column sticky (frozen) |
freezeColumns | number | 0 | Number of columns to freeze from the left |
Column Properties
| Property | Type | Description |
|---|---|---|
isFrozen | boolean | Mark column as frozen (moves to left automatically) |
Sorting Properties
| Property | Type | Default | Description |
|---|---|---|---|
sortMode | 'none' | 'single' | 'multi' | 'none' | Sorting mode: disabled, single column, or multi-column with Ctrl+Click |
sort | SortState[] | [] | Current sort state (for initial/controlled sort) |
Pagination Properties
| Property | Type | Default | Description |
|---|---|---|---|
isPageable | boolean | false | Enable pagination |
pageSize | number | 10 | Items per page |
currentPage | number | 1 | Current page (1-based) |
totalItems | number | - | Total items (for server-side pagination) |
pageSizes | number[] | [10, 25, 50, 100] | Available page size options |
showPagination | boolean | 'auto' | true | When to show: true=always, false=never, 'auto'=hide when 1 page |
paginationPosition | string | 'bottom-center' | Position(s): "bottom-center", "top-right|bottom-right" |
paginationLayout | string | - | Element order: "pageSize|previous|pageInfo|next" |
paginationLabelsCallback | function | - | Callback to customize pagination text |
Editing Properties
| Property | Type | Default | Description |
|---|---|---|---|
isEditable | boolean | false | Enable editing on all columns with editors |
editTrigger | EditTrigger | 'dblclick' | How editing is triggered: 'click', 'dblclick', 'button', 'always', 'navigate' |
dropdownToggleVisibility | 'always' | 'on-focus' | 'always' | When to show dropdown toggle button |
shouldOpenDropdownOnEnter | boolean | false | Enter opens dropdown (true) or moves down (false) |
isCheckboxAlwaysEditable | boolean | false | Make checkboxes always interactive |
invalidCells | CellValidationState[] | [] | Currently invalid cells (for external/server-side validation) |
editStartSelection | 'selectAll' | 'cursorAtStart' | 'cursorAtEnd' | 'mousePosition' | 'mousePosition' | Cursor position when entering edit mode |
shouldShowDropdownOnFocus | boolean | true | Show dropdown when cell receives focus |
focusedRowIndex | number | null | null | Currently focused row index (read-only) |
validationTooltipCallback | function | - | Grid-level callback returning HTML for validation error tooltips |
Pagination Mode
| Property | Type | Default | Description |
|---|---|---|---|
paginationMode | 'client' | 'server' | 'client' | Client-side pagination (grid paginates items) or server-side (you manage pages via ondatarequest) |
Cell Selection Properties
| Property | Type | Default | Description |
|---|---|---|---|
cellSelectionMode | 'disabled' | 'click' | 'shift' | 'click' | Cell selection behavior |
shouldCopyWithHeaders | boolean | false | Include column headers when copying to clipboard |
Paste Properties
Configure how Ctrl+V paste operations work in editable grids.
| Property | Type | Default | Description |
|---|---|---|---|
pasteMode | 'skip-non-editable' | 'all-columns' | 'editable-only' | 'skip-non-editable' | How to handle non-editable cells during paste: skip over them, paste to all columns, or only paste to editable columns |
shouldValidateOnPaste | boolean | true | Run column validation (beforeCommitCallback) on pasted values |
createRowCallback | (pastedData, rowIndex) => T | - | Callback to create new rows when pasting beyond existing data. Receives the parsed paste data and target row index. |
Row Toolbar Properties
| Property | Type | Default | Description |
|---|---|---|---|
isRowToolbarVisible | boolean | false | Enable row toolbar |
rowToolbar | RowToolbarConfig[] | ['add', 'delete', 'duplicate'] | Toolbar items: strings ('add', 'delete', etc.) or custom objects |
toolbarTrigger | 'hover' | 'click' | 'button' | 'hover' | How to show toolbar |
toolbarPosition | 'auto' | 'left' | 'right' | 'top' | 'inline' | 'auto' | Toolbar position. 'inline' renders as fixed column |
toolbarVerticalAlign | 'top' | 'center' | 'bottom' | 'bottom' | Vertical alignment of toolbar rows |
toolbarHorizontalAlign | 'start' | 'center' | 'end' | 'cursor' | 'center' | Horizontal alignment (for top position) |
inlineActionsTitle | string | '' | Column header for inline toolbar mode |
toolbarFollowsCursor | boolean | false | Toolbar tracks mouse cursor horizontally |
cellToolbar | function | - | Callback returning cell-specific toolbar items |
toolbarColumn | string | number | - | Pin toolbar over a specific column |
cellToolbarOffset | number | string | 0.2 | Horizontal offset for cell-specific toolbar |
toolbarBtnMinWidth | string | - | Minimum width for toolbar buttons (e.g., '80px') |
Keyboard Shortcuts Properties
| Property | Type | Default | Description |
|---|---|---|---|
rowShortcuts | RowShortcut[] | [] | Keyboard shortcuts for row operations (work on focused or hovered row) |
isShortcutsHelpVisible | boolean | false | Show info icon with available shortcuts overlay |
shortcutsHelpPosition | 'top-right' | 'top-left' | 'top-right' | Position of shortcuts help icon |
shortcutsHelpContentCallback | () => string | - | Custom HTML content for shortcuts overlay |
Row Selection Properties
Multi-row selection via row number cells with keyboard shortcuts for batch operations.
| Property | Type | Default | Description |
|---|---|---|---|
selectedRows | number[] | [] | Array of selected row indices (read-only, sorted ascending) |
rangeShortcuts | RangeShortcut[] | [] | Keyboard shortcuts that operate on all selected rows |
Selection Methods
| Method | Description |
|---|---|
selectRow(index, mode) | Select a row. Mode: 'replace' (default), 'toggle', or 'range' |
selectRowRange(from, to) | Select all rows in a range (inclusive) |
clearSelection() | Clear all selected rows |
isRowSelected(index) | Check if a specific row is selected |
getSelectedRowsData() | Get the data objects for all selected rows |
Focus & Editing Methods
| Method | Description |
|---|---|
focusCell(rowIndex, colIndex) | Focus a specific cell |
startEditing(rowIndex, colIndex) | Start editing a specific cell |
openCustomEditor(rowIndex, colIndex) | Open custom editor for a cell |
Draft Management Methods
| Method | Description |
|---|---|
getRowDraft(rowIndex) | Get the draft (edited) state of a row |
hasRowDraft(rowIndex) | Check if row has unsaved edits |
discardRowDraft(rowIndex) | Discard edits for a specific row |
discardCellDraft(rowIndex, field) | Discard edits for a specific cell (internal - available on WebGrid, not directly on the web component element) |
getDraftRowIndices() | Get indices of all rows with unsaved edits |
discardAllDrafts() | Discard all unsaved edits |
Validation Methods
| Method | Description |
|---|---|
isCellInvalid(rowIndex, field) | Check if a cell has a validation error |
getCellValidationError(rowIndex, field) | Get the validation error message for a cell |
canEditCell(rowIndex, field) | Check if a cell is editable (not locked, column is editable). Second parameter is the field name string |
Row Identification Methods
| Method | Description |
|---|---|
getRowId(row) | Get the ID of a row data object (uses idValueMember or idValueCallback) |
findRowById(id) | Find row index by ID |
updateRowById(id, changes) | Merge changes into a row identified by ID |
replaceRowById(id, newRow) | Replace entire row data by ID |
Row Locking Methods
| Method | Description |
|---|---|
isRowLocked(rowOrId) | Check if a row is locked. Takes a row data object or row ID |
getRowLockInfo(rowOrId) | Get lock info for a row. Takes a row data object or row ID |
lockRowById(id, lockInfo?) | Lock a row externally (for WebSocket scenarios) |
unlockRowById(id) | Unlock an externally locked row |
getExternalLocks() | Get all external locks |
clearExternalLocks() | Clear all external locks |
Cell Selection Methods
| Method | Description |
|---|---|
selectCellRange(range) | Select a range of cells. Takes a CellRange object with startRowIndex, startColIndex, endRowIndex, endColIndex |
clearCellSelection() | Clear cell selection |
getSelectedCells() | Get all selected cell coordinates |
copyCellSelectionToClipboard() | Copy selected cells to clipboard as TSV |
copySelectedRowsToClipboard() | Copy selected rows to clipboard |
Labels/i18n Properties
| Property | Type | Description |
|---|---|---|
labels | Partial<GridLabels> | Translatable UI strings (merged with defaults) |
Virtual Scroll Properties
| Property | Type | Default | Description |
|---|---|---|---|
isVirtualScrollEnabled | boolean | false | Enable virtual scrolling |
virtualScrollThreshold | number | 100 | Auto-enable when items >= threshold |
virtualScrollRowHeight | number | 38 | Fixed row height in pixels |
virtualScrollBuffer | number | 10 | Extra rows above/below viewport |
isInfiniteScrollEnabled | boolean | false | Enable infinite scroll (load more) |
infiniteScrollThreshold | number | 100 | Pixels from bottom to trigger load |
hasMoreItems | boolean | true | Set to false when no more data |
Scroll Properties
| Property | Type | Default | Description |
|---|---|---|---|
isScrollable | boolean | false | Constrain grid to viewport height |
scrollMaxHeight | string | '100vh' | Custom max-height for the grid container |
tableBorderOnly | boolean | false | Show border only around the table, not the full container |
Tooltip Properties
| Property | Type | Default | Description |
|---|---|---|---|
tooltipShowDelay | number | 400 | Delay in ms before showing tooltip |
tooltipHideDelay | number | 100 | Delay in ms before hiding tooltip |
Context Menu & Summary
Row Context Menu
| Property | Type | Default | Description |
|---|---|---|---|
contextMenu | ContextMenuItem[] | - | Right-click menu items for cells/rows (supports shortcut property) |
contextMenuXOffset | number | 8 | Horizontal offset from click position (pixels) |
contextMenuYOffset | number | 0 | Vertical offset from click position (pixels) |
Header Context Menu
| Property | Type | Default | Description |
|---|---|---|---|
headerContextMenu | HeaderMenuConfig[] | - | Right-click menu items for column headers. Accepts predefined strings or custom items. |
onheadercontextmenuopen | function | - | Callback before header menu opens: (ctx: HeaderMenuContext) => void | false. Return false to prevent opening. |
Summary
| Property | Type | Default | Description |
|---|---|---|---|
summaryPosition | string | - | Position(s): "bottom-left", "top-right|bottom-right" |
summaryContentCallback | function | - | Callback returning HTML content for summary |
isSummaryInline | boolean | true | Share row with pagination |
summaryMetadata | unknown | - | Server-provided metadata passed to summaryContentCallback |
New Empty Row Experimental
| Property | Type | Default | Description |
|---|---|---|---|
isNewRowEnabled | boolean | false | Show an empty row for adding new data |
newRowPosition | 'top' | 'bottom' | 'bottom' | Position of the new row |
newRowIndicator | string | '+' | Indicator shown in row number cell |
createEmptyRowCallback | () => T | - | Callback to create a new empty row object |
Row Locking Properties
Lock rows to prevent editing (useful for collaborative scenarios).
| Property | Type | Description |
|---|---|---|
idValueMember | string | Property name for row ID (e.g., 'id') |
idValueCallback | (row) => unknown | Callback to compute row ID |
rowLocking | RowLockingOptions | Row locking configuration (see below) |
Styling Callbacks
| Property | Type | Description |
|---|---|---|
customStylesCallback | () => string | Return custom CSS to inject into shadow DOM |
rowClassCallback | (row, rowIndex) => string | null | Dynamic CSS class for rows |
Grid Modes
The mode property sets sensible defaults for common use cases:
read-only
Display-only grid. Editing disabled, optimized for viewing data.
excel
Excel-like behavior. Navigate mode with arrow keys, type to edit, Enter/Tab to commit.
input-matrix
Form-like behavior. All cells editable, Tab moves between cells.
Callbacks
See Events API for full details. Key callbacks not listed in other sections:
| Callback | Description |
|---|---|
onrowfocus | Fired when focused row changes (master/detail) |
onrowlockchange | Fired when a row's lock state changes |
oncellselectionchange | Fired when cell selection changes |
onbeforepaste | Fired before paste operation - return false to cancel |
onpaste | Fired after paste operation completes |
idValueCallback | Callback to compute row ID (alternative to idValueMember) |
TypeScript Support
The component is fully typed with generic support:
Global API
Access component functionality through window.keenmate.grid:
| Method / Property | Returns | Description |
|---|---|---|
version() | string | Returns the component version |
config | object | Package metadata (name, version, author, etc.) |
register() | void | Manually register the custom element |
getInstances() | HTMLElement[] | Get all active grid instances on the page |
Important Notes
- Generic Types: Component supports any data structure via
Tparameter - Reactive: All properties are reactive - changes update the UI automatically
- Shadow DOM: Component uses Shadow DOM for style encapsulation
- CSS Variables: Customize appearance with 170+ CSS variables
- Events vs Callbacks: Events use
on*naming, callbacks use*Callbacksuffix