DataGrid

The DataGrid is a wrapper for Table that allows you to easily define table columns using the API and provides sorting & pagination capabilities.

Basic usage

The DataGrid component has several sub-components to help define your grid structure:

  • DataGrid.TopSection - A flex container to be rendered above the table. You can use this space to render other DataGrid components in whatever order you like. In the card view, TopSection will always include the sort buttons as the first element. You can use the justifyContent and spacing props to help with arranging elements and spacing them out from each other.
  • DataGrid.BottomSection - A flex container to be rendered below the table. You can use this space to render other DataGrid components in whatever order you like. You can use the justifyContent and spacing props to help with arranging elements and spacing them out from each other.
  • DataGrid.Table - A wrapper for our Table component which maps the data you pass to the columns that have been configured.
  • DataGrid.Column - Defines a column template that will be applied to the data passed to the table. Any extra props passed to Column will be passed on to Table.Cell internally.
  • DataGrid.PageSizeSelect - Renders a component that can be used to pick the number of rows per page.
  • DataGrid.Pagination - A wrapper for our Pagination component. This piece allows users to change pages. Note: when using this component, pageCount is required in paginationOptions.
  • DataGrid.PrevNext - A wrapper for our PrevNext component, which is a simpler form of pagination. This method of pagination does not require a pageCount.

DataGrid.Column

The Column API is central to making a DataGrid. There are several options for controlling what data is rendered and how, as well as controlling the column header.

  • id: the name of a property on the table data. Maps the value that will be rendered in each table cell; required if no render function or component is passed.
  • title: the contents of the header cell.
  • sortable: if true, the header cell will become a button that can be clicked to change the sort options; id and title are required on sortable columns.
  • order: the order in which the columns should appear; default is React render order, so 99% of the time this can be left blank.
  • headerProps: an object containing any extra props to be passed to the header cell
  • render/children: a function to render the cell contents. The first argument is the current data row being processed, and the second is a CellInfo object (definition shown below).
  • as: a component to use as the cell contents. It receives a row prop, as well as the CellInfo props.
  • Any other props are passed directly to the Table.Cell component, e.g. align.
interface CellInfo {
  id?: string // from Column's `id` prop
  value?: any // mapped from `row[id]`
  rowIndex: number
  colIndex: number
}

Best practices

  • The sortOptions & paginationOptions props can be used either controlled or uncontrolled. If using them uncontrolled, the onPagisort handler can be used to update the data source whenever a change is made to either pagination or sorting.
  • paginationOptions can be passed as a single object to the <DataGrid> element, or as individual props to the relevant sub-components: pageSize to PageSizeSelect, currentPage & pageCount to Pagination, etc.; if not using PageSizeSelect, pageSize can also be passed to Pagination or PrevNext.
  • Use the sortLabels prop on TopSection to pass internationalized labels for the sorting dropdowns used in the card view.
  • Just like the Table, the DataGrid should be rendered as a descendant of ScreenSizeProvider to take advantage of the card carousel feature.
  • If you would like to use the DataGrid.Pagination component, you must include pageCount OR itemCount & pageSize in paginationOptions. If no page count is known, you should use DataGrid.PrevNext instead.
  • Similar to the Table component, the DataGrid exposes the cardBreakpoint prop, where you can define at what breakpoint you would like to switch to card view. It defaults to tiny but you can select from any of our breakpoints: tiny, small, medium, large and extraLarge.
  • Alternatively, you can pass variant to directly control whether it renders as cards or a table.
  • Make sure the sub-components that are rendered with the table are positioned as expected in both table view and card view. You may need to make use of ScreenSizeContext to accomplish the positioning you desire depending on the screen’s size.

Example

const YesNo = ({ value }) => <div>{value ? 'YES' : 'NO'}</div>

const initialPageSize = 4
const DataGridContainer = ({ data: INITIAL_DATA }) => {
  const [data, setData] = React.useState(() => INITIAL_DATA.slice(0, initialPageSize))
  const onPagisort = ({ itemOffset, pageSize: newPageSize, sort: newSortOptions }) => {
    const sortId = newSortOptions[0].id
    const sortAscending = newSortOptions[0].sortAscending
    const dataCopy = [...INITIAL_DATA]
    if (sortId === 'created') {
      if (sortAscending) {
        dataCopy.sort((a, b) => {
          return new Date(a.created) - new Date(b.created)
        })
      } else {
        dataCopy.sort((a, b) => {
          return new Date(b.created) - new Date(a.created)
        })
      }
    } else if (sortId === 'active') {
      if (sortAscending) {
        dataCopy.sort((a, b) => {
          return a.active === b.active ? 0 : a.active ? 1 : -1
        })
      } else {
        dataCopy.sort((a, b) => {
          return a.active === b.active ? 0 : a.active ? -1 : 1
        })
      }
    }
    setData(dataCopy.slice(itemOffset, itemOffset + newPageSize))
  }
  return (
    <DataGrid onPagisort={onPagisort} cardBreakpoint="tiny">
      <DataGrid.TopSection justifyContent="flex-end" spacing={4}>
        <DataGrid.PageSizeSelect
           initialPageSize={initialPageSize}
           pageSizeOptions={[4, 6, 12]}
        />
      </DataGrid.TopSection>
      <DataGrid.Table data={data}>
        <DataGrid.Column id="name" title="Name" />
        <DataGrid.Column id="created" title="Created" sortable />
        <DataGrid.Column id="active" title="Active" sortable as={YesNo} />
        <DataGrid.Column>
          {(rowData) => (
            <SplitButton onSelectMainAction={() => {}} mainActionLabel="Edit">
              <SplitButton.Action onSelect={() => {}}>Clone</SplitButton.Action>
              <SplitButton.Action onSelect={() => {}}>Delete</SplitButton.Action>
            </SplitButton>
          )}
        </DataGrid.Column>
      </DataGrid.Table>
      <DataGrid.BottomSection justifyContent="flex-end">
        <DataGrid.Pagination itemCount={INITIAL_DATA.length} />
      </DataGrid.BottomSection>
    </DataGrid>
  )
}

Properties

DataGrid

Cactus Props

NameRequiredDefault ValueTypeDescription
cardBreakpointN"tiny" | "small" | "medium" | "large" | "extraLarge" | undefined
fullWidthNboolean | undefined
initialSortNSortOption[] | undefined
onPageChangeN((newPageOptions: PaginationOptions) => void) | undefined
onPagisortN((newPagisort: Pagisort) => void) | undefined
onSortN((newSortOptions: SortOption[]) => void) | undefined
paginationOptionsNPaginationOptions | undefined
sortOptionsNSortOption[] | undefined
variantNTableVariant | undefined

Styling Props

NameRequiredTypeDescription
mNResponsiveValue<string | number | symbol, Required<Theme<TLengthStyledSystem>>> | undefinedMargin on top, left, bottom and right
marginNResponsiveValue<string | number | symbol, Required<Theme<TLengthStyledSystem>>> | undefinedMargin on top, left, bottom and right
marginBottomNResponsiveValue<string | number | symbol, Required<Theme<TLengthStyledSystem>>> | undefinedMargin on bottom
marginLeftNResponsiveValue<string | number | symbol, Required<Theme<TLengthStyledSystem>>> | undefinedMargin on left
marginRightNResponsiveValue<string | number | symbol, Required<Theme<TLengthStyledSystem>>> | undefinedMargin on right
marginTopNResponsiveValue<string | number | symbol, Required<Theme<TLengthStyledSystem>>> | undefinedMargin on top
marginXNResponsiveValue<string | number | symbol, Required<Theme<TLengthStyledSystem>>> | undefinedMargin on left and right
marginYNResponsiveValue<string | number | symbol, Required<Theme<TLengthStyledSystem>>> | undefinedMargin on top and bottom
mbNResponsiveValue<string | number | symbol, Required<Theme<TLengthStyledSystem>>> | undefinedMargin on bottom
mlNResponsiveValue<string | number | symbol, Required<Theme<TLengthStyledSystem>>> | undefinedMargin on left
mrNResponsiveValue<string | number | symbol, Required<Theme<TLengthStyledSystem>>> | undefinedMargin on right
mtNResponsiveValue<string | number | symbol, Required<Theme<TLengthStyledSystem>>> | undefinedMargin on top
mxNResponsiveValue<string | number | symbol, Required<Theme<TLengthStyledSystem>>> | undefinedMargin on left and right
myNResponsiveValue<string | number | symbol, Required<Theme<TLengthStyledSystem>>> | undefinedMargin on top and bottom

DataGrid.TopSection

Cactus Props

NameRequiredDefault ValueTypeDescription
justifyContentNspace-betweenJustifyContent | undefined
sortLabelsN{ sortBy: 'Sort by', order: 'Order', ascending: 'Ascending', descending: 'Descending', }SortLabels | undefined
spacingN4string | 0 | 5 | 4 | 1 | 2 | 3 | 6 | 7 | undefined

DataGrid.Table

Cactus Props

NameRequiredDefault ValueTypeDescription
dataYDatum[]
dividersNboolean | undefined
rowFocusNFocusOption | undefined
rowHoverNboolean | undefined
stickyNStickyColAlignment | undefined

DataGrid.BottomSection

Cactus Props

NameRequiredDefault ValueTypeDescription
justifyContentNspace-betweenJustifyContent | undefined
spacingN4string | 0 | 5 | 4 | 1 | 2 | 3 | 6 | 7 | undefined

DataGrid.Pagination

Cactus Props

There are no custom props.

DataGrid.PrevNext

Cactus Props

There are no custom props.

DataGrid.Column

Cactus Props

NameRequiredDefault ValueTypeDescription
alignNCellAlignment | undefined
asNComponentType<any> | undefined
headerPropsNTableCellProps | undefined
idNstring | undefined
orderNnumber | undefined
renderNRenderFunc | undefined
sortableNboolean | undefined
titleNReactChild | undefined
variantNTableVariant | undefined

Styling Props

NameRequiredTypeDescription
widthNResponsiveValue<Width<TLengthStyledSystem>, Required<Theme<TLengthStyledSystem>>> | undefinedThe width utility parses a component's `width` prop and converts it into a CSS width declaration. - Numbers from 0-1 are converted to percentage widths. - Numbers greater than 1 are converted to pixel values. - String values are passed as raw CSS values. - And arrays are converted to responsive width styles.