Theme

npm_versionnpm Paragon package page

The DataTable component is a wrapper that uses the react-table library to create tables. It can be used as is, or its subcomponents can be used on their own, allowing the developer full control.

Paragon also exports all React hooks from react-table allowing the developers to use them and make customizations more freely without adding react-table as a separate dependency to their project. For full list of available hooks view react-table API reference.

How children get information

The table context gets the current react-table instance of the table from the DataTable component and makes it available to any child component within the DataTable provider. In addition to the react-table instance, itemCount, numBreakoutFilters, and bulkActions, and any props that are not listed in the props table below are available to child components through the DataTableContext.

How to use context in a custom component:

const instance = useContext(DataTableContext)

Frontend filtering and sorting

For small tables (less than ~10,000 rows), filtering, sorting and pagination can be done quickly and easily on the frontend.

In this example, a default TextFilter component is used for all columns. A default filter can be passed in, or a filter component can be defined on the column. See react-table filters documentation for more information.

Any Paragon component or export may be added to the code example.

Backend filtering and sorting

For larger tables, it may make sense to do filtering, pagination and sorting on the backend. The user must pass a fetchData function, which will be called when the filtering, sorting, or pagination data changes. The manualFilters, manualPagination, and manualSortBy props may also be needed.

When fetchData is called, it is given the necessary data to send a backend API request using the appropriate filters, page number, and/or ordering parameter. Once the request resolves, be sure to update the data prop to reflect the updated data.

Paginated selection

To enable proper selection behavior with backend pagination (i.e., when isSelectable is provided), for both individual rows and bulk actions, the controlled selection status and controlled select components must be used. When used, these components keep track of a user's row selections in a React context provider such that they persist during pagination, even when only 1 page of data is known at any given time. The following components must be used, as shown in the below example:

  • DataTable.ControlledSelectionStatus
  • DataTable.ControlledSelectHeader
  • DataTable.ControlledSelect
NOTE: While the below example doesn't demonstrate using true backend filtering, pagination, and sorting, it does mock the behavior of making an asynchronous API request and updating the table data.

Any Paragon component or export may be added to the code example.

View Switching

Card view is default when isDataViewToggleEnabled is true.

See dataViewToggleOptions props documentation for all supported props.

NOTE: you have to memoize data to persist filters choices during view switch, see code example below.

Any Paragon component or export may be added to the code example.

With a default active state specified

Any Paragon component or export may be added to the code example.

Loading state

Can be used to show the loading state when DataTable is asynchronously fetching new data.

Any Paragon component or export may be added to the code example.

Actions, Table actions and Bulk actions

Actions and bulk actions are actions that are performed on table rows, though bulk actions can be used for actions that apply to the whole table. It is up to the user to determine what the action does.

Table Actions

Table actions are actions that are enacted on the entire table. Their click handler is called with the react-table instance. The first two table actions will be displayed as buttons, while the remaining actions will be displayed in an overflow dropdown menu. Table actions are not visible if bulk actions are available and there are selected rows.

Bulk Actions

Bulk actions are action that are enacted on specific table rows. The bulk action click handler is called with the selected rows. The first two bulk actions will be displayed as buttons, while the remaining bulk actions will be displayed in a overflow dropdown menu. Bulk actions are not visible unless rows have been selected.

Actions

An action can also be defined as an additional column on the table. The Cell property can be defined to display any component that a user requires. It will receive the row as props. You can pass a function to render custom components for bulk actions and table actions.

Any Paragon component or export may be added to the code example.

Actions with Data view toggle enabled

Any Paragon component or export may be added to the code example.

CardView and alternate table components

You may choose to use any table component by using the following code in your display component:

const instance = useContext(DataTableContext)

The CardView takes a CardComponent that is personalized to the table in question and displays a responsive grid of cards.

Any Paragon component or export may be added to the code example.

Customizing number of Cards shown per row

Use columnSizes prop of CardView component to define how many Cards are shown per row at each breakpoint.

columnSizes is an object containing the desired column size at each breakpoint. The example below shows 1 Card per row at xs breakpoint, 2 Cards at sm and md, and 4 Cards at lg and higher. You can read more about the API at React-Bootstrap's grid documentation.

Any Paragon component or export may be added to the code example.

Horizontal view

You can also display Cards with horizontal view. If the table is selectable control position of selection checkbox with selectionPlacement prop, accepts right or left positions (relative to the Card).

Any Paragon component or export may be added to the code example.

For a more desktop friendly view, you can move filters into a sidebar by providing showFiltersInSidebar prop, try it out!

Any Paragon component or export may be added to the code example.

Expandable rows

DataTable supports expandable rows which once expanded render additional content under the row. Displayed content is controlled by the renderRowSubComponent prop, which is a function that receives row as its single prop and renders expanded view, you also need to pass isEpandable prop to DataTable to indicate that it should support expand behavior for rows. Finally, an additional column is required to be included into columns prop which will contain handlers for expand / collapse behavior, see examples below.

Default view

Here we use default expander column offered by Paragon and for each row render value of the name attribute as its subcomponent.

Any Paragon component or export may be added to the code example.

With custom expander column

You can create your own custom expander column and use it, see code example below.

Any Paragon component or export may be added to the code example.

Custom cell content

You can create your own cell content by passing the Cell property to a specific column.

Any Paragon component or export may be added to the code example.

maxSelectedRows and onMaxSelectedRows props

These props will allow us to handle the maximum number of selectable rows, which is necessary for validation. Using the maxSelectedRows prop, the implementation process can be simplified. You only need to pass the maximum number of rows you want to have selected.

After selecting the maximum possible number of rows, you can display an error message or perform other actions. This is achieved through the onMaxSelectedRows callback. In the example below, the callback will be executed when the table has 3 rows selected.

Any Paragon component or export may be added to the code example.

Theme Variables (SCSS)#

$data-table-background-color: $white !default;
$data-table-border: 1px solid $gray-200 !default;
$data-table-box-shadow: $box-shadow-sm !default;
$data-table-padding-x: .75rem !default;
$data-table-padding-y: .75rem !default;
$data-table-padding-small: .5rem !default;
$data-table-cell-padding: .5rem .75rem !default;
$data-table-footer-position: center !default;
$data-table-pagination-dropdown-max-height: 60vh !default;
$data-table-pagination-dropdown-min-width: 6rem !default;
$data-table-layout-sidebar-width: 12rem !default;

Props API#

DataTable Props API
  • columns shape {
    Header: func | node Required,
    accessor: requiredWhenNot(PropTypes.string, 'Cell'),
    Cell: func | element,
    Filter: func,
    filter: string,
    filterChoices: shape {
    name: string,
    number: number,
    value: string,
    }
    []
    ,
    }
    []
    Required

    Definition of table columns

  • data shape {}[] Required

    Data to be displayed in the table

  • isSelectable bool

    table rows can be selected

    Defaultfalse
  • manualSelectColumn shape {
    id: string Required,
    Header: func | node Required,
    Cell: func Required,
    disableSortBy: bool Required,
    }

    Alternate column for selecting rows. See react table useSort docs for more information

  • isSortable bool

    Table columns can be sorted

    Defaultfalse
  • manualSortBy bool

    Indicates that sorting will be done via backend API. A fetchData function must be provided

    Defaultfalse
  • isPaginated bool

    Paginate the table

    Defaultfalse
  • manualPagination bool

    Indicates that pagination will be done manually. A fetchData function must be provided

    Defaultfalse
  • pageCount requiredWhen(PropTypes.number, 'manualPagination')
  • isFilterable bool

    Table rows can be filtered, using a default filter in the default column values, or in the column definition

    Defaultfalse
  • manualFilters bool

    Indicates that filtering will be done via a backend API. A fetchData function must be provided

    Defaultfalse
  • defaultColumnValues shape {
    Filter: func | node,
    }

    defaults that will be set on each column. Will be overridden by individual column values

    Default{}
  • additionalColumns shape {
    id: string Required,
    Header: string | node,
    Cell: func | node,
    }
    []

    Actions or other additional non-data columns can be added here

    Default[]
  • fetchData func

    Function that will fetch table data. Called when page size, page index or filters change. Meant to be used with manual filters and pagination

    Defaultnull
  • initialState shape {
    pageSize: requiredWhen(PropTypes.number, 'isPaginated'),
    pageIndex: requiredWhen(PropTypes.number, 'isPaginated'),
    filters: requiredWhen(PropTypes.arrayOf(PropTypes.shape()), 'manualFilters'),
    sortBy: requiredWhen(PropTypes.arrayOf(PropTypes.shape()), 'manualSortBy'),
    selectedRowIds: shape {
    0: any,
    1: any,
    2: any,
    3: any,
    4: any,
    5: any,
    6: any,
    7: any,
    8: any,
    9: any,
    10: any,
    11: any,
    12: any,
    13: any,
    14: any,
    15: any,
    16: any,
    }
    ,
    selectedRowsOrdered: number[],
    }

    Initial state passed to react-table's documentation https://react-table.tanstack.com/docs/api/useTable

    Default{}
  • initialTableOptions shape {}

    Table options passed to react-table's useTable hook. Will override some options passed in to DataTable, such as: data, columns, defaultColumn, manualFilters, manualPagination, manualSortBy, and initialState

    Default{}
  • itemCount number Required

    Actions to be performed on the table. Called with the table instance. Not displayed if rows are selected.

  • bulkActions shape {
    buttonText: string Required,
    handleClick: func Required,
    className: string,
    variant: string,
    disabled: bool,
    }
    | func | element
    []
    | func | element

    Actions to be performed on selected rows of the table. Called with the selected rows. Only displayed if rows are selected.

    Default[]
  • tableActions shape {
    buttonText: string Required,
    handleClick: func Required,
    className: string,
    variant: string,
    disabled: bool,
    }
    | func | element
    []
    | func | element

    Function for rendering custom components, called with the table instance

    Default[]
  • numBreakoutFilters enum1 | 2 | 3 | 4

    Number between one and four filters that can be shown on the top row.

    Default1
  • EmptyTableComponent func

    Component to be displayed when the table is empty

    DefaultEmptyTableContent
  • RowStatusComponent func

    Component to be displayed for row status, ie, 10 of 20 rows. Displayed by default in the TableControlBar

    DefaultRowStatus
  • SelectionStatusComponent func

    Component to be displayed for selection status. Displayed when there are selected rows and no active filters

    DefaultSelectionStatus
  • FilterStatusComponent func

    Component to be displayed for filter status. Displayed when there are active filters.

    DefaultFilterStatus
  • children node[] | node

    If children are not provided a table with control bar and footer will be rendered

    Defaultnull
  • showFiltersInSidebar bool

    If true filters will be shown on sidebar instead

    Defaultfalse
  • dataViewToggleOptions shape {
    isDataViewToggleEnabled: bool,
    onDataViewToggle: func,
    defaultActiveStateValue: string,
    togglePlacement: string,
    }

    options for data view toggle

    Default{ isDataViewToggleEnabled: false, onDataViewToggle: () => {}, defaultActiveStateValue: 'card', togglePlacement: 'left', }
  • disableElevation bool

    Remove the default box shadow on the component

    Defaultfalse
  • renderRowSubComponent func

    A function that will render contents of expanded row, accepts row as a prop.

  • isExpandable bool

    Indicates whether table supports expandable rows.

    Defaultfalse
  • isLoading bool

    Indicates whether the table should show loading states.

    Defaultfalse
  • onSelectedRowsChanged func

    Callback function called when row selections change.

  • maxSelectedRows number

    Indicates the max of rows selectable in the table. Requires isSelectable prop

  • onMaxSelectedRows func

    Callback after selected max rows. Requires isSelectable and maxSelectedRows props

DataViewToggle Props API
This component does not receive any props.
BulkActions Props API
  • className string

    class names for the div wrapping the button components

    Defaultnull
TableActions Props API
  • className string

    class names for the div wrapping the button components

CardView Props API
  • className string

    The class name for the CardGrid component

  • columnSizes shape {
    xs: number,
    sm: number,
    md: number,
    lg: number,
    xl: number,
    }

    An object containing the desired column size at each breakpoint, following a similar props API as react-bootstrap/Col

    Default{ xs: 12, lg: 6, xl: 4, }
  • CardComponent func Required

    Your card component must be individualized to your table. It will be called with props from the "row" of data it will display

  • selectionPlacement enum'left' | 'right'

    If the Cards are selectable this prop determines from which side of the Card to show selection component.

    Default'right'
  • SkeletonCardComponent func

    Overrides default skeleton card component for loading state in CardView

  • skeletonCardCount number

    Customize the number of loading skeleton cards to display in CardView

    Default8
TableCell Props API
  • getCellProps func Required

    Props for the td element

  • render func Required

    Function that renders the cell contents. Will be called with the string 'Cell'

  • column shape {
    cellClassName: string,
    }
    Required

    Table column

TableHeaderCell Props API
  • getHeaderProps func Required

    Returns props for the th element

  • isSorted bool

    Indicates whether or not a column is sorted

    Defaultfalse
  • render func Required

    Renders the header content. Passed the string 'Header'

  • isSortedDesc bool

    Indicates whether the column is sorted in descending order

    Defaultfalse
  • getSortByToggleProps func

    Gets props related to sorting that will be passed to th

    Default() => {}
  • canSort bool

    Indicates whether a column is sortable

    Defaultfalse
  • headerClassName string

    Class(es) to be applied to header cells

    Defaultnull
TableHeaderRow Props API
  • headerGroups shape {
    headers: shape {
    getHeaderProps: func Required,
    }
    [] Required
    ,
    getHeaderGroupProps: func Required,
    }
    []
    Required
TableRow Props API
  • row shape {
    getRowProps: func Required,
    cells: shape {}[] Required,
    id: string Required,
    isSelected: bool,
    isExpanded: bool,
    }
    Required

    Row data that is received from react-table API.

FilterStatus Props API
  • className string
    Defaultnull
  • buttonClassName string
    Default'pgn__smart-status-button'
  • variant string
    Default'link'
  • size string
    Default'inline'
  • clearFiltersText element | string
  • showFilteredFields bool
    Defaulttrue
SelectionStatus Props API
  • className string

    A class name to append to the base element

  • clearSelectionText string | element

    A text that appears on the Clear selection button, defaults to 'Clear Selection'

SmartStatus Props API
This component does not receive any props.
TablePagination Props API
This component does not receive any props.
TextFilter Props API
  • column shape {
    setFilter: func Required,
    Header: func | node Required,
    getHeaderProps: func Required,
    filterValue: string,
    }
    Required

    Specifies a column object.

    setFilter: Function to set the filter value.

    Header: Column header used for labels and placeholders.

    getHeaderProps: Generates a key unique to the column being filtered.

    filterValue: Value for the filter input.

Usage Insights#

CardView

Project NameParagon VersionInstance Count
frontend-app-admin-portal20.46.32
frontend-app-course-authoring20.46.22
frontend-app-enterprise-public-catalog20.46.32
frontend-app-learning20.46.01

DataTable

Project NameParagon VersionInstance Count
edx-ora220.9.21
frontend-app-admin-portal20.46.317
frontend-app-communications20.46.22
frontend-app-course-authoring20.46.23
frontend-app-ecommerce20.46.21
frontend-app-enterprise-public-catalog20.46.32
frontend-app-gradebook20.45.03
frontend-app-learner-record20.46.31
frontend-app-learning20.46.03
frontend-app-ora-grading20.46.32
frontend-app-publisher20.46.21
frontend-app-support-tools20.46.02

DataTableEmptyTable

Project NameParagon VersionInstance Count
frontend-app-admin-portal20.46.39
frontend-app-course-authoring20.46.21
frontend-app-gradebook20.45.01
frontend-app-learner-record20.46.31

DataTableRowStatus

Project NameParagon VersionInstance Count
frontend-app-admin-portal20.46.32

DataTableTable

Project NameParagon VersionInstance Count
edx-ora220.9.21
frontend-app-admin-portal20.46.36
frontend-app-course-authoring20.46.22
frontend-app-ecommerce20.46.21
frontend-app-enterprise-public-catalog20.46.31
frontend-app-gradebook20.45.01
frontend-app-learner-record20.46.31
frontend-app-learning20.46.02
frontend-app-ora-grading20.46.32

DataTableTableControlBar

Project NameParagon VersionInstance Count
edx-ora220.9.21
frontend-app-admin-portal20.46.37
frontend-app-course-authoring20.46.21
frontend-app-enterprise-public-catalog20.46.31
frontend-app-gradebook20.45.01
frontend-app-ora-grading20.46.31

DataTableTableFooter

Project NameParagon VersionInstance Count
edx-ora220.9.21
frontend-app-admin-portal20.46.36
frontend-app-course-authoring20.46.21
frontend-app-enterprise-public-catalog20.46.31
frontend-app-learning20.46.01
frontend-app-ora-grading20.46.31