Skip to main content

Migration guide

The DataTableV2 is a component for building tables which organize information into rows and columns.

The DataTableV2 comes mostly with an API compatible with the DataTable component. There have been made some changes to the API where we can provide more type safety.

Codemod

We're providing a codemod for you to get started with the transition from DataTable to DataTableV2. This isn't meant as a complete transition codemod but will adjust your imports and renames JSX elements and attributes that have changed. If there are API changes they will be annotated as best as possible. Make sure you have saved and committed your work before running this codemod. To run the codemod, download this file:

DataTable to DataTableV2 codemod

The codemod is built on top of jscodeshift. Use this command to run the codemod on a file (make sure to not run it on the entire codebase).

npx jscodeshift --parser tsx -t <PATH_TO_THE_DOWNLOADED_FILE>/migrate-datatable-datatablev2.js <PATH_TO_THE_FILE_TO_MIGRATE>.tsx

Import changes

You can now import the DataTableV2 and the DataTableV2ColumnDef from the @dynatrace/strato-components-preview/tables package. All types and components associated with the DataTableV2 are also prefixed with DataTableV2 in order to avoid confusion.

import {
DataTableV2,
type DataTableV2ColumnDef,
} from '@dynatrace/strato-components-preview/tables';

Column definition changes

Display columns and group columns

We have improved on the column definition types for the DataTableV2. There is now a differentiation between the column groups and display columns. Group columns can hold another set of columns as their children, but might not allow some other members to be set.

Column width configuration

The most significant change in the column definition is regarding the width configuration. The properties width, autoWidth, ratioWidth, maxAutoWidth have been combined into the width property. Content aware property values like auto and content are only available on display columns.

// ratioWidth
- ratioWidth: 1
+ width: '1fr'

// autoWidth
- autoWidth: true
+ width: 'content'

// maxAutoWidth
- autoWidth: true
- maxAutoWidth: 500
+ width: { type: 'content', maxWidth: 500 }

Custom header and cell renderer

Custom header and cell renderer are still available in the same manner as you were using them in DataTable. However, the signature of the custom renderer functions have changed in order to maintain clear API consistency and no longer rely on third party typing.

header: () => <DataTableV2.Cell>{/* ... */}</DataTableV2.Cell>,
cell: ({
// The value of the cell.
value,
// The index of the current row.
rowIndex,
// The values that are within the row.
rowData,
// The id of the row.
rowId,
// A formatter function that would have been applied out of the box.
// With this you can replicate the built-in formatting of the DataTableV2,
// if you do not want to customize it.
format,
}) => <DataTableV2.Cell>{/* ... */}</DataTableV2.Cell>;

Type safety in column definitions

The DataTableV2ColumnDef interface now allows a generic to be set, which defines your row type. You can either define your own type that will mirror your row data, or use type inference if you have uniform data.

// Will result in an inferred type Array<{ name: string }>;
const data = useMemo(() => [{ name: 'John' }, { name: 'Andrea' }], []);

const columns = useMemo<DataTableV2ColumnDef<(typeof data)[number]>[]>(
() => [
{
header: 'Name',
accessor: 'name',
},
],
[],
);

Accessor changes

The accessor mostly functions the same way as in the DataTable. There have been smaller changes in the dot-notation and parameters that are passed to the accessor funciton in order to keep API consistency.

// There is no need for additional quotes around dot annotated accessors
- accessor: '"firstname.value"',
+ accessor: 'firstname.value',

// If field names contain . characters, these can be accessed with []
- accessor: accessor: (value) => value['dt.data.memoryTotal'],
+ accessor: 'value["dt.data.memoryTotal"]'

The accessor can still also be defined as a function, and will be passed the entire row data.

Column, cell and row actions

The render function API for DataTableV2.CellActions, DataTableV2.ColumnActions and DataTableV2.RowActions has changed to not over expose internal types.

<DataTableV2.CellActions>
{({
// The column definition associated with this cell.
columnDef,
// id of the row the given cell is in.
rowId,
// The data of the row for the given cell action.
row,
// value of the cell based on the accessor.
cellValue,
}) => (
<TableActionsMenu>
<TableActionsMenu.Item onSelect={() => undefined}>
{/* ... */}
</TableActionsMenu.Item>
</TableActionsMenu>
)}
</DataTableV2.CellActions>
<DataTableV2.ColumnActions>
// Invoked with the column definition of the given column
{(column) => (
<TableActionsMenu>
<TableActionsMenu.Item onSelect={() => undefined}>
{/* ... */}
</TableActionsMenu.Item>
</TableActionsMenu>
)}
</DataTableV2.ColumnActions>

The row actions column has been opened up and will now let you provide a way to render your custom actions per row.

<DataTableV2.RowActions>
// Invoked with the data of the given row.
{(row, { rowDensity }) => (
<>
<Button
size={rowDensity !== 'comfortable' ? rowDensity : 'default'}
color="primary"
>
Primary action
</Button>

<Menu>
<Menu.Content>
<Menu.Item onSelect={() => console.log('selected', row)}>
Row action 1
</Menu.Item>
<Menu.Item onSelect={() => console.log('selected', row)}>
Row action 2
</Menu.Item>
</Menu.Content>
</Menu>
</>
)}
</DataTableV2.RowActions>

Selectable rows

In the DataTableV2 we no longer expose the column definition for built in columns like the selectable rows. Configuration for specific parts of a feature have moved into the respective configuration object passed to the feature controlling property.

In case of the selectable row feature, this is the selectableRows property.

You can enable the feature with all built in defaults by adding the selectableRows property to the DataTableV2.

<DataTableV2
columns={/*...*/}
data={/*...*/}
selectableRows
/>

To configure certain aspects of the selectable rows feature, the property also accepts a configuration object:

<DataTableV2
columns={/*...*/}
data={/*...*/}
selectableRows={{
// `disableRowSelection` allows a function to be set that gets passed the
// current row data and returns a boolean determining the disabled state
// of the checkbox.
disableRowSelection: (row) => row.age > 50,
// `limit` Allows a maximum selection count to be set.
limit: 5,
// `selectAllBehavior` controls what will be selected when the select all button
// in the header is activated. It can either be set to `'page'`, which will only select the
// current page or set to `'all'`, which will select the entire data set.
selectAllBehavior: 'page',
}}
/>

Subrows

Similar to the selectable rows, we no longer expose the column definition for the built in column. To customize the subRowsAccessor and disableSubRows, you can pass a configuration object to the subRows property. The design of the subrows now also changed and their trigger is no longer located in an individual column, but is injected into the first visible column by default. You can create an override to lock the trigger into a specific column by providing the subRowColumnId in the configuration object.

<DataTableV2
columns={/*...*/}
data={/*...*/}
subRows={
{
// By default, this accessor is `subRows` and will query for nested data
// in the `subRows` member of your row data. You can provide a custom key
// or accessor function.
accessor: 'customSubrowMember'
// Here you can reference the columnId, where you want to inject the subRows trigger
subRowColumnId: 'customTriggerColumn'
}
}
/>

Thresholds

Cell and row thresholds function mostly the same as in DataTable. In order to allow row background highlighting and pill row highlighting, it is now required to specify a type of either 'pill' or 'highlight'. Internal logic to infer the type based on the color and backgroundColor configuration passed to the threshold object has been removed.

Expandable rows

DataTableV2.ExpandableRow control props expandableRows, defaultExpandableRows, onExpandedRowsChange have moved to the slot component instead of the DataTableV2 root component.

To disable individual row expansion now, instead of defining the canExpand on the column definition, you can now define a disableExpand function on the DataTableV2.ExpandableRow slot component.

<DataTableV2.ExpandableRow
disableExpand={(row) => /* condition */}
/>
Still have questions?
Find answers in the Dynatrace Community