Row Selection
Configure and manage single and multiple row selection in LyteNyte Grid with checkboxes, click interactions, and programmatic control.
LyteNyte Grid supports flexible row selection, including single and multiple selection modes. Users can select rows through clicks, checkboxes, or both.
Enable Row Selection
Set the rowSelectionMode property to "single" or "multiple". To enable click-based selection,
set rowSelectionActivator to "single-click" or "double-click".
Enabling Row Selection
"use client";import { Grid, useClientRowDataSource } from "@1771technologies/lytenyte-pro";import "@1771technologies/lytenyte-pro/grid.css";import type { Column } from "@1771technologies/lytenyte-pro/types";import { bankDataSmall } from "@1771technologies/sample-data/bank-data-smaller";import { useId } 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 RowSelection() {const ds = useClientRowDataSource({data: bankDataSmall,});const grid = Grid.useLyteNyte({gridId: useId(),rowDataSource: ds,columns,rowSelectionMode: "single",rowSelectionActivator: "single-click",});const view = grid.view.useValue();return (<div className="lng-grid" 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.HeaderCellkey={c.id}cell={c}className="flex h-full w-full items-center px-2 capitalize"/>);})}</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.Cellkey={c.id}cell={c}className="flex h-full w-full items-center px-2 text-sm"/>);})}</Grid.Row>);})}</Grid.RowsCenter></Grid.RowsContainer></Grid.Viewport></Grid.Root></div>);}
Multiple Row Selection
Set rowSelectionMode to "multiple" to allow selecting multiple rows. Clicking a row toggles its
selection. Hold Shift and click another row to select the range between it and the last selected
row.
Multiple Row Selection
"use client";import { Grid, useClientRowDataSource } from "@1771technologies/lytenyte-pro";import "@1771technologies/lytenyte-pro/grid.css";import type { Column } from "@1771technologies/lytenyte-pro/types";import { bankDataSmall } from "@1771technologies/sample-data/bank-data-smaller";import { useId } 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 RowSelectionMulti() {const ds = useClientRowDataSource({data: bankDataSmall,});const grid = Grid.useLyteNyte({gridId: useId(),rowDataSource: ds,columns,rowSelectionMode: "multiple",rowSelectionActivator: "single-click",});const view = grid.view.useValue();return (<div className="lng-grid" 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.HeaderCellkey={c.id}cell={c}className="flex h-full w-full items-center px-2 capitalize"/>);})}</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.Cellkey={c.id}cell={c}className="flex h-full w-full items-center px-2 text-sm"/>);})}</Grid.Row>);})}</Grid.RowsCenter></Grid.RowsContainer></Grid.Viewport></Grid.Root></div>);}
Row Selection with Group Rows
Group rows create hierarchical relationships with their child rows. Control whether selecting a
group row also selects its children with the rowSelectChildren property.
Row Selection Group Selection
"use client";import { Grid, useClientRowDataSource } from "@1771technologies/lytenyte-pro";import "@1771technologies/lytenyte-pro/grid.css";import { ChevronDownIcon, ChevronRightIcon } from "@1771technologies/lytenyte-pro/icons";import type { Column } from "@1771technologies/lytenyte-pro/types";import { bankDataSmall } from "@1771technologies/sample-data/bank-data-smaller";import { useId } 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 RowSelectionGroups() {const ds = useClientRowDataSource({data: bankDataSmall,});const grid = Grid.useLyteNyte({gridId: useId(),rowDataSource: ds,columns,rowGroupModel: ["job", "education"],rowSelectionMode: "multiple",rowSelectChildren: true,rowSelectedIds: new Set(["root:services"]),rowGroupColumn: {cellRenderer: ({ grid, row, column }) => {if (!grid.api.rowIsGroup(row)) return null;const field = grid.api.columnField(column, row);const isExpanded = grid.api.rowGroupIsExpanded(row);return (<divclassName="flex h-full w-full items-center gap-2"style={{ paddingLeft: row.depth * 16 }}><buttonclassName="flex items-center justify-center"onClick={(e) => {e.stopPropagation();grid.api.rowGroupToggle(row);}}>{!isExpanded && <ChevronRightIcon />}{isExpanded && <ChevronDownIcon />}</button><div>{`${field}`}</div></div>);},},rowGroupExpansions: {"root:services": true,"root:services/secondary": true,},});const view = grid.view.useValue();return (<div className="lng-grid" 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.HeaderCellkey={c.id}cell={c}className="flex h-full w-full items-center px-2 capitalize"/>);})}</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.Cellkey={c.id}cell={c}className="flex h-full w-full items-center px-2 text-sm"/>);})}</Grid.Row>);})}</Grid.RowsCenter></Grid.RowsContainer></Grid.Viewport></Grid.Root></div>);}
Checkbox Selection
When combining selection with group toggle buttons, stop event propagation to avoid triggering both
actions. Alternatively, set selection to "double-click" or implement your own checkbox selection
logic.
Row Selection Checkbox
"use client";import { Grid, useClientRowDataSource } from "@1771technologies/lytenyte-pro";import "@1771technologies/lytenyte-pro/grid.css";import type { Column } from "@1771technologies/lytenyte-pro/types";import { bankDataSmall } from "@1771technologies/sample-data/bank-data-smaller";import { useId } 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 RowSelectionCheckbox() {const ds = useClientRowDataSource({data: bankDataSmall,});const grid = Grid.useLyteNyte({gridId: useId(),rowDataSource: ds,columns,columnMarkerEnabled: true,columnMarker: {cellRenderer: ({ rowSelected, grid }) => {return (<div className="flex h-full w-full items-center justify-center"><inputtype="checkbox"checked={rowSelected}onChange={() => {}}onClick={(e) => {grid.api.rowHandleSelect({target: e.currentTarget,shiftKey: e.shiftKey,});}}/></div>);},},rowSelectionMode: "multiple",rowSelectionActivator: "none",});const view = grid.view.useValue();return (<div className="lng-grid" 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.HeaderCellkey={c.id}cell={c}className="flex h-full w-full items-center px-2 capitalize"/>);})}</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.Cellkey={c.id}cell={c}className="flex h-full w-full items-center px-2 text-sm"/>);})}</Grid.Row>);})}</Grid.RowsCenter></Grid.RowsContainer></Grid.Viewport></Grid.Root></div>);}
Use grid.api.rowHandleSelect to simplify selection handling in components. This method supports
shift-based range selection out of the box.
<inputtype="checkbox"checked={rowSelected}onChange={() => {}}onClick={(e) => {grid.api.rowHandleSelect({target: e.currentTarget,shiftKey: e.shiftKey,});}}/>
Attach the selection logic to the onClick event to easily detect Shift key presses.
Prevent Row Selection
To block selection for certain rows, listen for the rowSelectBegin event and call
preventDefault(). In the example below, odd-numbered rows cannot be selected.
See the event guide for more on handling grid events.
Prevent Row Selection
"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 } 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 RowSelectionPreventing() {const ds = useClientRowDataSource({ data: bankDataSmall });const grid = Grid.useLyteNyte({gridId: useId(),rowDataSource: ds,columns,rowSelectionMode: "multiple",rowSelectionActivator: "single-click",});const view = grid.view.useValue();return (<div style={{ display: "flex", flexDirection: "column" }}><div style={{ height: 500 }}><Grid.Rootgrid={grid}onRowSelectBegin={({ preventDefault, selected }) => {if (Number.parseInt(selected) % 2) preventDefault();}}><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.HeaderCellkey={c.id}cell={c}className="flex h-full w-full items-center px-2 capitalize"/>);})}</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.Cellkey={c.id}cell={c}className="flex h-full w-full items-center px-2 text-sm"/>);})}</Grid.Row>);})}</Grid.RowsCenter></Grid.RowsContainer></Grid.Viewport></Grid.Root></div></div>);}