Elyra
Elyra The coding agent e The native code editor Elyra Grove Native local development environment Askr The real server for Laravel & PHP Elyra Framework Rust + Svelte 5 framework for desktop apps Elyra Conductor Local project conductor Elyra SQL Server MySQL-compatible SQL server in Rust Elyra SQL Client Native desktop SQL workbench Elyra SQL Anywhere Replication-ready SQL engine Elyra DataGrid Server-driven data grid for Laravel
Elyra
Client core API (TypeScript)

Client core API (TypeScript)

@elyra/datagrid-client-core is the headless, framework-agnostic engine. The Svelte and Vue clients wrap it; you can also use it directly with any framework.

import { createGrid } from '@elyra/datagrid-client-core';
const grid = createGrid(options);
grid.subscribe((state) => { /* re-render */ });

GridOptions

interface GridOptions {
  columns: ColumnDef[];
  fetch: (request: GridRequest) => Promise<GridResponse>;
  key?: string;                 // key column, always fetched (default 'id')
  rowId?: (row) => RowId;       // default: row[key]

  // features — false | true | { ...options }
  header?: Feature<HeaderOptions>;       // default on
  sorting?: Feature<SortingOptions>;     // default on; { multi }
  paging?: Feature<PagingOptions>;       // default on (paged, 20)
  filtering?: Feature<FilteringOptions>; // default on; { facets, row, builder }
  search?: Feature<SearchOptions>;       // default off; { mode, fields, vectorField }
  selection?: Feature<SelectionOptions>; // default off; { mode, checkbox }
  grouping?: Feature<GroupingOptions>;   // default off; { rollup, aggregates, detailRows, detailLimit }
  columnOps?: Feature<ColumnOpsOptions>; // default off; { reorder, resize, freeze, visibility }
  masterDetail?: MasterDetailOptions;    // { load, initiallyExpanded }
  editing?: EditingOptions;              // { mode, trigger, batch, mutate } (mutate required)
  columnVirtual?: boolean | { defaultWidth?: number; overscan?: number };
  tree?: { parentField: string; rootValue?: unknown; hasChildrenField?: string };
  headerGroups?: { header: string; columns: string[] }[];

  aggregates?: AggregateSpec[];  // footer aggregates
  meta?: MetaFlag[];             // extra opt-ins
  autoFetch?: boolean;           // default true
  messages?: Partial<Messages>;  // i18n overrides
  exportUrl?: string;            // POST target for export
  persistKey?: string;           // localStorage persistence
  initialData?: GridResponse;    // server-seeded first page (skips initial fetch)
  initial?: { sort?; filter?; group?; viewport? };
}

Feature rule

Core display features (header, sorting, paging, filtering) default on. Interaction features (selection, grouping, search, columnOps, masterDetail, editing, columnVirtual) default off. false always forces off; true uses defaults; an object gives full control.

Feature option shapes

interface FilteringOptions { facets?: boolean; row?: boolean; builder?: boolean } // default true, except builder
interface GroupingOptions {
  rollup?: boolean; aggregates?: AggregateSpec[];
  detailRows?: boolean;   // expand an innermost group to reveal its rows (lazy)
  detailLimit?: number;   // max detail rows per expanded group (default 200)
}
interface EditingOptions {
  mode?: 'inline' | 'modal' | 'slideover' | 'incell';
  trigger?: 'cell' | 'row' | 'button';
  batch?: boolean;        // incell: accumulate dirty edits, persist via saveBatch()
  mutate: (m: GridMutation) => Promise<GridMutationResult>;   // required
}
// ColumnDef.frozen: boolean | 'left' | 'right'   (true = left)

PagingOptions

{ mode?: 'paged' | 'virtual'; pageSize?: number;   // default 20
  pageSizeOptions?: number[];                        // [20,50,100,200]
  allowAll?: boolean; maxAll?: number;               // "All" (capped 1000)
  rowHeight?: number; overscan?: number }            // virtual scroll

The Grid object

interface Grid {
  readonly features: ResolvedFeatures;
  getState(): GridState;
  subscribe(listener: (state: GridState) => void): () => void;
  refresh(): Promise<void>;

  // sorting
  toggleSort(field, additive?); setSort(sort);
  // filtering
  setFilter(filter | null); setSearch(query);
  setColumnFilterValue(field, value); setColumnFilterOp(field, op);
  clearColumnFilter(field); columnFilterOf(field);
  loadFacet(field, top?); isFacetLoading(field);
  // grouping
  groupBy(field); ungroup(field); setGroups(fields);
  toggleGroup(path); isGroupCollapsed(path);
  // selection
  toggleSelect(id); isSelected(id); selectAllOnPage(); clearSelection(); selectedIds();
  // paging
  setViewport(skip, take); setPageSize(size | 'all'); goToPage(page); onScroll(scrollTop, viewportHeight); pageCount();
  // grouping detail-rows (grouping.detailRows)
  toggleGroupDetail(path); isGroupDetailExpanded(path); groupDetailOf(path); isGroupDetailLoading(path);
  // master-detail
  toggleExpand(id); isExpanded(id); detailOf(id);
  // editing (inline/modal/slideover/incell)
  beginEdit(id, field?); beginCreate(); setDraft(field, value);
  cancelEdit(); commitEdit(); removeRow(id); isEditing(id, field?);
  // batch / in-cell editing (editing.mode 'incell')
  commitCell(); isDirty(id, field?); dirtyValueOf(id, field); cellValue(row, field);
  dirtyRowCount(); saveBatch(); cancelBatch();
  // columns
  setColumnVisible(field, visible); moveColumn(field, toIndex);
  moveColumnLeft(field); moveColumnRight(field); resizeColumn(field, width); freezeColumn(field, frozen);
  // clipboard + pinning + tree + column virtualization
  pasteAt(text); togglePinRow(id); isPinned(id);
  toggleTreeNode(id); isTreeExpanded(id); onScrollX(scrollLeft, viewportWidth);
  // keyboard / cell selection
  setActiveCell(r, c, extend?); isActiveCell(r, c); inSelectionRange(r, c); copySelection();
  moveActive(key, extend?, opts?: { ctrl?: boolean; pageRows?: number });
  //   key: Arrow*/Home/End/PageUp/PageDown; ctrl+Home/End => first/last cell of grid
  // export
  exportData();

  destroy();
}

GridState

interface GridState {
  columns: ResolvedColumn[];
  sort: SortSpec[];
  filter: FilterGroup | null;
  columnFilters: Record<string, ColumnFilter>;
  search: { query: string } | null;
  group: string[];
  collapsedGroups: string[];
  selection: { mode; ids: Set<RowId>; allPagesSelected };
  viewport: { skip; take };
  expanded: Set<RowId>;
  editing: EditingState | null;
  activeCell: CellRef | null; anchor: CellRef | null;
  pinnedRows: RowId[];
  treeExpanded: RowId[];
  colWindow: ColWindow | null;
  dirty: Record<string, Record<string, unknown>>;   // unsaved batch/in-cell edits (rowId => field=>value)
  expandedGroups: string[];                          // innermost-group paths showing detail rows
  groupDetail: Record<string, Row[]>;                // lazily loaded detail rows per group path
  groupDetailLoading: string[];
  data: { rows; total; groups; aggregates; facets; facetsLoading; loading; error };
}

Helpers

import { pageItems, computeWindow, computeColumnWindow,
         operatorsForType, defaultOpForType, headerBandRow,
         resolveMessages, defaultMessages,
         // advanced filter-builder tree helpers (immutable, path-addressed)
         newGroup, newCondition, addCondition, addGroup, setLogic,
         updateCondition, removeNode, isGroup, isEmptyFilter, countConditions }
  from '@elyra/datagrid-client-core';
  • pageItems(current, totalPages) — numbered pager items with ellipses.
  • computeWindow(input) — virtual row window from scroll position.
  • computeColumnWindow(widths, scrollLeft, viewportWidth, overscan) — column window.
  • operatorsForType(type) / defaultOpForType(type) — filter operators.
  • headerBandRow(cols, groups) — multi-column-header banner cells.
  • resolveMessages(partial) — merge i18n overrides onto English defaults.

Filter-builder helpers

Immutable helpers for building nested AND/OR filter trees (used by the advanced filter builder; edits are addressed by a path of child indices from the root group):

newGroup(logic?)                     // { logic, filters: [] }
newCondition(field, op?, value?)     // a leaf condition
addCondition(root, groupPath, cond)  // -> new tree
addGroup(root, groupPath, logic?)    // -> new tree
setLogic(root, groupPath, logic)     // AND <-> OR
updateCondition(root, path, patch)   // patch a leaf
removeNode(root, path)               // drop a node
isGroup(node) · isEmptyFilter(node) · countConditions(node)

Build a tree and hand it to grid.setFilter(tree).