Sophic Interface Systems
Components

Table

Table primitives and a nested-card data table.

Two building blocks for tabular data:

  1. Table — styled HTML table markup
  2. SlickDataTable — search, sort, filters, and pagination (vanilla card by default, or slick two-tone shell)

You might be looking for:

  • Item List

    Free-form selectable rows — not a table.

  • Key Value

    A muted label beside a medium value.

Table

Use this when you just need a styled HTML table.

TickerTypeQTY
ASMLStock24
VOOETF40
DBRBond10

Playground

<Table> <TableHeader> <TableRow> <TableHead>Ticker</TableHead> <TableHead>Type</TableHead> <TableHead className="text-right">QTY</TableHead> </TableRow> </TableHeader> <TableBody> <TableRow> <TableCell className="font-medium">ASML</TableCell> <TableCell>Stock</TableCell> <TableCell className="text-right">24</TableCell> </TableRow> {/* … */} </TableBody></Table>

Usage

import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@sophic/portal-ui/components/ui/table";
<Table density="relaxed">
  <TableHeader>
    <TableRow>
      <TableHead>Ticker</TableHead>
      <TableHead>Type</TableHead>
      <TableHead className="text-right">QTY</TableHead>
    </TableRow>
  </TableHeader>
  <TableBody>
    <TableRow>
      <TableCell className="font-medium">ASML</TableCell>
      <TableCell>Stock</TableCell>
      <TableCell className="text-right">24</TableCell>
    </TableRow>
  </TableBody>
</Table>

Set density on Table (condensed, default, or relaxed). Header and cell padding follow it.

Props

Table also accepts every native <table> attribute. Subcomponents accept their native element attributes.

Prop

Type

Default

SlickDataTable

Search, column filters, sorting, pagination, column visibility, and optional row actions. vanilla (default) is one bg-card surface with optional title / count inside. slick is the original two-tone shell: headers on a soft tint, rows in a nested white card, title outside.

Click a sortable header to cycle asc → desc → asc. The active column label turns bold. Pass onRowClick for hover (--hover) and keyboard-selectable rows; set activeRow to keep one row selected (--selected plus a 2px --selected-bar). Hovering another row does not move the selection; closing the drawer clears it.

ASML

ASML Holding

Stock2422.5%

VOO

Vanguard S&P 500

ETF4024.1%

DBR

Bund 2034

Bond1018.2%

BIL

SPDR Bloomberg 1-3 Month T-Bill

T-bill10012.0%

AAPL

Apple Inc.

Stock508.4%

MSFT

Microsoft Corp.

Stock307.1%

IWDA

iShares Core MSCI World

ETF806.2%

T

US Treasury 2026

Bond255.5%

IE00

iShares EUR Money Market

MMF2004.8%

NESN

Nestlé S.A.

Stock153.9%
12 results
Page size
Page 1 of 2

Playground

<SlickDataTable columns={columns} data={rows}  showPagination={false}/>

Usage

import { type ColumnDef, SlickDataTable } from "@sophic/portal-ui";

<SlickDataTable
  columns={columns}
  data={rows}
  pageSize={10}
  searchPlaceholder="Search…"
  activeRow={selected}
  onRowClick={(row) => {
    setSelected(row);
    window.alert(`${row.ticker} — ${row.name}`);
  }}
/>;

Give columns a size when you need header and body columns to stay lined up. Pass title and optional count on variant="vanilla" (the default) to put the section heading inside the shell. slick keeps the title outside. Pagination stacks on small screens (results, then page size and pager). Headers stay 15px and do not wrap — the table scrolls horizontally instead.

Props

columns and data are required. Generics show as unknown in the table below — use SlickDataTableProps<TData, TFormat> in your code.

Prop

Type

Default

Used by

  • Portal holdings table

Changelog

  • 4 October 2026 — Selected fill is 8% Soil on light, painted on cells. 1px edges (no 0.5px hairline). Full notes
  • 4 October 2026 — Interactive rows use --hover / --selected and a 2px selected bar. Keyboard focus is the field ring, inset. Full notes
  • 24 September 2026 — Row hover is neutral-100. Full notes
  • 17 September 2026 — Last body row has no hairline. Pagination has a subtle top border, matching the header split. Full notes
  • 15 September 2026 — Vanilla is the default. Headers are 15px and do not wrap; pagination stacks on small screens. Full notes
  • 8 September 2026 — variant: slick (tinted nested card) or vanilla (in-shell title). Full notes
  • 8 September 2026 — Slick Data Table shells use the same inset 0.5px hairline as Card. Full notes
  • 25 August 2026 — Holdings Table identity is name-first; % of holdings compact header is %. Full notes
  • 20 August 2026 — Slick Data Table descendant chrome in a CSS module; look unchanged. Full notes
  • 20 August 2026 — Table chrome in a CSS module; look unchanged. Full notes
  • 19 August 2026 — “You might be looking for” map to Item List. Full notes
  • 12 August 2026 — Pagination sits in the tint shell under the body (header flipped). Full notes
  • 12 August 2026 — Optional headerCompact (e.g. P&L below md with tooltip). Full notes
  • 10 August 2026 — Filter option rows use menu item padding for hover. Full notes
  • 29 July 2026 — Shell radius and hairline match Card tokens. Full notes
  • 21 July 2026 — Added Table + SlickDataTable under one docs page. Full notes

On this page