import type { GridOptions } from '../types/grid.types'; import { GridApi } from './grid-api'; export declare class GridCore { readonly api: GridApi; private ctx; /** Set during `buildContext` when any top-level `ColumnDef` has `children`. */ private columnGroupModel; private groupHeaderBuilder; /** New Display Group Engine — replaces `columnGroupModel` for group rendering. */ private displayGroupEngine; /** Set in `initialize` when `photonAI.enabled` — needs the live `GridApi`, so it cannot be built in `buildContext`. */ private photonAIService; /** * Owns registered feature plugins. `null` unless `GridOptions.plugins` was * supplied, so a grid without plugins allocates nothing. */ private pluginHost; /** The concrete formula adapter, retained so the clipboard/fill bridge can map ids ↔ data-model indices. */ private formulaAdapter; /** * The author-supplied columns fully normalized to `ColumnDef` (colId / header * / type defaults applied to leaves and groups). Computed once in * `buildContext` and reused by `initialize`, so the group tree and the flat * leaf list share the same generated colIds. */ private normalizedColumns; /** * Renders a cell's content after an edit commits. * * The same class the body renderer uses, so a just-edited cell is repainted * through the identical code path that drew it — see {@link renderCellValue} * for why that matters. */ private readonly editCellRenderer; constructor(containerEl: HTMLElement, options: GridOptions); private buildContext; private initialize; /** * Subscribes the loading state to the grid store: seeds `GridOptions.loading` * and makes the store the single place `LOADING_STARTED` / `LOADING_STOPPED` * are emitted from. * * Every producer of the flag — `GridApi.setLoading`, the Server-Side row * model, the Infinite row model — writes the same store key, so routing the * events through one watcher is what guarantees exactly one event per * transition regardless of who caused it. The store de-duplicates writes of an * unchanged value, so a producer that re-asserts `true` emits nothing. * * The seed is applied *before* the watcher is attached: the host passed * `loading` in explicitly, so announcing it back is noise, and no subscriber * exists this early anyway. * * Teardown is implicit — `GridApi.destroy()` calls `store.destroy()`, which * drops every subscriber. */ private wireLoadingState; /** * Subscribes the Summary Rows feature to the changes that can move its values * but do **not** run the row pipeline. * * The pipeline path is already covered — `GridApi.applyPipeline` recomputes * summaries after every refresh, which catches data, filter, sort, group and * pagination changes. Two things bypass it: * * - **Cell edits**, which patch cells in place rather than rebuilding rows. * - **Selection changes**, which never touch the displayed row set at all. * * Selection is subscribed only when a summary row actually scopes to it, so * the overwhelmingly common case (no `Selected` scope) pays nothing per click. * The check is deferred into the handler because `setSummaryRows` can * introduce such a row long after wiring. */ private wireSummary; private wireEventHandlers; /** * Backs `CellSelectionEngine.setTreeToggleHandler` — ArrowLeft collapses a * node (or jumps focus to its parent if already collapsed/leaf), ArrowRight * expands a node (or jumps focus to its first child if already expanded). * Returns `false` when Tree Data isn't enabled or the row has no children, * letting normal column navigation take over. */ private handleTreeToggleKey; /** * Wires cell-editing activation and teardown based on the configured * `editing.singleClickEdit` flag. * * - `singleClickEdit: true` → edit starts on the first click (CELL_CLICKED) * - `singleClickEdit: false` → edit starts on double-click (CELL_DOUBLE_CLICKED, default) * * On `CELL_EDIT_STOP` the cell's inner DOM is immediately restored with the * committed (or cancelled) value — no full grid refresh required. */ private wireEditing; /** * Wires the inline checkbox a `boolean` column renders in every one of its * cells. * * ### Why one delegated listener * A viewport can hold thousands of boolean cells, and every cell rebuild * (scroll, sort, column reorder, a Virtual DOM content patch) would have to * re-attach a per-cell listener. One listener on the grid root survives all of * it and costs nothing per cell — the same reason row clicks are delegated. * * ### Why the commit goes through the editor engine * A toggle is an edit. Routing it through `startEditing` → `updateValue` → * `stopEditing` means it gets the identical treatment a typed edit gets: * `editable`/`locked`/`editing.mode` enforcement, `parseValue` + * `validateValue`, a column `valueSetter`, the immutable row-data swap, * `CELL_EDIT_START` / `CELL_VALUE_CHANGED` / `CELL_EDIT_STOP`, and the commit * flash. Writing `row.data` here instead would be a second, quietly divergent * commit path. * * The checkbox is re-synced from the model afterwards, so a rejected edit * (failed validation, a `valueSetter` that declined) snaps the box back * instead of leaving the DOM claiming a value the row does not hold. */ /** * Wires the buttons a `button` cell renderer draws. * * One delegated listener on the grid root, for the same reason the boolean * checkbox uses one: a viewport can hold a button in every visible row, and * every cell rebuild would otherwise have to re-attach a handler. * * The grid does not act on the click — it reports it as * `CELL_BUTTON_CLICKED` and stops. A button column is an application action, * and only the application knows what it means. */ /** * Wires the `+N` counter an `avatarGroup` cell draws. * * One delegated listener on the grid root, like the cell button and the * boolean checkbox — a viewport can hold a counter in every visible row. * * The roster is resolved at click time rather than being built with the cell. * A team of two hundred renders three avatars and a counter; materialising * two hundred rows per cell up front, for a panel that is almost never * opened, is the cost this design exists to avoid. */ private wireAvatarGroups; /** * Wires the expand control a `longText` cell draws. * * One delegated listener on the grid root, like the cell button and the * avatar group's counter — a viewport can hold a long-text cell in every * visible row. * * The text is read out of the cell's own DOM rather than re-resolved from the * row. The renderer already wrote the untruncated value there (the truncation * is CSS), so re-deriving it here would mean re-running the column's * `valueFormatter` for a second, quietly divergent copy of the same string. */ private wireLongText; /** * Wires the controls an `actions` cell draws. * * One delegated listener on the grid root, like the cell button and the * avatar group's counter — a viewport can hold an actions cell in every * visible row, and every cell rebuild would otherwise have to re-attach a * handler per action. * * ### Why the declaration is re-resolved on every click * The cell carries only an action's `id`. The definition is looked up again * here and every predicate re-run against *current* row data, so a button * that became invisible or disabled between paint and click cannot be * invoked. A callback parked on the element would also be retained for as * long as that element lives, which in a recycled viewport is unbounded. * * Overflowed actions are resolved the same way when the menu opens, so the * two entry points cannot disagree about what a row offers. */ private wireCellActions; /** * Opens (or closes) the overflow menu for one actions cell. * * The actions are resolved at click time rather than being built with the * cell: a row offering twelve commands renders the DOM of one offering two, * and the menu reflects the row as it is *now* rather than as it was when the * cell was last painted. */ private openCellActionMenu; /** * Confirms and runs one action, then reports the outcome. * * `CELL_ACTION_CLICKED` fires after any confirmation is accepted and before * the action's own `onClick`, so a column can be driven entirely from the * event bus. A dismissed confirmation emits nothing — a "no" is not a * command. */ private invokeCellAction; private wireCellButtons; private wireBooleanCellToggle; /** * Re-renders a cell's inner element after an edit session ends, using the * current value from `row.data`. * * Delegates to `CellRenderer.renderCellContent` — the exact code path the * initial render and the Virtual DOM patch take — rather than reproducing the * rendering rules here. It used to hold its own copy of that logic, and the * copy had drifted: no `image` case, no `sparkline` case, a literal tick where * the cell renderer drew a checkbox, and `|| '—'` where the renderer used * `?? ''`. A committed edit therefore repainted some cells differently from * how they were first drawn, until the next full render put them back. */ private renderCellValue; private loadState; destroy(): void; } //# sourceMappingURL=grid-core.d.ts.map