Tables are used for displaying columns and rows of data.
Date | Expected Quantity | Actual Quantity |
---|---|---|
2019-10-01 | 2,025 eaches | 1,800 eaches |
2019-10-02 | 2,475 eaches | 2,250 eaches |
2019-10-03 | 2,475 eaches | 1,425 eaches |
2019-10-04 | 2,475 eaches | 675 eaches |
2019-10-07 | 2,475 eaches | 1,575 eaches |
2019-10-22 | 1,725 eaches | - |
2019-10-23 | 2,475 eaches | - |
2019-10-24 | 2,475 eaches | - |
import {Table} from "@nulogy/components";
const columns = [
{ label: "Date", dataKey: "date" },
{ label: "Expected Quantity", dataKey: "expectedQuantity" },
{ label: "Actual Quantity", dataKey: "actualQuantity" }
];
const rows = [
{
date: "2019-10-01",
expectedQuantity: "2,025 eaches",
actualQuantity: "1,800 eaches",
id: "r1"
},
{
date: "2019-10-02",
expectedQuantity: "2,475 eaches",
actualQuantity: "2,250 eaches",
id: "r2"
},
{
date: "2019-10-03",
expectedQuantity: "2,475 eaches",
actualQuantity: "1,425 eaches",
id: "r3"
},
...
{
date: "2019-10-24",
expectedQuantity: "2,475 eaches",
actualQuantity: "-",
id: "r8"
}
];
<Table columns={columns} rows={rows} keyField="date"/>
A custom component can be implemented using a CellFormatter (to maintain the existing cell styles) or CellRenderer (for completely custom styles).
Similarly headers can be customized using the HeaderFormatter function props. See Storybook for other examples of implementing different custom components.
Date | Expected Quantity | Actual Quantity | |
---|---|---|---|
Tue Oct 01 2019 | 2,025 eaches | 1,800 eaches | |
Wed Oct 02 2019 | 2,475 eaches | 2,250 eaches | |
Thu Oct 03 2019 | 2,475 eaches | 1,425 eaches | |
Fri Oct 04 2019 | 2,475 eaches | 675 eaches | |
Mon Oct 07 2019 | 2,475 eaches | 1,575 eaches | |
Tue Oct 22 2019 | 1,725 eaches | - | |
Wed Oct 23 2019 | 2,475 eaches | - | |
Thu Oct 24 2019 | 2,475 eaches | - |
const customCellRenderer = ({cellData}) => (
<IconicButton icon="delete">{cellData}</IconicButton>
);
const dateToString = ({cellData}) => {
return new Date(cellData).toDateString();
};
const customHeaderFormatter = ({ label }) => (
<>
<IconicButton icon="delete">{label}</IconicButton>
</>
);
const columnsWithCustomCells = [
{ label: "Date", dataKey: "date", cellFormatter: dateToString },
{ label: "Expected Quantity", dataKey: "expectedQuantity",},
{ label: "Actual Quantity", dataKey: "actualQuantity",},
{
label: "Remove all",
dataKey: "actions",
headerFormatter: customHeaderFormatter,
cellRenderer: customCellRenderer
}
];
<Table columns={columnsWithCustomCells} rows={rows} />
Setting hasSelectableRows on the Table will add a column of checkboxes to the table so that rows can be selected by the user. Using the checkbox in the head of the table will toggle the selection of all rows.
A keyField should be specified to provide unique ids for rows (by default the keyField will be "id" and expect a property of id in the row objects).
Date | Expected Quantity | Actual Quantity | |
---|---|---|---|
2019-10-01 | 2,025 eaches | 1,800 eaches | |
2019-10-02 | 2,475 eaches | 2,250 eaches | |
2019-10-03 | 2,475 eaches | 1,425 eaches | |
2019-10-04 | 2,475 eaches | 675 eaches | |
2019-10-07 | 2,475 eaches | 1,575 eaches | |
2019-10-22 | 1,725 eaches | - | |
2019-10-23 | 2,475 eaches | - | |
2019-10-24 | 2,475 eaches | - |
<Table
columns={columns}
rows={rows}
keyField="date"
HasSelectableRows
onRowSelectionChange={selectedRows => selectedRows}
/>
A width for a column can be set (as actual size or percentage) inside the column data.
Date | Expected Quantity | Actual Quantity |
---|---|---|
2019-10-01 | 2,025 eaches | 1,800 eaches |
2019-10-02 | 2,475 eaches | 2,250 eaches |
2019-10-03 | 2,475 eaches | 1,425 eaches |
2019-10-04 | 2,475 eaches | 675 eaches |
2019-10-07 | 2,475 eaches | 1,575 eaches |
2019-10-22 | 1,725 eaches | - |
2019-10-23 | 2,475 eaches | - |
2019-10-24 | 2,475 eaches | - |
const columnsWithWidths = [
{ label: "Date", dataKey: "date", width: "40%" },
{ label: "Expected Quantity", dataKey: "expectedQuantity" },
{ label: "Actual Quantity", dataKey: "actualQuantity" }
];
<Table columns={columnsWithWidths} rows={rows} />
The table can be set to loading while row data is being fetched. It will show rows when the loading prop is set to false.
Date | Expected Quantity | Actual Quantity |
---|---|---|
Loading... |
<Table loading columns={columns} rows={rows} />
The table can be set to use compact styling which decreases the paddings when the compact prop is set to true.
Date | Expected Quantity | Actual Quantity |
---|---|---|
2019-10-01 | 2,025 eaches | 1,800 eaches |
2019-10-02 | 2,475 eaches | 2,250 eaches |
2019-10-03 | 2,475 eaches | 1,425 eaches |
2019-10-04 | 2,475 eaches | 675 eaches |
2019-10-07 | 2,475 eaches | 1,575 eaches |
2019-10-22 | 1,725 eaches | - |
2019-10-23 | 2,475 eaches | - |
2019-10-24 | 2,475 eaches | - |
<Table columns={columns} rows={rows} compact />
The table header can remain fixed to the top of the table when scrolling by setting the prop stickyHeader to true.
Date | Expected Quantity | Actual Quantity |
---|---|---|
2019-10-01 | 2,025 eaches | 1,800 eaches |
2019-10-02 | 2,475 eaches | 2,250 eaches |
2019-10-03 | 2,475 eaches | 1,425 eaches |
2019-10-04 | 2,475 eaches | 675 eaches |
2019-10-07 | 2,475 eaches | 1,575 eaches |
2019-10-22 | 1,725 eaches | - |
2019-10-23 | 2,475 eaches | - |
2019-10-24 | 2,475 eaches | - |
<Table columns={columns} rows={rows} stickyHeader />
A footer can be added to the table by adding an array of rows to the footerRows prop.
Date | Expected Quantity | Actual Quantity |
---|---|---|
2019-10-01 | 2,025 eaches | 1,800 eaches |
2019-10-02 | 2,475 eaches | 2,250 eaches |
2019-10-03 | 2,475 eaches | 1,425 eaches |
2019-10-04 | 2,475 eaches | 675 eaches |
2019-10-07 | 2,475 eaches | 1,575 eaches |
2019-10-22 | 1,725 eaches | - |
2019-10-23 | 2,475 eaches | - |
2019-10-24 | 2,475 eaches | - |
Total | 18,000 eaches | 7,725 eaches |
Attainment | 41.5% |
import {Table} from "@nulogy/table";
const footerRows = [
{ date: "Total", expectedQuantity: "18,000 eaches", actualQuantity: "7,725 eaches" },
{ date: "Attainment", expectedQuantity: "", actualQuantity: " 41.5%" }
];
<Table columns={columns} rows={rows} footerRows={footerRows} />
Setting rowsPerPage on the Table will add a Pagination component to the table. A maximum of the specified rowsPerPage will be shown on each page.
Providing a function to onPageChange will allow tracking of the current page number. It is fired whenever the page changes and takes in the current page number as an argument.
Date | Expected Quantity | Actual Quantity |
---|---|---|
2019-10-01 | 2,025 eaches | 1,800 eaches |
2019-10-02 | 2,475 eaches | 2,250 eaches |
2019-10-03 | 2,475 eaches | 1,425 eaches |
<Table
columns={columns}
rows={rows}
rowsPerPage={3}
onPageChange={pageNum => pageNum}
/>
Headings that span the full width of a row can be added within the table's rows. To add a heading add a row with a key of heading The appearance of the heading can be customized by adding a cellRenderer to the row. See an example in Storybook.
Setting hasExpandableRows and providing expandedContent on a row will add a button that can be used to expand and collapse content.expandedContent should return a React node that should be rendered when the row is expanded.
A keyField should be specified to provide unique ids for rows (by default the keyField will be "id" and expect a property of id in the row objects).
Date | Expected Quantity | Actual Quantity | |
---|---|---|---|
2019-10-01 | 2,025 eaches | 1,800 eaches | |
2019-10-02 | 2,475 eaches | 2,250 eaches | |
2019-10-03 | 2,475 eaches | 1,425 eaches | |
2019-10-04 | 2,475 eaches | 675 eaches | |
2019-10-07 | 2,475 eaches | 1,575 eaches | |
2019-10-22 | 1,725 eaches | - | |
2019-10-23 | 2,475 eaches | - | |
2019-10-24 | 2,475 eaches | - |
<Table
columns={columns}
rows={rowDataWithExpandedContent}
hasExpandableRows
onRowExpansionChange={() => {}}
/>
The Pagination and Table components can also be used together to support server-side pagination or other custom behaviour. An example of such an implementation can be found in Storybook.
Filtering can be implemented by passing filtered rows to the rows prop of the table. See an example of filtering inStorybook.
Sorting can be implemented using the headerFormatter to pass a SortingHeader component or another custom header to the column that should be sortable. See an example of the complete implementation with table inStorybook.
Name | Type | Default | Description |
---|---|---|---|
columns | array | Required | An array of column objects consisting of a label and dataKey and optionally, align and cellRenderer |
rows | array | Required | An array of row objects, where the key name matches the dataKey of the column |
loading | boolean | false | A boolean that will show the table body in a loading state when set to true |
noRowsContent | string | No records have been created for this table. | What to display when the table has no data |
keyField | string | id | The name of the key to use as a unique identifier for individual rows |
stickyHeader | boolean | false | Sets the table header to sticky. NOTE: the vertical position of the sticky header is aligned to the top of the Table. If there is padding on an element wrapping the Table you will see that the header is offset according to the top padding. |
hasSelectableRows | boolean | false | Displays a column of checkboxes allowing the user to select rows in the table |
selectedRows | array | empty | An array of row id's that are marked as selected in the table |
onRowSelectionChange | function | none | The function that should be called when a row selection changes. The array of rows currently selected is passed in as an argument. |
expandedRows | array | empty | An array of row id's that are expanded in the table |
onRowExpansionChange | function | none | The function that should be called when a row is expanded or collapsed. The array of rows currently expanded is passed in as an argument. |
rowsPerPage | number | none | The number of rows to display per page |
onPageChange | function | none | The function that should be called when a current page changes. The page number that is currently selected is passed in as an argument. |
rowHovers | boolean | true | Whether or not to show a light grey background on a row when hovering it |
compact | boolean | false | Whether or not to display the table in compact mode |
selectAllLabel | string | When hasSelectableRows is true, replaces the aria-label for the unchecked select all checkbox | |
deselectAriaLabel | string | When hasSelectableRows is true, replaces the aria-label for the checked select all checkbox | |
onRowMouseEnter | ({row: rowData, e: Event}) => void | Event handler that is called whenever a mouse enters a row | |
onRowMouseLeave | ({row: rowData, e: Event}) => void | Event handler that is called whenever a mouse leaves a row |
Name | Type | Default | Description |
---|---|---|---|
label | string | Required | The label used in the header of the table column |
dataKey | string | Required | Unique key for the column, used as the keys to define cell content for the column of each row |
align | string enum ('left', 'right' or 'center') | left | sets the alignment of the text for the column in the default cell |
cellFormatter | function | Used to format the table cells in the column. It should return a string or react component. | |
cellRenderer | function | Used to override the cell component in the column. No padding or other styles will be added in this case. It should return a react component. | |
headerFormatter | function | Used to format the column's header. It should return a string or react component. |
Rows should have keys corresponding to the dataKeys provided in the columns. In addition, there are a few extra keys used by the table that can be provided to each row
Name | Type | Default | Description |
---|---|---|---|
id | string | Unique id for each row, required if another keyField is not passed to the Table | |
heading | string | Creates a heading out of the row that spans the full-width of the table | |
cellRenderer | function | Used to override the cell component in the row. No padding or other styles will be added in this case. It should return a react component. | |
expandAriaLabel | string | When hasExpandableRows is true, replaces the aria-label for the expand button | |
collapseAriaLabel | string | When hasExpandableRows is true, replaces the aria-label for the collapse button | |
selectAriaLabel | string | When hasSelectableRows is true, replaces the aria-label for the unchecked checkbox | |
deselectAriaLabel | string | When hasSelectableRows is true, replaces the aria-label for the checked checkbox |
Use CellFormatter to maintain the styles within the cell while providing a custom component or string. Use CellRenderer when using completely custom styles.
Name | Type | Default | Description |
---|---|---|---|
cellData | string | Text in the current cell, as passed in in the rows object | |
column | column | The column object the cell belongs to | |
row | row | The row object the cell belongs to |
Use HeaderFormatter to provide a custom header component. Styles on the header cell will be maintained.
Name | Type | Default | Description |
---|---|---|---|
column | column | The current column object |