| id | Table | |||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| cssPrefix | pf-v6-c-table | |||||||||||||||||||||||||||
| section | components | |||||||||||||||||||||||||||
| propComponents |
|
|||||||||||||||||||||||||||
| ouia | true |
Note: Table lives in its own package at @patternfly/react-table!
The Table component takes an explicit and declarative approach, and its implementation closely mirrors that of an HTML table.
The documentation for the deprecated table implementation can be found under the React deprecated tab. It is configuration based and takes a less declarative and more implicit approach to laying out the table structure, such as the rows and cells within it.
import { Fragment, isValidElement, useLayoutEffect, useCallback, useEffect, useRef, useState } from 'react'; import SearchIcon from '@patternfly/react-icons/dist/esm/icons/search-icon'; import CodeBranchIcon from '@patternfly/react-icons/dist/esm/icons/code-branch-icon'; import CodeIcon from '@patternfly/react-icons/dist/esm/icons/code-icon'; import CubeIcon from '@patternfly/react-icons/dist/esm/icons/cube-icon'; import LeafIcon from '@patternfly/react-icons/dist/esm/icons/leaf-icon'; import FolderIcon from '@patternfly/react-icons/dist/esm/icons/folder-icon'; import FolderOpenIcon from '@patternfly/react-icons/dist/esm/icons/folder-open-icon'; import SortAmountDownIcon from '@patternfly/react-icons/dist/esm/icons/sort-amount-down-icon'; import BlueprintIcon from '@patternfly/react-icons/dist/esm/icons/blueprint-icon'; import EllipsisVIcon from '@patternfly/react-icons/dist/esm/icons/ellipsis-v-icon'; import PencilAltIcon from '@patternfly/react-icons/dist/esm/icons/pencil-alt-icon'; import CheckIcon from '@patternfly/react-icons/dist/esm/icons/check-icon'; import RhMicronsCloseIcon from '@patternfly/react-icons/dist/esm/icons/rh-microns-close-icon';
import { css } from '@patternfly/react-styles'; import styles from '@patternfly/react-styles/css/components/Table/table'; import spacing from '@patternfly/react-styles/css/utilities/Spacing/spacing'; import textStyles from '@patternfly/react-styles/css/utilities/Text/text'; import inlineEditStyles from '@patternfly/react-styles/css/components/InlineEdit/inline-edit'; import t_global_background_color_secondary_default from '@patternfly/react-tokens/dist/esm/t_global_background_color_secondary_default';
This Table component differs from the deprecated Table component, in that it allows you to compose the table by nesting the relevant Thead, Tbody, Tr, Th and Td components within it. For a less declarative and more implicit approach, use the Table component instead.
Some general notes:
- Provide
dataLabelprop to theTdcomponents so that in mobile view the cell has a label to provide context. - If you want a table caption, simply place a
<Caption>My caption</Caption>as the first child within aTable. - You can set the
Tablevariant tocompact
- If you add the
noWrapprop toThead, it won't wrap it if there is no space - You can add the
textCenterprop toThorTdto center the contents - You can pass
className,styleand more toTr
To add a header tooltip or popover to Th, pass a ThInfoType object via the info prop.
To make a column sortable, pass a ThSortType object via the sort prop on a column's Th.
ThSortType includes an OnSort event handler which has the following signature:
type OnSort = (
event: React.MouseEvent,
columnIndex: number,
sortByDirection: SortByDirection,
extraData: IExtraColumnData
) => void;
The built in display for sorting is not fully responsive, as the column headers will be displayed per row when the screen size is small. To see a full page demo of a responsive sortable table, utilizing a toolbar item to control sorting for small screens, view the Sortable - responsive demo in the React demos tab.
Sorting a table may also be controlled manually with a toolbar control. To see a full page demo of a responsive table, view the Sortable - responsive demo in the React demos tab.
To make a row selectable, the table needs a selection column. The selection column is just another column, but with selection specific props added. We add it as the first header cell and also as the first body cell for each row.
To make a column sortable, pass a ThSelectType object via the select prop on a column's Th.
To make a row sortable, pass a TdSelectType object via the select prop on each rows's first Td.
Both the TdSelectType and the ThSelectType expect an OnSelect event handler with the following signature:
OnSelect:
type OnSelect = (
event: React.FormEvent<HTMLInputElement>,
isSelected: boolean,
rowIndex: number,
rowData: IRowData,
extraData: IExtraData
) => void;
Note: This example has a shift + select feature where holding shift while
checking checkboxes will check intermediate rows' checkboxes.
Similarly to the selectable example above, the radio buttons use the first column. The first header cell is empty, and each body row's first cell has radio button props.
This selectable rows feature is intended for use when a table is used to present a list of objects in a Primary-detail view.
This example shows a table with editable rows. Cells in a row can be edited after clicking on the edit icon.
This example demonstrates adding actions as the last column. The header's last cell is an empty cell, and each body row's last cell is an action cell.
To make a cell an action cell, render an ActionsColumn component inside a row's last Td and pass an array of IAction objects via the items prop of ActionsColumn.
If actions menus are getting clipped by other items on the page, such as sticky columns or rows, the ActionsColumn can be passed a menuAppendTo prop to adjust where the actions menu is appended.
When a table row contains mixed content of text and interactive elements, the hasAction property may be passed to a Td which contains interactive content like the below example's start Button. This will align buttons and other elements with other cells' text. Note that hasAction should not be used with Tds in an ActionsColumn because that comes with it's own spacing.
Using an OverflowMenu in the actions column, allowing the actions to condense into a dropdown if necessary for space.
To make a parent/child row pair expandable:
- Pass
isExpandabletoTable. - Make the first cell in every row an expandable cell by passing
TdExpandTypeobject to theexpandprop on theTd. - Wrap the content of each child row cell in
ExpandableRowContent. - Pass
isExpandedtoTbodyand theTrcontaining expandable content, and passisContentExpandedto theTrthat acts as the "control row".
The TdExpandType expects an OnCollapse event handler that has the following signature:
type OnCollapse = (
event: React.MouseEvent,
rowIndex: number,
isOpen: boolean,
rowData: IRowData,
extraData: IExtraData
) => void;
Note: Table column widths will respond automatically when toggling expanded rows. To retain column widths between expanded and collapsed states, column header and/or data cell widths must be set.
To make a parent/child row pair compound expandable:
- Pass
isExpandabletoTable. - Pass a
TdCompoundExpandTypeobject to thecompoundExpandprop on anyTdthat has an expandable child row. - Wrap the content of each child row cell in
ExpandableRowContent. - Pass
isExpandedtoTbodyand theTrcontaining expandable content, and passisContentExpandedto theTrthat acts as the "control row".
The TdCompoundExpandType expects an OnExpand event handler with the following signature
export type OnExpand = (
event: React.MouseEvent,
rowIndex: number,
colIndex: number,
isOpen: boolean,
rowData: IRowData,
extraData: IExtraData
) => void;
For a more complex compound expandable implementation with nested tables, see our table compound expansion demo.
If the "wrapModifier" property is set to "truncate", it's needed to ensure that the corresponding tooltip can be opened using both keyboard and screen reader. Since this particular Td element is generic and doesn't have any predefined decorators, the focus management required to trigger the tooltip needs to be handled manually by defining and manipulating the requisite props.
To make a row favoritable, the table needs a favoritable column.
Pass a TdFavoritesType object via the favorites prop on each rows's first Td in the favoritable column.
The TdFavoritesType expects an OnFavorite event handler with the following signature:
type OnFavorite = (
event: React.MouseEvent,
isFavorited: boolean,
rowIndex: number,
rowData: IRowData,
extraData: IExtraData
) => void;
To make a favoritable column sortable, pass a ThSortType object to the favoritable column's Th with isFavorites set to true.
To enable a tree table:
- Pass the
isTreeTableprop to theTablecomponent - Use a
TreeRowWrapperrather thanTr - Pass the following
propsto each row (both theTreeRowWrapperand thetreeRowin the first column):isExpanded- Flag indicating the node is expanded and its children are visibleisDetailsExpanded- (optional) Flag indicating the row's details are visible in responsive viewisHidden- Flag indicating the node's parent is expanded and this node is visiblearia-level- number representing how many levels deep this node is nestedaria-posinset- number representing where in the order this node sits amongst its siblingsaria-setsize- number representing the number of children this node hasisChecked- (optional) if this row uses checkboxes, flag indicating the checkbox checkedicon- (optional) ReactNode icon to display before the row titletoggleAriaLabel- (optional) accessible label for the expand/collapse children rows toggle arrowcheckAriaLabel- (optional) accessible label for the checkboxshowDetailsAriaLabel- (optional) accessible label for the show row details button in the responsive view
- The first
Tdin each row will pass the following to thetreeRowprop:onCollapse- Callback when user expands/collapses a row to reveal/hide the row's children.onCheckChange- (optional) Callback when user changes the checkbox on a row.onToggleRowDetails- (optional) Callback when user shows/hides the row details in responsive view.props- (as defined above)rowIndex- number representing the index of the row
Note: If this table is going to be tested using axe-core, the tests will flag the use of aria-level, aria-posinset, and aria-setsize as violations. This is an intentional choice at this time so that the voice over technologies will recognize the flat table structure as a tree.
To remove the inset used to leave space for the expand/collapse toggle in a flat tree table, use the hasNoInset prop on the Table component.
To make a row draggable:
- The table needs a draggable column.
- Each draggable
Trneeds to be passeddraggable,onDrop,onDragEnd, andonDragStartprops. - The
TbodyneedsonDragOver,onDrop, andonDragLeaveprops. - While the user is dragging a row, the
pf-m-drag-overclass needs to be applied toTable. - The draggable
Tdin each row needs aTdDraggableTypeobject passed to itsdraggableprop.
To make certain columns and the header sticky, the table must be wrapped in a combination of OuterScrollContainer and InnerScrollContainer. For sticky columns, only InnerScrollContainer is required. For sticky headers, and sticky headers with sticky columns, both containers are required to ensure the sticky behavior behaves correctly.
Note: Sticky table headers and columns have a higher z-index than the z-index used for menus (dropdown, select, etc). The intent is that the contents of a scrollable table will scroll under the sticky header/column, including any expanded menus. However, there may be use cases where a menu needs to appear on top of a sticky header/column, such as an expanded menu in a toolbar above a table with a sticky header.
There are a few ways this can be handled:
- Manipulate the
z-indexof the menu and/or table headers/columns manually. - Use the
menuAppendToprop in non-composable react components with menus to append the menu to an element outside of the table (e.g., the table's parent element) so that the menu has a higher stacking context than - and can appear on top of - sticky headers/columns as well as appear outside of any scrollable content in the table. - In the case where the menu is outside of the table (e.g., above the table in a toolbar, or below the table and the menu expands up), assign the entire table a lower
z-indexthan thez-indexof the menu. This creates a lower stacking context for the entire table compared to the menu, while preserving the stacking context of the elements inside of the table.
To make a column sticky, wrap Table with InnerScrollContainer and add the following properties to the Th or Td that should be sticky:
isStickyColumnhasRightBorderfor a left-aligned sticky column, orhasLeftBorderfor a right-aligned sticky column.
To prevent the default text wrapping behavior and allow horizontal scrolling, all Th or Td cells should also have the modifier="nowrap" property. To set the minimum width of the sticky column, use the stickyMinWidth property. For multiple sticky columns, use the stickyLeftOffset and stickyRightOffset properties for additional left or right sticky columns.
To make multiple left-aligned columns sticky:
- wrap
TablewithInnerScrollContainer - add
isStickyColumnto all columns that should be sticky - add
hasRightBorderto the rightmost sticky column - add
stickyLeftOffsetto each sticky column with a value that equals the combined width - set bystickyMindWidth- of the previous sticky columns. The leftmost sticky column should have a value of0, which is the default of this property.
To prevent the default text wrapping behavior and allow horizontal scrolling, all Th or Td cells should also have the modifier="nowrap" property.
To make multiple right-aligned columns sticky:
- wrap
TablewithInnerScrollContainer - add
isStickyColumnto all columns that should be sticky - add
hasLeftBorderto the leftmost sticky column - add
stickyRightOffsetto each sticky column with a value that equals the combined width - set bystickyMindWidth- of the next sticky columns. The rightmost sticky column should have a value of0, which is the default of this property.
To prevent the default text wrapping behavior and allow horizontal scrolling, all Th or Td cells should also have the modifier="nowrap" property.
To maintain proper sticky behavior across sticky columns and header, Table must be wrapped with OuterScrollContainer and InnerScrollContainer.
This example matches Sticky columns and header but uses the useTheadPinnedFromScrollParent hook with refs on InnerScrollContainer and Thead to toggle isPinned and apply the placeholder PINNED class when the inner scroll container has been scrolled. If the scroll-root ref is not set, the hook falls back to the exported getOverflowScrollParent helper using the thead ref.
To make a nested column header:
- Wrap
TablewithInnerScrollContainer. - Pass
nestedHeaderColumnSpanstoTable.nestedHeaderColumnSpansis an array of numbers representing the column spans of the top level columns toTable, where each number is equal to the number of sub columns for a column, or1if a column contains no sub columns. - Pass
hasNestedHeadertoThead. - Pass two
Tras children ofThead.
The first Tr represents the top level of columns, and each must pass either rowSpan if the column does not contain sub columns or colSpan if the column contains sub columns. The value of rowSpan is equal to the number of rows the nested header will span, typically 2, and the value of colSpan is equal to the number of sub columns in a column. Each Th except the last should also pass hasRightBorder.
The second Tr represents the second level of sub columns. The Th in this row each should pass isSubHeader, and the last sub column of a column should also pass hasRightBorder.
To apply striping to a basic table, add the isStriped property to Table.
To apply striping to an expandable table, add the isStriped and isExpandable properties to Table.
When there are multiple Tbody components within a table, a more granular application of striping may be controlled by adding either the isEvenStriped or isOddStriped properties to Tbody. These properties will stripe even or odd rows within that Tbody respectively.
To manually control striping, add the isStriped property to each desired Tr. This replaces adding the isStriped property to Table.