createFlexGridEngine

Creates the low-level layout engine for a grid

Available since @roku-sdk/flex-grid 3.3.0

import { createFlexGridEngine } from "@roku-sdk/flex-grid";
createFlexGridEngine<T>(config: EngineConfig<T>): GridEngine

Deprecated.

Use createFlexGrid and its handle instead of the low-level engine. Will be removed from the public exports in the next major version.

Description

Creates the low-level layout engine for a grid.

Parameters

NameTypeDescription
configEngineConfig<T>

Return values

Returns GridEngine.

Types

EngineConfig

Deprecated.

Use createFlexGrid and its handle instead of the low-level engine. Will be removed from the public exports in the next major version.

Configuration consumed by the low-level grid engine.

NameTypeDescription
cellVAlign?"top" | "center" | "bottom"Vertical alignment for cells with per-item heights. Default: "bottom".
collapsedRows?() => ReadonlySet<number> | undefinedThe rows that have loaded with zero items (store.rows[r] is []) and are therefore collapsed, or undefined when there are none. See below.
colWidths?number[]Per-column widths for variable geometry. If provided, overrides itemWidth.
containerX?numberX offset of the grid container on screen (used for focus X computation).
containerY?numberY offset of the grid container on screen (used for focus Y computation).
focusedRowAttachments?() => FocusedRowAttachment[]Reactive accessor for plugin nodes to re-parent into the focused row's slot on every focus change (see GridRowsInternals.attachToFocusedRow). Each entry carries a stable id, a reactive node accessor (null until the plugin's node mounts), and its local Y inside the slot.
focusHighlightVisible?Accessor<boolean>When false, cells are not marked focused (hides in-cell outlines and zoom-focus scale) while internal row/col focus is preserved. Also gates the default focus highlight in flex-grid-base.
getCellTemplateId?(cellData: T | undefined, row: number, col: number) => stringMaps cell data (or row index when data is not yet loaded) to its pool type string. See below.
getGridScrollGroupRef() => ContainerRef | null
getHiddenGroupRef() => ContainerRef
getRowHeight?(r: number) => numberReturns the render height of row r. When omitted, computed internally the same way as the getRowY fallback — falls back to itemHeight when rowHeights is absent.
getRowItemCount?(row: number) => numberReturns the actual number of items in a given row. Used by focus strategies to handle rows with fewer items than numCols. Returns numCols() if not provided.
getRowNumCols?(row: number) => numberReturns the logical column count for a given row. A row is "short" (quantized floating focus) only when its item count < getRowNumCols(row). Falls back to numCols() when not provided.
getRowY?(r: number) => numberReturns the Y position of row r in content space. When omitted, computed internally from a reactive cumY memo built off rowHeights (see rowHeights).
hasVariableRowHeights?() => booleanReturns true when variable row heights are active (including after setRowGeometry).
hGapnumber
hStrategyFocusStrategyPlugin<FocusStrategyBase>
hStrategyConfigFocusStrategyBase
itemHeightnumber
itemWidthnumber
nodeIdPrefix?stringPrefix for row-slot SceneGraph ids (geRowSlot_*). createFlexGrid passes an auto-generated unique prefix per grid instance. Direct createFlexGridEngine callers may set this to coordinate ids with other engines; default "".
numCols() => number
numRows() => number
onCardLayout?(vm: PooledNodeVM<T>, ctx: CardLayoutContext) => voidOptional per-card callback after position/focus updates each layout tick. createFlexGrid passes a dispatcher that runs all registerCardLayout handlers. Direct createFlexGridEngine callers may supply a single callback instead.
perf?PerfPlugin
poolCardPool<T>
poolHnumber
poolWnumber
rowCellWidths?RowGeometryInputPer-row cell widths. When row r has a different cell width than itemWidth, cards in that row are positioned using rowCellWidths[r] + hGap spacing.
rowHeights?RowGeometryInputPer-row heights for variable geometry. See below.
rowHGap?RowGeometryInputPer-row horizontal gap between cells. Falls back to hGap when omitted.
rowYOffset?(row: number, focusedRow: number) => numberReactive extra Y (px) a row adds to its target position, summed across plugin providers (see GridRowsInternals.registerRowYOffset). Used to open space between rows, e.g. a metadata block below the focused row. Omitted means no offset (rows sit at their natural Y). Called per row per layout pass and per binary-search probe, so it must stay cheap.
rowYOffsetsVersion?() => numberReactive counter bumped whenever the set of row Y offset providers changes. Read once per layout pass (never per row) so a provider registered or disposed after mount invalidates the cached row window — the providers' own state cannot signal their own arrival.
screenHeightnumber
screenWidthnumber
storeGridStore<T>
storeVersion?() => numberReactive signal that increments when store data changes.
tweenDurationSec?() => numberTween duration (seconds) for the per-row Y pitch animation. Default 0.333.
vGapnumber
viewportBuffer?{ bottom: number; left: number; right: number; top: number }See below.
vStrategyVerticalFocusStrategyPlugin
vStrategyConfig{ focusOffset: number }
wrapRowCards?RowCardsWrapWraps every row slot's cards in a plugin-owned node. Unset when no plugin asked for one.

EngineConfig.collapsedRows

The rows that have loaded with zero items (store.rows[r] is []) and are therefore collapsed, or undefined when there are none. Collapsed rows are excluded from the layout pass entirely: no row slot, no cards, and no row chrome — so a collapsed row cannot leave a title floating over the row that took its place.

Returning the whole set (rather than a per-row predicate) keeps the layout pass to a single reactive read per pass instead of one per row in the window, and lets a grid with no empty rows skip the per-row check on a reference compare. Rows that are merely undefined (still loading) are never collapsed. When omitted, layout falls back to a pure geometry-driven window.

EngineConfig.getCellTemplateId

Maps cell data (or row index when data is not yet loaded) to its pool type string.

col is the resolved data column. The public FlexGridConfig.getCellTemplateId takes only (cellData, row), and such a function stays assignable here — the third argument exists so plugin-contributed cell templates can match on column without the engine having to pass a placeholder value.

EngineConfig.rowHeights

Per-row heights for variable geometry. Two uses:

  • Construction-time snapshot for row-slot pool sizing (read once, untracked, at
    engine construction — see the slot-count estimation below).
  • Fallback source for this engine's own getRowY/getRowHeight when the caller
    does not supply those directly (see below). createFlexGrid always supplies its
    own — computed once in flex-grid-base and shared with the vertical strategy and
    title layer — so this fallback mainly serves direct createFlexGridEngine callers.

Pass an accessor (() => number[] | undefined) so the value stays reactive and callers can patch it (e.g. via FlexGridHandle.setRowGeometry) and have row-Y positions re-derive.

EngineConfig.viewportBuffer

Viewport buffer for row/column windowing (all values in pixels).

  • top: extra pixels to render above viewport (default: 500)
  • bottom: extra pixels to render below viewport (default: 500)
  • left: extra pixels to render left of viewport (default: 500)
  • right: extra pixels to render right of viewport (default: 500)

GridEngine

Deprecated.

Use createFlexGrid and its handle instead of the low-level engine. Will be removed from the public exports in the next major version.

Low-level engine controls used by the grid implementation.

NameTypeDescription
aliveRowsMap<number, { cards: Map<number, unknown>; slot: RowSlot }>
clearPrevScrollX() => voidRelease the previous-position columns kept alive during the horizontal (X) scroll animation. Call when the X scroll tween settles so the extra columns unioned into the focused row's window (for fastforward/rewind paging) release.
col() => number
cumXnumber[]
dataCol() => number
dispose() => void
focusedRowY() => number
focusedSlotRef() => unknown
focusHighlightLocalX() => numberX translation for geFocusHighlight when parented under geScrollGroup (not root).
focusHighlightLocalY() => numberY translation for geFocusHighlight when parented under geScrollGroup (not root).
focusX() => number
focusY() => number
forceSnapRows() => booleanTrue from setForceSnapRows(true) until the layout pass that snapped the rows has run.
getFocusedCardVm() => PooledNodeVM<unknown> | nullPool VM for the cell at (row(), dataCol()) when that slot is alive; else null.
getRowCumX(r: number) => number[]Get cumulative X array for a specific row (accounts for per-row cell widths).
getRowNumCols(r: number) => numberLogical column count for row r.
getRowY(r: number) => number
isWrapboolean
layoutTrigger() => number
requestLayout() => voidBump the layout memo so per-card layout runs again (e.g. after plugin-driven X offsets).
row() => number
rowColMapMap<number, number>
rowFloatScrollXMapMap<number, number>
rowPitch() => number
rowWinEnd() => number
rowWinStart() => number
scrollX() => number
scrollY() => number
setCol(c: number) => void
setFocusedRowY(y: number) => void
setFocusedSlotRef(ref: unknown) => void
setForceSnapRows(v: boolean) => voidSnap row-slot Y on the next layout pass (after jumpTo).
setRow(r: number, options: { clearPrev: boolean }) => void
registerRowChrome(render: (row: Accessor<number>) => unknown, layer?: "front" | "back") => void

FocusedRowAttachment

A plugin node the engine re-parents into the focused row's slot on focus change.

NameTypeDescription
idnumberStable id — keys the engine's "already mounted here" guard.
localY(row: number) => numberLocal Y (px) inside the focused slot's nodeRef.
node() => unknownReactive node accessor; null until the plugin's node mounts.

RowGeometryInput

Deprecated.

Use createFlexGrid and its handle instead of the low-level engine. Will be removed from the public exports in the next major version.

Per-row geometry input: a reactive accessor, so the value can re-derive when callers patch it (e.g. via FlexGridHandle.setRowGeometry).

type RowGeometryInput = () => number[] | undefined;

RowSlot

A row slot exposed by the deprecated engine interface.

NameTypeDescription
cardsRefContainerRefInner container that holds the row's pooled cards; carries horizontal scroll (setX).
elunknownRendered row content.
nodeRefContainerRefRow container reference.
dispose() => void
mountChrome(render: (row: Accessor<number>) => unknown, layer?: "front" | "back") => void
resetPosition() => void
setRow(r: number) => void
setX(x: number) => void
setY(y: number, animate?: boolean) => void

Did this page help you?