id | cssPrefix | section | propComponents | ouia | |||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Table |
pf-c-table |
components |
|
true |
Note: Table lives in its own package at @patternfly/react-table!
PatternFly has two implementations of a React table.
The first is the newer TableComposable
component. It takes a more explicit and declarative approach, and its implementation more closely mirrors that of an HTML table. Generally, updates and new feature requests are implemented in the TableComposable
.
The second is the original Table
component. It is configuration based and takes a less declarative and more implicit approach about laying out the table structure, such as the rows and cells within it. The documentation for the older table implementation can be found under the React legacy tab.
For most common use cases, we recommend using TableComposable
. Both implementations are supported and fully maintained.
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 { css } from '@patternfly/react-styles'; import styles from '@patternfly/react-styles/css/components/Table/table';
The TableComposable
component differs from the regular 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
dataLabel
prop to theTd
components 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 aTableComposable
. - You can set the
TableComposable
variant tocompact
- If you add the
noWrap
prop toThead
, it won't wrap it if there is no space - You can add the
textCenter
prop toTh
orTd
to center the contents - You can pass
className
,style
and 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 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
.
Useing 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:
- Make the first cell in every row an expandable cell by passing
TdExpandType
object to theexpand
prop on theTd
- Wrap the content of each child row cell in
ExpandableRowContent
. - Enclose each parent/child row pair in a
Tbody
component with anisExpanded
prop.
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 a
TdCompoundExpandType
object to thecompoundExpand
prop on anyTd
that has an expandable child row - Wrap the content of each child row cell in
ExpandableRowContent
. - Each child
Tr
has anisExpanded
prop.
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;
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
isTreeTable
prop to theTableComposable
component -
Use a
TreeRowWrapper
rather thanTr
-
Pass the following
props
to each row (both theTreeRowWrapper
and thetreeRow
in 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
Td
in each row will pass the following to thetreeRow
prop: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 make a row draggable:
- The table needs a draggable column.
- Each draggable
Tr
needs to be passeddraggable
,onDrop
,onDragEnd
, andonDragStart
props. - The
Tbody
needsonDragOver
,onDrop
, andonDragLeave
props. - While the user is dragging a row, the `` class needs to be applied to
TableComposable
. - The draggable
Td
in each row needs aTdDraggableType
object passed to itsdraggable
prop.
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-index
of the menu and/or table headers/columns manually. - Use the
menuAppendTo
prop 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-index
than thez-index
of 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 TableComposable
with InnerScrollContainer
and add the following properties to the Th
or Td
that should be sticky: isStickyColumn
and hasRightBorder
. 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.
To make multiple columns sticky, wrap TableComposable
with InnerScrollContainer
and add isStickyColumn
to all columns that should be sticky. The rightmost column should also have the hasRightBorder
property, and each sticky column after the first must define a stickyLeftOffset
property that equals the combined width of the previous sticky columns - set by stickyMinWidth
. 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, TableComposable
must be wrapped with OuterScrollContainer
and InnerScrollContainer
.
To make a nested column header:
- Wrap
TableComposable
withInnerScrollContainer
. - Pass
nestedHeaderColumnSpans
toTableComposable
.nestedHeaderColumnSpans
is an array of numbers representing the column spans of the top level columns toTableComposable
, where each number is equal to the number of sub columns for a column, or1
if a column contains no sub columns. - Pass
hasNestedHeader
toThead
. - Pass two
Tr
as 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 TableComposable
.
To apply striping to an expandable table, add the isStriped
and isExpandable
properties to TableComposable
.
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 TableComposable
.