Skip to content

Virtualized DataGrid

Andrew Sutton edited this page Jun 26, 2024 · 3 revisions

This example renders 2,000 rows. Properties that are mandatory for a virtualized Data Grid:

  1. dataGridBody.height (The height of the virtualized container.)
  2. dataGridBody.itemSize (The size of each row.)
  3. dataGridBody.children (fun (trd: TableRowData<'T, 'TKeyType>) (style: obj) (index: int) -> ...) (Children render function for rows.)
  4. dataGridRow.style (taking the obj styling passed to it)

Fui.virtualized.dataGridRow also needs to be a ReactComponent that takes the props passed to it from dataGridBody.children

2024-06-2611-21-21-ezgif com-video-to-gif-converter

type Item = {
    File: Icon
    Author: Status
    LastUpdated: TimeStamp
    LastUpdate: Icon
    Index: int
}

let items = [
    for index in [ 1.. 500 ] do
        {
            File = { Label = "Meeting notes"; Icon = Fui.icon.documentRegular [] }
            Author = { Label = "Max Mustermann"; Status = [ presenceBadge.status.available; presenceBadge.size.extraSmall ] }
            LastUpdated = { Label = "7h ago"; TimeStamp = 1 }
            LastUpdate = { Label = "You edited this"; Icon = (Fui.icon.editRegular []) }
            Index = index
        }
        {
            File = { Label = "Thursday presentation"; Icon = Fui.icon.folderRegular [] }
            Author = { Label = "Erika Mustermann"; Status = [ presenceBadge.status.busy; presenceBadge.size.large ]  }
            LastUpdated = { Label = "Yesterday at 1:45pm"; TimeStamp = 2 }
            LastUpdate = { Label = "You recently opened this"; Icon = Fui.icon.openRegular [] }
            Index = index
        }
        {
            File = { Label = "Training recording"; Icon = Fui.icon.videoRegular [] }
            Author = { Label = "John Doe"; Status = [ presenceBadge.status.away; presenceBadge.size.small ]  }
            LastUpdated = { Label = "Yesterday at 1:45pm"; TimeStamp = 2 }
            LastUpdate = { Label = "You recently opened this"; Icon = Fui.icon.openRegular [] }
            Index = index
        }
        {
            File = { Label = "Purchase order"; Icon = Fui.icon.documentPdfRegular []  }
            Author = { Label = "Jane Doe"; Status = [ presenceBadge.status.offline; presenceBadge.size.tiny ] }
            LastUpdated = { Label = "Tue at 9:30 AM"; TimeStamp = 3 }
            LastUpdate = { Label = "You shared this in a Teams chat"; Icon = Fui.icon.peopleRegular []  }
            Index = index
        }
]

[<ReactComponent>]
let RenderRow (trd: TableRowData<Item, int>) (style: obj) (index: int) =
    Fui.virtualized.dataGridRow [
        dataGridRow.style style
        dataGridRow.key trd.rowId
        dataGridRow.children (fun (tcd: TableColumnDefinition<Item, int>) _ ->
            Fui.virtualized.dataGridCell [
                dataGridCell.focusMode.group
                dataGridCell.children [
                    tcd.renderCell(trd.item)
                ]
            ]
        )
    ]

[<ReactComponent>]
let DataGridTest () =
    let selectedRows, setSelectedRows = React.useState ([ ])
    let sortState, setSortState = React.useState((None, SortDirection.ascending))

    let columnSizingOptions = [
        tableColumnSizingOptions.staticColumnWidth ("file", 200)
        tableColumnSizingOptions.staticColumnWidth ("lastUpdate", 120)
        tableColumnSizingOptions.staticColumnWidth ("lastUpdated", 200)
        tableColumnSizingOptions.staticColumnWidth ("author", 150)
    ]

    let columns = [
        Fui.createTableColumn [
            createTableColumnOption.columnId "file"
            createTableColumnOption.compare (fun (a: Item) (b: Item) ->
                let a = $"{a.Index}-{a.File.Label}"
                let b = $"{b.Index}-{b.File.Label}"
                a.CompareTo (Some b))
            createTableColumnOption.renderHeaderCell (fun _ -> "File")
            createTableColumnOption.renderCell (fun item ->
                let key: string = $"[{item.Index}]-{item.File.Label}"
                Fui.tableCellLayout [
                    tableCellLayout.key key
                    tableCellLayout.media (
                        item.File.Icon
                    )
                    tableCellLayout.children [
                        Fui.text key
                    ]
                ]
            )
        ]
        Fui.createTableColumn [
            createTableColumnOption.columnId  "author"
            createTableColumnOption.compare  (fun a b -> a.Author.Label.CompareTo (b.Author.Label))
            createTableColumnOption.renderHeaderCell  (fun _ -> "Author")
            createTableColumnOption.renderCell  (fun item ->
                Fui.tableCellLayout [
                    tableCellLayout.key item.Author.Label
                    tableCellLayout.media (
                        Fui.avatar [
                            avatar.ariaLabel item.Author.Label
                            avatar.name item.Author.Label
                            avatar.badge item.Author.Status
                        ]
                    )
                    tableCellLayout.children [
                        Fui.text item.Author.Label
                    ]
                ]
            )
        ]
        Fui.createTableColumn [
            createTableColumnOption.columnId "lastUpdated"
            createTableColumnOption.compare (fun a b -> a.LastUpdated.TimeStamp - b.LastUpdated.TimeStamp)
            createTableColumnOption.renderHeaderCell (fun _ -> "Last Updated")
            createTableColumnOption.renderCell (fun item -> item.LastUpdated.Label)
        ]
        Fui.createTableColumn [
            createTableColumnOption.columnId "lastUpdate"
            createTableColumnOption.compare (fun a b -> a.LastUpdate.Label.CompareTo (b.LastUpdate.Label))
            createTableColumnOption.renderHeaderCell (fun _ -> "Last Update")
            createTableColumnOption.renderCell (fun item ->
                Fui.tableCellLayout [
                    tableCellLayout.key item.LastUpdate.Label
                    tableCellLayout.media (
                        item.LastUpdate.Icon
                    )
                    tableCellLayout.children [
                        Fui.text item.LastUpdate.Label
                    ]
                ]
            )
        ]
    ]

    Fui.virtualized.dataGrid [
        dataGrid.items items
        dataGrid.columns columns
        dataGrid.sortable true
        dataGrid.selectionAppearance.brand
        dataGrid.selectionMode.multiselect
        dataGrid.resizableColumnsOptions [ resizableColumnsOptions.autoFitColumns false ]
        dataGrid.selectedItems (selectedRows: list<string>)
        dataGrid.sortState sortState
        dataGrid.onSortChange (fun s -> setSortState s)
        dataGrid.resizableColumns true
        dataGrid.columnSizingOptions columnSizingOptions
        dataGrid.onSelectionChange (fun (data: OnSelectionChangeData<string>) -> setSelectedRows data.selectedItems)
        dataGrid.children [
            Fui.virtualized.dataGridHeader [
                Fui.virtualized.dataGridRow [
                    dataGridRow.children (fun tcd _ ->
                        Fui.virtualized.dataGridHeaderCell [
                            tcd.renderHeaderCell()
                        ]
                    )
                ]
            ]
            Fui.virtualized.dataGridBody [
                dataGridBody.itemSize 50
                dataGridBody.height 400
                dataGridBody.width 900
                dataGridBody.children (fun trd style index ->
                    RenderRow trd style index
                )
            ]
        ]
    ]
Clone this wiki locally