Render the Table
Let's put it all together and render our first basic table before adding more elements.
module Partas.Solid.Example.TableTest
open Partas.Solidopen Partas.Solid.Example.TestColumnDefsopen Partas.Solid.TanStack.Tableopen Fable.Core
let userData = [| { Name = "Name"; Color = "Color"; Code = "Code" } { Name = "Name1"; Color = "Color1"; Code = "Code1" } { Name = "Name2"; Color = "Color2"; Code = "Code2" } |]
[<SolidComponent>]let Test () = let table = createTable( TableOptions<User>( getCoreRowModel = getCoreRowModel() ) .data(fun _ -> userData) .columns(fun _ -> columnDefs) ) DataTable(table = table)
Why are data & columns methods?
TanStack requires the data
and columns
to be get
properties of
the TableOptions
object passed to createTable
.
The .data
and .columns
method take care of this for you.
Code | Name | Color |
---|---|---|
Code | Name | Color |
Code1 | Name1 | Color1 |
Code2 | Name2 | Color2 |
All example code
module Partas.Solid.examples.datatable
open Partas.Solidopen Fable.Coreopen Fable.Core.JsInteropopen Partas.Solid.TanStack.Table
importSideEffects "~/app.css"
type [<Erase>] Lib = [<Import("twMerge", "tailwind-merge")>] static member twMerge (classes: string) : string = jsNative [<Import("clsx", "clsx")>] static member clsx(classes: obj): string = jsNative static member cn (classes: string array): string = classes |> Lib.clsx |> Lib.twMerge
[<Erase>]type TableCaption() = inherit caption() [<SolidTypeComponent>] member props.__ = caption(class' = Lib.cn [| "mt-4 text-sm text-muted-foreground" props.class' |]).spread props[<Erase>]type Table() = inherit table() [<SolidTypeComponent>] member props.__ = div(class' = "relative w-full overflow-auto") { table(class' = Lib.cn [| "w-full caption-bottom text-sm" props.class' |]).spread props }[<Erase>]type TableHeader() = inherit thead() [<SolidTypeComponent>] member props.constructor = thead(class' = Lib.cn [| "[&_tr]:border-b" props.class' |]) .spread props
[<Erase>]type TableBody() = inherit tbody() [<SolidTypeComponent>] member props.constructor = tbody(class' = Lib.cn [| "[&_tr:last-child]:border-0" props.class' |]).spread props
[<Erase>]type TableFooter() = inherit tfoot() [<SolidTypeComponent>] member props.constructor = tfoot(class' = Lib.cn [| "bg-primary font-medium text-primary-foreground" props.class' |]).spread props
[<Erase>]type TableRow() = inherit tr() [<SolidTypeComponent>] member props.constructor = tr( class' = Lib.cn [| "border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted" props.class' |] ).spread props
[<Erase>]type TableHead() = inherit th() [<SolidTypeComponent>] member props.constructor = th( class' = Lib.cn [| "h-10 px-2 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0" props.class' |] ).spread props
[<Erase>]type TableCell() = inherit td() [<SolidTypeComponentAttribute>] member props.constructor = td(class' = Lib.cn [| "p-2 align-middle [&:has([role=checkbox])]:pr-0"; props.class' |]).spread props[<Erase>]type DataTable<'T>() = interface VoidNode [<DefaultValue>] val mutable table: Table<'T> [<SolidTypeComponent>] member props.__ = let table = props.table Table() { TableHeader() { For(each = table.getHeaderGroups()) { yield fun headerGroup _ -> TableRow() { For(each = headerGroup.headers) { yield fun header _ -> TableHead(colspan = header.colSpan) { Show(when' = not header.isPlaceholder) { flexRender(header.column.columnDef.header, header.getContext()) } } } } } } TableBody() { Show( when' = unbox (table.getRowModel().rows.Length) ,fallback = (TableRow() { TableCell(colspan = (8), class' = "h-24 text-center") { "No Results." } }) ) { For(each = table.getRowModel().rows) { yield fun row _ -> TableRow().data("state", !!(row.getIsSelected() && !!"selected")) { For(each = row.getVisibleCells()) { yield fun cell _ -> TableCell() { flexRender(cell.column.columnDef.cell, cell.getContext()) } } } } } } }type User = { Code: string Name: string Color: string}[<SolidComponent>]let codeColumn = ColumnDef<User>( accessorFn = fun user _ -> user.Code ,header = !!"Code" ,cell = fun props -> div(class' = "w-14 hover:scale-102 flex justify-center bg-black text-white") { props.getValue() :?> string })[<SolidComponent>]let nameColumn = ColumnDef<User>( accessorFn = fun user _ -> user.Name ,header = !!"Name" ,cell = fun props -> div(class' = "w-14 hover:scale-102 flex justify-center bg-black text-white") { props.getValue() :?> string })[<SolidComponent>]let colorColumn = ColumnDef<User>( accessorFn = fun user _ -> user.Color ,header = !!"Color" ,cell = fun props -> div(class' = "w-14 hover:scale-102 flex justify-center bg-black text-white") { props.getValue() :?> string })
let columnDefs = [| codeColumn nameColumn colorColumn|]
let userData = [| { Name = "Name"; Color = "Color"; Code = "Code" } { Name = "Name1"; Color = "Color1"; Code = "Code1" } { Name = "Name2"; Color = "Color2"; Code = "Code2" } |]
[<SolidComponent>]let Test () = let table = createTable( TableOptions<User>( getCoreRowModel = getCoreRowModel() ) .data(fun _ -> userData) .columns(fun _ -> columnDefs) ) DataTable(table = table)
import { twMerge } from "tailwind-merge";import { clsx } from "clsx";import { Show, For, splitProps } from "solid-js";import { getCoreRowModel, createSolidTable, flexRender } from "@tanstack/solid-table";import { Record } from "../fable_modules/fable-library-js.5.0.0-alpha.13/Types.js";import { record_type, string_type } from "../fable_modules/fable-library-js.5.0.0-alpha.13/Reflection.js";import "~/app.css";
export function Lib_cn_Z35CD86D0(classes) { return twMerge(clsx(classes));}
export function TableCaption(props) { const [PARTAS_LOCAL, PARTAS_OTHERS] = splitProps(props, ["class"]); return <caption class={Lib_cn_Z35CD86D0(["mt-4 text-sm text-muted-foreground", PARTAS_LOCAL.class])} {...PARTAS_OTHERS} bool:n$={false} />;}
export function Table(props) { const [PARTAS_LOCAL, PARTAS_OTHERS] = splitProps(props, ["class"]); return <div class="relative w-full overflow-auto"> <table class={Lib_cn_Z35CD86D0(["w-full caption-bottom text-sm", PARTAS_LOCAL.class])} {...PARTAS_OTHERS} bool:n$={false} /> </div>;}
export function TableHeader(props) { const [PARTAS_LOCAL, PARTAS_OTHERS] = splitProps(props, ["class"]); return <thead class={Lib_cn_Z35CD86D0(["[&_tr]:border-b", PARTAS_LOCAL.class])} {...PARTAS_OTHERS} bool:n$={false} />;}
export function TableBody(props) { const [PARTAS_LOCAL, PARTAS_OTHERS] = splitProps(props, ["class"]); return <tbody class={Lib_cn_Z35CD86D0(["[&_tr:last-child]:border-0", PARTAS_LOCAL.class])} {...PARTAS_OTHERS} bool:n$={false} />;}
export function TableFooter(props) { const [PARTAS_LOCAL, PARTAS_OTHERS] = splitProps(props, ["class"]); return <tfoot class={Lib_cn_Z35CD86D0(["bg-primary font-medium text-primary-foreground", PARTAS_LOCAL.class])} {...PARTAS_OTHERS} bool:n$={false} />;}
export function TableRow(props) { const [PARTAS_LOCAL, PARTAS_OTHERS] = splitProps(props, ["class"]); return <tr class={Lib_cn_Z35CD86D0(["border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted", PARTAS_LOCAL.class])} {...PARTAS_OTHERS} bool:n$={false} />;}
export function TableHead(props) { const [PARTAS_LOCAL, PARTAS_OTHERS] = splitProps(props, ["class"]); return <th class={Lib_cn_Z35CD86D0(["h-10 px-2 text-left align-middle font-medium\r\n text-muted-foreground [&:has([role=checkbox])]:pr-0", PARTAS_LOCAL.class])} {...PARTAS_OTHERS} bool:n$={false} />;}
export function TableCell(props) { const [PARTAS_LOCAL, PARTAS_OTHERS] = splitProps(props, ["class"]); return <td class={Lib_cn_Z35CD86D0(["p-2 align-middle [&:has([role=checkbox])]:pr-0", PARTAS_LOCAL.class])} {...PARTAS_OTHERS} bool:n$={false} />;}
export function DataTable(props) { const [PARTAS_LOCAL, PARTAS_OTHERS] = splitProps(props, ["table"]); const table = PARTAS_LOCAL.table; return <Table> <TableHeader> <For each={table.getHeaderGroups()}> {(headerGroup, _arg) => <TableRow> <For each={headerGroup.headers}> {(header, _arg_1) => <TableHead colspan={header.colSpan}> <Show when={!header.isPlaceholder}> {flexRender(header.column.columnDef.header, header.getContext())} </Show> </TableHead>} </For> </TableRow>} </For> </TableHeader> <TableBody> <Show when={table.getRowModel().rows.length} fallback={<TableRow> <TableCell colspan={8} class="h-24 text-center"> No Results. </TableCell> </TableRow>}> <For each={table.getRowModel().rows}> {(row, _arg_2) => <TableRow data-state={row.getIsSelected() && "selected"}> <For each={row.getVisibleCells()}> {(cell, _arg_3) => <TableCell> {flexRender(cell.column.columnDef.cell, cell.getContext())} </TableCell>} </For> </TableRow>} </For> </Show> </TableBody> </Table>;}
export class User extends Record { constructor(Code, Name, Color) { super(); this.Code = Code; this.Name = Name; this.Color = Color; }}
export function User_$reflection() { return record_type("Partas.Solid.examples.datatable.User", [], User, () => [["Code", string_type], ["Name", string_type], ["Color", string_type]]);}
export const codeColumn = { accessorFn: (user, _arg) => user.Code, header: "Code", cell: (props) => <div class="w-14 hover:scale-102 flex justify-center bg-black text-white"> {props.getValue()} </div>,};
export const nameColumn = { accessorFn: (user, _arg) => user.Name, header: "Name", cell: (props) => <div class="w-14 hover:scale-102 flex justify-center bg-black text-white"> {props.getValue()} </div>,};
export const colorColumn = { accessorFn: (user, _arg) => user.Color, header: "Color", cell: (props) => <div class="w-14 hover:scale-102 flex justify-center bg-black text-white"> {props.getValue()} </div>,};
export const columnDefs = [codeColumn, nameColumn, colorColumn];
export const userData = [new User("Code", "Name", "Color"), new User("Code1", "Name1", "Color1"), new User("Code2", "Name2", "Color2")];
export function Test() { let this$_3, this$_1; const table = createSolidTable((this$_3 = ((this$_1 = { getCoreRowModel: getCoreRowModel(), }, (Object.defineProperty(this$_1, "data", { get: () => userData, }), this$_1))), (Object.defineProperty(this$_3, "columns", { get: () => columnDefs, }), this$_3))); return <DataTable table={table} />;}
Last updated: 7/10/25, 7:05 AM