Table RS

Edit Component

📊 Table RS Yew Usage

Adding Table RS to your project is simple:

  1. Make sure your project is set up with Yew. Follow their Getting Started Guide for setup instructions.

  2. Add the Table RS component to your dependencies by including it in your Cargo.toml file:

    cargo add table-rs --features=yew
    
  3. Import the Table component into your Yew component and start using it in your app.

🛠️ Usage

Incorporating Table RS into your Yew application is easy. Follow these steps:

  1. Import the Table component into your Yew project:

    use yew::prelude::*;
    use table_rs::yew::table::Table;
    use table_rs::yew::types::Column;
    use maplit::hashmap;
  2. Use the Table component within your Yew application:

    use yew::prelude::*;
    use table_rs::yew::table::Table;
    use table_rs::yew::types::Column;
    use maplit::hashmap;
    
    
    #[function_component(App)]
    pub fn app() -> Html {
        let data = vec![
            hashmap! { "name" => "Ferris".to_string(), "email" => "ferris@opensass.org".to_string() },
            hashmap! { "name" => "Ferros".to_string(), "email" => "ferros@opensass.org".to_string() },
            hashmap! { "name" => "Crab".to_string(), "email" => "crab@opensass.org".to_string() },
        ];
    
        let columns = vec![
            Column {
                id: "name",
                header: "Name",
                sortable: true,
                ..Default::default()
            },
            Column {
                id: "email",
                header: "Email",
                sortable: false,
                ..Default::default()
            },
        ];
    
        html! {
            <Table data={data} columns={columns} />
        }
    }

🔧 Props

Table Component Props

Main Props

PropertyTypeDescriptionDefault
dataVec<HashMap<&'static str, String>>The row data to be rendered in the table.[]
columnsVec<Column>List of column definitions.[]
page_sizeusizeNumber of rows per page.10
loadingboolWhether to show a loading state.false
paginateboolEnables pagination UI.false
searchboolEnables search input field.false
classesTableClassesCSS class names for customization.See below
stylesHashMap<&'static str, &'static str>Inline styles for different parts of the table.{}
textsTableTextsCustomizable text labels for UI elements.See below

Column Props

PropertyTypeDescriptionDefault
id&'static strKey used to fetch data from row objects.""
header&'static strText shown in the table header.""
accessorCallback<()>Optional callback for custom rendering or cell behavior.Callback::noop()
sortableboolWhether this column can be sorted.false
min_widthu32Minimum width for the column in pixels.100
styleOption<&'static str>Optional inline styles for the column header.Some("padding: 8px; font-weight: 600; text-align: left;")
classOption<&'static str>Optional CSS class for the column header.Some("table-header-cell")

TableClasses (Class Name Overrides)

PropertyTypeDescriptionDefault
container&'static strWrapper container for the whole table."table-container"
table&'static strThe <table> element."table"
thead&'static strThe <thead> element."thead"
tbody&'static strThe <tbody> element."tbody"
pagination&'static strPagination controls wrapper."pagination-controls"
search_input&'static strClass for the search input element."search-input"
header_cell&'static strClass for table header cells (<th>)."th"
body_cell&'static strClass for table body cells (<td>)."td"
row&'static strClass for rows (<tr>)."tr"
loading_row&'static strRow shown during loading state."loading-row"
empty_row&'static strRow shown when there's no data."empty-row"
pagination_button&'static strClass for pagination buttons."pagination-button"

TableTexts (UI Labels)

PropertyTypeDescriptionDefault
loading&'static strText shown during loading state."Loading..."
empty&'static strText shown when no data matches the filter."No results found"
search_placeholder&'static strPlaceholder text for search input."Search..."
previous_button&'static strLabel for the previous page button."Previous"
next_button&'static strLabel for the next page button."Next"
page_indicator&'static strFormat string for pagination text."Page {current} of {total}"

🧱 Style/Layout Structure

+-------------------------------------------------------------+
|                      [container]                            |  <-- class: "table-container"
|                                                             |
|   +-----------------------------------------------------+   |
|   |                    [search_input]                   |   |  <-- class: "search-input"
|   |          (optional search <input> element)          |   |
|   +-----------------------------------------------------+   |
|                                                             |
|   +-----------------------------------------------------+   |
|   |                       [table]                       |   |  <-- class: "table"
|   |   +--------------------[thead]--------------------+ |   |  <-- class: "thead"
|   |   |   Column Headers (e.g., Name, Email)          | |   |
|   |   +-----------------------------------------------+ |   |
|   |   +--------------------[tbody]--------------------+ |   |  <-- class: "tbody"
|   |   |  Data rows (from `data` prop, each row = <tr>)| |   |
|   |   +-----------------------------------------------+ |   |
|   +-----------------------------------------------------+   |
|                                                             |
|   +-----------------------------------------------------+   |
|   |                  [pagination]                       |   |  <-- class: "pagination-controls"
|   |   Page selector / next-prev buttons (if enabled)    |   |
|   +-----------------------------------------------------+   |
+-------------------------------------------------------------+

💡 Notes

  • The data must match the id values defined in each Column.
  • The search prop enables input-based filtering across all columns.
  • Pagination is controlled using the page_size and paginate props.
  • Sorting is column-specific via sortable = true and on_sort_column.
  • All style classes can be customized via TableClasses.
  • All texts are configurable via TableTexts.
  • The component handles loading and empty states out-of-the-box.
  • You can inject additional per-column styling via Column.style and Column.class.

📊 Benchmark: TanStack Table vs Table RS

MetricTanStack Table (React)Table RS (Yew + WASM)
Page Load Time (1M rows)~10 seconds~2 seconds
Memory Heap Usage>3 GB (heap overflow)~1.1 GB (stable)
Initial RenderingHeavy blocking, slow DOM paintEfficient, lightweight rendering
Browser ResponsivenessDelayed interactivitySmooth after hydration
Sorting Performance2-4s for large columnsSub-1s due to WASM speed
Search PerformanceAcceptable, but slowerInstantaneous, even at scale
Lighthouse Performance Score49/10060/100
ScalabilityLimited due to memory and VDOMNear-native scalability

🟨 TanStack Table (React)

  • Uses Virtual DOM and JS heap to manage massive data.
  • Runtime bottlenecks emerge with >100k rows.
  • Memory allocation during sorting and filtering can spike to 3GB+, often leading to heap overflow during intensive usage.
  • Lighthouse audit shows poor TTI and CPU blocking.

🟩 Table RS (Yew + WASM)

  • WASM-compiled logic is highly memory-efficient and deterministic.
  • DOM rendering is direct, bypassing React's reconciliation.
  • ~1.1 GB of memory heap used even with 1 million rows.
  • Built-in support for search/sort with stable paging.
  • No hydration issues (client-only generation).
  • Lighthouse performance significantly better, especially in CPU/Memory metrics.

For large-data UI benchmarks like tables with millions of rows, table-rs in Yew/WASM is a superior choice compared to React + TanStack.

Usage

CLI Usage

You can import Table RS directly into your project to customize and modify it using the opensass cli:

os add table-rs yew