Row Height
LyteNyte Grid allows developers to control row height. Rows can have a fixed height, vary in height per row, or expand to fill the available viewport space.
The rowHeight property on the grid state controls how LyteNyte Grid
calculates each row's height in pixels. This property accepts three possible values:
- Numbers: Sets all rows to a fixed height in pixels.
- Functions: Returns the height in pixels for each row. Use this option to create variable row heights.
- Fill String: A string of the form
fill:<number>. For example,fill:24instructs LyteNyte Grid to distribute the available viewport space across all rows, while enforcing a minimum height of24pxper row.
Number Row Heights
Set rowHeight to a number to give all rows a uniform height. The numeric value
represents the row height in pixels. The demo below shows fixed row heights in action.
Fixed Row Height
"use client";import { Grid, useClientRowDataSource } from "@1771technologies/lytenyte-pro";import "@1771technologies/lytenyte-pro/grid.css";import type { Column } from "@1771technologies/lytenyte-pro/types";import { useEffect, useId, useState } from "react";import {ExchangeCell,makePerfHeaderCell,NetworkCell,PercentCell,PercentCellPositiveNegative,SymbolCell,ToggleGroup,ToggleItem,tw,} from "./components";import type { DEXPerformanceData } from "@1771technologies/grid-sample-data/dex-pairs-performance";import { data } from "@1771technologies/grid-sample-data/dex-pairs-performance";const columns: Column<DEXPerformanceData>[] = [{ id: "Symbol", cellRenderer: SymbolCell, width: 220, field: "symbol" },{ id: "Network", cellRenderer: NetworkCell, width: 220, field: "network" },{ id: "Exchange", cellRenderer: ExchangeCell, width: 220, field: "exchange" },{id: "Change % 24h",cellRenderer: PercentCellPositiveNegative,headerRenderer: makePerfHeaderCell("Change", "24h"),type: "number,",field: "change24h",},{field: "perf1w",cellRenderer: PercentCellPositiveNegative,headerRenderer: makePerfHeaderCell("Perf %", "1w"),id: "Perf % 1W",type: "number,",},{field: "perf1m",cellRenderer: PercentCellPositiveNegative,headerRenderer: makePerfHeaderCell("Perf %", "1m"),id: "Perf % 1M",type: "number,",},{field: "perf3m",cellRenderer: PercentCellPositiveNegative,headerRenderer: makePerfHeaderCell("Perf %", "3m"),id: "Perf % 3M",type: "number,",},{field: "perf6m",cellRenderer: PercentCellPositiveNegative,headerRenderer: makePerfHeaderCell("Perf %", "6m"),id: "Perf % 6M",type: "number,",},{field: "perfYtd",cellRenderer: PercentCellPositiveNegative,headerRenderer: makePerfHeaderCell("Perf %", "YTD"),id: "Perf % YTD",type: "number",},{ field: "volatility", cellRenderer: PercentCell, id: "Volatility", type: "number" },{field: "volatility1m",cellRenderer: PercentCell,headerRenderer: makePerfHeaderCell("Volatility", "1m"),id: "Volatility 1M",type: "number",},];export default function RowHeight() {const ds = useClientRowDataSource({ data: data });const grid = Grid.useLyteNyte({gridId: useId(),rowDataSource: ds,columns,columnBase: { width: 80 },});const view = grid.view.useValue();const [height, setHeight] = useState("medium");useEffect(() => {if (height === "small") grid.state.rowHeight.set(30);if (height === "medium") grid.state.rowHeight.set(40);if (height === "large") grid.state.rowHeight.set(60);}, [grid.state.rowHeight, height]);return (<><div className={tw("flex h-full items-center gap-1 text-nowrap border-b px-2 py-2")}><div className={tw("text-light hidden text-xs font-medium md:block")}>Row Height:</div><ToggleGrouptype="single"value={height}className={tw("flex flex-wrap")}onValueChange={(c) => {if (!c) return;setHeight(c);}}><ToggleItem value="small">Small</ToggleItem><ToggleItem value="medium">Medium</ToggleItem><ToggleItem value="large">Large</ToggleItem></ToggleGroup></div><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={tw("text-ln-gray-60! dark:text-ln-gray-70! flex h-full w-full items-center text-nowrap px-2 text-xs capitalize",c.column.type === "number" && "justify-end",)}/>);})}</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="text-xs! flex h-full w-full items-center px-2"/>);})}</Grid.Row>);})}</Grid.RowsCenter></Grid.RowsContainer></Grid.Viewport></Grid.Root></div></>);}
import type {CellRendererParams,HeaderCellRendererParams,} from "@1771technologies/lytenyte-pro/types";import { ToggleGroup as TG } from "radix-ui";import type { ClassValue } from "clsx";import clsx from "clsx";import { twMerge } from "tailwind-merge";import type { DEXPerformanceData } from "@1771technologies/grid-sample-data/dex-pairs-performance";import {exchanges,networks,symbols,} from "@1771technologies/grid-sample-data/dex-pairs-performance";export function tw(...c: ClassValue[]) {return twMerge(clsx(...c));}export function SymbolCell({ grid: { api }, row }: CellRendererParams<DEXPerformanceData>) {if (!api.rowIsLeaf(row) || !row.data) return null;const ticker = row.data.symbolTicker;const symbol = row.data.symbol;const image = symbols[row.data.symbolTicker];return (<div className="grid grid-cols-[20px_auto_auto] items-center gap-1.5"><div><imgsrc={image}alt={`Logo for symbol ${symbol}`}className="h-full w-full overflow-hidden rounded-full"/></div><div className="bg-ln-gray-20 text-ln-gray-100 flex h-fit items-center justify-center rounded-lg px-2 py-px text-[10px]">{ticker}</div><div className="w-full overflow-hidden text-ellipsis">{symbol.split("/")[0]}</div></div>);}export function NetworkCell({ grid: { api }, row }: CellRendererParams<DEXPerformanceData>) {if (!api.rowIsLeaf(row) || !row.data) return null;const name = row.data.network;const image = networks[name];return (<div className="grid grid-cols-[20px_1fr] items-center gap-1.5"><div><imgsrc={image}alt={`Logo for network ${name}`}className="h-full w-full overflow-hidden rounded-full"/></div><div className="w-full overflow-hidden text-ellipsis">{name}</div></div>);}export function ExchangeCell({ grid: { api }, row }: CellRendererParams<DEXPerformanceData>) {if (!api.rowIsLeaf(row) || !row.data) return null;const name = row.data.exchange;const image = exchanges[name];return (<div className="grid grid-cols-[20px_1fr] items-center gap-1.5"><div><imgsrc={image}alt={`Logo for exchange ${name}`}className="h-full w-full overflow-hidden rounded-full"/></div><div className="w-full overflow-hidden text-ellipsis">{name}</div></div>);}export function PercentCellPositiveNegative({grid: { api },column,row,}: CellRendererParams<DEXPerformanceData>) {if (!api.rowIsLeaf(row) || !row.data) return null;const field = api.columnField(column, row);if (typeof field !== "number") return "-";const value = (field > 0 ? "+" : "") + (field * 100).toFixed(2) + "%";return (<divclassName={tw("h-ful flex w-full items-center justify-end tabular-nums",field < 0 ? "text-red-600 dark:text-red-300" : "text-green-600 dark:text-green-300",)}>{value}</div>);}export function PercentCell({grid: { api },column,row,}: CellRendererParams<DEXPerformanceData>) {if (!api.rowIsLeaf(row) || !row.data) return null;const field = api.columnField(column, row);if (typeof field !== "number") return "-";const value = (field > 0 ? "+" : "") + (field * 100).toFixed(2) + "%";return <div className="h-ful flex w-full items-center justify-end tabular-nums">{value}</div>;}export const makePerfHeaderCell = (name: string, subname: string) => {return (_: HeaderCellRendererParams<DEXPerformanceData>) => {return (<div className="flex h-full w-full flex-col items-end justify-center"><div>{name}</div><div className="font-mono uppercase">{subname}</div></div>);};};export function ToggleGroup(props: Parameters<typeof TG.Root>[0]) {return (<TG.Root{...props}className={tw("bg-ln-gray-20 flex items-center gap-2 rounded-xl px-2 py-1", props.className)}></TG.Root>);}export function ToggleItem(props: Parameters<typeof TG.Item>[0]) {return (<TG.Item{...props}className={tw("text-ln-gray-70 flex items-center justify-center px-2 py-1 text-xs font-bold outline-none focus:outline-none","data-[state=on]:text-ln-gray-90 data-[state=on]:bg-linear-to-b from-ln-gray-02 to-ln-gray-05 data-[state=on]:rounded-md",props.className,)}></TG.Item>);}
Updating Row Height
In the demo above, clicking the toggle buttons updates the row height.
You can change the row height by setting the grid.state.rowHeight property.
Updating this value causes the grid to recalculate row layout,
so avoid changing it inside hot or frequently running code paths.
The following example sets the row height to 40px:
grid.state.rowHeight.set(40);
If you need to update a variable row height after grid initialization, set rowHeight to a function
that returns your height function. This pattern prevents you from overwriting
the state setter with the height function itself.
const myRowHeightFunction = (i: number) => {/* implementation */};// ❌ Incorrectgrid.state.rowHeight.set(myRowHeightFunction);// ✅ Correctgrid.state.rowHeight.set(() => myRowHeightFunction);
Variable Row Height
LyteNyte Grid supports variable row heights through a function callback. This function must return a number representing the row height in pixels, and the returned value may differ per row.
LyteNyte Grid calls this function for every row during layout, so performance is critical. Keep the implementation simple and avoid expensive calculations inside the callback.
The demo below illustrates variable row heights in practice.
Variable Row Height
"use client";import { Grid, useClientRowDataSource } from "@1771technologies/lytenyte-pro";import "@1771technologies/lytenyte-pro/grid.css";import type { Column } from "@1771technologies/lytenyte-pro/types";import { useId } from "react";import {ExchangeCell,makePerfHeaderCell,NetworkCell,PercentCell,PercentCellPositiveNegative,SymbolCell,tw,} from "./components";import type { DEXPerformanceData } from "@1771technologies/grid-sample-data/dex-pairs-performance";import { data } from "@1771technologies/grid-sample-data/dex-pairs-performance";const columns: Column<DEXPerformanceData>[] = [{ id: "Symbol", cellRenderer: SymbolCell, width: 220, field: "symbol" },{ id: "Network", cellRenderer: NetworkCell, width: 220, field: "network" },{ id: "Exchange", cellRenderer: ExchangeCell, width: 220, field: "exchange" },{id: "Change % 24h",cellRenderer: PercentCellPositiveNegative,headerRenderer: makePerfHeaderCell("Change", "24h"),type: "number,",field: "change24h",},{field: "perf1w",cellRenderer: PercentCellPositiveNegative,headerRenderer: makePerfHeaderCell("Perf %", "1w"),id: "Perf % 1W",type: "number,",},{field: "perf1m",cellRenderer: PercentCellPositiveNegative,headerRenderer: makePerfHeaderCell("Perf %", "1m"),id: "Perf % 1M",type: "number,",},{field: "perf3m",cellRenderer: PercentCellPositiveNegative,headerRenderer: makePerfHeaderCell("Perf %", "3m"),id: "Perf % 3M",type: "number,",},{field: "perf6m",cellRenderer: PercentCellPositiveNegative,headerRenderer: makePerfHeaderCell("Perf %", "6m"),id: "Perf % 6M",type: "number,",},{field: "perfYtd",cellRenderer: PercentCellPositiveNegative,headerRenderer: makePerfHeaderCell("Perf %", "YTD"),id: "Perf % YTD",type: "number",},{ field: "volatility", cellRenderer: PercentCell, id: "Volatility", type: "number" },{field: "volatility1m",cellRenderer: PercentCell,headerRenderer: makePerfHeaderCell("Volatility", "1m"),id: "Volatility 1M",type: "number",},];export default function RowHeight() {const ds = useClientRowDataSource({ data: data });const grid = Grid.useLyteNyte({gridId: useId(),rowDataSource: ds,columns,columnBase: { width: 80 },rowHeight: (i) => [30, 50, 80, 120][i % 4],});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={tw("text-ln-gray-60! dark:text-ln-gray-70! flex h-full w-full items-center text-nowrap px-2 text-xs capitalize",c.column.type === "number" && "justify-end",)}/>);})}</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="text-xs! flex h-full w-full items-center px-2"/>);})}</Grid.Row>);})}</Grid.RowsCenter></Grid.RowsContainer></Grid.Viewport></Grid.Root></div></>);}
import type {CellRendererParams,HeaderCellRendererParams,} from "@1771technologies/lytenyte-pro/types";import type { ClassValue } from "clsx";import clsx from "clsx";import { twMerge } from "tailwind-merge";import type { DEXPerformanceData } from "@1771technologies/grid-sample-data/dex-pairs-performance";import {exchanges,networks,symbols,} from "@1771technologies/grid-sample-data/dex-pairs-performance";export function tw(...c: ClassValue[]) {return twMerge(clsx(...c));}export function SymbolCell({ grid: { api }, row }: CellRendererParams<DEXPerformanceData>) {if (!api.rowIsLeaf(row) || !row.data) return null;const ticker = row.data.symbolTicker;const symbol = row.data.symbol;const image = symbols[row.data.symbolTicker];return (<div className="grid grid-cols-[20px_auto_auto] items-center gap-1.5"><div><imgsrc={image}alt={`Logo for symbol ${symbol}`}className="h-full w-full overflow-hidden rounded-full"/></div><div className="bg-ln-gray-20 text-ln-gray-100 flex h-fit items-center justify-center rounded-lg px-2 py-px text-[10px]">{ticker}</div><div className="w-full overflow-hidden text-ellipsis">{symbol.split("/")[0]}</div></div>);}export function NetworkCell({ grid: { api }, row }: CellRendererParams<DEXPerformanceData>) {if (!api.rowIsLeaf(row) || !row.data) return null;const name = row.data.network;const image = networks[name];return (<div className="grid grid-cols-[20px_1fr] items-center gap-1.5"><div><imgsrc={image}alt={`Logo for network ${name}`}className="h-full w-full overflow-hidden rounded-full"/></div><div className="w-full overflow-hidden text-ellipsis">{name}</div></div>);}export function ExchangeCell({ grid: { api }, row }: CellRendererParams<DEXPerformanceData>) {if (!api.rowIsLeaf(row) || !row.data) return null;const name = row.data.exchange;const image = exchanges[name];return (<div className="grid grid-cols-[20px_1fr] items-center gap-1.5"><div><imgsrc={image}alt={`Logo for exchange ${name}`}className="h-full w-full overflow-hidden rounded-full"/></div><div className="w-full overflow-hidden text-ellipsis">{name}</div></div>);}export function PercentCellPositiveNegative({grid: { api },column,row,}: CellRendererParams<DEXPerformanceData>) {if (!api.rowIsLeaf(row) || !row.data) return null;const field = api.columnField(column, row);if (typeof field !== "number") return "-";const value = (field > 0 ? "+" : "") + (field * 100).toFixed(2) + "%";return (<divclassName={tw("h-ful flex w-full items-center justify-end tabular-nums",field < 0 ? "text-red-600 dark:text-red-300" : "text-green-600 dark:text-green-300",)}>{value}</div>);}export function PercentCell({grid: { api },column,row,}: CellRendererParams<DEXPerformanceData>) {if (!api.rowIsLeaf(row) || !row.data) return null;const field = api.columnField(column, row);if (typeof field !== "number") return "-";const value = (field > 0 ? "+" : "") + (field * 100).toFixed(2) + "%";return <div className="h-ful flex w-full items-center justify-end tabular-nums">{value}</div>;}export const makePerfHeaderCell = (name: string, subname: string) => {return (_: HeaderCellRendererParams<DEXPerformanceData>) => {return (<div className="flex h-full w-full flex-col items-end justify-center"><div>{name}</div><div className="font-mono uppercase">{subname}</div></div>);};};
In this example, the row height cycles through a predefined set of values. While this demo uses a simple pattern, your own logic can be as complex as needed, as long as it remains performant.
const grid = Grid.useLyteNyte({// Other grid propertiesrowHeight: (i) => [30, 50, 80, 120][i % 4],});
Fill Row Height
Use the fill row height syntax "fill:<n>" to make rows expand and fill
the available viewport space, where n is the minimum row height in pixels.
LyteNyte Grid assigns each row its minimum height, calculates the remaining available space, and then distributes that space evenly across all rows. This approach works well when the grid displays only a small number of rows and you want them to occupy the full viewport height.
Fill Row Height
"use client";import { Grid, useClientRowDataSource } from "@1771technologies/lytenyte-pro";import "@1771technologies/lytenyte-pro/grid.css";import type { Column } from "@1771technologies/lytenyte-pro/types";import { useId } from "react";import type { OrderData } from "@1771technologies/grid-sample-data/orders";import { data } from "@1771technologies/grid-sample-data/orders";import {AvatarCell,EmailCell,IdCell,PaymentMethodCell,PriceCell,ProductCell,PurchaseDateCell,tw,} from "./components";const columns: Column<OrderData>[] = [{ id: "id", width: 60, widthMin: 60, cellRenderer: IdCell, name: "ID" },{ id: "product", cellRenderer: ProductCell, width: 200 },{ id: "price", type: "number", cellRenderer: PriceCell, width: 100 },{ id: "customer", cellRenderer: AvatarCell, width: 180 },{ id: "purchaseDate", cellRenderer: PurchaseDateCell, name: "Purchase Date", width: 120 },{ id: "paymentMethod", cellRenderer: PaymentMethodCell, name: "Payment Method", width: 150 },{ id: "email", cellRenderer: EmailCell, width: 220 },];export default function ColumnBase() {const ds = useClientRowDataSource({ data: data.slice(0, 8) });const grid = Grid.useLyteNyte({gridId: useId(),rowDataSource: ds,columns,rowHeight: "fill:50",});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={tw("flex h-full w-full items-center text-nowrap px-3 text-sm capitalize",c.column.type === "number" && "justify-end",)}/>);})}</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-3 text-sm"/>);})}</Grid.Row>);})}</Grid.RowsCenter></Grid.RowsContainer></Grid.Viewport></Grid.Root></div>);}
import type { CellRendererParams } from "@1771technologies/lytenyte-pro/types";import type { ClassValue } from "clsx";import clsx from "clsx";import { twMerge } from "tailwind-merge";import { format } from "date-fns";import type { JSX, ReactNode } from "react";import type { OrderData } from "@1771technologies/grid-sample-data/orders";export function tw(...c: ClassValue[]) {return twMerge(clsx(...c));}export function ProductCell({ grid: { api }, row }: CellRendererParams<OrderData>) {if (!api.rowIsLeaf(row) || !row.data) return;const url = row.data?.productThumbnail;const title = row.data.product;const desc = row.data.productDescription;return (<div className="flex h-full w-full items-center gap-2"><img className="border-ln-gray-50 h-7 w-7 rounded-lg border" src={url} alt={title + desc} /><div className="text-ln-gray-90 flex flex-col gap-0.5"><div className="font-semibold">{title}</div><div className="text-ln-gray-70 text-xs">{desc}</div></div></div>);}export function AvatarCell({ grid: { api }, row }: CellRendererParams<OrderData>) {if (!api.rowIsLeaf(row) || !row.data) return;const url = row.data?.customerAvatar;const name = row.data.customer;return (<div className="flex h-full w-full items-center gap-2"><img className="border-ln-gray-50 h-7 w-7 rounded-full border" src={url} alt={name} /><div className="text-ln-gray-90 flex flex-col gap-0.5"><div>{name}</div></div></div>);}const formatter = new Intl.NumberFormat("en-Us", {minimumFractionDigits: 2,maximumFractionDigits: 2,});export function PriceCell({ grid: { api }, row }: CellRendererParams<OrderData>) {if (!api.rowIsLeaf(row) || !row.data) return;const price = formatter.format(row.data.price);const [dollars, cents] = price.split(".");return (<div className="flex h-full w-full items-center justify-end"><div className="flex items-baseline tabular-nums"><span className="text-ln-gray-80 font-semibold">${dollars}</span>.<span className="relative text-xs">{cents}</span></div></div>);}export function PurchaseDateCell({ grid: { api }, row }: CellRendererParams<OrderData>) {if (!api.rowIsLeaf(row) || !row.data) return;const formattedDate = format(row.data.purchaseDate, "dd MMM, yyyy");return <div className="flex h-full w-full items-center">{formattedDate}</div>;}export function IdCell({ grid: { api }, row }: CellRendererParams<OrderData>) {if (!api.rowIsLeaf(row) || !row.data) return;return <div className="text-xs tabular-nums">{row.data.id}</div>;}export function PaymentMethodCell({ grid: { api }, row }: CellRendererParams<OrderData>) {if (!api.rowIsLeaf(row) || !row.data) return;const cardNumber = row.data.cardNumber;const provider = row.data.paymentMethod;let Logo: ReactNode = null;if (provider === "Visa") Logo = <VisaLogo className="w-6" />;if (provider === "Mastercard") Logo = <MastercardLogo className="w-6" />;return (<div className="flex h-full w-full items-center gap-2"><div className="flex w-7 items-center justify-center">{Logo}</div><div className="flex items-center"><div className="bg-ln-gray-40 size-2 rounded-full"></div><div className="bg-ln-gray-40 size-2 rounded-full"></div><div className="bg-ln-gray-40 size-2 rounded-full"></div><div className="bg-ln-gray-40 size-2 rounded-full"></div></div><div className="tabular-nums">{cardNumber}</div></div>);}export function EmailCell({ grid: { api }, row }: CellRendererParams<OrderData>) {if (!api.rowIsLeaf(row) || !row.data) return;return <div className="text-ln-primary-50 flex h-full w-full items-center">{row.data.email}</div>;}const VisaLogo = (props: JSX.IntrinsicElements["svg"]) => (<svgxmlns="http://www.w3.org/2000/svg"width={2500}height={812}viewBox="0.5 0.5 999 323.684"{...props}><pathfill="#1434cb"d="M651.185.5c-70.933 0-134.322 36.766-134.322 104.694 0 77.9 112.423 83.28 112.423 122.415 0 16.478-18.884 31.229-51.137 31.229-45.773 0-79.984-20.611-79.984-20.611l-14.638 68.547s39.41 17.41 91.734 17.41c77.552 0 138.576-38.572 138.576-107.66 0-82.316-112.89-87.537-112.89-123.86 0-12.91 15.501-27.053 47.662-27.053 36.286 0 65.892 14.99 65.892 14.99l14.326-66.204S696.614.5 651.185.5zM2.218 5.497.5 15.49s29.842 5.461 56.719 16.356c34.606 12.492 37.072 19.765 42.9 42.353l63.51 244.832h85.138L379.927 5.497h-84.942L210.707 218.67l-34.39-180.696c-3.154-20.68-19.13-32.477-38.685-32.477H2.218zm411.865 0L347.449 319.03h80.999l66.4-313.534h-80.765zm451.759 0c-19.532 0-29.88 10.457-37.474 28.73L709.699 319.03h84.942l16.434-47.468h103.483l9.994 47.468H999.5L934.115 5.497h-68.273zm11.047 84.707 25.178 117.653h-67.454z"/></svg>);const MastercardLogo = (props: JSX.IntrinsicElements["svg"]) => (<svgxmlns="http://www.w3.org/2000/svg"width={2500}height={1524}viewBox="55.2 38.3 464.5 287.8"{...props}><pathfill="#f79f1a"d="M519.7 182.2c0 79.5-64.3 143.9-143.6 143.9s-143.6-64.4-143.6-143.9S296.7 38.3 376 38.3s143.7 64.4 143.7 143.9z"/><pathfill="#ea001b"d="M342.4 182.2c0 79.5-64.3 143.9-143.6 143.9S55.2 261.7 55.2 182.2 119.5 38.3 198.8 38.3s143.6 64.4 143.6 143.9z"/><pathfill="#ff5f01"d="M287.4 68.9c-33.5 26.3-55 67.3-55 113.3s21.5 87 55 113.3c33.5-26.3 55-67.3 55-113.3s-21.5-86.9-55-113.3z"/></svg>);
When using fill row heights, if the combined minimum height of all rows exceeds the viewport height, the grid cannot distribute additional space. In this case, each row renders at exactly its minimum height, behaving the same as fixed-height rows.
Next Steps
- Row Pinning: Freeze specific rows at the top or bottom of the viewport.
- Row Full Width: Create rows that expand to the full width of the viewport.
- Row Selection: Select individual or multiple rows.
- Row Sorting: Learn about the row sort model and how rows are ordered.
Overview
Learn how the LyteNyte grid creates, renders, and manages rows. LyteNyte Grid has two types of rows, group rows and leaf rows. These rows define the grid's main content.
Row Pinning
LyteNyte Grid can freeze rows at the top or bottom of the grid viewport. Pinned rows remain visible as the user scrolls.