Table
Tables display sets of data organized in rows and columns.
Introduction
The Joy UI Table component lets you use plain HTML structure to assemble a table in JSX.
ID | Job Title | Name |
---|---|---|
1 | Doctor | Chris Johnson |
2 | Electrician | Joseph Morris |
3 | Operator | Aiden Moreno |
4 | Baker | Mike Simmons |
5 | Clerk | Enoch Addison |
Total | 4 people |
<Sheet>
<Table />
</Sheet>
Playground
Basics
Joy UI Table will apply the styles based on a table structure using <thead>
, <tbody>
, and <tfoot>
elements.
import Table from '@mui/joy/Table';
Dessert (100g serving) | Calories | Fat (g) | Carbs (g) | Protein (g) |
---|---|---|---|---|
Frozen yoghurt | 159 | 6 | 24 | 4 |
Ice cream sandwich | 237 | 9 | 37 | 4.3 |
Eclair | 262 | 16 | 24 | 6 |
Cupcake | 305 | 3.7 | 67 | 4.3 |
Gingerbread | 356 | 16 | 49 | 3.9 |
Customization
Column width
Use the sx
prop to target the header and provide the width as a number or percentage.
Columns that don't have an explicit width will spread equally to fill the rest of the area.
Column width (40%) | Calories | Fat (g) | Carbs (g) | Protein (g) |
---|---|---|---|---|
Frozen yoghurt | 159 | 6 | 24 | 4 |
Ice cream sandwich | 237 | 9 | 37 | 4.3 |
Eclair | 262 | 16 | 24 | 6 |
Cupcake | 305 | 3.7 | 67 | 4.3 |
Gingerbread | 356 | 16 | 49 | 3.9 |
Inline style
An alternative way of controlling the column's width is to use inline styles on the <th>
element:
<thead>
<tr>
<th style={{ width: '40%' }}>Column 1</th>
<th style={{ width: '64px' }}>Column 2</th>
</tr>
</thead>
Alignment
Use the sx
prop to target columns with the appropriate CSS selector and apply the text-align
property.
// target cells that are not the first in their respective rows.
<Table sx={{ '& tr > *:not(:first-child)': { textAlign: 'right' } }}>
Column width (40%) | Calories | Fat (g) | Carbs (g) | Protein (g) |
---|---|---|---|---|
Frozen yoghurt | 159 | 6 | 24 | 4 |
Ice cream sandwich | 237 | 9 | 37 | 4.3 |
Eclair | 262 | 16 | 24 | 6 |
Cupcake | 305 | 3.7 | 67 | 4.3 |
Gingerbread | 356 | 16 | 49 | 3.9 |
Variants
Table supports Joy UI's four global variants: plain
(default), outlined
, soft
, and solid
.
Dessert (100g serving) | Calories | Fat (g) | Carbs (g) | Protein (g) |
---|---|---|---|---|
Frozen yoghurt | 159 | 6 | 24 | 4 |
Ice cream sandwich | 237 | 9 | 37 | 4.3 |
Eclair | 262 | 16 | 24 | 6 |
Cupcake | 305 | 3.7 | 67 | 4.3 |
Gingerbread | 356 | 16 | 49 | 3.9 |
Sizes
The component comes in three sizes: sm
, md
(default), and lg
.
Dessert (100g serving) | Calories | Fat (g) | Carbs (g) | Protein (g) |
---|---|---|---|---|
Frozen yoghurt | 159 | 6 | 24 | 4 |
Ice cream sandwich | 237 | 9 | 37 | 4.3 |
Eclair | 262 | 16 | 24 | 6 |
Cupcake | 305 | 3.7 | 67 | 4.3 |
Gingerbread | 356 | 16 | 49 | 3.9 |
Stripe
To create contrast between rows, use the stripe
prop with odd
or even
values.
Dessert (100g serving) | Calories | Fat (g) | Carbs (g) | Protein (g) |
---|---|---|---|---|
Frozen yoghurt | 159 | 6 | 24 | 4 |
Ice cream sandwich | 237 | 9 | 37 | 4.3 |
Eclair | 262 | 16 | 24 | 6 |
Cupcake | 305 | 3.7 | 67 | 4.3 |
Gingerbread | 356 | 16 | 49 | 3.9 |
Hover
To highlight a row of the table body when hovering over it, set the hoverRow
prop to true.
Column width (40%) | Calories | Fat (g) | Carbs (g) | Protein (g) |
---|---|---|---|---|
Frozen yoghurt | 159 | 6 | 24 | 4 |
Ice cream sandwich | 237 | 9 | 37 | 4.3 |
Eclair | 262 | 16 | 24 | 6 |
Cupcake | 305 | 3.7 | 67 | 4.3 |
Gingerbread | 356 | 16 | 49 | 3.9 |
Border
Use the borderAxis
prop to control the border appearance.
Dessert (100g serving) | Calories | Fat (g) | Carbs (g) | Protein (g) |
---|---|---|---|---|
Frozen yoghurt | 159 | 6 | 24 | 4 |
Ice cream sandwich | 237 | 9 | 37 | 4.3 |
Eclair | 262 | 16 | 24 | 6 |
Cupcake | 305 | 3.7 | 67 | 4.3 |
Gingerbread | 356 | 16 | 49 | 3.9 |
Adding custom borders
Customize the table theme based on borderAxis
prop using the extendTheme()
function.
import { CssVarsProvider, extendTheme } from '@mui/joy/styles';
const theme = extendTheme({
components: {
JoyTable: {
styleOverrides: {
root: ({ ownerState }) => ({
...(ownerState.borderAxis === 'header' && {
// this example applies borders between <thead> and <tbody>
'& thead th:not([colspan])': {
borderBottom: '2px solid var(--TableCell-borderColor)',
},
}),
});
}
}
}
})
<CssVarsProvider theme={theme}>…</CssVarsProvider>
For TypeScript, you have to add the new values via module augmentation:
// this could be any file that's included in your tsconfig.json
declare module '@mui/joy/Table' {
interface TablePropsBorderAxisOverrides {
header: true;
}
}
Sticky header and footer
Set the stickyHeader
to true to always stick the header at the top as users scroll the table.
Set the stickyFooter
to true to always stick the footer at the bottom of the table.
The table body is scrollable.
Row | Calories | Fat (g) | Carbs (g) | Protein (g) |
---|---|---|---|---|
1 | 159 | 6 | 24 | 4 |
2 | 237 | 9 | 37 | 4.3 |
3 | 262 | 16 | 24 | 6 |
4 | 305 | 3.7 | 67 | 4.3 |
5 | 356 | 16 | 49 | 3.9 |
6 | 159 | 6 | 24 | 4 |
7 | 237 | 9 | 37 | 4.3 |
8 | 262 | 16 | 24 | 6 |
9 | 305 | 3.7 | 67 | 4.3 |
10 | 356 | 16 | 49 | 3.9 |
Totals | 2638.00 | 101.40 | 402.00 | 45.00 |
3186.4 Kcal |
Caption
Add a caption to summarize the contents of a Table by inserting a <caption>
element as the Table's first child.
Menu | Calories | Fat (g) | Carbs (g) | Protein (g) |
---|---|---|---|---|
Frozen yoghurt | 159 | 6 | 24 | 4 |
Ice cream sandwich | 237 | 9 | 37 | 4.3 |
Eclair | 262 | 16 | 24 | 6 |
Cupcake | 305 | 3.7 | 67 | 4.3 |
Gingerbread | 356 | 16 | 49 | 3.9 |
Menu | Calories | Fat (g) | Carbs (g) | Protein (g) |
---|---|---|---|---|
Frozen yoghurt | 159 | 6 | 24 | 4 |
Ice cream sandwich | 237 | 9 | 37 | 4.3 |
Eclair | 262 | 16 | 24 | 6 |
Cupcake | 305 | 3.7 | 67 | 4.3 |
Gingerbread | 356 | 16 | 49 | 3.9 |
Totals | 1,319 | 50.7 | 201 | 22.5 |
Row head
Set scope="row"
to <th>
elements inside <tbody>
to apply the same style as column headers.
The demo below illustrates a common use case: setting the first column to match the header styles.
Column width (40%) | Calories | Fat (g) | Carbs (g) | Protein (g) |
---|---|---|---|---|
Frozen yoghurt | 159 | 6 | 24 | 4 |
Ice cream sandwich | 237 | 9 | 37 | 4.3 |
Eclair | 262 | 16 | 24 | 6 |
Cupcake | 305 | 3.7 | 67 | 4.3 |
Gingerbread | 356 | 16 | 49 | 3.9 |
Row and column span
Use rowSpan
and columnSpan
to expand a cell across multiple rows or columns.
Name | ID | Membership Dates | Balance | |
---|---|---|---|---|
Joined | Canceled | |||
Margaret Nguyen | 427311 | n/a | 0.00 | |
Edvard Galinski | 533175 | 37.00 | ||
Hoshi Nakamura | 601942 | n/a | 15.00 |
Text ellipsis
To truncate the text, set noWrap
to true.
The header cells always truncate the text to keep the header's height predictable.
Name | Description (you should see a part of this message) |
---|---|
Morty D Ardiousdellois Addami Writer, Youtuber | Cras non velit nec nisi vulputate nonummy. Maecenas tincidunt lacus at velit. Vivamus vel nulla eget eros elementum pellentesque. Quisque porta volutpat erat. Quisque erat eros, viverra eget, congue eget, semper rutrum, nulla. |
Joseph Morriso | ℹ️In eleifend quam a odio. Suspendisse potenti in hac habitasse platea dictumst. |
CSS variables playground
Play around with the CSS variables available to the Table component to see how the design changes.
You can use these to customize the components with both the sx
prop and the theme.
Name | Role |
---|---|
Adam | Developer |
Joseph | Manager |
<Table />
CSS variables
Usage with Sheet
import Sheet from @mui/joy/Sheet
When Table becomes a child of Sheet component, the table header background is inherited from the Sheet.
Column width (40%) | Calories | Fat (g) | Carbs (g) | Protein (g) |
---|---|---|---|---|
Frozen yoghurt | 159 | 6 | 24 | 4 |
Ice cream sandwich | 237 | 9 | 37 | 4.3 |
Eclair | 262 | 16 | 24 | 6 |
Cupcake | 305 | 3.7 | 67 | 4.3 |
Gingerbread | 356 | 16 | 49 | 3.9 |
Color inversion
When color inversion is enabled, the Table's styles will adapt based on its variant.
Column width (40%) | Calories | Fat (g) | Carbs (g) | Protein (g) |
---|---|---|---|---|
Frozen yoghurt | 159 | 6 | 24 | 4 |
Ice cream sandwich | 237 | 9 | 37 | 4.3 |
Eclair | 262 | 16 | 24 | 6 |
Cupcake | 305 | 3.7 | 67 | 4.3 |
Gingerbread | 356 | 16 | 49 | 3.9 |
Common examples
Sort and selection
Use form components such as Button, Select and Switch to create sort and selection features.
Frozen yoghurt | 159 | 6 | 24 | 4 | |
---|---|---|---|---|---|
Ice cream sandwich | 237 | 9 | 37 | 4.3 | |
Eclair | 262 | 16 | 24 | 6 | |
Cupcake | 305 | 3.7 | 67 | 4.3 | |
Marshmallow | 318 | 0 | 81 | 2 | |
1–5 of 13 |
← Scroll direction →
Row | Calories | Fat (g) | Carbs (g) | Protein (g) | |
---|---|---|---|---|---|
1 | 159 | 6 | 24 | 4 | |
2 | 237 | 9 | 37 | 4.3 | |
3 | 262 | 16 | 24 | 6 | |
4 | 305 | 3.7 | 67 | 4.3 |
Dessert (100g serving) | Calories | Fat (g) | Carbs (g) | Protein (g) | |||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Frozen yoghurt | 159 | 6 | 24 | 4 | |||||||||||||
History
| |||||||||||||||||
Ice cream sandwich | 237 | 9 | 37 | 4.3 | |||||||||||||
Eclair | 262 | 16 | 24 | 6 | |||||||||||||
Cupcake | 305 | 3.7 | 67 | 4.3 | |||||||||||||
Gingerbread | 356 | 16 | 49 | 3.9 | |||||||||||||
Applying global variants
Use theme.variants.*
to apply global variant styles to the Table.
Player | Gloobles | Za'taak |
---|---|---|
TR-7 | 7 | 4,569 |
Khiresh Odo | 7 | 7,223 |
Mia Oolong | 9 | 6,219 |
Scrolling shadows
Inspired by this article from Lea Verou on CSS scrolling shadows, the shadows appear and hide when scrolling on the Table.
The table body is scrollable.
Row | Calories | Fat (g) | Carbs (g) | Protein (g) |
---|---|---|---|---|
1 | 159 | 6 | 24 | 4 |
2 | 237 | 9 | 37 | 4.3 |
3 | 262 | 16 | 24 | 6 |
4 | 305 | 3.7 | 67 | 4.3 |
5 | 356 | 16 | 49 | 3.9 |
6 | 159 | 6 | 24 | 4 |
7 | 237 | 9 | 37 | 4.3 |
8 | 262 | 16 | 24 | 6 |
9 | 305 | 3.7 | 67 | 4.3 |
10 | 356 | 16 | 49 | 3.9 |