import {
columnResizingFeature,
columnSizingFeature,
createColumnHelper,
createTable,
tableFeatures,
} from '@tanstack/solid-table'
import { For, createMemo, createSignal } from 'solid-js'
import type { Table as SolidTableType } from '@tanstack/solid-table'
import { makeData } from './makeData'
import type { Person } from './makeData'
const _features = tableFeatures({ columnSizingFeature, columnResizingFeature })
const columnHelper = createColumnHelper<typeof _features, Person>()
const columns = columnHelper.columns([
columnHelper.group({
header: 'Name',
footer: (props) => props.column.id,
columns: columnHelper.columns([
columnHelper.accessor('firstName', {
cell: (info) => info.getValue(),
footer: (props) => props.column.id,
}),
columnHelper.accessor((row) => row.lastName, {
id: 'lastName',
cell: (info) => info.getValue(),
header: () => <span>Last Name</span>,
footer: (props) => props.column.id,
}),
]),
}),
columnHelper.group({
header: 'Info',
footer: (props) => props.column.id,
columns: columnHelper.columns([
columnHelper.accessor('age', {
header: () => 'Age',
footer: (props) => props.column.id,
}),
columnHelper.accessor('visits', {
header: () => <span>Visits</span>,
footer: (props) => props.column.id,
}),
columnHelper.accessor('status', {
header: 'Status',
footer: (props) => props.column.id,
}),
columnHelper.accessor('progress', {
header: 'Profile Progress',
footer: (props) => props.column.id,
}),
]),
}),
])
function App() {
const [data] = createSignal(makeData(200))
const table = createTable(
{
_features,
_rowModels: {},
columns,
get data() {
return data()
},
defaultColumn: { minSize: 60, maxSize: 800 },
columnResizeMode: 'onChange',
debugTable: true,
debugHeaders: true,
debugColumns: true,
},
(state) => ({
columnSizing: state.columnSizing,
columnResizing: state.columnResizing,
}),
)
const columnSizeVars = createMemo(() => {
const headers = table.getFlatHeaders()
const colSizes: Record<string, number> = {}
for (const header of headers) {
colSizes[`--header-${header.id}-size`] = header.getSize()
colSizes[`--col-${header.column.id}-size`] = header.column.getSize()
}
return colSizes
})
return (
<div class="p-2">
<i>
This example has artificially slow cell renders to simulate complex
usage
</i>
<div class="h-4" />
<pre style={{ 'min-height': '10rem' }}>
{JSON.stringify(table.store.state, null, 2)}
</pre>
<div class="h-4" />({data().length} rows)
<div class="overflow-x-auto">
<div
class="divTable"
style={{
...columnSizeVars(),
width: `${table.getTotalSize()}px`,
}}
>
<div class="thead">
<For each={table.getHeaderGroups()}>
{(headerGroup) => (
<div class="tr">
<For each={headerGroup.headers}>
{(header) => (
<div
class="th"
style={{
width: `calc(var(--header-${header.id}-size) * 1px)`,
}}
>
{header.isPlaceholder ? null : (
<table.FlexRender header={header} />
)}
<div
onDblClick={() => header.column.resetSize()}
onMouseDown={header.getResizeHandler()}
onTouchStart={header.getResizeHandler()}
class={`resizer ${header.column.getIsResizing() ? 'isResizing' : ''}`}
/>
</div>
)}
</For>
</div>
)}
</For>
</div>
<TableBody table={table} />
</div>
</div>
</div>
)
}
function TableBody({
table,
}: {
table: SolidTableType<typeof _features, Person>
}) {
return (
<div class="tbody">
<For each={table.getRowModel().rows}>
{(row) => (
<div class="tr">
<For each={row.getAllCells()}>
{(cell) => {
// simulate expensive render
for (const _ of Array.from({ length: 10000 })) {
Math.random()
}
return (
<div
class="td"
style={{
width: `calc(var(--col-${cell.column.id}-size) * 1px)`,
}}
>
{cell.renderValue<any>()}
</div>
)
}}
</For>
</div>
)}
</For>
</div>
)
}
export default App
import {
columnResizingFeature,
columnSizingFeature,
createColumnHelper,
createTable,
tableFeatures,
} from '@tanstack/solid-table'
import { For, createMemo, createSignal } from 'solid-js'
import type { Table as SolidTableType } from '@tanstack/solid-table'
import { makeData } from './makeData'
import type { Person } from './makeData'
const _features = tableFeatures({ columnSizingFeature, columnResizingFeature })
const columnHelper = createColumnHelper<typeof _features, Person>()
const columns = columnHelper.columns([
columnHelper.group({
header: 'Name',
footer: (props) => props.column.id,
columns: columnHelper.columns([
columnHelper.accessor('firstName', {
cell: (info) => info.getValue(),
footer: (props) => props.column.id,
}),
columnHelper.accessor((row) => row.lastName, {
id: 'lastName',
cell: (info) => info.getValue(),
header: () => <span>Last Name</span>,
footer: (props) => props.column.id,
}),
]),
}),
columnHelper.group({
header: 'Info',
footer: (props) => props.column.id,
columns: columnHelper.columns([
columnHelper.accessor('age', {
header: () => 'Age',
footer: (props) => props.column.id,
}),
columnHelper.accessor('visits', {
header: () => <span>Visits</span>,
footer: (props) => props.column.id,
}),
columnHelper.accessor('status', {
header: 'Status',
footer: (props) => props.column.id,
}),
columnHelper.accessor('progress', {
header: 'Profile Progress',
footer: (props) => props.column.id,
}),
]),
}),
])
function App() {
const [data] = createSignal(makeData(200))
const table = createTable(
{
_features,
_rowModels: {},
columns,
get data() {
return data()
},
defaultColumn: { minSize: 60, maxSize: 800 },
columnResizeMode: 'onChange',
debugTable: true,
debugHeaders: true,
debugColumns: true,
},
(state) => ({
columnSizing: state.columnSizing,
columnResizing: state.columnResizing,
}),
)
const columnSizeVars = createMemo(() => {
const headers = table.getFlatHeaders()
const colSizes: Record<string, number> = {}
for (const header of headers) {
colSizes[`--header-${header.id}-size`] = header.getSize()
colSizes[`--col-${header.column.id}-size`] = header.column.getSize()
}
return colSizes
})
return (
<div class="p-2">
<i>
This example has artificially slow cell renders to simulate complex
usage
</i>
<div class="h-4" />
<pre style={{ 'min-height': '10rem' }}>
{JSON.stringify(table.store.state, null, 2)}
</pre>
<div class="h-4" />({data().length} rows)
<div class="overflow-x-auto">
<div
class="divTable"
style={{
...columnSizeVars(),
width: `${table.getTotalSize()}px`,
}}
>
<div class="thead">
<For each={table.getHeaderGroups()}>
{(headerGroup) => (
<div class="tr">
<For each={headerGroup.headers}>
{(header) => (
<div
class="th"
style={{
width: `calc(var(--header-${header.id}-size) * 1px)`,
}}
>
{header.isPlaceholder ? null : (
<table.FlexRender header={header} />
)}
<div
onDblClick={() => header.column.resetSize()}
onMouseDown={header.getResizeHandler()}
onTouchStart={header.getResizeHandler()}
class={`resizer ${header.column.getIsResizing() ? 'isResizing' : ''}`}
/>
</div>
)}
</For>
</div>
)}
</For>
</div>
<TableBody table={table} />
</div>
</div>
</div>
)
}
function TableBody({
table,
}: {
table: SolidTableType<typeof _features, Person>
}) {
return (
<div class="tbody">
<For each={table.getRowModel().rows}>
{(row) => (
<div class="tr">
<For each={row.getAllCells()}>
{(cell) => {
// simulate expensive render
for (const _ of Array.from({ length: 10000 })) {
Math.random()
}
return (
<div
class="td"
style={{
width: `calc(var(--col-${cell.column.id}-size) * 1px)`,
}}
>
{cell.renderValue<any>()}
</div>
)
}}
</For>
</div>
)}
</For>
</div>
)
}
export default App