Table

Organize and display large amout of data in table format.

The <Table> is a structured component used to organize and display tabular data in rows and columns. It enhances the functionality of regular <table> elements with the possibility to interact and select the data, and helps with accessibility by enabling keyboard navigation.

What is tabular data?

Tabular data is a structured form of data that is organized in rows and columns and resembles a table format.

Our table allows user to selecting one or multiple rows, it includes an action cell, and supports sorting columns. Additionally, it features a sticky header, can stretch to full size, and allows columns to be aligned to the left, center, or right. The table also supports nesting columns and having fixed column widths.

These features will be explained in more detail in the usage section further down the page.

Anatomy

A table is composed of a container element that organizes data into rows and columns. Each cell within the table can hold either plain text or focusable elements. If the table allows multiple row selection, the first column of each row include a checkbox for selecting that row and the first column header will contain a "select all" checkbox.

Anatomy of table

Appearance

The appearance of a component can be customized using the variant and size props. These props adjust the visual style and dimensions of the component, available values are based on the active theme.

Variant
Size
The selected theme does not has any options for "size".
IdEventDate
1234ConcertMittwoch, 10. Januar 2024
82374Open Air FestivalDienstag, 9. Juli 2024
724423Live on StageMontag, 25. November 2024
23497Open Air SummertimeSamstag, 1. Juni 2024
PropertyTypeDescription
variantdefault | grid | mutedThe available variants of this component.
size-The available sizes of this component.

Usage

Use a <Table> if you need to organize and display large amout of data. Grouping informations provide a structured and organized way to display data, making it easier to understand and analyze. Tables allow you to group related information in a clear and concise manner, which enhances data readability and comprehension.

They are ideal for comparing data points. Unlike cards, tables enable users to compare multiple rows and columns without having to move their eyes too much or rely on memory. Also with the support of single or multiple row actions, they make it convenient to perform data-specific actions such as deleting, sharing, or editing records directly within the table.

Do
Use tables with clear understandable content

Provide descriptive column headers for each column that accurately represent the data.

Don't
Dont use tables with empty column headers.

Avoid using vague or misleading column headers that do not clearly represent the data.

Do
Stretch tables to available width.
Stretch tables to available width.

Don't
Dont use tables for layouts
Don't use a table for layouting content.

Display secondary information

Secondary data in a cell is needed when additional context or details are necessary to fully understand the primary data. The primary data of a table cell should always be displayed clearly. It provides better readability and can improve the user experience. Too much secondary data can overwelm users and make the table complexer and harder to read.

IdNameUser
Do
Use tables with clear understandable content

Keep cell content concise. Only add additional data when necessary to help understand the data.

Don't
Dont use tables with too much informations inside

Avoid overloading cells with too much information or complex data, and multiple data values in one cell.

If you have large data tables, setting the header to sticky can provide context when scrolling. To do this, set the stickyHeader property on the <Table> and wrap it in the Scrollable component with a specified height, as shown in the example below.

IdNameUser

Highlight data

This is an example of how you can use the <Badge> within the <Table>. Badges can be used in a table to highlight or categorize certain data, making it easier for users to quickly identify key information. This is a common use case if you need to add status indicators, categorizations, labels or tags within the table.

IdEventDateStatus
16382462873ConcertMittwoch, 10. Januar 2024
updated
383262736Open Air FestivalDienstag, 9. Juli 2024
new
62836432Live on StageMontag, 25. November 2024-
82742834Open Air SummertimeSamstag, 1. Juni 2024
updated
78263482OperaDonnerstag, 12. Dezember 2024
new
9823742MusicalMontag, 19. August 2024
updated
Do

Place badges consistently within the table, preferably in a dedicated column.

Don't

Don't place badges randomly within the table or overload the table with too many badges.

Sorting

Enable the sorting function to help users organize and find data efficiently. This is especially useful since different user tasks may require different sorting orders.

The <Table> is sortable through allowsSorting prop on it. Sorting controls, indicated by an arrow icon, are located in the column headers and allow for ascending or descending order. For this purpose the properties onSortChange which handles the direction when changing and sortDescriptor, containing the current column and direction must be specified.

To make async sorting more convenient, you can use the useAsyncList hook. The hook manages the async list data and provides convenience methods for updating the data.

NameHeightMassBirth Year

Handling numeric values

With our formatting helper components for dates and numeric values you can easily ensure consistent and accurate display. See NumericFormat, DateFormat for more informations.

Also you see how to use the align property on the columns. With that you can set the content of a column to left, center or right.

EventDatePriceTicket Number
Music FestivalFreitag, 25. August 2023$50.00123456789
Red Carpet TheaterSonntag, 10. September 2023$150.00987654321
ConferenceDonnerstag, 5. Oktober 2023$220.50246813579
Sports TournamentMontag, 20. November 2023$75.00135792468
OperaMontag, 15. Mai 2023$500.00128216789
Do
  • Align numeric values and their header cells to the right.
  • Format numbers to provide tabular numeric font style.

Action on records

Action cells are useful when you need to perform actions. For example, if you need to edit the content of a cell, you can provide an action to open a modal and edit the fields associated with the content.

In this example an <ActionMenu> is used to make interaction possible. The table should only be used with one action cell at the end of the columns.

EventDateTicket NumberAction
Music FestivalFreitag, 25. August 2023123456789
Red Carpet TheaterSonntag, 10. September 2023987654321
ConferenceDonnerstag, 5. Oktober 2023246813579
Sports TournamentMontag, 20. November 2023135792468
OperaMontag, 15. Mai 2023128216789
Do

Only use one cell with one action at the end of the Table to call actions.

Don't
  • Don't use two or more action cells
  • Don't write two or more action components in one action cell.

Nested columns

Nested columns can be useful in tables when you need to organize complex or hierarchical data in a more structured format. These columns can be nested, which will result in more than one header row to be created.

Note the usage of isRowHeader in the example below. It controls which columns are included in the accessibility name for each row. By default, only the first column is included, meaning the aria label will be on the first column only.

NameInformation
First NameLast NameBirthdayAge
SamSmithMay 336
JuliaJonesFebruary 1024
PeterParkerSeptember 728
BruceWayneDecember 1832
Do

Keep nested columns simple to avoid overwhelming users with too much information at once. Only use one level of nesting.

Don't

Don't use multiple levels of nested columns, this can make the table complex and difficult to navigate.

Multiple Line Table

If your table contains cells with multiple lines of text, use the alignY="top" property on the <Table> component to align cell content to the top. This ensures text consistently starts at the top of each cell, making it easier to scan down columns. It also keeps buttons, text, and icons visually aligned, avoiding uneven spacing caused by varying content heights.

Props

Hint: Dynamic Collections

You don't have to hard code the table items, you could also create a dynamic collection and iterate through it. You can read more about these collections here.

Did you know? You can explore, test, and customize props live in Marigold's storybook. Watch the effects they have in real-time!

Table

alignY?
"top" | "middle";
Control the vertical alignment of table content.
Defaults to:
"middle"
children?
[
  ReactElement<TableHeaderProps<object>, string | JSXElementConstructor<any>>,
  ReactElement<TableBodyProps<object>, string | JSXElementConstructor<...>>,
];
The elements that make up the table. Includes the TableHeader, TableBody, Columns, and Rows.
collection?
TableCollection<object>;
A pre-constructed collection to use instead of building one from items and children.
defaultSelectedKeys?
Iterable<Key> | "all";
The initial selected keys in the collection (uncontrolled).
disableKeyboardNavigation?
boolean;
Disable keyboard navigation. Use if you have input fields in your table. Be aware that this is bad for accessibility.
Defaults to:
"false"
disabledBehavior?
DisabledBehavior;
Whether disabledKeys applies to all interactions, or only selection.
disabledKeys?
Iterable<Key>;
A list of row keys to disable.
disallowEmptySelection?
boolean;
Whether the collection allows empty selection.
emptyState?
() => ReactNode;
Content to display when there are no rows in the table.
focusMode?
"row" | "cell";
Whether initial grid focus should be placed on the grid row or grid cell.
Defaults to:
'row'
onCellAction?
(key: Key) => void;
Handler that is called when a user performs an action on the cell.
onRowAction?
(key: Key) => void;
Handler that is called when a user performs an action on the row.
onSelectionChange?
(keys: Selection) => void;
Handler that is called when the selection changes.
onSortChange?
(descriptor: SortDescriptor) => any;
Handler that is called when the sorted column or direction changes.
selectedKeys?
Iterable<Key> | "all";
The currently selected keys in the collection (controlled).
selectionBehavior?
SelectionBehavior;
How multiple selection should behave in the collection.
selectionMode?
SelectionMode;
The type of selection that is allowed in the collection.
Defaults to:
"none"
sortDescriptor?
SortDescriptor;
The current sorted column and direction.
stickyHeader?
boolean;
Make the column sticky to the top of the table.
Defaults to:
"true"
stretch?
boolean;
Stretch table to fill the container.
Defaults to:
"false"

Table.Header

children
ColumnElement<T> | (ColumnElement < T > []) | ColumnRenderer<T>;
A list of Column(s) or a function. If the latter, a list of columns must be provided using the columns prop.
columns?
T[]
A list of table columns.

Table.Column

allowsResizing?
boolean;
Whether the column allows resizing.
allowsSorting?
boolean;
Whether the column allows sorting.
childColumns?
T[]
A list of child columns used when dynamically rendering nested child columns.
children
ReactNode | ColumnElement<T> | (ColumnElement < T > []);
Static child columns or content to render as the column header.
defaultWidth?
ColumnSize | null;
The default width of the column.
isRowHeader?
boolean;
Whether a column is a row header and should be announced by assistive technology during row navigation.
maxWidth?
ColumnStaticSize | null;
The maximum width of the column.
minWidth?
ColumnStaticSize | null;
The minimum width of the column.
textValue?
string;
A string representation of the column's contents, used for accessibility announcements.
title?
ReactNode;
Rendered contents of the column if children contains child columns.
width?
WidthProp;
The width of the column.

Table.Body

children
RowElement<T> | (RowElement < T > []) | ((item: T) => RowElement<T>);
The contents of the table body. Supports static items or a function for dynamic rendering.
items?
Iterable<T>;
A list of row objects in the table body used when dynamically rendering rows.
loadingState?
LoadingState;
The current loading state of the table.
onLoadMore?
() => any;
Handler that is called when more items should be loaded, e.g. while scrolling near the bottom.

Table.Row

children
CellElement | CellElement[] | CellRenderer
Rendered contents of the row or row child items.
download?
string | boolean;
Causes the browser to download the linked URL. A string may be provided to suggest a file name. See MDN.
href?
string;
A URL to link to. See MDN.
hrefLang?
string;
Hints at the human language of the linked URL. SeeMDN.
ping?
string;
A space-separated list of URLs to ping when the link is followed. See MDN.
referrerPolicy?
HTMLAttributeReferrerPolicy;
How much of the referrer to send when following the link. See MDN.
rel?
string;
The relationship between the linked resource and the current page. See MDN.
routerOptions?
undefined;
Options for the configured client side router.
target?
HTMLAttributeAnchorTarget;
The target window for the link. See MDN.
textValue?
string;
A string representation of the row's contents, used for features like typeahead.

Table.Cell

children
ReactNode;
The contents of the cell.
colSpan?
number;
Indicates how many columns the data cell spans.
textValue?
string;
A string representation of the cell's contents, used for features like typeahead.

Alternative components

Choosing the right alternative to data tables is crucial for effectively displaying your data and enhancing user interaction. Depending on the type of data and the desired user experience, different components can offer different benefits. Here are some alternatives to data tables that might better suit your needs:

  • SelectionList: Displays a list of interactive items, useful to create an actionable list of related items, such as a list of users.

  • Cards: Helpful if the data needs to be displayed with more visual hierarchy. Keep in mind that you can't compare data in this way not as good as tables, because the eyes have to move much more.

  • List: When presenting a simple, linear collection of items, often with less data per item. Easy to read and navigate, especially for data that doesn’t require complex organization.

  • Grid: Layout in a table-like structure. This gives you full control over the size of the columns and rows and allows you to align them according to your needs.

  • Columns: Create columns in one row, useful if you need to align content in a table-like way with fewer rows.

Is there still not the right alternative for you please get in touch with us!

Last update: 7 minutes ago