Skip to content

Cell Flash

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
}

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}`,
* }),
* },
* ];
  • 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: (templateOrOptions?: CellTemplate | CellFlashArrowTemplateOptions | undefined, templateOptions?: CellFlashArrowTemplateOptions | undefined) => CellTemplate | undefined;

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;

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';

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';

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';

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>
}

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
}

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);

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)
}

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)
}

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
}

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
}

interface CellFlashState {
rowIndex: number;
prop?: ColumnProp;
type: DimensionRows;
value?: unknown;
previousValue?: unknown;
direction: CellFlashDirection;
className?: string;
rowClassName?: string;
ariaLabel?: string;
startedAt: number;
duration: number
}

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
}

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
}

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
}

interface CellFlashTemplatePropExtension {
previousValue?: any;
flashDirection?: CellFlashDirection;
flashState?: any
}

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;