The Basics

What it is

The DataTable component is designed to structure and present related data points in a grid layout, facilitating quick comparison and analysis. It supports both client-side and server-side data fetching, allowing for efficient handling of large datasets.

How it works

DataTable relies on three core elements:

  • Column headers: the descriptive titles that appear at the top of each column.
    • In sortable columns, column headers have arrow icons for sorting. The user can click the sorting icons (or focus and press the Enter key or Space bar) to reorder the column data in ascending or descending order.
  • Data columns: the table's vertical sections. Each column displays data that corresponds to its column header. These columns are optionally sortable.
  • Data rows: the horizontal sections that span the data columns. Each row contains one unique set of data points. Rows are optionally expandable and can respond to filter actions.
    • Hovering on a row highlights it with a blue background color, to help the user scan across the table.
    • If any rows are expandable, the user can click the row’s expand control to show/hide an additional container below it (following rows are pushed down).

Functionally, DataTable can be set to client-side fetching, where data is loaded in memory based on the rowData prop. Alternatively, server-side fetching can be used to load the data progressively for larger data sets.

When to use

  • To organize and display structured information
  • To help users find and compare data points

When not to use

  • For simple image- or text-based lists that do not need as much structure
  • As a replacement for grid. DataTable should only be used when information must be presented in a tabular format, not just to visually align content.

What to use instead

Grid

Use grid to visually align elements without the need for additional DataTable functionality.

List

Use List if you are trying to display a less structured list of data

How to use

To get started, follow these steps to plan your DataTable. The features mentioned here are described in detail in the subsequent sections of this page.

Step 1: Consider What Each Row of Your DataTable Will Capture

  • Data rows are the horizontal sections that span your table’s columns. Each row contains a unique set of interrelated data points, often referred to as an observation.
  • Decide what one observation will represent in your content. For example, one row could represent one patient, one day, or one entry.

Step 2: Consider What Information Will Exist in the Columns of Your DataTable

  • Column headers are the descriptive titles that appear at the top of each column.
  • Decide how to organize your columns from left to right in a meaningful order, such as by importance or alphabetically.
    • The first column should contain a unique identifier for each row (e.g., "Name" or "ID" in a table of patients) to facilitate easy scanning of data, even after sorting or filtering.

Step 3: Consider the Format of Data in Your Columns

  • Data columns are the vertical sections of the table. Each column displays data corresponding to its header and contains a specific data type (e.g., numeric, text).
  • Determine the data type required for each of your column. Content can either be defined by the implementing team or captured by user input 
  • Possible column types include:
    • Currency
    • Date Input (data inputted from DateInput component)
    • Date String
    • Icon (contains a Forge Icon)
    • Id (number or string)
    • Long Text
    • Numeric
    • Percent
    • Radio Group (data inputted from RadioGroup component)
    • Select (data inputted from Select component)
    • Tag (contains a Forge Tag)
    • Text
    • Action (contains buttons related to row actions)
    • Checkbox (contains checkboxes for selecting rows related to bulk actions)
    • Custom (can contain links or buttons to do things like opening a new tab, modal, or popover)
  • By default, text is left-aligned, and numbers are right-aligned for easier comparison.

Step 4: Consider What Additional Functionality Your DataTable May Need

  • Consider what technical features your users may need in your DataTable:
    • Column Configuration: users can optionally show and hide columns or drag and drop to reorder column orders, thus configuring views to meet their needs.
    • Sort: users can sort columns by clicking on header icons, enabling ascending or descending order.
    • Filter: users can filter options in their table to only display certain rows. Filtering can be applied in three ways:
      • Filter Panel: a visual panel that contains FormField elements like select or input allowing users to apply multiple table-level filters in one grouping.
      • Column Filters: Icon buttons displayed next to column headers to open popups that filter table one column at a time. 
      • Quick Filters: a visual panel that surfaces predefined filter combinations such as quick action buttons. 
    • Search: adds a search bar to the table control panel that filters data based on input for easy data retrieval. 
    • Expandable Rows: rows can be expanded to reveal additional details, enhancing data context without cluttering the main view.
    • Row Click: users can display a context menu when they right-click a table row.
    • Action Buttons: an additional column that holds action buttons for editing, deleting, or performing custom actions on each table row.
      • Action buttons are configurable and can be added to all rows, some rows, or dynamically defined rows
    • Editing
      • Inline Editing: users can edit data directly within the table, with validation options to ensure data integrity. Inline edits can be at a custom cell level or dynamically determined by the application.
      • Table Edit: users can edit the entire table by triggering an element that opens the entire table in an editable state.
      • Row Edit: an action button (edit icon) that, when enabled, opens all cells in the row for editing, transitioning the icons in the action field to save/cancel buttons.
      • Adding Entities: users can add a row to the table through the UI using either a modal or a form panel above the table.
      • Validation: implementing teams can provide validation logic that appears in the edit views before the user clicks save. This validation can prevent the user from saving and will follow the same guidance as the Standard Error Banner.
      • Alerting When Navigating Away: to prevent users from losing unsaved changes, implementing teams can add a pop-up  that will automatically appear if users attempt to navigate away or close the tab while edits are unsaved.
    • Bulk Actions: users can perform actions on multiple rows simultaneously.
      • These bulk actions can be triggered using individual checkboxes, multi-option menus, single action buttons, pop-up modals, or complex multi-action control rows.
    • CSV Download: users can download table data in CSV format for external use.
    • Refresh: by default, DataTable data is automatically fetched on page reload, but users can also manually refresh the data if needed.

Step 5: Consider How You Would Like to Style Your DataTable

  • Style Options to Consider:
    • Layout: DataTable offers two layout settings: medium and compact. 
      • The medium layout (default) is suitable for most tables, while the compact layout is best for dense datasets with many numbers, such as a table of recent transactions.
    • Sticky Styling: optional styling that allows columns, row headers, and/or row footers to be sticky, meaning they remain visible as users scroll.
    • Pagination: optional styling that adds visual pagination can be added to manage large datasets, with options for client-side and server-side pagination.
    • Alert Styling: optional styling that adds alert-colored bars to individual data table rows or alert icons to individual cells.
    • Cell Tooltips: optional styling that adds tooltips on a per-cell basis.
    • Deleted/Archived/Void Rows: optional styling that visually handles deleted, archived, and voided rows through recoloring of text and background colors.
    • Empty State: configurable messaging that allows you to display a placeholder message when the table has no data (e.g., when filters don’t match any data, the search function returns no results, or the user has completed all available tasks).

Style

Design details

DataTable’s column widths are typically determined by the longest string in each column, which makes columns widths vary. This makes it easier for users to scan the table, because it reduces extra white space in the table's cells and shows data points closer together.

By default, DataTable’s width is the sum of its column widths. DataTable width can be set to a specific size, but it shouldn’t be too wide, because this can add white space between data points that makes it harder to scan the table. For this reason, don’t set small DataTables to span the full width of a page.

Row height is set by the layout option:

  • Medium (default):  36px row height
  • Compact: 24px row height

Placement and hierarchy

Content

To add a title to the DataTable, use the `title` prop. Use title case for this heading (“Today’s Schedule”, not “Today’s schedule”).

Use title case for column headers (“Date of Service”, not “Date of service”). Column headers are automatically displayed in bold. To avoid text wrapping:

  • Keep column header text short. Leave out information that’s obvious from the context or the DataTable title. For example, if the DataTable title is “Patients”, use “Name” as a column header, not “Patient Name”.
  • Use DataTable’s built-in option for forcing the column header text onto a single line. With this setting enabled, header text is automatically truncated with an ellipsis when the column width is smaller than the width of the header text.

The details

Now that you know how to get started, here are specific instructions for each feature of DataTable linked to live examples of each behavior.

 

Kitchen Sink Demos of All Features

NameDescriptionStorybook Demo with Code LinkFigma Notes
Client-Side DemoA demo that shows all available features in client-side DataTable.data-table-client-side-demo'Example DataTable' component can be found in the Data Table page of the Figma libraries.
Server-Side DemoA demo that shows all available features in server-side DataTable.

data-table-server-side-demo

'Example DataTable' component can be found in the Data Table page of the Figma libraries.

 

Column Features

NameDescriptionStorybook Demo with Code LinkFigma Notes
Cell TooltipsTooltips can be added to individual cells or to column headers.cell-tooltips-demoFor column headers, tooltips can be mimicked in Figma and is accessed by turning on 'header' boolean property found in the 'TableCell' component. Then, turning on 'tool tip' boolean property nested within the 'cell content' component.
Column Types

Possible column types include:

  • Currency
  • Date Input (data inputted from DateInput component)
  • Date String
  • Icon (contains a Forge Icon)
  • Id (number or string)
  • Long Text
  • Numeric
  • Percent
  • Radio Group (data inputted from RadioGroup component)
  • Select (data inputted from Select component)
  • Tag (contains a Forge Tag)
  • Text
  • Action (contains buttons related to row actions)
  • Checkbox (contains checkboxes for selecting rows related to bulk actions)
  • Custom (can contain links or buttons to do things like opening a new tab, modal, or popover) (mention custom column filters)

By default, text is left-aligned, and numbers are right-aligned for easier comparison.

all-column-type-demo

currency-column-demo

date-input-column-demo

date-string-column-demo

icon-column-demo

id-column-demo

long-text-column-demo

numeric-column-demo

percent-column-demo

radio-group-column-demo

single-select-column-demo

tag-column-demo

text-column-demo

Column types are handled on a case by case basis in Figma.

For numeric/percent/currency columns choose 'quantity' type cell content.

For text/string choose 'default' cell content type.

 

Row Features

NameDescriptionStorybook Demo with Code LinkFigma Notes
Adding Entities

DataTable users can add rows to the table through the UI using either a modal or a form panel above the table.

When a user adds the row, we also refresh the DataTable and data can be passed in in any given order as determined by the consuming team. 

add-entity-demo

*to add an entity, press the add row button at the very top of the table in the demo

This feature will be added to Figma soon.
Expandable Rows

Expandable rows add additional details to rows in the table but do not display them by default. Rather, they are shown when an interactive clickable arrow is toggled on and off for each row.

  • Detail rows are hidden/collapsed by default.

When row detail information is passed in, the parent row will automatically include a clickable arrow for revealing the detail row.
You can insert other components (ex., cards) or custom HTML. If you are considering inserting another table in the expanded area, evaluate whether that data should be included in the parent table.

expandable-row-demoRow expand icons are shown as 'expandable' a boolean property found in the 'TableCell' component.
Row ClickRow Click is an optional feature that allows the table viewer to open a configurable context menu when they right-click a table row. This menu is comprised of the forge Menu component.row-click-demoAdd 'menu' component in Figma to mimic this feature

 

Sort, Search, Filter

NameDescriptionStorybook Demo with Code LinkFigma Notes
Filter

Filtering allows DataTable viewers to only display certain rows based on column criteria. Filtering can be applied in three visual ways:

  • Filter Panel: A visual panel that contains FormField elements like select or input allowing users to apply multiple table-level filters in one grouping.
    • Filters appear automatically in a panel above the table. The panel can be set to always open or to be collapsible through the "hideable" prop, to enable more space on the page. 
  • Column Filters: Icon buttons displayed next to column headers to open popups that filter table one column at a time.
  • Quick Filters: A visual panel that surfaces predefined filter combinations such as quick action buttons.
    • If you have many filters or want to sort your filters by topic, we recommend using the quickFilter This will allow you to create header sections for your filter panel for grouping the filters more elegantly.

       

We have made adding filters easier by providing native support for all current input types that could be filters and ensuring the formatting works as intended. Native filter types include:

  • DateInputFilter
  • DateRangeInputFilter
  • NumericInputFilter
  • NumericRangeInputFilter
  • RadioGroupFilter
  • SelectFilter
  • TextInputFilter

 

Additionally, filters can be created for any custom column or FormField element type to allow filtering based on their unique content. For app-controlled filters that may be located elsewhere on the page or not visible at all, a custom filter can also be written. 

  • Example:  you could create a filter for height split into one input each for feet and inches, based on the custom column that holds height as '5' 3"'.

 

Custom filters can also be flexible. or dependent/strict.

  • Flexible: i.e. two related inputs modify each other in any order as the user interacts with them.
  • Dependent/Strict: : i.e. two related inputs modify each other, but only in a specific order of interaction. Fields are disabled until their preceding fields are interacted with.

 

filter-panel demo

column-filter-demo

quick-filter-demo

custom-height-column-example-demo

custom-flexible-filter-demo

custom-strict-filter-demo

 

Filtering is found in the following Figma components:

Filter Panel: 'DataTable Filter Panel'

Quick Filters: 'DataTable Quick Filters'

Column Filters: 'Table Cell' as the 'Filter' boolean option available for 'header' type

Search

Separate from the filter panel, DataTable also offers a simple text search. The search input field appears immediately above the table in the control row and provides a string-based text search.

Consumers can turn off search on specific columns (ex. if you want to have only one searchable column). Search will bring up results with partial matches. The search functionality can be client-side (which works immediately upon typing) or server-side (which requires the user to enter the string first and click the search button).

client-side-search-demo

server-side-search-demo

Search is housed in the 'TableControlRow' component as a boolean layer that can be turned on and off.
Sort

DataTable allows users to sort columns by clicking on arrow icons found next to column headers. This lets users change the order of values in that column (e.g., sorting payment amounts from smallest to largest) and reorders all rows in the DataTable.

  • The default sorting order is ascending and descending.
  • You can also build custom handling for more complex data points (ex., height, split into feet and inches).
sort-demoColumn sort icons are shown as 'sort' a boolean property found in the 'TableCell' component.

 

Edit and Bulk Action Features

NameDescriptionStorybook Demo with Code LinkFigma Notes
Action Buttons

Action buttons are an additional DataTable column that holds buttons for editing, deleting, or performing custom actions on each table row.

Action buttons are located in the right-most cell of each row. This provides a standard, grouped location for any row-level actions you want to provide. Action buttons are configurable and can be added to all rows, some rows, or dynamically defined rows. 

  • Button Format: The array of action buttons defaults to icon-only buttons, but other button types can be used. They will shrink for compact table layouts.
  • Edit & Delete: We provide standard the Edit (pencil) and Delete (trash) actions as part of the table. These will enable row edit (see edit below) and delete for a row (see deleted rows below). 
  • Custom Actions: We have also enabled consumers to add their own actions to the action column. Teams will have to provide their own functionality behind other actions.  

edit-and-save-action-button-row-demo

delete-and-restore-action-button-row-demo

Action buttons can be found in 'right actions' a variant property found in the 'TableCell' component.
Bulk Actions

Bulk actions are actions performed by DataTable users on multiple rows simultaneously. These bulk actions can be triggered using individual checkboxes, multi-option menus, single action buttons, pop-up modals, or complex multi-action control rows.

 

We have built in the ability to act on multiple rows at the same time. Please be mindful of the language you are putting into your bulk action sections to be clear about the exact action that the user is taking. For example, instead of “Bulk Edit” or “Bulk Assign”, you can put “Update Status” or “Assign Claims”.  

  • Selecting rows for bulk action: Each row includes a checkbox on the far-left side. When selected, a row will automatically appear shaded for easy scanning. The “select all” checkbox in the table’s left-most column header will select all rows on the current visible page only. If you select a row and then navigate to another page, the row selections on the initial page persist. When the bulk action is taken, all selected rows across all the pages are sent to the consuming application. The consuming action will always need to program the result of the bulk action. 
  • Single simple bulk action – Button: If you have a simple bulk action where you only ever need to provide one action for the user to take (ex., Assign), we offer a single bulk action button on the left side of the control row. The button text will show the number of rows selected, but the application will need to provide the text to describe the bulk action itself.
  • Multiple simple bulk actions – Menu: If you have a small number of actions that don’t need additional detail to describe, we provide a bulk action dropdown menu on the left side of the control row. The number of rows selected will appear in the menu text, but the application will need to provide the menu option text for the bulk actions. The menu can include actions that require a lightbox or modal, but those should be grouped in a section of the menu, separate from quick actions.
  • Medium complexity bulk actions - Control row: If you need more space to display a simple bulk action that doesn’t require a modal or lightbox, we provide the option for bulk action in a second control row, situated between the standard control row and the column headers. The bulk action row indicates the number of rows selected, followed by a one-line form element. This setup provides slightly more space to give context for what the action is by, for example, writing it out as a sentence (ex., 25 Plans Selected / Change status to [selector with list of statuses] and reassign to [selector with list of users]). This format should be used if you need to provide additional context on the bulk action and can keep it to a single line. 
  • Complex bulk actions - ModalIf you have a more complicated bulk action and you need to provide the user with additional details (or kick off a workflow), this component provides a button that launches a Modal intended for bulk actions. The information inside the modal is completely application controlled.

bulk-edit-demo-button style layout

bulk-edit-demo-menu style layout

bulk-edit-demo-row style layout

Bulk action design is housed in the 'TableControlRow' component as a boolean layer that can be turned on and off.

Bulk action styling is handled by nested component 'Table Element Bulk Action'.

Edit

We currently offer two types of inline edit built into the table table edit and row edit, both of which provide built-in edit fields for selects and inputs (including date input)*. For custom cells, if you want it to be editable in the table itself you will need to provide an editable state for the cell. 

  • Table Edit: We provide a table level edit that is enabled above the table. When toggled, all fields that have been set to have an editable state will switch to the input version. We will not send the data to the client until user hits save. Save is done on the entire table. 
  • Row Edit: We provide an action button of edit (pencil) that can be included for row level editing. When enabled all cells in the row clicked will become editable and the icons in the action field will transition to a save and cancel button (all other actions are restricted when a row is in edit). Data will be sent to the consuming application when the user hits save. 

Edit functionality has optional validation and alerting that can be configured as follows:

  • Validation: Consumers can provide validation that they want to appear in the edit views before the use clicks save. The logic for validation is left to the consumers but will appear below the editing field when it is missing. The validation can prevent the user from saving and follow the same guidance as [Standard Error Banner] 
  • Alerting when navigating away: To prevent users from losing unsaved changes if the user tries to navigate away or close the tab while an edit has not been executed, we will automatically generate a pop-up asking them if they would like to change noting the unsaved changes.   

We also enable the application to determine which columns and rows are editable with the ability to disable editing at a per cell level. For bulk edit (i.e., making the same change to multiple rows at one time) please see Bulk Action feature notes.

*Note: You can only have one type of edit available on the table at once. We are planning on adding single cell inline edit functionality, too, which will enable editing/saving one cell at a time. That is currently in development.

inline-edit-row-demo

edit-full-table-demo

edit-row-in-modal-demo

Edit functionality is housed within action buttons, which are shown as 'right actions' a variant property found in the 'TableCell' component.

 

Table Control Features

NameDescriptionStorybook Demo with Code LinkFigma Notes
Column ConfigurationColumn configuration is an option in the Table Control row that allows DataTable viewers to show, hide or reorder individual columns, thus configuring views to meet their needs. Reordering is completed using drag and drop functionality, while show/hide is completed with one toggleSwitch per table column.column-config-demoColumn configuration is housed in the 'TableControlRow' component as a boolean layer that can be turned on and off.
CSV Download

CSV download enables downloading a copy of the data available in the table into a CSV.

  • To allow downloading, enable the csvDownload prop.
  • If you want to pass in data that is not visible in the table or want to enabledownloads that filter based on filter criteria (see filtering below) or search (see search below), use fetchCSV which will expect the return of the CSV you want to generate.
csv-download-demoThis feature will be added to Figma soon.
Deleted/Archived/Void Rows

Deleted rows can optionally be visually displayed with modified styling. We have standardized the look and interaction on deleted, archived, and voided rows.

  • When a row is marked as deleted, its row and font color change, its text is italicized, and its actions are automatically disabled except for an action to ‘Restore’ the row.
  • If a row is restored, its style will be returned to normal (row color, font color, text style) and its actions will be re-enabled.
  • Note: If you are using custom cell renders you will need to supply a deleted version in your cell renderer to be able to use the feature. 

The option to show deleted rows can be toggled on and off using a checkbox in the Table Control row.

delete-and-restore-row-demo

The checkbox to toggle showing deleted rows on and off is housed in the 'TableControlRow' component as a boolean layer called 'show deleted'

Deleted styling is found by adjusting the 'state' variant to 'deleted' in the 'cell content' component that is nested within each 'table cell' component.

Pagination

Pagination is the grouping of table contents into multiple pages that can be navigated via a visual element called a paginator. In DataTable, the Paginator component is built in to allow navigation. We recommend turning on pagination if you have more than 20 rows in your table. Pagination and row counting can be displayed in the table control row at the top or bottom of your DataTable

These supporting elements for pagination are included:

  • Paginator: Used for navigating among the pages of content. Paginator is displayed at the top right (above the table) by default. It can also be set to appear in bottom right corners, too, to provide quick navigation from the bottom of the page.
    • Paginator can be set to either its default or compact mode. Compact is recommended to allow layout space for other table functionality in the same control row (e.g., bulk action, search, etc.).
  • Row count: Displays the number of rows displayed and total rows (e.g., “1-20 of 375”).
    • This appears next to the Paginator.
    • If you do not have an exact count of the number of rows, you can set the row count to show an approximate (imprecise) count. You can set the imprecise text to use the format “A-B of ~X” or “A-B of X+” with units of K and M auto applying (ex 3M+)
  • Set rows per page: When row counts are in use, you can allow the user to set how many rows are displayed per page. With this setting enabled, the row count becomes a clickable menu. The user can select how many rows they would like to be able to see at a time. These increments can be set by the consuming application to easily enable teams to set increments that make sense for their data.

 

Functionally, you will choose one of these pagination approaches:

  • Client-side: Your application provides the full table contents, and the component automatically handles dividing and displaying it in pages. This is managed by splitting the rowData prop into smaller chunks.
  • Server-side: Your application provides only the “page” or chunk of table contents that should be currently visible. This is managed via the serverSideFetchRowDataFn callback function.

pagination-posistion-demo

pagination-default-layout-demo

pagination-compact-layout-demo  

pagination-with-page-jump-demo

 

Paginator and Row Count are housed in the 'TableControlRow' component as 'Table Element Row Count' and 'Paginator' respectively.
Refresh

DataTable data is automatically fetched on page reload, but if you have a need to allow your users to refresh data more frequently, we offer the ability to manually refresh the data.

When manual refresh is enabled the refresh icon will appear above the table along with the last time the data was pulled. When the button is clicked the table will call the consuming application to fetch the data again. The last fetch time of data can also be displayed next to the refresh button allowing the user to easily see when it was last updated. 

You can also trigger loading with an external component.

server-side-refresh-demo

external-loader-demo

This feature will be added to Figma soon.

 

UI Change Features

NameDescriptionStorybook Demo with Code LinkFigma Notes
Alert Styling

DataTable alert styling exists in two forms:

  • Row-Based: Alert colored bars that are added to the left side of entire rows.
  • Cell-Based: Alert style icons added to individual cells.

alert-styling-demo

Colored alert bars are added via 'left actions' a variant property found in the 'TableCell' component.

Individual alert icons are added via 'alert' a boolean found in the 'cell content' component that is nested within the 'TableCell' component.

LayoutDataTable offers two layout settings: medium and compact. The medium layout (default) is suitable for most tables, while the compact layout is best for dense datasets with many numbers, such as a table of recent transactions.

layout-demo

(use the button at the top of the control panel called 'Demo Options' to toggle layout)

Table Layout is handled by the 'Table Layout' variant found in the 'TableCell' component. Layout must be applied to ALL cells/rows in your figma example.
Sticky StylingSticky styling is an optional UI change that allows columns, row headers, and/or row footers to be sticky, meaning they remain visible as users scroll to assist with visual table navigation.

sticky-header-and-footer-demo

sticky-column-demo

Sticky headers, footers, and columns cannot be perfectly mimicked in Figma.

To quasi-mimick the feature, select all cells in one row or one column and use prototyping features to set the elements as sticky and the other columns/rows as 'scroll with parent'.

For help with this please reach out to Veronica Agne.

Entity name Changes

You can define what each row of a table means and displaying table row counts with that name. i.e. 50 people instead of 50 rows

entity-renaming-demo

This feature will be added to Figma soon.

Column Header StylingFor unique UI needs, column headers can be styled with line breaks or to wrap/not wrap accordingly.

wrap-no-wrap-demo

line-breaks-in-header-demo

To access line breaks or second lines in column headers, first turn on the boolean 'header' prop in the 'Table Cell' component then toggle on '2nd line' boolean prop in the nested 'cell content' component

Custom UI Styling For unique UI needs, the entire table can have class and style modifications for a custom look.

table-style-and-class-demo

This is not available in Figma.

Demos

Basic Share

Sorting Share

Quick Filter Sort With Pagination Share

Edit Row In Dialog Share

Clickable Row Share

Custom Column Share

Coding

Developer tips

Storybook files

DataTable has so many features that it's difficult to create representative demos for everything in this guide, as performance of this page would degrade. For this reason, it's strongly encouraged to view the storybook files in the source code and see them run at http://go/forge-storybook.

createDataTable factory function

DataTable breaks many paradigms shared by a typical Forge component, in part because it is so huge. There is no DataTable export. Instead, most aspects of DataTable are accessed via the createDataTable factory function.

const DT = createDataTable<RowData>({ tableId: 'patient-table' });
const patients:RowData[] = [...]
const PatientTable = (): ReactElement => {
return <DT.DataTable tableType="client-side" columns={columns} rowData={patients} {...props} />
}

The reason behind the createDataTable factory function is to bind the type of RowData to the implementation. It's important to call createDataTable outside of a component's render function. Otherwise, React will unmount and remount the entire table on every re-render of your component.

While Forge does export all of the Typescript types cited in the props documentation, we also provide abstractions of these types for easier access. For example, to define your own CustomAddRowComponent, you need the DataTableHooks to define its supported props. You can either

import { DataTableHooks } from '@athena/forge';
const CustomAddRowComponent = (
props: DataTableHooks<RowData>
): ReactElement => <></>;

or

const DT = createDataTable<RowData>({ tableId: 'patient-table' });
const CustomAddRowComponent = (
props: typeof DT.Type.Hooks
): ReactElement => <></>;

See createDataTable implementation for details of what is included.

DataTable vs. SingletonDataTable vs. Advanced DataTable

  • DT.DataTable works like a regular React component. Whenever the props of your DataTable change, the entire DataTable component will be re-rendered. You can use ref.current.getState to get the current internal state and ref.current.dispatch to change it.
  • DT.SingletonDataTable can only be used if your React app needs just one DataTable instance. DT.SingletonDataTable performs better than DT.DataTable because it only re-renders the subcomponents when specific states change. You can also use ref.current.getState to get the current internal state and ref.current.dispatch to change it.
    • You can't create a reusable React component using based on the SingletonDataTable.
    • SingletonDataTable is implemented using the React Context API.
  • Advanced DataTable: DT.Provider, DT.DataTableRender, DT.DataTableInterface, DT.useSelector, and DT.useDispatch are used for the scalable DataTable component.
  • Scalability: Advanced DataTable > DT.SingletonDataTable > DT.DataTable. It’s recommended to start with the DT.DataTable.

Repository

Implementation links

DataTable directory in Bitbucket

Implementation details

It is strongly recommended to familiarize yourself with the Forge source code. While this documentation is a best effort to document the intent and usage of a component, sometimes some features only become clear when looking at the source code. Also, looking at Forge's source code may help identify and fix bugs in either your application or Forge itself.

Storybook files

Forge maintains at least one storybook file per component. While the primary audience for these files is typically the Forge team, these storybook files may cover usages of the component not covered by a demo. The storybook for the latest version of forge can be found at go/forge-storybook.

Testing library

Forge strongly encourages using testing-library to write tests for your application.

"The more your tests resemble the way your software is used, the more confidence they can give you."

If you're having trouble testing a Forge component using testing-library, it would be a good idea to see how Forge tests its own components. For the most part, Forge tries to use screen.getByRole as much as it can, as that API provides the best feedback on a11y compliance. Forge discourages the use of document.querySelector and screen.getByTestId as both APIs encourage using implementation details to test your component, and discourage adding roles to your component.

With that being said, many of Forge's components were not built with accessibility in mind. These components do break the recommendations listed above.

Import statements

In Nimbus applications

athenaOne serves the Forge bundle independently from your application's bundle. Importing Forge components directly from '@athena/forge' takes advantage of this feature.

import { createDataTable } from '@athena/forge'

In standalone applications

Importing components using the exact path to the module takes advantage of webpack's tree shaking feature. Webpack will include only that module and its dependencies.

import { createDataTable } from '@athena/forge/DataTable';

To use this import guidance, Typescript applications must use typescript >= 4.7.3, and should add this setting to their tsconfig.json file:

{ "compilerOptions": { "moduleResolution": "Node16", } } If this setting doesn't work for your application, use this import statement instead:

import { createDataTable } from '@athena/forge/dist/DataTable';

Props