Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@leafygreen-ui/table

Package Overview
Dependencies
Maintainers
5
Versions
101
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@leafygreen-ui/table

leafyGreen UI Kit Table

  • 12.7.0
  • latest
  • Source
  • npm
  • Socket score

Version published
Maintainers
5
Created
Source

Table

npm (scoped)

Upgrading from pre-v10? Check out our upgrade guide for help on how to migrate to the updated API.

The Table component displays data in rows and columns and optionally supports row selection, sorting, and other features.

Supported features

The LeafyGreen Table wraps TanStack's react-table's hooks and types. Although all react-table features are supported using LeafyGreen Table, only the following features are styled according to design system guidelines:

  • Virtualized scrolling
  • Nested rows
  • Expandable rows
  • Selectable rows
  • Sortable rows
  • Sticky headers

Although other features from react-table are supported, we discourage developers from utilizing them as they would not align with MongoDB design systems guidelines.

Installation


Yarn

yarn add @leafygreen-ui/table

NPM

npm install @leafygreen-ui/table

Basic Example


import {
  Table,
  TableHead,
  HeaderRow,
  TableBody,
  Row,
  Cell,
} from '@leafygreen-ui/table';

<Table {...args}>
  <TableHead>
    <HeaderRow>
      {columns.map((columnName: string) => (
        <HeaderCell key={columnName}>{columnName}</HeaderCell>
      ))}
    </HeaderRow>
  </TableHead>
  <TableBody>
    {data.map((row: { [key: string]: any }) => (
      <Row key={row.id}>
        {Object.keys(row).map((cellKey: string, index: number) => {
          return <Cell key={`${cellKey}-${index}`}>{row[cellKey]}</Cell>;
        })}
      </Row>
    ))}
  </TableBody>
</Table>;

Example using useLeafyGreenTable

import {
  Table,
  TableHead,
  HeaderRow,
  TableBody,
  Row,
  Cell,
} from '@leafygreen-ui/table';

const tableContainerRef = React.useRef<HTMLDivElement>(null);
const data = React.useState(() => makeData(false, 10_000))[0];

const columns = React.useMemo<Array<ColumnDef<Person>>>(
  () => [
    {
      accessorKey: 'id',
      header: 'ID',
      size: 60,
    },
    {
      accessorKey: 'firstName',
      header: 'First Name',
      cell: info => info.getValue(),
    },
  ],
  [],
);

const table = useLeafyGreenTable<Person>({
  containerRef: tableContainerRef,
  data,
  columns,
});

const { rows } = table.getRowModel();

<Table
  {...args}
  table={table}
  ref={tableContainerRef}
>
  <TableHead>
    {table.getHeaderGroups().map((headerGroup: HeaderGroup<Person>) => (
      <HeaderRow key={headerGroup.id}>
        {headerGroup.headers.map(header => {
          return (
            <HeaderCell key={header.id} header={header}>
              {flexRender(
                header.column.columnDef.header,
                header.getContext(),
              )}
            </HeaderCell>
          );
        })}
      </HeaderRow>
    ))}
  </TableHead>
  <TableBody>
    {rows.map((row: LeafyGreenTableRow<Person>) => (
      <Row key={row.id}>
        {row.getVisibleCells().map((cell: LeafyGreenTableCell<Person>) => {
          return (
            <Cell key={cell.id}>
              {flexRender(
                cell.column.columnDef.cell,
                cell.getContext(),
              )}
            </Cell>
          );
        })}
      </Row>
    )}
  </TableBody>
</Table>

More specific code samples are available below pertaining to each documented feature.

Exports


useLeafygreenTable

useLeafygreenTable wraps react-table and react-virtual to support advanced table functionalities and virtual scrolling.

useLeafygreenTable takes an options object and returns a table.

https://github.com/mongodb/leafygreen-ui/blob/63877b7ef6f40e165f691a39ca00fc5de39b690d/packages/table/src/Table.story.tsx#L660-L669

Options

useLeafygreenTable exposes all options used in react-table, with the following exceptions:


hasSelectableRows?: boolean

Setting this prop will inject checkbox cells into all rows. Refer to our Storybook deployment to find examples.


allowSelectAll?: boolean

This prop controls whether a 'select all' checkbox will be rendered in the header row. This will be set to true by default.


withPagination?: boolean

Setting this prop will indicate that the Table component is being used with the Pagination component. This will expose various pagination utilities from table.getState().pagination. Find an example of how this prop should be used on our Storybook deployment.


useVirtualScrolling

react-virtual's useVirtual hook will be called if this option is set. When this option is set, the object returned by useLeafygreenTable will include virtualRows, totalSize and scrollToIndex. Refer to our Storybook deployment to find examples.

Note that the number of virtual rows rendered depends on the height passed to the Table component. For a reasonably performant use of virtual scrolling, ensure that there is a height set on the component to reduce the number of virtual rows rendered.


data / renderExpandedContent

useLeafygreenTable extends react-table's data option to allow a renderExpandedContent prop to be passed to the table's data type.

https://github.com/mongodb/leafygreen-ui/blob/63877b7ef6f40e165f691a39ca00fc5de39b690d/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.types.ts#L19-L22

This option determines how the row's expanded content will be rendered. Refer to Storybook deployment for an example.


data / subRows

useLeafygreenTable extends react-table's data option to allow a subRows prop to be passed to the table's data type.

https://github.com/mongodb/leafygreen-ui/blob/63877b7ef6f40e165f691a39ca00fc5de39b690d/packages/table/src/useLeafyGreenTable/useLeafyGreenTable.types.ts#L19-L22

This option defines the data displayed in nested rows and expects an array of objects with the same shape as other rows. Rows can be nested multiple times. Refer to Storybook deployment for an example.


columns / align

useLeafygreenTable extends react-table's columns option to allow a align prop to be passed to the column's data.

This option determines the alignment of the column. Refer to Storybook deployment for an example.


Table

Props
NameDescriptionTypeDefault
shouldAlternateRowColorDetermines whether alternating rows will have dark backgroundsbooleanfalse
disableAnimationsDisables all transition animations for smoother rendering of tall content where appropriatebooleanfalse
baseFontSizeThe base font size of the title and text rendered in children13 | 1613
darkModeRender the component in dark mode.booleanfalse

+ other HTML table element props

TableHead

Props
NameDescriptionTypeDefault
isStickyDetermines whether the table head will stick as the user scrolls down.booleanfalse

+ other HTML thead element props

If isSticky is set to true, the Table component will need to have a CSS height value set in pixels.

HeaderRow

Props

All HTML tr element props

HeaderCell

Props
NameDescriptionTypeDefault
sortStateDetermines the current sorting direction.SortState'asc' 'desc' 'off' 'none'
headerHeader object returned from the useLeafygreenTable hook.Header<T, any>-

+ other HTML th element props

TableBody

TableBody accepts HTML tbody element props.

The TableBody will render as a React.Fragment when Tables have expandable or nested rows to support virtualized scrolling on rows with unknown heights.

This is done to ensure that dynamic heights of rows with expandable content can be measured using a ref using a tbody element. In lieu of a rowgroup HTML element, expandable content relies on tbody to track groups of rows. This means the TableBody needs to render as a React.Fragment to ensure there aren't tbody elements inside tbody elements.

Row

NameDescriptionTypeDefault
disabledDetermines whether the row is disabledbooleanfalse
rowRow object passed from the useLeafygreenTable hook.LeafygreenTableRow<T>-
virtualRowVirtual row object passed from the useLeafygreenTable hook.VirtualItem-

+ other HTML tr element props

Cell

Cell accepts HTML td element props.

All nested row animations are set at the Cell level, with a max-height set to 40vh, which should cover most cases with a relatively smooth animation. For taller content, set disableAnimation={true} or override the max-height with a & > div { max-height: ... } CSS selector on the Cell component.

Feature Examples

Virtualized Scrolling

Demo

https://github.com/mongodb/leafygreen-ui/blob/63877b7ef6f40e165f691a39ca00fc5de39b690d/packages/table/src/TableWithVS.story.tsx#L115-L158

Note that the number of virtual rows rendered depends on the height passed to the Table component. For a reasonably performant use of virtual scrolling, ensure that there is a height set on the component to reduce the number of virtual rows rendered.

Sortable Rows

Demo

Demo with virtualized scrolling

https://github.com/mongodb/leafygreen-ui/blob/f61df48a196c731764864d594d7d043634a9bcdc/packages/table/src/Table/TableWithVS.stories.tsx#L42-L48

Selectable Rows

Demo

Demo with virtualized scrolling

https://github.com/mongodb/leafygreen-ui/blob/f61df48a196c731764864d594d7d043634a9bcdc/packages/table/src/Table/Table.stories.tsx#L375-L385

Expandable Content

Demo

Demo with virtualized scrolling

To add expandable content to your Table, ensure the renderExpandedContent prop is passed to the row's data through useLeafygreenTable's data prop.

React 18

For cases where you anticipate having more than 20 rows with nested rows, it is advisable to opt for virtual scrolling to improve performance of row transitions.

Test Harnesses

getTestUtils()

getTestUtils() is a util that allows consumers to reliably interact with LG Table in a product test suite. If the Table component cannot be found, an error will be thrown.

Usage

import { Table, getTestUtils } from '@leafygreen-ui/table';

const utils = getTestUtils(lgId?: string); // lgId refers to the custom `data-lgid` attribute passed to `Table`. It defaults to 'lg-table' if left empty.
Single Table
import { render } from '@testing-library/react';
import { Table, getTestUtils } from '@leafygreen-ui/table';

...

test('table', () => {
  render(<Table>...</Table>);
  const { getAllVisibleRows } = getTestUtils();
  expect(getAllVisibleRows().length).toEqual(3);
});
Multiple Tables
import { render } from '@testing-library/react';
import { Table, getTestUtils } from '@leafygreen-ui/table';

...

test('returns the correct rows', () => {
  render(
    <>
      <Table>...</Table>
      <Table data-lgid="lg-table-2">...</Table>
    </>,
  );

  // First Table
  const { getAllVisibleRows } = getTestUtils();
  expect(getAllVisibleRows().length).toEqual(3);

  // Second Table
  const { getAllVisibleRows: getAllVisibleRowsB } = getTestUtils('lg-table-2');
  expect(getAllVisibleRowsB().length).toEqual(4);
});

Test Utils

const {
  getTable,
  getAllHeaders,
  getHeaderByIndex: (index: number) => { getElement, getSortIcon },
  getSelectAllCheckbox,
  getAllVisibleRows,
  getRowByIndex: (index: number) => {
    getElement,
    getAllCells,
    getCheckbox,
    getExpandButton,
    isExpanded,
    isSelected,
    isDisabled,
  },
  getAllVisibleSelectedRows,
} = getTestUtils();
UtilDescriptionReturns
getTable()Returns the table node or null if the table node is not found.HTMLTableElement
getAllHeaders()Returns an array of <th>(<HeaderCell>) in the DOM. Throws if there are no elements.Array<HTMLTableCellElement>
getHeaderByIndex(index: number)Returns utils for an individual <th>(<HeaderCell>) in the DOMHeaderUtils | null
getSelectAllCheckbox()Returns the input node for the select all checkbox or nullHTMLInputElement | null
getAllVisibleRows()Returns an array of all visible <tr>(<Row>) in the DOM. Throws if there are no elements.Array<HTMLTableRowElement>
getRowByIndex(index: number)Returns utils for an indivudial <tr>(<Row>) in the DOMRowUtils | null
getAllVisibleSelectedRowsReturns an array of all visible selected <tr>(<Row>) in the DOMArray<HTMLTableRowElement>
HeaderUtilsDescriptionReturns
getElement()Returns the <th> elementHTMLTableCellElement
getSortIcon()Returns the sort button or nullHTMLButtonElement | null
RowUtilsDescriptionReturns
getElement()Returns the <tr>(<HeaderCell>) elementHTMLTableRowElement
getAllCells()Returns an array with all the <td>(<Cell>) elements in the rowArray<HTMLTableCellElement>
getCheckbox()Returns the input element or nullHTMLInputElement | null
getExpandButton()Returns the expand button element or nullHTMLButtonElement | null
isExpanded()Returns if the <tr>(<Row>) is expandedboolean
isSelected()Returns if the <tr>(<Row>) is selectedboolean
isDisabled()Returns if the <tr>(<Row>) is disabledboolean

FAQs

Package last updated on 16 Sep 2024

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc