Cell Flash
Module Extensions
Section titled “Module Extensions”CellTemplateProp (Extended from @revolist/revogrid)
Section titled “CellTemplateProp (Extended from @revolist/revogrid)”interface CellTemplateProp { /** * Previous value captured when the flash was requested. */ previousValue?: any; /** * Direction resolved by the flash plugin. */ flashDirection?: CellFlashDirection; /** * Active flash state for the rendered cell. */ flashState?: any}ColumnRegular (Extended from @revolist/revogrid)
Section titled “ColumnRegular (Extended from @revolist/revogrid)”interface ColumnRegular { /** * Enables flash feedback for this column. * * Legacy `(value) => boolean` predicates are supported. Context-aware * predicates can inspect the previous value, row model, row type, and edit * event metadata, and can return a decision object to customize a flash. * * @example * ```ts * const columns = [ * { prop: 'name', name: 'Name', flash: value => Boolean(value) }, * { * prop: 'price', * name: 'Price', * flash: (value, context) => ({ * flash: value !== context.previousValue, * rowFlash: true, * direction: Number(value) > Number(context.previousValue) ? 'up' : 'down', * }), * }, * ]; * ``` */ flash?: CellFlashPredicate}HTMLRevoGridElement (Extended from @revolist/revogrid)
Section titled “HTMLRevoGridElement (Extended from @revolist/revogrid)”interface HTMLRevoGridElement { /** * Cell flash plugin configuration. * * @example * ```ts * const grid = document.querySelector('revo-grid'); * grid.plugins = [CellFlashPlugin, EventManagerPlugin]; * grid.cellFlash = { * duration: 1200, * mode: 'cell-and-row', * queue: 'merge', * }; * ``` */ cellFlash?: CellFlashConfig}AdditionalData (Extended from @revolist/revogrid)
Section titled “AdditionalData (Extended from @revolist/revogrid)”interface AdditionalData { /** * Additional data property for cell flash configuration. * * Useful for framework wrappers where all plugin options are passed through * one memoized or computed `additionalData` object. * * @example * ```tsx * const additionalData = useMemo(() => ({ * cellFlash: { * duration: 900, * mode: 'cell-and-row', * }, * }), []); * ``` */ cellFlash?: CellFlashConfig}Plugin API
Section titled “Plugin API”CellFlashPlugin
Section titled “CellFlashPlugin”Highlights recently changed cells and rows.
Existing usage with flash: (value) => true, FLASH_CELL_EVENT, and
cellFlashArrowTemplate() remains supported. Configure richer behavior
through grid.cellFlash or call the instance methods for manual dashboard
updates.
Example:
* import { CellFlashPlugin, EventManagerPlugin } from '@revolist/revogrid-pro'; * * const grid = document.querySelector('revo-grid'); * grid.plugins = [CellFlashPlugin, EventManagerPlugin]; * grid.columns = [ * { prop: 'name', name: 'Name' }, * { prop: 'price', name: 'Price', flash: value => value !== undefined }, * ]; * *Example:
* grid.cellFlash = { * mode: 'cell-and-row', * queue: 'merge', * duration: 900, * rowDuration: 1400, * aria: { enabled: true }, * }; * *Example:
* grid.columns = [ * { * prop: 'inventory', * name: 'Inventory', * flash: (value, context) => ({ * flash: value !== context.previousValue, * rowFlash: Number(value) === 0, * direction: Number(value) > Number(context.previousValue) ? 'up' : 'down', * ariaLabel: `Inventory changed to ${value}`, * }), * }, * ];Dependencies
Section titled “Dependencies”- Event integration
EventManagerPlugin: Integrates with EventManagerPlugin edit events for automatic edit flashes. - Event integration
HistoryPlugin: Integrates with HistoryPlugin undo and redo flash events when present. - Config integration
additionalData.cellFlash: Reads cell flash configuration from additionalData.cellFlash.
class CellFlashPlugin { /** * Flashes one cell manually. * * Use this for live-feed updates or external actions that do not come through * RevoGrid edit events. The method keeps the old event-driven behavior intact * and only applies an additional manual flash state. * * @param target Cell coordinates and optional flash metadata. * * @example * ```ts * const plugin = grid.getPlugins?.().find(p => p instanceof CellFlashPlugin); * plugin?.flashCell({ * rowIndex: 3, * prop: 'price', * previousValue: 42, * value: 45, * direction: 'up', * duration: 800, * }); * ``` */ flashCell(target: CellFlashCellTarget);
/** * Flashes a batch of changed cells using the same detail shape as the * `flashcell` event. * * Column `flash` predicates are evaluated for each changed prop. Queue and * mode options override the configured defaults for this call only. * * @param detail Batch detail containing changed values, row type, and optional previous values. * @param options Optional queue, mode, and duration overrides for this batch. * * @example * ```ts * plugin.flashCells( * { * type: 'rgRow', * data: { 0: { price: 45, status: 'Updated' } }, * previousData: { 0: { price: 42, status: 'Draft' } }, * eventTypes: ['live-feed'], * }, * { queue: 'merge', mode: 'cell-and-row' }, * ); * ``` * * @example * ```ts * grid.dispatchEvent(new CustomEvent('flashcell', { * detail: { * type: 'rgRow', * data: { 1: { price: 50 } }, * previousData: { 1: { price: 48 } }, * }, * })); * ``` */ flashCells(detail: FlashBatchDetail, options?: CellFlashApplyOptions);
/** * Flashes one or more rows manually. * * Row flashes are rendered through `beforerowrender`, so virtualized rows keep * the correct visual state when they re-enter the viewport before expiry. * * @param targets One row target or an array of row targets. * @param options Optional queue, mode, and row duration overrides. * * @example * ```ts * plugin.flashRows( * [ * { rowIndex: 0, direction: 'changed' }, * { rowIndex: 4, direction: 'down', rowClassName: 'risk-row-flash' }, * ], * { queue: 'merge', rowDuration: 1200 }, * ); * ``` */ flashRows(targets: CellFlashRowTarget | CellFlashRowTarget[], options?: CellFlashApplyOptions);
/** * Clears active flash state. * * Without a target, all active cell and row flashes are cleared. Passing a * row target clears the row plus all active cell flashes in that row. Passing * both `rowIndex` and `prop` clears one cell. * * @param target Optional cell or row target to clear. * * @example * ```ts * plugin.clearFlash(); // clear all flashes * plugin.clearFlash({ rowIndex: 2 }); // clear row 2 and its cell flashes * plugin.clearFlash({ rowIndex: 2, prop: 'price' }); // clear one cell * ``` */ clearFlash(target?: Partial<CellFlashCellTarget & CellFlashRowTarget>);
destroy();}cellFlashArrowTemplate
Section titled “cellFlashArrowTemplate”cellFlashArrowTemplate: (templateOrOptions?: CellTemplate | CellFlashArrowTemplateOptions | undefined, templateOptions?: CellFlashArrowTemplateOptions | undefined) => CellTemplate | undefined;resolveCellFlashConfig
Section titled “resolveCellFlashConfig”Resolves partial public configuration into the plugin’s internal defaults.
Example:
* ```ts * const config = resolveCellFlashConfig({ duration: 1500, queue: 'merge' }); * console.log(config.mode); // "cell" * ```export function resolveCellFlashConfig( config?: CellFlashConfig,): ResolvedCellFlashConfig;CellFlashDirection
Section titled “CellFlashDirection”Direction metadata attached to an active cell or row flash.
The default resolver returns up or down for numeric changes,
changed for non-numeric value changes, and none when no previous value
is available.
Example:
* ```ts * const columns = [ * { * prop: 'price', * name: 'Price', * flash: (value, context) => ({ * flash: true, * direction: Number(value) > Number(context.previousValue) ? 'up' : 'down', * }), * }, * ]; * ```/** * Direction metadata attached to an active cell or row flash. * * The default resolver returns `up` or `down` for numeric changes, * `changed` for non-numeric value changes, and `none` when no previous value * is available. * * @example * ```ts * const columns = [ * { * prop: 'price', * name: 'Price', * flash: (value, context) => ({ * flash: true, * direction: Number(value) > Number(context.previousValue) ? 'up' : 'down', * }), * }, * ]; * ``` */export type CellFlashDirection = 'up' | 'down' | 'changed' | 'none';CellFlashMode
Section titled “CellFlashMode”Defines whether flash requests affect cells, rows, or both.
Example:
* ```ts * grid.cellFlash = { * mode: 'cell-and-row', * rowDuration: 1400, * }; * ```/** * Defines whether flash requests affect cells, rows, or both. * * @example * ```ts * grid.cellFlash = { * mode: 'cell-and-row', * rowDuration: 1400, * }; * ``` */export type CellFlashMode = 'cell' | 'row' | 'cell-and-row';CellFlashQueueMode
Section titled “CellFlashQueueMode”Controls how new flash requests interact with active flashes.
replace preserves the legacy behavior by clearing existing flashes before
applying a new batch. merge keeps existing flashes active until their own
timers expire.
Example:
* ```ts * grid.cellFlash = { * queue: 'merge', * maxActive: 300, * }; * ```/** * Controls how new flash requests interact with active flashes. * * `replace` preserves the legacy behavior by clearing existing flashes before * applying a new batch. `merge` keeps existing flashes active until their own * timers expire. * * @example * ```ts * grid.cellFlash = { * queue: 'merge', * maxActive: 300, * }; * ``` */export type CellFlashQueueMode = 'replace' | 'merge';CellFlashContext
Section titled “CellFlashContext”Runtime information passed to context-aware column flash predicates and direction resolvers.
Example:
* ```ts * const columns = [ * { * prop: 'status', * name: 'Status', * flash: (value, context) => { * return context.previousValue !== value && context.eventTypes?.includes('edit'); * }, * }, * ]; * ```interface CellFlashContext { /** New value from the edit/manual flash batch. */ value: unknown; /** Previous value captured from the event detail or current row model. */ previousValue: unknown; /** Row index in the target row type. */ rowIndex: number; /** Column property for the changed cell. */ prop: ColumnProp; /** Column definition for the changed cell. */ column: ColumnRegular; /** Current row model, when available from the data provider. */ model?: DataType; /** RevoGrid row bucket, for example `rgRow`, `rowPinStart`, or `rowPinEnd`. */ type: DimensionRows; /** Edit/history event type metadata when emitted by EventManagerPlugin. */ eventTypes?: string[]; /** Original flash/edit event detail for advanced consumers. */ detail?: Partial<BeforeRangeSaveDataDetails>}CellFlashDecision
Section titled “CellFlashDecision”Per-change decision returned from a context-aware column flash predicate.
Returning true is equivalent to { flash: true }. Return a decision object
to customize duration, direction, classes, row flashing, or accessibility
text for a specific value change.
Example:
* ```ts * const columns = [ * { * prop: 'inventory', * name: 'Inventory', * flash: (value, context) => ({ * flash: true, * rowFlash: Number(value) === 0, * direction: Number(value) > Number(context.previousValue) ? 'up' : 'down', * className: Number(value) === 0 ? 'cell-flash-danger' : undefined, * ariaLabel: `Inventory changed to ${value}`, * }), * }, * ]; * ```interface CellFlashDecision { /** Whether the changed cell should flash. Defaults to true for decision objects. */ flash?: boolean; /** Whether the containing row should flash for this change. */ rowFlash?: boolean; /** Cell flash duration in milliseconds for this change. */ duration?: number; /** Row flash duration in milliseconds for this change. */ rowDuration?: number; /** Direction metadata for templates, attributes, and CSS selectors. */ direction?: CellFlashDirection; /** Additional class applied to the flashing cell. */ className?: string; /** Additional class applied to the flashing row. */ rowClassName?: string; /** Message announced through the plugin aria-live region when enabled. */ ariaLabel?: string}CellFlashPredicate
Section titled “CellFlashPredicate”Column flash configuration.
Legacy predicates that only accept (value) => boolean still work. New
predicates may accept the second CellFlashContext argument and return a
CellFlashDecision.
Example:
* ```ts * const columns = [ * { prop: 'name', name: 'Name', flash: true }, * { * prop: 'price', * name: 'Price', * flash: (value, context) => ({ * flash: value !== context.previousValue, * direction: Number(value) > Number(context.previousValue) ? 'up' : 'down', * }), * }, * ]; * ```/** * Column flash configuration. * * Legacy predicates that only accept `(value) = > boolean` still work. New * predicates may accept the second `CellFlashContext` argument and return a * `CellFlashDecision`. * * @example * ```ts * const columns = [ * { prop: 'name', name: 'Name', flash: true }, * { * prop: 'price', * name: 'Price', * flash: (value, context) => ({ * flash: value !== context.previousValue, * direction: Number(value) > Number(context.previousValue) ? 'up' : 'down', * }), * }, * ]; * ``` */export type CellFlashPredicate = | boolean | ((value: unknown, context: CellFlashContext) => boolean | CellFlashDecision);CellFlashAriaConfig
Section titled “CellFlashAriaConfig”Accessibility announcement configuration for cell and row flashes.
Example:
* ```ts * grid.cellFlash = { * aria: { * enabled: true, * label: state => `Row ${state.rowIndex + 1} changed`, * }, * }; * ```interface CellFlashAriaConfig { /** Enables aria-live announcements for flash requests. */ enabled?: boolean; /** Live-region politeness. Defaults to `polite`. */ live?: 'off' | 'polite' | 'assertive'; /** Controls the `aria-atomic` attribute on the live region. Defaults to true. */ atomic?: boolean; /** CSS class applied to the generated live region. */ liveRegionClassName?: string; /** Static label or callback that returns the announcement text. */ label?: string | ((state: CellFlashState) => string)}CellFlashLabels
Section titled “CellFlashLabels”User-facing labels used by the plugin.
These labels are used for default accessibility announcements. A decision or
manual target ariaLabel still has highest priority, followed by
aria.label, then these per-kind labels.
Example:
* ```ts * grid.cellFlash = { * aria: true, * labels: { * cellUpdated: state => `Updated ${String(state.prop)} on row ${state.rowIndex + 1}`, * rowUpdated: state => `Updated row ${state.rowIndex + 1}`, * }, * }; * ```interface CellFlashLabels { /** Default announcement for cell flashes. */ cellUpdated?: string | ((state: CellFlashState) => string); /** Default announcement for row flashes. */ rowUpdated?: string | ((state: CellFlashState) => string)}CellFlashConfig
Section titled “CellFlashConfig”Public plugin configuration accepted by grid.cellFlash and
additionalData.cellFlash.
Defaults preserve the original plugin behavior: flashing is enabled, cell-only, lasts 1000ms, replaces active flashes on each event, and clears on source reset.
Example:
* ```ts * grid.plugins = [CellFlashPlugin, EventManagerPlugin]; * grid.cellFlash = { * duration: 1200, * mode: 'cell-and-row', * queue: 'merge', * rowClassName: 'price-row-flash', * aria: { enabled: true }, * labels: { * cellUpdated: state => `Price cell changed on row ${state.rowIndex + 1}`, * rowUpdated: state => `Market row ${state.rowIndex + 1} changed`, * }, * directionResolver: ({ value, previousValue }) => { * if (Number(value) > Number(previousValue)) return 'up'; * if (Number(value) < Number(previousValue)) return 'down'; * return 'changed'; * }, * }; * ```interface CellFlashConfig { /** Enables or disables new flash requests. */ enabled?: boolean; /** Default cell flash duration in milliseconds. */ duration?: number; /** Default row flash duration in milliseconds. */ rowDuration?: number; /** Default flash target mode. */ mode?: CellFlashMode; /** Default active flash queue behavior. */ queue?: CellFlashQueueMode; /** Maximum number of active cell and row flashes retained at once. */ maxActive?: number; /** Clears active flash state when the grid source changes. */ clearOnSourceChange?: boolean; /** Disables animation when the user prefers reduced motion. */ respectReducedMotion?: boolean; /** Enables or configures aria-live announcements. */ aria?: boolean | CellFlashAriaConfig; /** User-facing labels used by default plugin announcements. */ labels?: CellFlashLabels; /** Base class applied to flashing cells. */ className?: string; /** Base class applied to flashing rows. */ rowClassName?: string; /** Optional custom direction resolver used before the default resolver. */ directionResolver?: (context: CellFlashContext) => CellFlashDirection}ResolvedCellFlashConfig
Section titled “ResolvedCellFlashConfig”interface ResolvedCellFlashConfig { enabled: boolean; duration: number; rowDuration: number; mode: CellFlashMode; queue: CellFlashQueueMode; maxActive: number; clearOnSourceChange: boolean; respectReducedMotion: boolean; aria: Required<Pick<CellFlashAriaConfig, 'enabled' | 'live' | 'atomic' | 'liveRegionClassName'>> & Pick<CellFlashAriaConfig, 'label'>; labels: Required<CellFlashLabels>; className: string; rowClassName: string; directionResolver?: (context: CellFlashContext) => CellFlashDirection}CellFlashState
Section titled “CellFlashState”interface CellFlashState { rowIndex: number; prop?: ColumnProp; type: DimensionRows; value?: unknown; previousValue?: unknown; direction: CellFlashDirection; className?: string; rowClassName?: string; ariaLabel?: string; startedAt: number; duration: number}CellFlashCellTarget
Section titled “CellFlashCellTarget”Target accepted by CellFlashPlugin.flashCell().
Example:
* ```ts * const plugin = grid.getPlugins?.().find(p => p instanceof CellFlashPlugin); * plugin?.flashCell({ * rowIndex: 0, * prop: 'price', * previousValue: 42, * value: 47, * direction: 'up', * }); * ```interface CellFlashCellTarget { rowIndex: number; prop: ColumnProp; type?: DimensionRows; value?: unknown; previousValue?: unknown; duration?: number; direction?: CellFlashDirection; className?: string; ariaLabel?: string}CellFlashRowTarget
Section titled “CellFlashRowTarget”Target accepted by CellFlashPlugin.flashRows().
Example:
* ```ts * const plugin = grid.getPlugins?.().find(p => p instanceof CellFlashPlugin); * plugin?.flashRows([ * { rowIndex: 2, direction: 'changed', rowClassName: 'row-flash-warning' }, * { rowIndex: 5, direction: 'down' }, * ]); * ```interface CellFlashRowTarget { rowIndex: number; type?: DimensionRows; duration?: number; direction?: CellFlashDirection; rowClassName?: string; ariaLabel?: string}CellFlashApplyOptions
Section titled “CellFlashApplyOptions”Per-call options for manual and event-driven flash batches.
Example:
* ```ts * plugin.flashCells( * { type: 'rgRow', data: { 0: { price: 12 } }, previousData: { 0: { price: 10 } } }, * { queue: 'merge', mode: 'cell-and-row', duration: 800 }, * ); * ```interface CellFlashApplyOptions { queue?: CellFlashQueueMode; mode?: CellFlashMode; duration?: number; rowDuration?: number}CellFlashTemplatePropExtension
Section titled “CellFlashTemplatePropExtension”interface CellFlashTemplatePropExtension { previousValue?: any; flashDirection?: CellFlashDirection; flashState?: any}CellFlashArrowTemplateOptions
Section titled “CellFlashArrowTemplateOptions”Options for cellFlashArrowTemplate().
Defaults preserve the original helper output: wrapper class cell-flash,
arrow class cell-flash-arrow, up/down/changed direction classes,
and ↑ / ↓ symbols.
Example:
* ```ts * cellTemplate: cellFlashArrowTemplate({ * symbols: { up: '+', down: '-', changed: '~' }, * className: 'market-flash', * arrowClassName: 'market-flash-icon', * directionClassNames: { up: 'positive', down: 'negative' }, * }) * ```interface CellFlashArrowTemplateOptions { /** Direction symbols rendered before the cell content. */ symbols?: Partial<Record<CellFlashDirection, string>>; /** Wrapper class applied around the arrow and cell content. */ className?: string; /** Class applied to the symbol element. */ arrowClassName?: string; /** Direction-specific wrapper classes. */ directionClassNames?: Partial<Record<CellFlashDirection, string>>}CellFlashTemplateParams (Extended from index.ts)
Section titled “CellFlashTemplateParams (Extended from index.ts)”export type CellFlashTemplateParams = CellTemplateProp & CellFlashTemplatePropExtension;