Row Pinning Feature Guide
Material React Table has a powerful row pinning feature that allows you to either pin rows to the top and bottom of the table as a user scrolls, or pin rows to the top and bottom of the table regardless of scrolling.
Relevant Table Options
# | Prop Name 0 | Type 0 | Default Value 0 | More Info Links 0 | |
---|---|---|---|---|---|
1 |
| ||||
2 |
|
| |||
3 |
| TanStack Table Pinning Docs | |||
4 |
|
| |||
Relevant State
# | State Option 0 | Type 0 | Default Value 0 | More Info Links 0 | |
---|---|---|---|---|---|
1 |
|
| TanStack Table Column Pinning Docs | ||
Row Pinning Display Modes
You can enable the row pinning feature with the enableRowPinning
table option. There are multiple display modes that you can choose from with the rowPinningDisplayMode
table option.
const table = useMaterialReactTable({columns,data,enableRowPinning: true,rowPinningDisplayMode: 'sticky', // default});
sticky
- This is the default display mode. It will make rows stick to the top and bottom of the table as a user scrolls.top
- This will statically pin rows to the top of the table upon pinning.bottom
- This will statically pin rows to the bottom of the table upon pinning.top-and-bottom
- This allows the user to statically pin rows to either the top or bottom of the table.select-sticky
- This pins selected rows to the top and bottom of the table as a user scrolls. (alternative pinning UI)select-top
- This statically pins selected rows to the top of the table upon pinning. (alternative pinning UI)select-bottom
- This statically pins selected rows to the bottom of the table upon pinning. (alternative pinning UI)
Sticky Row Pinning
By default, the row pinning feature will add a position sticky style to the pinned rows. This means that the pinned rows will stay in place if the row is already in view. However, the rows will stay in view as the user scrolls up or down.
Sticky row pinning will work best if you give your rows a fixed height, or at least disable any kind of whitespace wrapping.
const table = useMaterialReactTable({columns,data,enableRowPinning: true,muiTableBodyRowProps: ({ row, table }) => {const { density } = table.getState();return {sx: {//Set a fixed height for pinned rowsheight: row.getIsPinned()? `${//Default mrt row height estimates. Adjust as needed.density === 'compact' ? 37 : density === 'comfortable' ? 53 : 69}px`: undefined,},};},rowPinningDisplayMode: 'sticky', // default});
Pin | First Name 0 | Last Name 0 | Email 0 | City 0 |
---|---|---|---|---|
Dylan | Murray | dmurray@yopmail.com | East Daphne | |
Raquel | Kohler | rkholer33@yopmail.com | Columbus | |
Ervin | Reinger | ereinger@mailinator.com | South Linda | |
Brittany | McCullough | bmccullough44@mailinator.com | Lincoln | |
Branson | Frami | bframi@yopmain.com | New York | |
Ben | Murray | benm@email.com | Salt Lake City | |
Elena | Smith | esmith@yopmail.com | Los Angeles | |
Michael | Johnson | mjohnson@mailinator.com | Chicago | |
Sophia | Brown | sbrown@yopmail.com | Houston | |
Lucas | Davis | ldavis@mailinator.com | Phoenix | |
Olivia | Garcia | ogarcia@yopmail.com | Philadelphia | |
Liam | Rodriguez | lrodriguez@mailinator.com | San Antonio | |
Emma | Martinez | emartinez@yopmail.com | San Diego | |
Noah | Hernandez | nhernandez@mailinator.com | Dallas | |
Ava | Lopez | alopez@yopmail.com | San Jose | |
William | Gonzalez | wgonzalez@mailinator.com | Austin | |
Isabella | Wilson | iwilson@yopmail.com | Jacksonville | |
James | Anderson | janderson@mailinator.com | Fort Worth | |
Mia | Thomas | mthomas@yopmail.com | Columbus | |
Alexander | Taylor | ataylor@mailinator.com | Charlotte | |
Grace | Moore | gmoore@yopmail.com | Indianapolis | |
Ethan | White | ewhite@mailinator.com | San Francisco | |
Lily | Harris | lharris@yopmail.com | Seattle | |
Daniel | Martin | dmartin@mailinator.com | Denver | |
Zoe | Jackson | zjackson@yopmail.com | Boston | |
Matthew | Thompson | mthompson@mailinator.com | Nashville | |
Ella | Garcia | egarcia@yopmail.com | Detroit | |
David | Martinez | dmartinez@mailinator.com | Portland | |
Aria | Robinson | arobinson@yopmail.com | Las Vegas | |
Joseph | Clark | jclark@mailinator.com | Baltimore |
1import { useMemo } from 'react';2import {3 MaterialReactTable,4 useMaterialReactTable,5 type MRT_ColumnDef,6} from 'material-react-table';7import { data, type Person } from './makeData';89const Example = () => {10 const columns = useMemo<MRT_ColumnDef<Person>[]>(11 () => [12 {13 accessorKey: 'firstName',14 header: 'First Name',15 },16 {17 accessorKey: 'lastName',18 header: 'Last Name',19 },20 {21 accessorKey: 'email',22 header: 'Email',23 },24 {25 accessorKey: 'city',26 header: 'City',27 },28 ],29 [],30 );3132 const table = useMaterialReactTable({33 columns,34 data,35 enableRowPinning: true,36 enablePagination: false,37 enableStickyHeader: true,38 getRowId: (row) => row.email,39 initialState: {40 rowPinning: {41 top: ['rkholer33@yopmail.com', 'egarcia@yopmail.com'],42 bottom: [],43 },44 },45 muiTableContainerProps: {46 sx: {47 maxHeight: '400px',48 },49 },50 muiTableBodyRowProps: ({ row, table }) => {51 const { density } = table.getState();52 return {53 sx: {54 //Set a fixed height for pinned rows55 height: row.getIsPinned()56 ? `${57 //Default mrt row height estimates. Adjust as needed.58 density === 'compact' ? 37 : density === 'comfortable' ? 53 : 6959 }px`60 : undefined,61 },62 };63 },64 });6566 return <MaterialReactTable table={table} />;67};6869export default Example;70
Note: Sticky Row Pinning is not currently compatible with row virtualization.
Static Row Pinning
Some of the other row pinning modes will show pinned rows at the top or bottom of the the table regardless of scrolling. This is a simpler implementation of the row pinning feature.
Static row pinning does not require set row heights, as they will render in a normal <tbody>
element that itself is what is sticky.
Pin | First Name 0 | Last Name 0 | Email 0 | City 0 |
---|---|---|---|---|
Dylan | Murray | dmurray@yopmail.com | East Daphne | |
Raquel | Kohler | rkholer33@yopmail.com | Columbus | |
Ervin | Reinger | ereinger@mailinator.com | South Linda | |
Brittany | McCullough | bmccullough44@mailinator.com | Lincoln | |
Branson | Frami | bframi@yopmain.com | New York | |
Ben | Murray | benm@email.com | Salt Lake City | |
Elena | Smith | esmith@yopmail.com | Los Angeles | |
Michael | Johnson | mjohnson@mailinator.com | Chicago | |
Sophia | Brown | sbrown@yopmail.com | Houston | |
Lucas | Davis | ldavis@mailinator.com | Phoenix | |
Olivia | Garcia | ogarcia@yopmail.com | Philadelphia | |
Liam | Rodriguez | lrodriguez@mailinator.com | San Antonio | |
Emma | Martinez | emartinez@yopmail.com | San Diego | |
Noah | Hernandez | nhernandez@mailinator.com | Dallas | |
Ava | Lopez | alopez@yopmail.com | San Jose | |
William | Gonzalez | wgonzalez@mailinator.com | Austin | |
Isabella | Wilson | iwilson@yopmail.com | Jacksonville | |
James | Anderson | janderson@mailinator.com | Fort Worth | |
Mia | Thomas | mthomas@yopmail.com | Columbus | |
Alexander | Taylor | ataylor@mailinator.com | Charlotte | |
Grace | Moore | gmoore@yopmail.com | Indianapolis | |
Ethan | White | ewhite@mailinator.com | San Francisco | |
Lily | Harris | lharris@yopmail.com | Seattle | |
Daniel | Martin | dmartin@mailinator.com | Denver | |
Zoe | Jackson | zjackson@yopmail.com | Boston | |
Matthew | Thompson | mthompson@mailinator.com | Nashville | |
Ella | Garcia | egarcia@yopmail.com | Detroit | |
David | Martinez | dmartinez@mailinator.com | Portland | |
Aria | Robinson | arobinson@yopmail.com | Las Vegas | |
Joseph | Clark | jclark@mailinator.com | Baltimore |
1import { useMemo } from 'react';2import {3 MaterialReactTable,4 useMaterialReactTable,5 type MRT_ColumnDef,6} from 'material-react-table';7import { data, type Person } from './makeData';89const Example = () => {10 const columns = useMemo<MRT_ColumnDef<Person>[]>(11 () => [12 {13 accessorKey: 'firstName',14 header: 'First Name',15 },16 {17 accessorKey: 'lastName',18 header: 'Last Name',19 },20 {21 accessorKey: 'email',22 header: 'Email',23 },24 {25 accessorKey: 'city',26 header: 'City',27 },28 ],29 [],30 );3132 const table = useMaterialReactTable({33 columns,34 data,35 enableRowPinning: true,36 enablePagination: false,37 enableStickyHeader: true,38 rowPinningDisplayMode: 'top-and-bottom',39 getRowId: (row) => row.email,40 muiTableContainerProps: {41 sx: {42 maxHeight: '400px',43 },44 },45 });4647 return <MaterialReactTable table={table} />;48};4950export default Example;51
Alternative Selection Row Pinning UI
By default, the row pinning feature adds a pinning display column with pinning buttons for each row. However, you can instead combine the row pinning feature with the row selection feature to pin selected rows.
const table = useMaterialReactTable({columns,data,enableRowPinning: true,enableRowSelection: true,rowPinningDisplayMode: 'select-sticky',});
First Name 0 | Last Name 0 | Email 0 | City 0 | |
---|---|---|---|---|
Dylan | Murray | dmurray@yopmail.com | East Daphne | |
Raquel | Kohler | rkholer33@yopmail.com | Columbus | |
Ervin | Reinger | ereinger@mailinator.com | South Linda | |
Brittany | McCullough | bmccullough44@mailinator.com | Lincoln | |
Branson | Frami | bframi@yopmain.com | New York | |
Ben | Murray | benm@email.com | Salt Lake City | |
Elena | Smith | esmith@yopmail.com | Los Angeles | |
Michael | Johnson | mjohnson@mailinator.com | Chicago | |
Sophia | Brown | sbrown@yopmail.com | Houston | |
Lucas | Davis | ldavis@mailinator.com | Phoenix | |
Olivia | Garcia | ogarcia@yopmail.com | Philadelphia | |
Liam | Rodriguez | lrodriguez@mailinator.com | San Antonio | |
Emma | Martinez | emartinez@yopmail.com | San Diego | |
Noah | Hernandez | nhernandez@mailinator.com | Dallas | |
Ava | Lopez | alopez@yopmail.com | San Jose | |
William | Gonzalez | wgonzalez@mailinator.com | Austin | |
Isabella | Wilson | iwilson@yopmail.com | Jacksonville | |
James | Anderson | janderson@mailinator.com | Fort Worth | |
Mia | Thomas | mthomas@yopmail.com | Columbus | |
Alexander | Taylor | ataylor@mailinator.com | Charlotte | |
Grace | Moore | gmoore@yopmail.com | Indianapolis | |
Ethan | White | ewhite@mailinator.com | San Francisco | |
Lily | Harris | lharris@yopmail.com | Seattle | |
Daniel | Martin | dmartin@mailinator.com | Denver | |
Zoe | Jackson | zjackson@yopmail.com | Boston | |
Matthew | Thompson | mthompson@mailinator.com | Nashville | |
Ella | Garcia | egarcia@yopmail.com | Detroit | |
David | Martinez | dmartinez@mailinator.com | Portland | |
Aria | Robinson | arobinson@yopmail.com | Las Vegas | |
Joseph | Clark | jclark@mailinator.com | Baltimore |
1import { useMemo } from 'react';2import {3 MaterialReactTable,4 useMaterialReactTable,5 type MRT_ColumnDef,6} from 'material-react-table';7import { data, type Person } from './makeData';89const Example = () => {10 const columns = useMemo<MRT_ColumnDef<Person>[]>(11 //column definitions...32 );3334 const table = useMaterialReactTable({35 columns,36 data,37 enablePagination: false,38 enableRowPinning: true,39 enableRowSelection: true,40 enableStickyHeader: true,41 rowPinningDisplayMode: 'select-sticky',42 getRowId: (row) => row.email,43 initialState: {44 rowPinning: {45 top: ['ereinger@mailinator.com'],46 },47 rowSelection: {48 'ereinger@mailinator.com': true,49 },50 },51 muiTableContainerProps: {52 sx: {53 maxHeight: '400px',54 },55 },56 muiTableBodyRowProps: ({ row, table }) => {57 const { density } = table.getState();58 return {59 sx: {60 //Set a fixed height for pinned rows61 height: row.getIsPinned()62 ? `${63 //Default mrt row height estimates. Adjust as needed.64 density === 'compact' ? 37 : density === 'comfortable' ? 53 : 6965 }px`66 : undefined,67 },68 };69 },70 });7172 return <MaterialReactTable table={table} />;73};7475export default Example;76