LyteNyte Grid fires events in response to specific user interactions or
when imperative API methods run. For example, when a cell enters edit
mode, the grid fires the editBegin
event.
This guide explains how to respond to events from LyteNyte Grid and shows methods to trigger events imperatively when needed.
For a complete list of available events and their triggers, see the Events API Reference Page.
The Grid.Root
component accepts event listeners for all events LyteNyte
Grid may fire. Add listeners as you would any other props in React. This
familiar approach is the recommended way to add event listeners.
Furthermore, like native events, some events have a preventDefault
property
that will stop the default action of that event from happening. For example,
we can prevent odd rows from being selected by listening to the rowSelectBegin
event and calling preventDefault
when it fires.
"use client";
import "@1771technologies/lytenyte-pro/grid.css";
import { Grid, useClientRowDataSource } from "@1771technologies/lytenyte-pro";
import type { Column } from "@1771technologies/lytenyte-pro/types";
import { bankDataSmall } from "@1771technologies/sample-data/bank-data-smaller";
import { useId, useState } from "react";
type BankData = (typeof bankDataSmall)[number];
const columns: Column<BankData>[] = [
{ id: "age", type: "number" },
{ id: "job" },
{ id: "balance", type: "number" },
{ id: "education" },
{ id: "marital" },
{ id: "default" },
{ id: "housing" },
{ id: "loan" },
{ id: "contact" },
{ id: "day", type: "number" },
{ id: "month" },
{ id: "duration" },
{ id: "campaign" },
{ id: "pdays" },
{ id: "previous" },
{ id: "poutcome" },
{ id: "y" },
];
export default function UseEventsHook() {
const ds = useClientRowDataSource({ data: bankDataSmall });
const grid = Grid.useLyteNyte({
gridId: useId(),
rowDataSource: ds,
columns,
rowSelectionMode: "multiple",
rowSelectionActivator: "single-click",
});
const [events, setEvents] = useState(0);
const view = grid.view.useValue();
return (
<div
className="lng-grid"
style={{ display: "flex", flexDirection: "column" }}
>
<div>Row selection events recorded: {events}</div>
<div style={{ height: 500 }}>
<Grid.Root
grid={grid}
onRowSelectBegin={({ preventDefault, selected }) => {
if (Number.parseInt(selected) % 2) preventDefault();
}}
onRowSelectEnd={() => setEvents((prev) => prev + 1)}
>
<Grid.Viewport>
<Grid.Header>
{view.header.layout.map((row, i) => {
return (
<Grid.HeaderRow key={i} headerRowIndex={i}>
{row.map((c) => {
if (c.kind === "group") return null;
return (
<Grid.HeaderCell
key={c.id}
cell={c}
className="flex w-full h-full capitalize px-2 items-center"
/>
);
})}
</Grid.HeaderRow>
);
})}
</Grid.Header>
<Grid.RowsContainer>
<Grid.RowsCenter>
{view.rows.center.map((row) => {
if (row.kind === "full-width") return null;
return (
<Grid.Row row={row} key={row.id}>
{row.cells.map((c) => {
return (
<Grid.Cell
key={c.id}
cell={c}
className="text-sm flex items-center px-2 h-full w-full"
/>
);
})}
</Grid.Row>
);
})}
</Grid.RowsCenter>
</Grid.RowsContainer>
</Grid.Viewport>
</Grid.Root>
</div>
</div>
);
}
api.eventAddListener
MethodSometimes you may need to add an event listener to LyteNyte Grid outside
a render function. Use the api.eventAddListener
method in such cases.
This method adds a listener for the specified event and returns a
function to remove it. You can also call api.eventRemoveListener
to
remove a listener explicitly.
When using api.eventAddListener
, you must handle cleanup yourself. The
example below demonstrates correct usage with proper cleanup.
"use client";
import "@1771technologies/lytenyte-pro/grid.css";
import { Grid, useClientRowDataSource } from "@1771technologies/lytenyte-pro";
import type { Column } from "@1771technologies/lytenyte-pro/types";
import { bankDataSmall } from "@1771technologies/sample-data/bank-data-smaller";
import { useEffect, useId, useState } from "react";
type BankData = (typeof bankDataSmall)[number];
const columns: Column<BankData>[] = [
{ id: "age", type: "number" },
{ id: "job" },
{ id: "balance", type: "number" },
{ id: "education" },
{ id: "marital" },
{ id: "default" },
{ id: "housing" },
{ id: "loan" },
{ id: "contact" },
{ id: "day", type: "number" },
{ id: "month" },
{ id: "duration" },
{ id: "campaign" },
{ id: "pdays" },
{ id: "previous" },
{ id: "poutcome" },
{ id: "y" },
];
export default function AddEventListener() {
const ds = useClientRowDataSource({ data: bankDataSmall });
const grid = Grid.useLyteNyte({
gridId: useId(),
rowDataSource: ds,
columns,
rowSelectionMode: "multiple",
rowSelectionActivator: "single-click",
});
const [events, setEvents] = useState(0);
const view = grid.view.useValue();
useEffect(() => {
return grid.api.eventAddListener(
"rowSelectBegin",
({ selected, preventDefault }) => {
if (Number.parseInt(selected) % 2) preventDefault();
}
);
}, []);
useEffect(() => {
return grid.api.eventAddListener("rowSelectEnd", () => {
setEvents((prev) => prev + 1);
});
});
return (
<div
className="lng-grid"
style={{ display: "flex", flexDirection: "column" }}
>
<div>Row selection events recorded: {events}</div>
<div style={{ height: 500 }}>
<Grid.Root grid={grid}>
<Grid.Viewport>
<Grid.Header>
{view.header.layout.map((row, i) => {
return (
<Grid.HeaderRow key={i} headerRowIndex={i}>
{row.map((c) => {
if (c.kind === "group") return null;
return (
<Grid.HeaderCell
key={c.id}
cell={c}
className="flex w-full h-full capitalize px-2 items-center"
/>
);
})}
</Grid.HeaderRow>
);
})}
</Grid.Header>
<Grid.RowsContainer>
<Grid.RowsCenter>
{view.rows.center.map((row) => {
if (row.kind === "full-width") return null;
return (
<Grid.Row row={row} key={row.id}>
{row.cells.map((c) => {
return (
<Grid.Cell
key={c.id}
cell={c}
className="text-sm flex items-center px-2 h-full w-full"
/>
);
})}
</Grid.Row>
);
})}
</Grid.RowsCenter>
</Grid.RowsContainer>
</Grid.Viewport>
</Grid.Root>
</div>
</div>
);
}
The LyteNyte Grid API provides the eventFire
method, which lets you
manually trigger an event as if it originated from the grid. This is
useful when building custom functionality that mimics grid event
behavior, but you should avoid it unless necessary.