Make data-driven table rendering easy with Dioxus

Overview

Dioxus Table

Make data-driven table rendering easy with Dioxus

Installation

Until the next release of Dioxus this requires Dioxus nightly from git. Thus no published crate yet. It is still easy to use in your project though. Add this to your Cargo.toml:

[dependencies]
dioxus-table = { git = "https://github.com/Synphonyte/dioxus-table", version = "0.1.0" }

Quickstart

Attach the derive macro TableData to a struct that represents a row of a table.

// in mod hotel:

#[derive(PartialEq, TableData)]
pub struct Hotel {
    #[table(class = "text-end")] // right align numbers
    pub id: i32,

    #[table(title = "Hotel Name")] // custom title
    pub name: String,

    pub city: String,
    
    #[table(skip)] // don't show this column
    pub internal: u32,
}

This generates a Dioxus component called Table in the module hotel ready to be used in your app.

// in your app:
use hotel::{Hotel, Table as HotelTable};

fn App(cx: Scope) -> Element {
    // get some hotels
    let hotels = vec![
        Hotel { id: 1, name: "Hotel 1".to_owned(), city: "City 1".to_owned(), internal: 42 },
        Hotel { id: 2, name: "Hotel 2".to_owned(), city: "City 2".to_owned(), internal: 42 },
    ];

    cx.render(rsx! {
        h1 { "Hotel Table" }
        HotelTable {
            class: "table",
            items: &hotels,
        }
    })
}

And that's it! Easy, right?

You can look at the examples in the examples directory to get a more complete overview of what dioxus-table can do.

Event Handlers

The generated table component provides two events: Clicking on a row or a head cell. Let's add some event handlers to our previous example.

cx.render(rsx! {
    h1 { "Hotel Table" }
    HotelTable {
        class: "table",
        items: &hotels,
        onrowclick: move |evt: TableRowEvent<_, _>| {
            web_sys::console::log_1(&format!("Row {}", evt.row_index).into());
        },
        onheadclick: move |evt: TableHeadEvent<_>| {
            web_sys::console::log_1(&format!("Head {} '{}'", evt.column_index, evt.field).into());
        },
    }
})

When you click on a head cell or on a data row you'll see some information logged to the console.

Customization

You can customize most aspects of the table rendering. Here is an overview of all available options.

Per-column/field options

Option Description
class HTML class(es) added to the <th> and <td> tags
cell_class HTML class(es) added only to the <td> cell tag
head_class HTML class(es) added only to the <th> head tag
title Custom title that is put into the <th>. By default the capitalized field name is used.
precision For decimal types this sets the number of digits after the decimal point
renderer Custom cell render component
skip Don't render this column

Per-table options

Option Description
row_class HTML class(es) added to the <tr> row tags except the first one (the header row)
head_row_class Added only to the first <tr> (the header row)
tag The HTML tag name used for the root of the table. Defaults to "table".
row_renderer Custom row renderer component
head_cell_renderer Custom head cell renderer component

Custom renderers

Custom renderers are a powerful way to customize almost all aspects of the table rendering. Yet they are very easy to use.

Custom cell renderer

Probably the most common use for a custom renderer is to customize the representation of a value in a table cell.

Let's say we have a table of books with a title and a rating field. The rating field is an integer number from 1 to 5 that represents the number of stars a book has received.

#[derive(PartialEq, TableData)]
pub struct Book {
    pub title: i32,
    pub rating: u8,
}

With the default renderer we only see a number in the "Rating" column. If we want to display this number as stars we can write a custom renderer.

#[derive(PartialEq, TableData)]
pub struct Book {
    pub title: i32,
    
    #[table(cell_renderer = "StarRenderer")] // specify the custom renderer
    pub rating: u8,
}

// The actual renderer component. It has to accept the DefaultTableCellProps.
pub fn StarRenderer(cx: Scope<DefaultTableCellProps<i32>>) -> Element {
    // the value of the rating field is provided as cx.props.value here
    let count = cx.props.value as usize; 

    // create a string with #count filled stars.
    let mut stars = "".to_owned();
    for _ in 0..count {
        stars += "β˜…";
    }
    // then fill up the rest of the 5 stars with emtpy stars
    for _ in count..5 {
        stars += "β˜†";
    }

    // display the string
    cx.render(rsx! {
        td {
            class: "{cx.props.class}",
            "{stars}"
        }
    })
}

Now the rating is properly displayed as stars. To see this in action run the hotels example in the examples/ folder.

Custom row and head cell renderers

They work basically the same as the cell renderers but are specified above the struct definition.

#[derive(PartialEq, TableData)]
#[table(row_renderer = "MyRowRenderer", head_cell_renderer = "MyHeadCellRenderer")]
pub struct Book {
    pub title: i32,
    pub rating: u8,
}

To see how to implement them please refer to the default renderers in src/cell_renderers.rs and src/row_enderers.rs. The easiest way to get going is to copy and paste the respective default renderer and customize from there.

You might also like...
Deploy dioxus-web to Vercel.

Dioxus demo This demo shows how to use Dioxus to build a static web application and deploy it to Vercel. Local development To run the demo locally, yo

An html macro for dioxus applications.

dioxus html macro This crate offers an html! like macro for dioxus applications. It expands to the equivalent rsx! macro call you would have made othe

Open source email client written in Rust and Dioxus. Under πŸ—οΈ
Open source email client written in Rust and Dioxus. Under πŸ—οΈ

Blazemail A full-featued, beautiful, mail client that doesn't suck. Works on mac, windows, linux, mobile, web, etc. Features, status Blazemail is curr

A library to provide abstractions to access common utilities when developing Dioxus applications.

🧰 Dioxus Standard Library πŸš€ A platform agnostic library for supercharging your productivity with Dioxus. dioxus-std is a Dioxus standard library tha

 (Pre-Release Software) Secure, Encrypted, P2P chat written atop Warp, IPFS, LibP2P, Dioxus and many more awesome projects and protocols.
(Pre-Release Software) Secure, Encrypted, P2P chat written atop Warp, IPFS, LibP2P, Dioxus and many more awesome projects and protocols.

Uplink Privacy First, Modular, P2P messaging client built atop Warp. Uplink is written in pure Rust with a UI in Dioxus (which is also written in Rust

🧬 Material Icons for Dioxus

🧬 Dioxus Material Icons This project provides a simple but configurable component to render Google's Material Icons in Dioxus. πŸš€ How to get started

πŸ¦€πŸ”¨ DevBcn Workshop - Full Stack Rust - Actix - Postgres - Shuttle - Dioxus
πŸ¦€πŸ”¨ DevBcn Workshop - Full Stack Rust - Actix - Postgres - Shuttle - Dioxus

Building a Movie Collection Manager - Full Stack Workshop with Rust, Actix, SQLx, Dioxus, and Shuttle Welcome to the this workshop! In this hands-on w

Fully-typed, async, reusable state management and synchronization for Dioxus 🧬

dioxus-query πŸ¦€ ⚑ Fully-typed, async, reusable state management and synchronization for Dioxus 🧬. Inspired by TanStack Query. ⚠️ Work in progress ⚠️

Resize observer hooks for Dioxus 🧬

dioxus-resize-observer Resize observer hooks for Dioxus 🧬. Support 0.1.0 - Dioxus v0.4 🧬 git - Dioxus v0.5 Web renderer (WASM) Example use dioxus::p

Owner
null
Execute Javascript code in the Dioxus, and get the return value ( for Dioxus )

Golde Dioxus Execute Javascript code in the Dioxus, and get the return value. This demo can help use Javascript to calc the + operator formula. use di

YuKun Liu 15 Dec 27, 2022
A template for starting a dioxus project to be used with dioxus-cli

A template for starting a dioxus project to be used with dioxus-cli

Dioxus 6 Nov 25, 2022
Fermyon Spin + Dioxus - Client Side Rendering (CSR) template with TailwindCSS

spin-dioxus-csr Fermyon Spin + Dioxus - Client Side Rendering (CSR) template with Tailwind Setup Accomodate "chicken & egg" issue for https://github.c

null 4 Apr 9, 2024
CLI tool for displaying table

tv Format json into table display $ cat test.json [ { "name": "test", "age": 10, "lang": "ja" }, { "name": "uzimaru", "age":

uzimaru0000 322 Jan 7, 2023
A more compact and intuitive ASCII table in your terminal: an alternative to "man 7 ascii" and "ascii"

asciit A more compact and intuitive ASCII table in your terminal: an alternative to man 7 ascii and ascii. Colored numbers and letters are much more e

Qichen Liu 刘启辰 5 Nov 16, 2023
Lightweight & Fast LWW CRDT Table

Lightweight & Fast LWW CRDT Table Supports millions of operations per second Suitable for real-time collaboration Supports delta updates It is a CRDT,

Zixuan Chen 26 Feb 24, 2024
A tiny crate to make it easy to share and apply Git hooks for Rust projects

Shareable git hooks for Rust project. Sloughi is a friend of Husky from North Africa! :algeria:

Walid ZIOUCHE 24 Oct 6, 2022
Workflows make it easy to browse, search, execute and share commands (or a series of commands)--without needing to leave your terminal.

Workflows The repo for all public Workflows that appear within Warp and within commands.dev. To learn how to create local or repository workflows, see

Warp 369 Jan 2, 2023
Workflows make it easy to browse, search, execute and share commands (or a series of commands)--without needing to leave your terminal.

Workflows The repo for all public Workflows that appear within Warp and within commands.dev. To learn how to create local or repository workflows, see

Warp 227 Jun 1, 2022
global state management for dioxus built on the concept of atoms. currently under πŸ—

Fermi: A global state management solution for Dioxus, inspired by Recoil.Js Fermi provides primitives for managing global state in Dioxus applications

Dioxus 15 Feb 12, 2022