Skip to content

The DataTable component

With the styled bases in place, build the basic DataTable component. It receives the @tanstack/solid-table object and renders it. Create DataTable.fs:

namespace Partas.Solid.Example

open Partas.Solid
open Partas.Solid.TanStack.Table
open Fable.Core
open Fable.Core.JsInterop

[<Erase>]
type DataTable<'T>() =
    interface VoidNode
Why VoidNode?

DataTable takes no children, so it implements VoidNode. Passing it children is a compile error.

DataTable needs a property that receives the TanStack table object. In Partas.Solid.TanStack.Table its type is Table<'T>.

F# has several ways to declare an optional constructor parameter. Here it is [<DefaultValue>] with val mutable, which makes a get/set property. The value you would give it here never reaches the compiled output; only the type matters.

    [<DefaultValue>]
    val mutable table: Table<'T>

The body follows the @tanstack/table API:

[<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())
                                        }
                                }
                            }
                    }
                }
            }
        }
Why SolidTypeComponent and not SolidComponent?

With this implementation there is no real reason to use SolidTypeComponent, except that it lets you use the component the same way as the rest of the DSL.

DataTable does not spread any of the optional properties it might receive, such as class. To get something out of SolidTypeComponent, spread props into the top-level Table.

Next: Column definitions.

Edit this page