# Example: Cell presentations

A positions grid using all four presentation components together — PretableEntity for the symbol and name, PretableDelta for day P&L, PretableStatus for settlement, and PretableBadge for a risk or watch flag.

Source: https://pretable.ai/examples/cell-presentations.md

```tsx CellPresentationsGrid.tsx
"use client";

import { PretableSurface } from "@pretable/react";

import { columns } from "./columns";
import { positions, type Position } from "./data";

const VIEWPORT_HEIGHT = 400;

export function CellPresentationsGrid() {
  return (
    <div>
      <p style={{ margin: "0 0 8px", fontSize: 13 }}>
        <strong>Position</strong> is a <code>PretableEntity</code>,{" "}
        <strong>Day P&amp;L</strong> a <code>PretableDelta</code>,{" "}
        <strong>Settlement</strong> a <code>PretableStatus</code>, and{" "}
        <strong>Flag</strong> a <code>PretableBadge</code> — none of the four
        speaks in colour alone.
      </p>
      <PretableSurface<Position>
        ariaLabel="Positions"
        columns={columns}
        getRowId={(row) => row.id}
        rows={positions}
        viewportHeight={VIEWPORT_HEIGHT}
      />
    </div>
  );
}
```

```tsx columns.tsx
import {
  numberFormats,
  PretableBadge,
  PretableDelta,
  PretableEntity,
  PretableStatus,
  type PretableColumn,
} from "@pretable/react";

import type { Position } from "./data";

export const columns: PretableColumn<Position>[] = [
  {
    id: "symbol",
    header: "Position",
    widthPx: 170,
    render: ({ row }) => (
      <PretableEntity primary={row.symbol} secondary={row.name} />
    ),
  },
  {
    id: "dayPnl",
    header: "Day P&L",
    type: "number",
    widthPx: 130,
    numberFormat: numberFormats.money({
      currency: "USD",
      signDisplay: "always",
    }),
    render: ({ row, formattedValue }) => (
      <PretableDelta value={row.dayPnl}>{formattedValue}</PretableDelta>
    ),
  },
  {
    id: "settlementState",
    header: "Settlement",
    widthPx: 130,
    render: ({ row }) => (
      <PretableStatus tone={row.settled ? "positive" : "warning"}>
        {row.settlementState}
      </PretableStatus>
    ),
  },
  {
    id: "flag",
    header: "Flag",
    widthPx: 90,
    render: ({ row }) => (
      <PretableBadge tone={row.flag === "risk" ? "negative" : "warning"}>
        {row.flag}
      </PretableBadge>
    ),
  },
];
```

```ts data.ts
export interface Position {
  id: string;
  symbol: string;
  name: string;
  dayPnl: number;
  settled: boolean;
  settlementState: string;
  flag: "risk" | "watch";
}

/**
 * Deliberately decorrelated: settlement state, day P&L direction, and flag
 * each vary independently across rows, so no single column's tone can be
 * read off another's.
 */
export const positions: Position[] = [
  {
    id: "p1",
    symbol: "NVDA",
    name: "NVIDIA Corp.",
    dayPnl: 8420.5,
    settled: true,
    settlementState: "Settled",
    flag: "watch",
  },
  {
    id: "p2",
    symbol: "TSLA",
    name: "Tesla, Inc.",
    dayPnl: -3190.25,
    settled: false,
    settlementState: "Pending",
    flag: "risk",
  },
  {
    id: "p3",
    symbol: "AAPL",
    name: "Apple Inc.",
    dayPnl: 1205.1,
    settled: true,
    settlementState: "Settled",
    flag: "risk",
  },
  {
    id: "p4",
    symbol: "META",
    name: "Meta Platforms, Inc.",
    dayPnl: -640.75,
    settled: true,
    settlementState: "Settled",
    flag: "watch",
  },
  {
    id: "p5",
    symbol: "MSFT",
    name: "Microsoft Corp.",
    dayPnl: 0,
    settled: false,
    settlementState: "Pending",
    flag: "watch",
  },
  {
    id: "p6",
    symbol: "AMZN",
    name: "Amazon.com, Inc.",
    dayPnl: 2755.4,
    settled: false,
    settlementState: "Pending",
    flag: "risk",
  },
];
```
