react-table/examples/sub-components/src/App.js

200 lines
4.9 KiB
JavaScript

import React from 'react'
import styled from 'styled-components'
import { useTable, useExpanded } from 'react-table'
import makeData from './makeData'
const Styles = styled.div`
padding: 1rem;
table {
border-spacing: 0;
border: 1px solid black;
tr {
:last-child {
td {
border-bottom: 0;
}
}
}
th,
td {
margin: 0;
padding: 0.5rem;
border-bottom: 1px solid black;
border-right: 1px solid black;
:last-child {
border-right: 0;
}
}
}
`
// A simple way to support a renderRowSubComponent is to make a render prop
// This is NOT part of the React Table API, it's merely a rendering
// option we are creating for ourselves in our table renderer
function Table({ columns: userColumns, data, renderRowSubComponent }) {
const {
getTableProps,
getTableBodyProps,
headerGroups,
rows,
prepareRow,
flatColumns,
state: { expanded },
} = useTable(
{
columns: userColumns,
data,
},
useExpanded // We can useExpanded to track the expanded state
// for sub components too!
)
return (
<>
<pre>
<code>{JSON.stringify({ expanded }, null, 2)}</code>
</pre>
<table {...getTableProps()}>
<thead>
{headerGroups.map(headerGroup => (
<tr {...headerGroup.getHeaderGroupProps()}>
{headerGroup.headers.map(column => (
<th {...column.getHeaderProps()}>{column.render('Header')}</th>
))}
</tr>
))}
</thead>
<tbody {...getTableBodyProps()}>
{rows.map((row, i) => {
prepareRow(row)
return (
// Use a React.Fragment here so the table markup is still valid
<>
<tr {...row.getRowProps()}>
{row.cells.map(cell => {
return (
<td {...cell.getCellProps()}>{cell.render('Cell')}</td>
)
})}
</tr>
{/*
If the row is in an expanded state, render a row with a
column that fills the entire length of the table.
*/}
{row.isExpanded ? (
<tr>
<td colSpan={flatColumns.length}>
{/*
Inside it, call our renderRowSubComponent function. In reality,
you could pass whatever you want as props to
a component like this, including the entire
table instance. But for this example, we'll just
pass the row
*/}
{renderRowSubComponent({ row })}
</td>
</tr>
) : null}
</>
)
})}
</tbody>
</table>
<br />
<div>Showing the first 20 results of {rows.length} rows</div>
</>
)
}
function App() {
const columns = React.useMemo(
() => [
{
// Make an expander cell
Header: () => null, // No header
id: 'expander', // It needs an ID
Cell: ({ row }) => (
// Use Cell to render an expander for each row.
// We can use the getExpandedToggleProps prop-getter
// to build the expander.
<span {...row.getExpandedToggleProps()}>
{row.isExpanded ? '👇' : '👉'}
</span>
),
},
{
Header: 'Name',
columns: [
{
Header: 'First Name',
accessor: 'firstName',
},
{
Header: 'Last Name',
accessor: 'lastName',
},
],
},
{
Header: 'Info',
columns: [
{
Header: 'Age',
accessor: 'age',
},
{
Header: 'Visits',
accessor: 'visits',
},
{
Header: 'Status',
accessor: 'status',
},
{
Header: 'Profile Progress',
accessor: 'progress',
},
],
},
],
[]
)
const data = React.useMemo(() => makeData(10), [])
// Create a function that will render our row sub components
const renderRowSubComponent = React.useCallback(
({ row }) => (
<pre
style={{
fontSize: '10px',
}}
>
<code>{JSON.stringify({ values: row.values }, null, 2)}</code>
</pre>
),
[]
)
return (
<Styles>
<Table
columns={columns}
data={data}
// We added this as a prop for our table component
// Remember, this is not part of the React Table API,
// it's merely a rendering option we created for
// ourselves
renderRowSubComponent={renderRowSubComponent}
/>
</Styles>
)
}
export default App