### Quick Start with Virtuoso Message List Source: https://virtuoso.dev/message-list Basic setup for VirtuosoMessageList, including data generation and license key. Use this for a minimal working example. ```jsx import { VirtuosoMessageListLicense, VirtuosoMessageList, VirtuosoMessageListProps } from '@virtuoso.dev/message-list' import { useMemo } from 'react' const licenseKey = 'your-license-key' export default function App() { const data = useMemo['data']>(() => { return { data: Array.from({ length: 100 }, (_, index) => ({ id: index, content: `Message ${index}` })), scrollModifier: { type: 'item-location', location: { index: 'LAST', align: 'end', }, }, } }, []) return (
{data.content}
} />
) } ``` -------------------------------- ### Basic Data-table Setup with Columns Source: https://virtuoso.dev/data-table/guides/migrating-from-table-virtuoso Use this example to set up a basic data-table with local data, defining columns for name, category, and status. The 'status' column is set to be sticky on the right. ```javascript import { DataTable, DataTableCell, DataTableColumn, DataTableColumnHeader } from '@/components/ui/data-table' import { localModel } from '@virtuoso.dev/data-table' const rows = Array.from({ length: 40 }, (_, index) => ({ id: `SKU-${String(index + 1).padStart(3, '0')}`, name: `Product ${index + 1}`, category: ['Office', 'Peripherals', 'Audio'][index % 3]!, status: ['In stock', 'Low stock', 'Backorder'][index % 3]!, })) const model = localModel({ data: rows }) export default function App() { return ( data.id} model={model} style={{ height: 340 }}> Name {({ row }) => (
{row.data.name} {row.data.id}
)}
Category {({ cellValue }) => String(cellValue)} Status {({ cellValue }) => String(cellValue)}
) } ``` -------------------------------- ### Minimum Known-Good Virtuoso Data Table Example Source: https://virtuoso.dev/data-table/guides/troubleshooting This example demonstrates the essential setup for a Virtuoso Data Table, including explicit height, wrapper import, and basic data configuration. Use this as a baseline for comparison if your table is not rendering correctly. ```javascript import { DataTable, DataTableCell, DataTableColumn, DataTableColumnHeader } from '@/components/ui/data-table' import { localModel } from '@virtuoso.dev/data-table' const rows = [ { name: 'Standing Desk', category: 'Office' }, { name: 'USB-C Dock', category: 'Peripherals' }, { name: 'Mechanical Keyboard', category: 'Peripherals' }, ] const model = localModel({ data: rows }) export default function App() { return (

This is the minimum known-good layout: explicit height, installed wrapper import, and plain data.

Product {({ cellValue }) => String(cellValue)} Category {({ cellValue }) => String(cellValue)}
) } ``` -------------------------------- ### Basic VirtuosoMessageList Setup Source: https://virtuoso.dev/message-list/imperative-data-api This snippet shows a basic setup for the VirtuosoMessageList component with initial data and a simple item content renderer. It includes necessary imports and a ref for imperative control. ```javascript import { scrollToBottomIfAtBottom, VirtuosoMessageList, VirtuosoMessageListLicense, VirtuosoMessageListMethods, } from '@virtuoso.dev/message-list' import { useRef } from 'react' export default function App() { const ref = useRef (null) const offset = useRef(100) return ( <>
{data}
} ref={ref} style={{ height: 500 }} initialData={Array.from({ length: 100 }, (_, index) => index)} />
) } ``` -------------------------------- ### Install React Virtuoso Source: https://virtuoso.dev/react-virtuoso Install the React Virtuoso package using npm. ```bash npm install react-virtuoso ``` -------------------------------- ### App Component Setup for Data Table Source: https://virtuoso.dev/data-table/examples/table-instance-dashboard Sets up the main application component, including the Virtuoso DataTable and an external ControlPanel. It initializes the data model and uses `useEngineRef` to get a reference to the table's engine. ```tsx import { DataTable, DataTableCell, DataTableColumn, DataTableColumnHeader } from '@/components/ui/data-table' import { localModel, useEngineRef } from '@virtuoso.dev/data-table' import { ControlPanel } from './ControlPanel' import { products } from './data' const model = localModel({ data: products }) export default function App() { const engineRef = useEngineRef() return (
Product {({ row }) => row.data.name} Category {({ cellValue }) => String(cellValue)} Status {({ cellValue }) => String(cellValue)} Region {({ cellValue }) => String(cellValue)}
) } ``` -------------------------------- ### Basic Auto Resizing List Setup Source: https://virtuoso.dev/react-virtuoso/virtuoso/auto-resizing Demonstrates the basic setup of a React Virtuoso list that automatically resizes with its container. No special configuration is needed for auto-resizing. ```javascript import { Virtuoso } from 'react-virtuoso' import { useMemo } from 'react' export default function App() { const users = useMemo(() => { return Array.from({ length: 100000 }, (_, index) => ({ name: `User ${index}`, description: `Description for user ${index}`, })) }, []) return (
(

{user.name}

{user.description}

)} />
) } ``` -------------------------------- ### Minimal Headless Virtuoso Data Table Example Source: https://virtuoso.dev/data-table/installation/headless A minimal example demonstrating the usage of the headless Virtuoso Data Table with custom column headers and cells. This setup is suitable when you need full control over the table's markup and styling. ```typescript import { Cell, Column, ColumnHeader, VirtuosoDataTable, localModel } from '@virtuoso.dev/data-table' import { rows } from './data' const currency = new Intl.NumberFormat('en-US', { currency: 'USD', style: 'currency', }) const model = localModel({ data: rows }) export default function App() { return ( {() =>
Product
}
{({ cellValue }) => (
{String(cellValue)}
)}
{() =>
Category
}
{({ cellValue }) => (
{String(cellValue)}
)}
{() => (
Price
)}
{({ cellValue }) => (
{currency.format(Number(cellValue))}
)}
) } ``` -------------------------------- ### Basic VirtuosoMasonry Usage Source: https://virtuoso.dev/masonry/api-reference/virtuoso-masonry Demonstrates the basic setup for VirtuosoMasonry with a specified number of columns and data. ```jsx ``` -------------------------------- ### Install Virtuoso Masonry Source: https://virtuoso.dev/masonry Install the Virtuoso Masonry package using npm. ```bash npm install @virtuoso.dev/masonry ``` -------------------------------- ### Basic Column Grouping Example Source: https://virtuoso.dev/data-table/columns/column-groups Demonstrates how to group columns like 'Catalog', 'Inventory', and 'Fulfillment' using ColumnGroup and ColumnGroupHeader components. This setup is useful for organizing related data in wide tables. ```javascript import { localModel } from '@virtuoso.dev/data-table' import { ColumnGroup, ColumnGroupHeader, DataTable, DataTableCell, DataTableColumn, DataTableColumnHeader, } from '@/components/ui/data-table' const rows = [ { name: 'Standing Desk', category: 'Office', stock: 14, status: 'Ready', region: 'US' }, { name: 'USB-C Dock', category: 'Device', stock: 42, status: 'Ready', region: 'EU' }, { name: 'Keyboard', category: 'Device', stock: 8, status: 'Low', region: 'APAC' }, ] const model = localModel({ data: rows }) const groupHeaderClassName = 'flex h-8 items-center justify-center bg-muted/40 px-2 text-xs font-medium text-muted-foreground' export default function App() { return ( {() => 'Catalog'} Product {({ cellValue }) => String(cellValue)} {() => 'Inventory'} Stock {({ cellValue }) => String(cellValue)} Status {({ cellValue }) => String(cellValue)} {() => 'Fulfillment'} Region {({ cellValue }) => String(cellValue)} Category {({ cellValue }) => String(cellValue)} ) } ``` -------------------------------- ### Basic Column Reordering Setup Source: https://virtuoso.dev/data-table/columns/column-reordering This snippet demonstrates the basic setup for column reordering in a Virtuoso Data Table. It includes necessary imports and the structure for defining columns with reordering components. ```javascript import { DataTable, DataTableCell, DataTableColumn, DataTableColumnHeader, HeaderOverlay, HeaderStart } from '@/components/ui/data-table' import { ReorderDropZone, ReorderGrip } from '@/components/ui/data-table/column-reorder' import { localModel } from '@virtuoso.dev/data-table' const rows = Array.from({ length: 40 }, (_, index) => ({ id: `SKU-${String(index + 1).padStart(3, '0')}`, name: `Product ${index + 1}`, category: ['Office', 'Peripherals', 'Audio'][index % 3]!, status: ['In stock', 'Low stock', 'Backorder'][index % 3]!, region: ['US', 'EU', 'APAC'][index % 3]!, })) const model = localModel({ data: rows }) const columns = [ ['name', 'Product', 'font-medium'], ['category', 'Category', ''], ['status', 'Status', ''], ['region', 'Region', ''], ] as const export default function App() { return ( data.id} model={model} style={{ height: 320 }}> {columns.map(([field, label, cellClassName]) => ( {() => label} {({ cellValue }) => String(cellValue)} ))} ) } ``` -------------------------------- ### VirtuosoMessageList Live Example Source: https://virtuoso.dev/virtuoso-message-list A comprehensive example demonstrating a chat-like message list. It includes custom message rendering, adding new messages, and simulating bot responses with text updates. Use this for a full-featured chat interface implementation. ```jsx import { VirtuosoMessageListProps, VirtuosoMessageListMethods, VirtuosoMessageListLicense, VirtuosoMessageList, } from '@virtuoso.dev/message-list' import { randTextRange, randPhrase } from '@ngneat/falso' import { useRef, useMemo, useState } from 'react' interface Message { key: string text: string user: 'me' | 'other' } let idCounter = 0 function randomMessage(user: Message['user']): Message { return { user, key: `${idCounter++}`, text: randTextRange({ min: user === 'me' ? 20 : 100, max: 200 }) } } const ItemContent: VirtuosoMessageListProps['ItemContent'] = ({ data }) => { const ownMessage = data.user === 'me' return (
{data.text}
) } export default function App() { const virtuoso = useRef>(null) const [data, setData] = useState['data']>(() => { return { data: Array.from({ length: 100 }, (_, index) => randomMessage(index % 2 === 0 ? 'me' : 'other')), scrollModifier: { type: 'item-location', location: { index: 'LAST', align: 'end', }, }, } }) return (
data={data} ref={virtuoso} style={{ flex: 1 }} computeItemKey={({ data }) => data.key} ItemContent={ItemContent} />
) } ``` -------------------------------- ### Install React Virtuoso Plugin for Claude Source: https://virtuoso.dev/skills Install the react-virtuoso plugin and virtuoso-skills for use with Claude. ```bash /plugin marketplace add petyosi/react-virtuoso /plugin install virtuoso-skills@virtuoso ``` -------------------------------- ### Basic Header and Footer Example Source: https://virtuoso.dev/message-list/headers-footers Demonstrates a basic Virtuoso Message List with custom Header and Footer components defined. ```jsx import { VirtuosoMessageListProps, VirtuosoMessageList, useVirtuosoMethods, VirtuosoMessageListLicense, VirtuosoMessageListMethods, } from '@virtuoso.dev/message-list' const StickyHeader: VirtuosoMessageListProps ``` -------------------------------- ### HeaderStart Source: https://virtuoso.dev/data-table/api-reference/misc A component for rendering the start of the header. It accepts props and returns null. ```APIDOC ## HeaderStart ### Description A component for rendering the start of the header. It accepts props and returns null. ### Parameters - **props** (HeaderSlotProps) - Description: N/A ### Returns - null - Description: N/A ``` -------------------------------- ### Tuned Viewport Example Source: https://virtuoso.dev/data-table/guides/performance Demonstrates how to configure a Virtuoso data table for optimal performance by setting `columnOverscanCount` and `increaseViewportBy`. This example uses a local model for data and defines custom row keys. ```javascript import { DataTable, DataTableCell, DataTableColumn, DataTableColumnHeader } from '@/components/ui/data-table' import { localModel } from '@virtuoso.dev/data-table' const rows = Array.from({ length: 240 }, (_, index) => ({ id: `SKU-${String(index + 1).padStart(3, '0')}`, name: `Product ${index + 1}`, region: ['US', 'EU', 'APAC'][index % 3]!, status: ['In stock', 'Low stock', 'Backorder'][index % 3]!, })) const model = localModel({ data: rows }) export default function App() { return ( ('id' in data ? data.id : String(data))} model={model} increaseViewportBy={120} style={{ height: 360 }} > Product {({ cellValue }) => String(cellValue)} Region {({ cellValue }) => String(cellValue)} Status {({ cellValue }) => String(cellValue)} ) } ``` -------------------------------- ### Install Data Table Sort Header Button Source: https://virtuoso.dev/data-table/examples/remote-column-sorting Install the optional sort button wrapper for data tables using npx. ```bash npx shadcn@latest add petyosi/react-virtuoso/data-table-sort-header-button ``` -------------------------------- ### Install Headless Package Source: https://virtuoso.dev/data-table/installation/headless Install the headless Virtuoso Data Table package using pnpm. npm, yarn, and bun are also supported. ```bash pnpm add @virtuoso.dev/data-table ``` -------------------------------- ### Minimal DataTable Setup with State Persistence Source: https://virtuoso.dev/data-table/state-persistence This example demonstrates the basic integration of DataTableStatePersistence with column visibility and width persistence adapters. Ensure the DataTableStatePersistence component is mounted within the DataTable and pass the desired adapters. ```javascript import { DataTable, DataTableCell, DataTableColumn, DataTableColumnHeader, HeaderEdge } from '@/components/ui/data-table' import { ResizeHandle } from '@/components/ui/data-table/column-resize' import { columns$, localModel, useCellValue, usePublisher } from '@virtuoso.dev/data-table' import { columnWidthPersistenceAdapter } from '@virtuoso.dev/data-table/column-resize' import { columnVisibilityPersistenceAdapter, columnVisibilityState$, setColumnVisibility$, } from '@virtuoso.dev/data-table/column-visibility' import { DataTableStatePersistence } from '@virtuoso.dev/data-table/state-persistence' const rows = [ { id: 'SKU-001', product: 'Standing Desk', category: 'Office', stock: 14, internalId: 'inv-001' }, { id: 'SKU-002', product: 'USB-C Dock', category: 'Peripherals', stock: 42, internalId: 'inv-002' }, { id: 'SKU-003', product: 'Mechanical Keyboard', category: 'Peripherals', stock: 28, internalId: 'inv-003' }, { id: 'SKU-004', product: 'Noise-canceling Headset', category: 'Audio', stock: 9, internalId: 'inv-004' }, ] const model = localModel({ data: rows }) const adapters = [columnVisibilityPersistenceAdapter(), columnWidthPersistenceAdapter()] function ColumnPicker() { const columns = useCellValue(columns$) const visibility = useCellValue(columnVisibilityState$) const setColumnVisibility = usePublisher(setColumnVisibility$) return (
{[...columns].map(([key, column]) => { const visible = visibility.get(key) ?? column.visible !== false return ( ) })}
) } export default function App() { return ( data.id} model={model} style={{ height: 360 }}> {() => 'Product'} {({ cellValue }) => String(cellValue)} {() => 'Category'} {({ cellValue }) => String(cellValue)} {() => 'Stock'} {({ cellValue }) => String(cellValue)} {() => 'Internal ID'} {({ cellValue }) => String(cellValue)} ) } ``` -------------------------------- ### Install React Virtuoso Plugin for Codex Source: https://virtuoso.dev/skills Install the react-virtuoso plugin and virtuoso-skills for use with Codex. ```bash codex plugin marketplace add petyosi/react-virtuoso --ref main --sparse .agents/plugins --sparse plugins/virtuoso-skills codex plugin add virtuoso-skills@virtuoso ``` -------------------------------- ### Install Virtuoso Message List Source: https://virtuoso.dev/message-list Install the Virtuoso Message List package using npm. ```bash npm install @virtuoso.dev/message-list ``` -------------------------------- ### Install Falso for Data Generation Source: https://virtuoso.dev/message-list/tutorial/intro Add the @ngneat/falso package to your project to generate random data for messages and users. ```bash npm install @ngneat/falso ``` -------------------------------- ### Install Data Table Resize Handle Source: https://virtuoso.dev/data-table/columns/column-resizing Install the shadcn registry item for data table column resizing. This command adds the necessary components to your project. ```bash npx shadcn@latest add petyosi/react-virtuoso/data-table-resize-handle ``` -------------------------------- ### GroupedVirtuoso Component Setup Source: https://virtuoso.dev/react-virtuoso Illustrates how to use GroupedVirtuoso with grouped data. It requires `groupedCounts` to define group sizes and `groupContent` to render group headers. ```jsx import { GroupedVirtuoso } from 'react-virtuoso' const groupCounts = [] for (let index = 0; index < 1000; index++) { groupCounts.push(10) } export default function App() { return ( { return ( // add background to the element to avoid seeing the items below it
Group {index * 10} – {index * 10 + 10}
) }} itemContent={(index, groupIndex) => { // Example item content, actual implementation would go here return
Item {index} in Group {groupIndex}
; }} /> ) } ``` -------------------------------- ### Full Example: Inspecting Row Re-renders Source: https://virtuoso.dev/data-table/guides/debug-instrumentation A complete example demonstrating how to inspect row re-renders in a Virtuoso Data Table. It includes enabling row render events, capturing and displaying them, and providing controls to scroll to specific rows. ```javascript import * as React from 'react' import { Button } from '@/components/ui/button' import { DataTable, DataTableCell, DataTableColumn, DataTableColumnHeader } from '@/components/ui/data-table' import { localModel, scrollToRow$, unstableEnableRowRenderEvents$, unstableRowRender$, useEngineRef, usePublisher, useRemotePublisher, } from '@virtuoso.dev/data-table' import { useEngine } from '@virtuoso.dev/reactive-engine-react' import type { UnstableRowRenderEvent } from '@virtuoso.dev/data-table' const rowRenderEvents = new EventTarget() const rows = Array.from({ length: 80 }, (_, index) => ({ id: `SKU-${String(index + 1).padStart(3, '0')}`, name: `Product ${index + 1}`, status: ['In stock', 'Low stock', 'Backorder'][index % 3]!, })) function emitRowRender(event: UnstableRowRenderEvent) { queueMicrotask(() => { rowRenderEvents.dispatchEvent(new CustomEvent('row-render', { detail: event })) }) } function RowRenderProbe() { const engine = useEngine() const enableRowRenderEvents = usePublisher(unstableEnableRowRenderEvents$) React.useLayoutEffect(() => { enableRowRenderEvents(true) const unsubscribe = engine.sub(unstableRowRender$, emitRowRender) return () => { unsubscribe() enableRowRenderEvents(false) } }, [enableRowRenderEvents, engine]) return null } function EventLog() { const [events, setEvents] = React.useState([]) React.useEffect(() => { const recordEvent = (event: Event) => { setEvents((current) => [(event as CustomEvent).detail, ...current].slice(0, 4)) } rowRenderEvents.addEventListener('row-render', recordEvent) return () => { rowRenderEvents.removeEventListener('row-render', recordEvent) } }, []) return (
Captured events: {events.length}
{events.length === 0 ? ( No events captured ) : ( events.map((event, index) => (
row {event.index}, {event.section}
)) )}
) } const model = localModel({ data: rows }) export default function App() { const engineRef = useEngineRef() const scrollToRow = useRemotePublisher(scrollToRow$, engineRef) return (
data.id} model={model} engineRef={engineRef} style={{ height: 320 }}> Product {({ cellValue }) => String(cellValue)} Status {({ cellValue }) => String(cellValue)}
) } ``` -------------------------------- ### Importing from Shadcn Wrapper Source: https://virtuoso.dev/data-table/guides/troubleshooting Use this import path when you have successfully installed the shadcn UI wrapper for Virtuoso Data Table. If the wrapper is not installed, import directly from `@virtuoso.dev/data-table`. ```javascript import { DataTable } from '@/components/ui/data-table' ``` -------------------------------- ### initialTopMostItemIndex Source: https://virtuoso.dev/react-virtuoso/api-reference/grouped-table-virtuoso Configures the list to start scrolled to a specific item, identified by its index or an alignment object. ```APIDOC ## initialTopMostItemIndex ### Description Set to a value between 0 and totalCount - 1 to make the list start scrolled to that item. Pass in an object to achieve additional effects similar to `scrollToIndex`. ### Parameters #### Path Parameters - None #### Query Parameters - None #### Request Body - None ### Request Example - None ### Response #### Success Response (200) - None #### Response Example - None ### Inherited from `Omit.initialTopMostItemIndex` ``` -------------------------------- ### startReached() Source: https://virtuoso.dev/react-virtuoso/api-reference/grouped-table-virtuoso Callback function invoked when the user scrolls to the start of the list. It receives the current index. ```APIDOC ## startReached() ### Description Called when the user scrolls to the start of the list. ### Parameters #### Path Parameters - **index** (number) - Description: The index at which the start was reached. ### Returns - void ``` -------------------------------- ### Defining Data for VirtuosoMasonry Source: https://virtuoso.dev/masonry/api-reference/virtuoso-masonry An example of how to structure the data array for VirtuosoMasonry, including item IDs, titles, and image URLs. ```javascript const items = [ { id: 1, title: 'Item 1', imageUrl: '...' }, { id: 2, title: 'Item 2', imageUrl: '...' }, ] ``` -------------------------------- ### Basic Virtuoso Component Usage Source: https://virtuoso.dev/react-virtuoso/api-reference/virtuoso Demonstrates the basic setup for the Virtuoso component, rendering a list with a specified total count and custom item content. ```jsx
Item {index}
} /> ``` -------------------------------- ### Example Usage of Pipe and Signal Source: https://virtuoso.dev/gurx/api-reference/misc Demonstrates creating a signal, piping its values through a transformation (incrementing by 1), and subscribing to the transformed signal to log output. ```typescript const signal$ = Signal(true, (r) => { const signalPlusOne$ = r.pipe(signal$, map(i => i + 1)) r.sub(signalPlusOne$, console.log) }) const r = new Realm() r.pub(signal$, 1) ``` -------------------------------- ### Wrap VirtuosoMessageList with License Component Source: https://virtuoso.dev/message-list/licensing Wrap your VirtuosoMessageList component with VirtuosoMessageListLicense and pass your license key as a prop. This is the basic setup for applying the license. ```jsx {/* Your application code */} {/* Your application code */} ``` -------------------------------- ### Get Node Value Example Source: https://virtuoso.dev/gurx/api-reference/misc Demonstrates how to retrieve the current value of a stateful node and how the value updates after publishing a new value. ```typescript const foo$ = Cell('foo') const r = new Realm() r.getValue(foo$) // 'foo' r.pub(foo$, 'bar') //... r.getValue(foo$) // 'bar' ``` -------------------------------- ### Remove Range of Items with deleteRange Source: https://virtuoso.dev/message-list/imperative-data-api Use `data.deleteRange` to remove multiple items from the list efficiently. This example removes 10 items starting from index 5. ```javascript import { VirtuosoMessageList, useVirtuosoMethods, VirtuosoMessageListLicense, VirtuosoMessageListMethods } from '@virtuoso.dev/message-list' import { useRef } from 'react' function ItemContent({ data }) { return
Item {data}
} export default function App() { const ref = useRef (null) return ( <> ( ) ``` -------------------------------- ### Grouped Messages Example Source: https://virtuoso.dev/message-list/examples/grouped-messages This example showcases a chat that groups consecutive messages from the same user. The `ItemContent` component receives the `nextData` and `prevData` props, which allow you to determine the position of the message in the conversation. Based on the position, the message is styled differently to indicate the start, middle, or end of a message group. ```javascript import { VirtuosoMessageList, VirtuosoMessageListLicense, VirtuosoMessageListProps, DataWithScrollModifier, VirtuosoMessageListMethods, } from '@virtuoso.dev/message-list' import { randTextRange } from '@ngneat/falso' interface Message { key: string text: string user: 'me' | 'other' } let idCounter = 0 function randomMessage(user: Message['user']): Message { return { user, key: `${idCounter++}`, text: randTextRange({ min: user === 'me' ? 20 : 100, max: 200 }) } } export default function App() { const [data, setData] = useState([]) const sendMessage = () => { setData(currentData => [ ...currentData, randomMessage('me'), ]) } const receiveMessage = () => { setData(currentData => [ ...currentData, randomMessage('other'), ]) } const messageListProps: VirtuosoMessageListProps = { data, // The following props are used to group messages // You can use them to conditionally render elements based on message position itemContent: (message, index, data) => { const prevData = index > 0 ? data[index - 1] : null const nextData = index < data.length - 1 ? data[index + 1] : null const isGroupStart = !prevData || prevData.user !== message.user const isGroupEnd = !nextData || nextData.user !== message.user return (
{message.text}
) }, } return (
) } ``` -------------------------------- ### Basic Table Implementation Source: https://virtuoso.dev/data-table/examples/basic-table This snippet shows how to set up a basic data table with hardcoded products. It utilizes `DataTable`, `DataTableColumn`, `DataTableColumnHeader`, `DataTableCell`, and `localModel` from Virtuoso. Ensure the `products` data and the `currency` formatter are defined. ```tsx import { DataTable, DataTableCell, DataTableColumn, DataTableColumnHeader } from '@/components/ui/data-table' import { products } from './data' import { localModel } from '@virtuoso.dev/data-table' const currency = new Intl.NumberFormat('en-US', { currency: 'USD', style: 'currency', }) const model = localModel({ data: products }) ``` -------------------------------- ### Basic Styled Data Table Example Source: https://virtuoso.dev/data-table/installation/shadcn Demonstrates how to set up and render a basic styled data table using the shadcn/ui wrapper and Virtuoso's local model. ```tsx import { DataTable, DataTableCell, DataTableColumn, DataTableColumnHeader } from '@/components/ui/data-table' import { products } from './data' import { localModel } from '@virtuoso.dev/data-table' const currency = new Intl.NumberFormat('en-US', { currency: 'USD', style: 'currency', }) const model = localModel({ data: products }) export default function App() { return ( Product {({ cellValue }) => String(cellValue)} Category {({ cellValue }) => String(cellValue)} Price {({ cellValue }) => currency.format(Number(cellValue))} Stock {({ cellValue }) => String(cellValue)} ) } ``` -------------------------------- ### Get Multiple Cell Values with useCellValues Source: https://virtuoso.dev/gurx/api-reference/misc Use this hook to retrieve values from multiple cells. It optimizes re-renders by updating the component only when any of the specified cells change. This example shows retrieving two cell values. ```javascript const foo$ = Cell('foo') const bar$ = Cell('bar') //... function MyComponent() { const [foo, bar] = useCellValues(foo$, bar$) return
{foo} - {bar}
} ``` -------------------------------- ### get() Source: https://virtuoso.dev/message-list/api-reference/imperative-api Gets a shallow copy of the current data in the list. ```APIDOC ## get() ### Description Gets a shallow copy of the current data in the list. ### Method get ### Returns `Data`[] ```