MDK Logo

Table

Data tables, grids, and tabular display components

Components for displaying and interacting with tabular data.

Prerequisites

  • Install the packages
npm install \
  @tetherto/mdk-react-devkit \
  @tetherto/mdk-react-adapter \
  @tetherto/mdk-ui-foundation

Install zod@^4.6.6 first. @tetherto/mdk-react-devkit@0.12.1 declares zod@^4.6.6 as a peer while its @hookform/resolvers peer pulls a chain that pins zod 3, so the command above aborts with ERESOLVE in a project that has no zod. Installing zod 4 at the project root resolves it:

npm install zod@^4.6.6
  • Import styles: import '@tetherto/mdk-react-devkit/styles.css'

Components

@tetherto/mdk-react-devkit

Data table

import { DataTable } from '@tetherto/mdk-react-devkit'

Sortable, paginated, optionally selectable / expandable table built on TanStack React Table. Controlled and uncontrolled modes for each piece of state.

Data contracts

DataTableColumnDef, DataTableRow, DataTableSortingState, DataTablePaginationState, DataTableRowSelectionState, DataTableExpandedState are re-exported from @tetherto/mdk-react-devkit.

Example

/**
 * Runnable example for DataTable.
 */
import type { DataTableColumnDef } from '@tetherto/mdk-react-devkit'
import { DataTable } from '@tetherto/mdk-react-devkit'

type Miner = {
  id: string
  status: 'online' | 'warning' | 'offline'
  hashrate: number
  power_w: number
}

const data: Miner[] = [
  { id: 'miner-01', status: 'online', hashrate: 102.4, power_w: 3200 },
  { id: 'miner-02', status: 'warning', hashrate: 95.1, power_w: 3450 },
  { id: 'miner-03', status: 'offline', hashrate: 0, power_w: 0 },
]

const columns: DataTableColumnDef<Miner, unknown>[] = [
  { accessorKey: 'id', header: 'Miner' },
  { accessorKey: 'status', header: 'Status' },
  { accessorKey: 'hashrate', header: 'Hashrate (TH/s)' },
  { accessorKey: 'power_w', header: 'Power (W)' },
]

export const DataTableExample = () => {
  return <DataTable<Miner> data={data} columns={columns} getRowId={(row) => row.id} />
}
@tetherto/mdk-react-devkit

Import the public APIs on this page from @tetherto/mdk-react-devkit.

AlertConfirmationModal

Modal that confirms acknowledging or clearing one or more alerts before applying the change

agent-ready

Source

src/domain/components/alerts/current-alerts/alert-confirmation-modal/USAGE.md

src/domain/components/alerts/current-alerts/alert-confirmation-modal/alert-confirmation-modal.tsx

Props

PropStatusType / OptionsDefaultDescription
isOpenRequiredboolean-Controls dialog visibility
onOkRequiredVoidFunction-Called when the user confirms the action

AlertsTableTitle

Title strip for an alerts table with the section heading and an optional count badge

agent-ready

Source

src/domain/components/alerts/alerts-table-title/USAGE.md

src/domain/components/alerts/alerts-table-title/alerts-table-title.tsx

Props

PropStatusType / OptionsDefaultDescription
titleRequiredReact.ReactNode-Section heading
classNameOptionalstring-Additional CSS class
subtitleOptionalReact.ReactNode-Optional subtitle or count badge

CurrentAlerts

Sortable, searchable data table of currently active alerts derived from a raw devices payload. Plays an audible beep when a critical alert is present (gated by isSoundEnabled + user confirmation modal)

agent-ready

Source

src/domain/components/alerts/current-alerts/USAGE.md

src/domain/components/alerts/current-alerts/current-alerts.tsx

Props

PropStatusType / OptionsDefaultDescription
filterTagsRequiredstring[]-Search tags (controlled)
localFiltersRequiredAlertLocalFilters-Filters controlled outside (typically by URL severity param)
onFilterTagsChangeRequired(tags: string[]) => void-Setter for the tags above
onLocalFiltersChangeRequired(filters: AlertLocalFilters) => void-Setter for the filters above
classNameOptionalstring-Additional class names
devicesOptionalDevice[]-Devices carrying alerts (last.alerts), as a flat list. Unwrapping any backend envelope is the data layer's job, not this component's
isDemoModeOptionalbooleanfalseSkip sound entirely (e.g. in demo/preview environments), including the one-time "sound notifications" confirmation modal
isLoadingOptionalbooleanfalseShow DataTable loading overlay
isSoundEnabledOptionalbooleanfalseWhether sound notifications are enabled in user preferences (e.g. theme slice)
onAlertClickOptional((id?: string | undefined, uuid?: string | undefined) => void)-Click handler when the user opens an alert (right arrow icon in the row)
selectedAlertIdOptionalstring-Optional id used to focus on a single alert (deep-link from URL)
typeFiltersForSiteOptionalCascaderOption[]-Optional site-specific overrides for the type filter

DataTable

Generic typed data table built on TanStack React Table. Supports pagination, sorting, expansion, row selection and custom column renderers

agent-ready

Source

src/primitives/components/data-table/USAGE.md

src/primitives/components/data-table/data-table.tsx

Props

PropStatusType / OptionsDefaultDescription
columnsRequiredColumnDef<I, any>[]-The column configuration table. See https://tanstack.com/table/v8/docs/guide/column-defs
dataRequiredI[]-The data to be shown in the table. See https://tanstack.com/table/v8/docs/guide/data
borderedOptionalbooleanfalseAdd borders to all cells
canRowExpandOptional((row: Row<I>) => boolean)falseCallback to check if a row can be expanded
contentClassNameOptionalstring-Classname of the content element
defaultSortingOptionalSortingState[]Default sorting applied when the table is first mounted (uncontrolled mode). Ignored when sorting is provided
enableMultiRowSelectionOptionalbooleantrueEnables selection of multiple rows
enablePaginationOptionalbooleantrueShow pagination
enableRowExpansionOptionalbooleanfalseShow a columns with a button which can expand the row
enableRowSelectionOptionalboolean | ((row: Row<I>) => boolean)falseShow a checkbox column and enables selection
expandedRowsOptionalExpandedState-Specify the expanded rows If undefined, the expansions are managed internally Object with the key of row ID and a boolean specifying if the row is selected. The default row ID is the index. This can be changed using getRowId prop
fullWidthOptionalbooleantrueIs table full width
getRowIdOptional((row: I, index: number, parent?: Row<I> | undefined) => string)indexGet the row ID for a row. If not specified index is the default row ID
loadingOptionalbooleanfalseShow a loading indicator overlay
onExpandedRowsChangeOptional((expandedRows: ExpandedState) => void)-Callback to be called when the rows are expanded or collapsed
onPaginationChangeOptional((pagination: PaginationState) => void)-Callback to be called when the pagination params change
onRowClickOptional((rowData: I) => void)-Called when a body row is clicked. When set, rows become interactive (pointer cursor, role="button", keyboard-activatable with Enter/Space). Clicks originating from an interactive control in the row (button, link, input, checkbox, or anything marked data-no-row-click) are ignored, so the selection checkbox and expand toggle keep working independently
onSelectionsChangeOptional((selections: RowSelectionState) => void)-Callback to be called when the row are selected / unselected
onSortingChangeOptional((sorting: SortingState) => void)-Callback to be called when the sorting changes
paginationOptionalPaginationStateundefinedSpecify the pagination params. Object of shape { pageIndex: number, pageSize: number }. If undefined then the pagination is managed internally
renderExpandedContentOptional((row: Row<I>) => React.ReactNode)-Render the content of the expanded row. Required when enableRowExpansion is true
selectionsOptionalRowSelectionStateundefinedSpecify the selected rows. If undefined, the selections are managed internally Object with the key of row ID and a boolean specifying if the row is selected. The default row ID is the index. This can be changed using getRowId prop
sortingOptionalSortingStateundefinedSpecify the sorting params. If undefined then the sorting is managed internally
tableClassNameOptionalstring-Classname of the table element
wrapperClassNameOptionalstring-Classname of the wrapper element

DeviceExplorer

Device explorer: filter + search toolbar over a sortable, selectable device table. Shows the miner columns by default; pass columns to change them (spread getMinerColumns(...) to extend the default set). Designed to be controlled by URL state in the host app

agent-ready

Source

src/domain/components/device-explorer/USAGE.md

src/domain/components/device-explorer/device-explorer.tsx

Props

PropStatusType / OptionsDefaultDescription
dataRequiredDevice[]-Rows
filterOptionsRequiredDeviceExplorerFilterOption[]-Filter category definitions
getFormattedDateRequired(date: Date) => string-Date formatter from the host's timezone setup; used by the default miner columns
onFiltersChangeRequired(value: LocalFilters) => void-Setter for filters
onSearchTagsChangeRequired(tags: string[]) => void-Setter for search tags
searchOptionsRequiredDeviceExplorerSearchOption[]-Searchable column definitions
searchTagsRequiredstring[]-Active search-tag chips
classNameOptionalstring-Additional class names
columnsOptionalColumnDef<Device>[]-Table columns. Defaults to the miner columns (getMinerColumns)
filtersOptionalLocalFilters-Controlled filter values
onRowClickOptional((device: Device) => void)-Called when a row is clicked (e.g. to open the device's detail page)
onSelectedDevicesChangeOptional((selections: RowSelectionState) => void)-Setter for row selection
onSortingChangeOptional((sorting: SortingState) => void)--
selectedDevicesOptionalRowSelectionState-Controlled row-selection state
DeviceExplorerFilterOption
PropStatusType / OptionsDefaultDescription
labelRequiredstring-Text shown in the filter cascader
valueRequiredstring-Category key at the top level (e.g. status), or a selectable value under it; selections reach onFiltersChange as [category, value] paths
childrenOptionalDeviceExplorerFilterOption[]-Values selectable under this category; omit on leaf options
DeviceExplorerSearchOption
PropStatusType / OptionsDefaultDescription
labelRequiredstring-Suggestion text, matched case-insensitively against the typed query and shown on the chip
valueRequiredstring-Tag added to searchTags when this suggestion is picked (free-text tags are also allowed)

HistoricalAlerts

Sortable data table of historical alerts within a controlled date range. Renders a header with title + DateRangePicker, then the table

agent-ready

Source

src/domain/components/alerts/historical-alerts/USAGE.md

src/domain/components/alerts/historical-alerts/historical-alerts.tsx

Props

PropStatusType / OptionsDefaultDescription
dateRangeRequiredHistoricalAlertsRange-Selected date range for the historical query (controlled)
filterTagsRequiredstring[]-Shared with CurrentAlerts
localFiltersRequiredAlertLocalFilters-Filters and search tags coming from the parent (typically shared with CurrentAlerts)
onDateRangeChangeRequired(range: HistoricalAlertsRange) => void-Setter for the date range
alertsOptionalAlertRecord[][]Pre-fetched historical alerts log entries (each with a thing device payload)
classNameOptionalstring-Additional class names
isLoadingOptionalbooleanfalseShow DataTable loading overlay
onAlertClickOptional((id?: string | undefined, uuid?: string | undefined) => void)-Called when the user opens an alert
HistoricalAlertsRange
PropStatusType / OptionsDefaultDescription
endRequirednumber-Range end, epoch ms; seeds the picker's to date
startRequirednumber-Range start, epoch ms; seeds the picker's from date

TagFilterBar

Horizontal strip of removable tag chips that narrow a list view; clicking a chip removes the filter

agent-ready

Source

src/domain/components/alerts/tag-filter-bar/USAGE.md

src/domain/components/alerts/tag-filter-bar/tag-filter-bar.tsx

Props

PropStatusType / OptionsDefaultDescription
filterTagsRequiredstring[]-Active tag filter values
localFiltersRequiredAlertLocalFilters-Current local filter state
onLocalFiltersChangeRequired(filters: AlertLocalFilters) => void-Called when any local filter changes
onSearchTagsChangeRequired(tags: string[]) => void-Called when tag filter changes
classNameOptionalstring-Additional CSS class
placeholderOptionalstring-Search input placeholder
typeFiltersForSiteOptionalCascaderOption[]-Site-specific overrides for the "type" filter children. If provided, the "Type" filter group will use these instead of the defaults

On this page