import React from 'react' import ReactDOM from 'react-dom/client' import './index.css' import { ColumnDef, flexRender, getCoreRowModel, useReactTable, } from '@tanstack/react-table' type Person = { firstName: string lastName: string age: number visits: number status: string progress: number } const defaultData: Person[] = [ { firstName: 'tanner', lastName: 'linsley', age: 24, visits: 100, status: 'In Relationship', progress: 50, }, { firstName: 'tandy', lastName: 'miller', age: 40, visits: 40, status: 'Single', progress: 80, }, { firstName: 'joe', lastName: 'dirte', age: 45, visits: 20, status: 'Complicated', progress: 10, }, ] const defaultColumns: ColumnDef<Person>[] = [ { header: 'Name', footer: props => props.column.id, columns: [ { accessorKey: 'firstName', cell: info => info.getValue(), footer: props => props.column.id, }, { accessorFn: row => row.lastName, id: 'lastName', cell: info => info.getValue(), header: () => <span>Last Name</span>, footer: props => props.column.id, }, ], }, { header: 'Info', footer: props => props.column.id, columns: [ { accessorKey: 'age', header: () => 'Age', footer: props => props.column.id, }, { header: 'More Info', columns: [ { accessorKey: 'visits', header: () => <span>Visits</span>, footer: props => props.column.id, }, { accessorKey: 'status', header: 'Status', footer: props => props.column.id, }, { accessorKey: 'progress', header: 'Profile Progress', footer: props => props.column.id, }, ], }, ], }, ] function App() { const [data, setData] = React.useState(() => [...defaultData]) const [columns] = React.useState<typeof defaultColumns>(() => [ ...defaultColumns, ]) const [columnVisibility, setColumnVisibility] = React.useState({}) const rerender = React.useReducer(() => ({}), {})[1] const table = useReactTable({ data, columns, state: { columnVisibility, }, onColumnVisibilityChange: setColumnVisibility, getCoreRowModel: getCoreRowModel(), debugTable: true, debugHeaders: true, debugColumns: true, }) return ( <div className="p-2"> <div className="inline-block border border-black shadow rounded"> <div className="px-1 border-b border-black"> <label> <input {...{ type: 'checkbox', checked: table.getIsAllColumnsVisible(), onChange: table.getToggleAllColumnsVisibilityHandler(), }} />{' '} Toggle All </label> </div> {table.getAllLeafColumns().map(column => { return ( <div key={column.id} className="px-1"> <label> <input {...{ type: 'checkbox', checked: column.getIsVisible(), onChange: column.getToggleVisibilityHandler(), }} />{' '} {column.id} </label> </div> ) })} </div> <div className="h-4" /> <table> <thead> {table.getHeaderGroups().map(headerGroup => ( <tr key={headerGroup.id}> {headerGroup.headers.map(header => ( <th key={header.id} colSpan={header.colSpan}> {header.isPlaceholder ? null : flexRender( header.column.columnDef.header, header.getContext() )} </th> ))} </tr> ))} </thead> <tbody> {table.getRowModel().rows.map(row => ( <tr key={row.id}> {row.getVisibleCells().map(cell => ( <td key={cell.id}> {flexRender(cell.column.columnDef.cell, cell.getContext())} </td> ))} </tr> ))} </tbody> <tfoot> {table.getFooterGroups().map(footerGroup => ( <tr key={footerGroup.id}> {footerGroup.headers.map(header => ( <th key={header.id} colSpan={header.colSpan}> {header.isPlaceholder ? null : flexRender( header.column.columnDef.footer, header.getContext() )} </th> ))} </tr> ))} </tfoot> </table> <div className="h-4" /> <button onClick={() => rerender()} className="border p-2"> Rerender </button> <div className="h-4" /> <pre>{JSON.stringify(table.getState().columnVisibility, null, 2)}</pre> </div> ) } const rootElement = document.getElementById('root') if (!rootElement) throw new Error('Failed to find the root element') ReactDOM.createRoot(rootElement).render( <React.StrictMode> <App /> </React.StrictMode> )
import React from 'react' import ReactDOM from 'react-dom/client' import './index.css' import { ColumnDef, flexRender, getCoreRowModel, useReactTable, } from '@tanstack/react-table' type Person = { firstName: string lastName: string age: number visits: number status: string progress: number } const defaultData: Person[] = [ { firstName: 'tanner', lastName: 'linsley', age: 24, visits: 100, status: 'In Relationship', progress: 50, }, { firstName: 'tandy', lastName: 'miller', age: 40, visits: 40, status: 'Single', progress: 80, }, { firstName: 'joe', lastName: 'dirte', age: 45, visits: 20, status: 'Complicated', progress: 10, }, ] const defaultColumns: ColumnDef<Person>[] = [ { header: 'Name', footer: props => props.column.id, columns: [ { accessorKey: 'firstName', cell: info => info.getValue(), footer: props => props.column.id, }, { accessorFn: row => row.lastName, id: 'lastName', cell: info => info.getValue(), header: () => <span>Last Name</span>, footer: props => props.column.id, }, ], }, { header: 'Info', footer: props => props.column.id, columns: [ { accessorKey: 'age', header: () => 'Age', footer: props => props.column.id, }, { header: 'More Info', columns: [ { accessorKey: 'visits', header: () => <span>Visits</span>, footer: props => props.column.id, }, { accessorKey: 'status', header: 'Status', footer: props => props.column.id, }, { accessorKey: 'progress', header: 'Profile Progress', footer: props => props.column.id, }, ], }, ], }, ] function App() { const [data, setData] = React.useState(() => [...defaultData]) const [columns] = React.useState<typeof defaultColumns>(() => [ ...defaultColumns, ]) const [columnVisibility, setColumnVisibility] = React.useState({}) const rerender = React.useReducer(() => ({}), {})[1] const table = useReactTable({ data, columns, state: { columnVisibility, }, onColumnVisibilityChange: setColumnVisibility, getCoreRowModel: getCoreRowModel(), debugTable: true, debugHeaders: true, debugColumns: true, }) return ( <div className="p-2"> <div className="inline-block border border-black shadow rounded"> <div className="px-1 border-b border-black"> <label> <input {...{ type: 'checkbox', checked: table.getIsAllColumnsVisible(), onChange: table.getToggleAllColumnsVisibilityHandler(), }} />{' '} Toggle All </label> </div> {table.getAllLeafColumns().map(column => { return ( <div key={column.id} className="px-1"> <label> <input {...{ type: 'checkbox', checked: column.getIsVisible(), onChange: column.getToggleVisibilityHandler(), }} />{' '} {column.id} </label> </div> ) })} </div> <div className="h-4" /> <table> <thead> {table.getHeaderGroups().map(headerGroup => ( <tr key={headerGroup.id}> {headerGroup.headers.map(header => ( <th key={header.id} colSpan={header.colSpan}> {header.isPlaceholder ? null : flexRender( header.column.columnDef.header, header.getContext() )} </th> ))} </tr> ))} </thead> <tbody> {table.getRowModel().rows.map(row => ( <tr key={row.id}> {row.getVisibleCells().map(cell => ( <td key={cell.id}> {flexRender(cell.column.columnDef.cell, cell.getContext())} </td> ))} </tr> ))} </tbody> <tfoot> {table.getFooterGroups().map(footerGroup => ( <tr key={footerGroup.id}> {footerGroup.headers.map(header => ( <th key={header.id} colSpan={header.colSpan}> {header.isPlaceholder ? null : flexRender( header.column.columnDef.footer, header.getContext() )} </th> ))} </tr> ))} </tfoot> </table> <div className="h-4" /> <button onClick={() => rerender()} className="border p-2"> Rerender </button> <div className="h-4" /> <pre>{JSON.stringify(table.getState().columnVisibility, null, 2)}</pre> </div> ) } const rootElement = document.getElementById('root') if (!rootElement) throw new Error('Failed to find the root element') ReactDOM.createRoot(rootElement).render( <React.StrictMode> <App /> </React.StrictMode> )
Your weekly dose of JavaScript news. Delivered every Monday to over 100,000 devs, for free.
Your weekly dose of JavaScript news. Delivered every Monday to over 100,000 devs, for free.