DXC Logo
Halstack Design System
v16.1.0

Data Grid

The datagrid component is used to display and manage large sets of data in a tabular format, allowing users to sort, filter, and interact with the data efficiently.

Props

NameTypeDescriptionDefault
Required
columns

GridColumn[]being GridColumn:

{ key: string; label: string; resizable?: boolean; sortable?: boolean; sortFn?: (a: ReactNode, b: ReactNode) => number; draggable?: boolean; textEditable?: boolean; summaryKey?: string; alignment?: "left" | "right" | "center"; }
Each GridColumn object has the following properties:
  • key: Key that will be rendered from each row in rows.
  • label: Label that will be used for the column header.
  • resizable: Whether the column is resizable or not.
  • sortable: Whether the column is sortable or not.
  • sortFn: Custom function with the criteria for the column sorting.
  • draggable: Whether the column can be dragged or not to another position or not.
  • textEditable: Whether the column cells are editable or not.
  • summaryKey: Value that will be rendered from the summaryRow
  • alignment: Sets the alignment inside the cells.
-
defaultPagenumberDefault page in which the datagrid is rendered.-
expandablebooleanWhether the rows can expand or not.-
itemsPerPagenumberNumber of items per page.5
itemsPerPageFunction(value: number) => voidThis function will be called when the user selects an item per page option. The value selected will be passed as a parameter.-
itemsPerPageOptionsnumber[]An array of numbers representing the items per page options.-
New
childrenTrigger
(open: boolean, triggerRow: HierarchyGridRow) => (HierarchyGridRow[] | GridRow[]) | Promise<HierarchyGridRow[] | GridRow[]>
Function called whenever a cell with children (HierarchyGridRow) is expanded or collapsed (based on the value of open). Returns (or resolves to) the array of child rows nested under this row to display when expanded.-
onGridRowsChange(rows: GridRow[] | HierarchyGridRow[] | ExpandableGridRow[]) => voidFunction called whenever a cell is edited.-
onPageChange(page: number) => voidFunction called whenever the current page is changed.-
onSelectRows(selectedRows: Set<number | string>) => voidFunction called whenever the selected values changes. This prop is mandatory if selectable is set to true.The uniqueRowId key will be used to identify the rows.-
onSort(sortColumn?: { columnKey: string, direction: 'ASC' | 'DESC' }) => voidFunction called whenever a column is sorted. Receives the sorted column and direction, or `undefined` if no sorting is applied.-
Required
rows
GridRow[] | HierarchyGridRow[] | ExpandableGridRow[]

Each one of them being in order:

{ [key: string]: React.ReactNode | undefined; }

GridRow & { childRows?: HierarchyGridRow[] | GridRow[]; childrenTrigger?: ( open: boolean, triggerRow: HierarchyGridRow ) => (HierarchyGridRow[] | GridRow[]) | Promise<HierarchyGridRow[] | GridRow[]>; }

GridRow & { expandedContent?: React.ReactNode; expandedContentHeight?: number; contentIsExpanded?: boolean; }

List of rows that will be rendered in each cell based on the key in each column.-
selectablebooleanWhether the rows are selectable or not.-
selectedRowsSet<string | number>Set of selected rows. This prop is mandatory if selectable is set to true. The uniqueRowId key will be used to identify the each row.-
showGoToPagebooleanIf true, a select component for navigation between pages will be displayed.true
showPaginatorbooleanIf true, paginator will be displayed.false
summaryRowGridRowExtra row that will be always visible.-
totalItemsnumberNumber of total items.-
uniqueRowIdstringThis prop indicates the unique key that can be used to identify each row. The value of that key can be either a number or a string. This prop is mandatory if selectable is set to true, expandable is set to true or rows is of type HierarchyGridRow[].-

DxcDataGrid.ActionsCell

A compound component aimed to be used inside the table to display up to three actions.

Props

NameTypeDescriptionDefault
Required
actions
{ icon: string | SVG; title: string; onClick: () => void; disabled?: boolean; tabIndex?: number; }[] | { title: string; onClick: (value?: string) => void; disabled?: boolean; tabIndex?: number; options: Option[]; }[]

It represents a list of interactive elements that will work as buttons or as a dropdown. Those with an icon from Material Symbols or a SVG are treated as buttons. If any element lacks an icon and includes options, it is interpreted as a dropdown. Only the first action with options will be displayed and only up to 3 actions. In the case of the dropdown the click function will pass the value assigned to the option, click here for more details.

-

Examples

Basic usage

() => {
  const columns = [
    {
      key: "id",
      label: "ID",
      resizable: true,
      draggable: true,
    },
    {
      key: "complete",
      label: "% Complete",
      resizable: true,
      draggable: true,
      alignment: "right",
    },
  ];
  
  const rows = [
    {
      id: "Row 1",
      complete: 46, 
    },
    {
      id: "Row 2",
      complete: 51,
    },
    {
      id: "Row 3",
      complete: 40,
    },
    {
      id: "Row 4",
      complete: 10,
    },
  ];
  
  return (
    <DxcInset space="var(--spacing-padding-xl)">
      <DxcDataGrid columns={columns} rows={rows} uniqueRowId="id" />
    </DxcInset>
  );
}

Actions cell

() => {
const actions = [
    {
      icon: "delete",
      title: "Delete",
      onClick: () => {},
    },
    {
      title: "edit",
      onClick: (value) => {},
      options:[
        {
          value: "1",
          label: "Edit",
        },
        {
          value: "2",
          label: "Mark as selected",
        },
      ]
    },
  ];
  const columns = [
    {
      key: "id",
      label: "ID",
      resizable: true,
      draggable: true,
    },
    {
      key: "complete",
      label: "% Complete",
      resizable: true,
      draggable: true,
      alignment: "right",
    },
    {
        key: "actions",
        label: "Actions",
        alignment: "center",
    },
  ];
  
  const rows = [
    {
      id: "Row 1",
      complete: 46,
      actions: <DxcDataGrid.ActionsCell actions={actions} />,
    },
    {
      id: "Row 2",
      complete: 51,
      actions: <DxcDataGrid.ActionsCell actions={actions} />,
    },
    {
      id: "Row 3",
      complete: 40,
      actions: <DxcDataGrid.ActionsCell actions={actions} />,
    },
    {
      id: "Row 4",
      complete: 10,
      actions: <DxcDataGrid.ActionsCell actions={actions} />,
    },
  ];
  
  return (
    <DxcInset space="var(--spacing-padding-xl)">
      <DxcDataGrid columns={columns} rows={rows} uniqueRowId="id" />
    </DxcInset>
  );
}

Selectable data grid

() => {
  const columns = [
    {
      key: "id",
      label: "ID",
      resizable: true,
      draggable: true,
    },
    {
      key: "complete",
      label: "% Complete",
      resizable: true,
      draggable: true,
      alignment: "right",
    },
  ];
  
  const rows = [
    {
      id: "Row 1",
      complete: 46, 
    },
    {
      id: "Row 2",
      complete: 51,
    },
    {
      id: "Row 3",
      complete: 40,
    },
    {
      id: "Row 4",
      complete: 10,
    },
  ];
  
  const [selectedRows, setSelectedRows] = useState(new Set());
  return (
    <DxcInset space="var(--spacing-padding-xl)">
      <DxcDataGrid
          columns={columns}
          rows={rows}
          uniqueRowId="id"
          selectable
          selectedRows={selectedRows}
          onSelectRows={setSelectedRows}
        />
    </DxcInset>
  );
}

Expandable data grid

() => {
  const columns = [
    {
      key: "id",
      label: "ID",
      resizable: true,
      draggable: true,
    },
    {
      key: "complete",
      label: "% Complete",
      resizable: true,
      draggable: true,
      alignment: "right",
    },
  ];
  
  const rows = [
    {
      id: "Row 1",
      complete: 46,
      expandedContent: "Expanded content"
    },
    {
      id: "Row 2",
      complete: 51,
      expandedContent: "Expanded content",
      expandedContentHeight: 100
    },
    {
      id: "Row 3",
      complete: 40,
    },
    {
      id: "Row 4",
      complete: 10,
    },
  ];
  
  return (
    <DxcInset space="var(--spacing-padding-xl)">
      <DxcDataGrid columns={columns} rows={rows} expandable uniqueRowId="id" />
    </DxcInset>
  );
}

Hierarchical data grid

() => {
  const columns = [
    {
      key: "name",
      label: "Label",
      summaryKey: "label"
    },
    {
      key: "value",
      label: "Value",
      alignment: "right",
      summaryKey: "total"
    },
  ];
  
  const rows = [
    {
        name: "Root Node 1",
        value: "1",
        id: "a",
        childRows: [
            {
                name: "Child Node 1.1",
                value: "1.1",
                id: "aa",
                childRows: [
                {
                    name: "Grandchild Node 1.1.1",
                    value: "1.1.1",
                    id: "aaa",
                },
                {
                    name: "Grandchild Node 1.1.2",
                    value: "1.1.2",
                    id: "aab",
                },
                ],
            },
            {
                name: "Child Node 1.2",
                value: "1.2",
                id: "ab",
            },  
        ],
    },
    {
        name: "Root Node 2",
        value: "2",
        id: "b",
        childRows: [
            {
                name: "Child Node 2.1",
                value: "2.1",
                id: "ba",
                childRows: [
                {
                    name: "Grandchild Node 2.1.1",
                    value: "2.1.1",
                    id: "baa",
                },
                ],
            },
            {
                name: "Child Node 2.2",
                value: "2.2",
                id: "bb",
            },
            {
                name: "Child Node 2.3",
                value: "2.3",
                id: "bc",
            },
        ],
    },
  ];

  const summaryRow = { label: "Total", total: 100, id: "summary" }

  return (
    <DxcInset space="var(--spacing-padding-xl)">
      <DxcDataGrid columns={columns} rows={rows} summaryRow={summaryRow} uniqueRowId="id" />
    </DxcInset>
  );
}

Hierarchical and selectable data grid

() => {
  const [columns] = useState([
    {
      key: "name",
      label: "Label",
      summaryKey: "label"
    },
    {
      key: "value",
      label: "Value",
      alignment: "right",
      summaryKey: "total"
    },
  ]);

  const [rows] = useState([
    {
        name: "Root Node 1",
        value: "1",
        id: "a",
        childRows: [
            {
                name: "Child Node 1.1",
                value: "1.1",
                id: "aa",
                childRows: [
                {
                    name: "Grandchild Node 1.1.1",
                    value: "1.1.1",
                    id: "aaa",
                },
                {
                    name: "Grandchild Node 1.1.2",
                    value: "1.1.2",
                    id: "aab",
                },
                ],
            },
            {
                name: "Child Node 1.2",
                value: "1.2",
                id: "ab",
            },  
        ],
    },
    {
        name: "Root Node 2",
        value: "2",
        id: "b",
        childRows: [
            {
                name: "Child Node 2.1",
                value: "2.1",
                id: "ba",
                childRows: [
                {
                    name: "Grandchild Node 2.1.1",
                    value: "2.1.1",
                    id: "baa",
                },
                ],
            },
            {
                name: "Child Node 2.2",
                value: "2.2",
                id: "bb",
            },
            {
                name: "Child Node 2.3",
                value: "2.3",
                id: "bc",
            },
        ],
    },
  ]);

  const [selectedRows, setSelectedRows] = useState(new Set());
  return (
    <DxcInset space="var(--spacing-padding-xl)">
      <DxcDataGrid
          columns={columns}
          rows={rows}
          uniqueRowId="id"
          selectable
          selectedRows={selectedRows}
          onSelectRows={setSelectedRows}
        />
    </DxcInset>
  );
}

Paginator

() => {
  const columns = [
    {
      key: "id",
      label: "ID",
      resizable: true,
      draggable: true,
    },
    {
      key: "complete",
      label: "% Complete",
      resizable: true,
      draggable: true,
      alignment: "right",
    },
  ];
  
  const rows = [
    {
      id: "Row 1",
      complete: 46, 
    },
    {
      id: "Row 2",
      complete: 51,
    },
    {
      id: "Row 3",
      complete: 40,
    },
    {
      id: "Row 4",
      complete: 10,
    },
  ];
  
  return (
    <DxcInset space="var(--spacing-padding-xl)">
      <DxcDataGrid columns={columns} rows={rows} uniqueRowId="id" showPaginator itemsPerPage={2} />
    </DxcInset>
  );
}

Custom sorting

() => {
  const columns = [
    {
      key: "id",
      label: "ID",
      resizable: true,
      draggable: true,
      sortable: true,
    },
    {
      key: "complete",
      label: "% Complete",
      resizable: true,
      draggable: true,
      sortable: true,
      alignment: "right",
    },
  ];
  
  const rows = [
    {
      id: "Row 1",
      complete: 46, 
    },
    {
      id: "Row 2",
      complete: 51,
    },
    {
      id: "Row 3",
      complete: 40,
    },
    {
      id: "Row 4",
      complete: 10,
    },
  ];

  
  const [itemsPerPage, setItemsPerPage] = useState(2);
  const [rowsControlled, setRowsControlled] = useState(rows.slice(0, itemsPerPage));
  const [page, setPage] = useState(0);

  return (
    <DxcInset space="var(--spacing-padding-xl)">
      <DxcDataGrid
          columns={columns}
          rows={rowsControlled}
          uniqueRowId="id"
          onSort={(sortColumn) => {
            if (sortColumn) {
              const { columnKey, direction } = sortColumn;
              console.log("Sorting the column " + columnKey + " by " + direction);
              setRowsControlled((currentRows) => {
                return currentRows.sort((a, b) => {
                  if (direction === "ASC") {
                    return a[columnKey] < b[columnKey] ? -1 : a[columnKey] > b[columnKey] ? 1 : 0;
                  } else {
                    return a[columnKey] < b[columnKey] ? 1 : a[columnKey] > b[columnKey] ? -1 : 0;
                  }
                });
              });
            } else {
              console.log("Removed sorting criteria")
              setRowsControlled(rows.slice(page * itemsPerPage, page * itemsPerPage + itemsPerPage));
            }
          }}
          onPageChange={(page) => {
            const internalPage = page - 1;
            setPage(internalPage);
            setRowsControlled(rows.slice(internalPage * itemsPerPage, internalPage * itemsPerPage + itemsPerPage));
          }}
          showPaginator
          itemsPerPage={itemsPerPage}
          itemsPerPageOptions={[2, 4]}
          itemsPerPageFunction={(n) => 
            {
              setItemsPerPage(n);
              setRowsControlled(rows.slice(0, n));
            }
          }
          totalItems={rows.length}
        />
    </DxcInset>
  );
}