MDK Logo

Data display

Cards, tables, tags, and data presentation components

Data display

Components for displaying data in cards, tables, badges, tags, and other visual formats.

Prerequisites

Before using these components, complete the @mdk/core installation and add the dependency.

DataTable

Full-featured data table built on TanStack Table with sorting, pagination, and row selection.

Import

import { DataTable } from '@mdk/core'

// Types for column definitions
import type {
  DataTableColumnDef,
  DataTableSortingState,
  DataTablePaginationState,
  DataTableRowSelectionState,
} from '@mdk/core'

Basic usage

import { DataTable } from '@mdk/core'
import type { DataTableColumnDef } from '@mdk/core'

type Miner = {
  id: string
  name: string
  hashrate: number
  status: string
}

const columns: DataTableColumnDef<Miner>[] = [
  {
    accessorKey: 'name',
    header: 'Name',
  },
  {
    accessorKey: 'hashrate',
    header: 'Hashrate',
    cell: ({ row }) => `${row.original.hashrate} TH/s`,
  },
  {
    accessorKey: 'status',
    header: 'Status',
  },
]

function MinersTable() {
  return <DataTable columns={columns} data={miners} />
}

With sorting and pagination

const [sorting, setSorting] = useState<DataTableSortingState>([])
const [pagination, setPagination] = useState<DataTablePaginationState>({
  pageIndex: 0,
  pageSize: 10,
})

<DataTable
  columns={columns}
  data={miners}
  sorting={sorting}
  onSortingChange={setSorting}
  pagination={pagination}
  onPaginationChange={setPagination}
/>

With row selection

const [rowSelection, setRowSelection] = useState<DataTableRowSelectionState>({})

<DataTable
  columns={columns}
  data={miners}
  rowSelection={rowSelection}
  onRowSelectionChange={setRowSelection}
  enableRowSelection
/>

Styling

  • .mdk-data-table: Root container
  • .mdk-data-table__header: Header row
  • .mdk-data-table__body: Table body
  • .mdk-data-table__row: Data row
  • .mdk-data-table__cell: Table cell

Card

Flexible container component with optional header, body, and footer slots.

Import

import { Card, CardHeader, CardBody, CardFooter } from '@mdk/core'

Props

PropTypeDefaultDescription
classNamestringnoneAdditional CSS class
onClickfunctionnoneClick handler (adds clickable styling)
childrenReactNodenoneCard content

Basic usage

<Card>
  <Card.Header>Title</Card.Header>
  <Card.Body>Content goes here</Card.Body>
  <Card.Footer>Actions</Card.Footer>
</Card>

Default children are automatically wrapped in the body slot:

<Card>
  <Card.Header>Title</Card.Header>
  This content goes to the body automatically
</Card>

Clickable card

<Card onClick={() => navigate('/details')}>
  <Card.Header>Click me</Card.Header>
  <Card.Body>Navigates on click</Card.Body>
</Card>

Styling

  • .mdk-card: Root container
  • .mdk-card--clickable: Applied when onClick is provided
  • .mdk-card__header: Header slot
  • .mdk-card__body: Body slot
  • .mdk-card__footer: Footer slot

LabeledCard

Card component with a prominent label header for categorized content.

Import

import { LabeledCard } from '@mdk/core'

Basic usage

<LabeledCard label="Statistics">
  <p>Card content here</p>
</LabeledCard>

Accordion

Collapsible content sections built on Radix UI primitives.

Import

import {
  Accordion,
  AccordionItem,
  AccordionTrigger,
  AccordionContent,
} from '@mdk/core'

Accordion props

PropTypeDefaultDescription
titlestring''Accordion header title
isOpenedbooleanfalseInitially expanded
isRowbooleanfalseRow layout for content
unpaddedbooleanfalseRemove content padding
noBorderbooleanfalseRemove trigger border
solidBackgroundbooleanfalseSolid background color
showToggleIconbooleantrueShow expand/collapse icon
toggleIconPosition'left' | 'right''left'Icon position
customLabelReactNodenoneCustom label next to title
onValueChangefunctionnoneCallback when state changes

Basic usage

<Accordion title="FAQ Section">
  <p>This content can be expanded or collapsed.</p>
</Accordion>

With custom label

<Accordion
  title="System Status"
  customLabel={<Badge variant="success">Active</Badge>}
  showToggleIcon={false}
>
  <p>All systems operational.</p>
</Accordion>

Multiple items

<AccordionRoot type="multiple">
  <AccordionItem value="item-1">
    <AccordionTrigger>Section 1</AccordionTrigger>
    <AccordionContent>Content 1</AccordionContent>
  </AccordionItem>
  <AccordionItem value="item-2">
    <AccordionTrigger>Section 2</AccordionTrigger>
    <AccordionContent>Content 2</AccordionContent>
  </AccordionItem>
</AccordionRoot>

Styling

  • .mdk-accordion: Root container
  • .mdk-accordion--solid-background: Solid background variant
  • .mdk-accordion__item: Individual item
  • .mdk-accordion__trigger: Clickable header
  • .mdk-accordion__content: Collapsible content area

Badge

Numeric or status badge that can wrap content or stand alone.

Import

import { Badge } from '@mdk/core'

Props

PropTypeDefaultDescription
countnumber0Number to display
overflowCountnumber99Max count before showing "99+"
showZerobooleanfalseShow badge when count is 0
dotbooleanfalseShow as dot instead of number
textstringnoneCustom text content
colorColorVariant'primary'Badge color
size'sm' | 'md' | 'lg''md'Badge size
status'success' | 'processing' | 'error' | 'warning' | 'default'noneStatus variant
squarebooleanfalseSquare badge (no border-radius)
offset[number, number][0, 0]Position offset [x, y]

Basic usage

// Number badge on content
<Badge count={5}>
  <Button>Messages</Button>
</Badge>

// Overflow
<Badge count={100} overflowCount={99}>
  <BellIcon />
</Badge>
// Shows "99+"

Dot badge

<Badge dot>
  <NotificationIcon />
</Badge>

Status badge

<Badge status="success" text="Online" />
<Badge status="error" text="Offline" />
<Badge status="processing" text="Syncing" />
<Badge status="warning" text="Warning" />

Standalone badge

<Badge count={25} />
<Badge text="NEW" color="primary" square />

Styling

  • .mdk-badge: Badge element
  • .mdk-badge--{color}: Color variant
  • .mdk-badge--{size}: Size variant
  • .mdk-badge--dot: Dot variant
  • .mdk-badge--status: Status variant
  • .mdk-badge-wrapper: Wrapper when wrapping content

Pagination

Page navigation with size selector.

Import

import { Pagination } from '@mdk/core'

Props

PropTypeDefaultDescription
currentnumber1Current page number
totalnumber0Total number of items
pageSizenumber20Items per page
pageSizeOptionsnumber[][10, 20, 50, 100]Page size options
showSizeChangerbooleantrueShow page size dropdown
showTotalbooleanfalseShow total count text
disabledbooleanfalseDisable pagination
size'sm' | 'md' | 'lg''sm'Size variant
onChangefunctionnonePage/size change callback

Basic usage

const [page, setPage] = useState(1)
const [pageSize, setPageSize] = useState(20)

<Pagination
  current={page}
  total={500}
  pageSize={pageSize}
  onChange={(newPage, newSize) => {
    setPage(newPage)
    setPageSize(newSize)
  }}
/>

With total display

<Pagination
  current={1}
  total={100}
  pageSize={20}
  showTotal
/>
// Shows "1-20 of 100"

Styling

  • .mdk-pagination: Root container
  • .mdk-pagination__pages: Page buttons container
  • .mdk-pagination__button: Navigation button
  • .mdk-pagination__button--active: Active page
  • .mdk-pagination__total: Total count text
  • .mdk-pagination__size-changer: Page size select

Tag

Removable tag/chip component.

Import

import { Tag } from '@mdk/core'

Basic usage

<Tag>Default Tag</Tag>
<Tag color="primary">Primary</Tag>
<Tag color="success">Success</Tag>
<Tag onClose={() => handleRemove()}>Removable</Tag>

Avatar

User avatar display component.

Import

import { Avatar } from '@mdk/core'

Basic usage

<Avatar src="/user.jpg" alt="User" />
<Avatar>JD</Avatar>
<Avatar src="/user.jpg" size="lg" />

Skeleton

Loading placeholder animation.

Import

import { Skeleton } from '@mdk/core'

Basic usage

// Text skeleton
<Skeleton className="h-4 w-48" />

// Circle skeleton
<Skeleton className="h-12 w-12 rounded-full" />

// Card skeleton
<Card>
  <Card.Body>
    <Skeleton className="h-4 w-full mb-2" />
    <Skeleton className="h-4 w-3/4" />
  </Card.Body>
</Card>

EmptyState

Placeholder component for empty data states.

Import

import { EmptyState } from '@mdk/core'

Props

PropTypeDefaultDescription
descriptionReactNodenoneRequired. Description text
image'default' | 'simple' | ReactNode'default'Image/icon to display
size'sm' | 'md' | 'lg''md'Size variant

Basic usage

<EmptyState description="No data available" />

<EmptyState
  description="No miners found matching your search"
  image="simple"
  size="sm"
/>

Custom image

<EmptyState
  description="No alerts at this time"
  image={<BellOffIcon size={48} />}
/>

Styling

  • .mdk-empty-state: Root container
  • .mdk-empty-state--{size}: Size variant
  • .mdk-empty-state__image: Image container
  • .mdk-empty-state__description: Description text

Additional data display components

ComponentDescription
TypographyText styling components (headings, paragraphs)
IndicatorStatus dot for online/offline/warning states
CurrencyTogglerSwitch between currency display formats
ListViewFilterFilter controls for list/table views
MosaicGrid layout for dashboard widgets
DividerVisual separator between content sections
SeparatorHorizontal or vertical dividing line

On this page