Data Display
Components for showing structured data and user-generated content: tables, trees, code, logs, kanban, and timelines.
Components in this category
Standard data table with sortable headers and footers.
TableContainerScrollable container for wide tables.
DataGridFeature-rich data grid with sorting, filtering and cell editing.
VirtualListVirtualised scrolling list for large datasets.
ListStandard list with selectable, clickable items.
ListItemSingle row in a List, ListSection or standalone.
ListSectionCategorized section within a List.
ListDividerHorizontal divider between list items.
DescriptionListLabel–value pair list, like a spec sheet.
ResourceRowCompact row for a cloud/IT resource with icon and meta.
TagListHorizontal list of tags or keywords.
TruncateText clipping with line limits, middle ellipsis, and an overflow tooltip.
ImageLazy image with a reserved box, a placeholder and a failure fallback.
TreeViewHierarchical tree with expand/collapse.
TreeTableTreeView rendered as a table with columns.
JsonViewerInteractive JSON tree with syntax highlighting.
CodeBlockSyntax-highlighted code block with copy.
InlineCodeInline code snippet within running text.
DiffViewerUnified or split diff viewer.
LogViewerScrollable log viewer with severity badges and search.
KanbanBoardDrag-and-drop kanban board.
KanbanColumnSingle column in a KanbanBoard.
KanbanCardCard inside a KanbanColumn.
PaginationPage-number pagination with first/last shortcuts.
PageButtonIndividual page button used inside Pagination.
TimelineOrdered event rows with configurable styles and content slots.
TimelineItemOne event, composed by hand.
ActivityFeedActivity rows with actor, action, target, and timestamp.
CommentThreadThreaded comment system with reactions.
CommentViewSingle comment display.
CommentComposerRich text comment input.
Tables & Grids
Table / Th / Td / Tr / TableFooter
Table, Th, Td, Tr, and TableFooter are the standard table primitives. Th has a num prop for right-aligned numeric headers; Td adds num, name (bold), and mono variants. Tr supports hover, attn (highlighted), sel (selected), and dimmed.
import {
Table,
TableContainer,
Th,
Td,
Tr,
TableFooter,
} from "@solarius/onset";DataGrid
DataGrid provides sortable columns, row selection, cell editing, virtual scrolling, zebra striping, and a sticky footer summary. Built on useVirtualRange for performance on large datasets.
| Prop | Type | Default | Description |
|---|---|---|---|
rows | T[] | — | The data rows. |
columns | DataGridColumn<T>[] | — | Column definitions. |
getRowId | (row: T, index: number) => string | — | Stable row identity. |
rowHeight | number | — | Fixed row height in px. |
sort | DataGridSort | null | — | Current sort state. |
onSortChange | (sort: DataGridSort | null) => void | — | Sort change handler. |
selectedIds | string[] | — | Selected row ids. |
onSelectionChange | (ids: string[]) => void | — | Selection change handler. |
onCellEdit | (edit: CellEdit<T>) => void | — | Cell edit commit handler. |
onRowClick | (row: T, index: number) => void | — | Row click handler. |
striped | boolean | — | Zebra striping. |
bordered | boolean | — | Border and corner radius around the grid. |
import { DataGrid } from "@solarius/onset";
import type { DataGridColumn, DataGridSort, CellEdit } from "@solarius/onset";
const columns: DataGridColumn<MyRow>[] = [
{ key: "name", header: "Name", sortable: true },
{ key: "status", header: "Status", numeric: true },
{
key: "actions",
header: "",
render: (row) => <Button size="sm">View</Button>,
},
];
<DataGrid
rows={data}
columns={columns}
getRowId={(row) => row.id}
rowHeight={36}
height={400}
sort={sort}
onSortChange={setSort}
selectedIds={selected}
onSelectionChange={setSelected}
/>;VirtualList
VirtualList renders only the visible slice of a long list, using the useVirtualRange hook for windowing math. Supports both fixed and variable row heights.
import { VirtualList, useVirtualRange } from "@solarius/onset";
<VirtualList
data={items}
itemHeight={40}
height={300}
renderItem={(item, index) => <div>{item.name}</div>}
overscan={8}
/>;List / ListItem / ListSection / ListDivider
Generic vertical list primitive. The base under ActivityFeed, InboxPanel, and ad hoc row layouts. ListItem has slots for media, title, description, meta, and actions.
DescriptionList
Key/value fact sheet, as in a "Details" card. Rows are DescriptionRow objects with key, value, optional mono font, and optional onClick.
ResourceRow
ResourceRow renders a cloud resource row with an icon, title, subtitle, and right-aligned meta/value pair. Exported from DescriptionList.
TagList
TagList renders a horizontal list of Tag components from a string array.
Trees & JSON
TreeView
Hierarchical explorer (account trees, resource groups, file paths) with disclosure carets and single selection.
import { TreeView } from "@solarius/onset";
import type { TreeNode } from "@solarius/onset";TreeTable
TreeTable combines the hierarchical disclosure of TreeView with the column grid of a table — expandable rows with per-column values. Exported from JsonViewer.
import { TreeTable } from "@solarius/onset";
import type { TreeTableColumn, TreeTableNode } from "@solarius/onset";JsonViewer
Interactive JSON tree with collapsible nodes, search highlighting, and a copy button. Accepts any plain object, array, or primitive.
import { JsonViewer } from "@solarius/onset";Code & Logs
CodeBlock
Syntax-highlighted code block with line numbers and a copy button. Supports ts, tsx, js, json, bash, sql, css, yaml, and text. Highlighting uses a small rule-based tokenizer, not a parser.
| Prop | Type | Default | Description |
|---|---|---|---|
language | CodeLanguage | — | "ts" | "tsx" | "js" | "json" | "bash" | "sql" | "css" | "yaml" | "text" |
code | string | — | The source code string. |
copyable | boolean | true | Show the copy button. |
InlineCode
InlineCode wraps a short code fragment in a styled <code> element for use inside running text.
npm install @solarius/onsetDiffViewer
DiffViewer renders a unified diff with colored add/delete lines, line-number gutters, and a collapsed-file-header row. Pass a raw diff string or pre-parsed DiffLine[]. The exported parseUnifiedDiff helper converts unified diff text into typed lines.
import { DiffViewer, parseUnifiedDiff } from "@solarius/onset";
<DiffViewer
diff={`--- a/file.ts
+++ b/file.ts
@@ -1,3 +1,3 @@
-const old = true;
+const updated = false;
unchanged;`}
/>;LogViewer
Live-tailing log stream with time, level, and unit columns. Renders from an array of LogEntry objects.
| Prop | Type | Default | Description |
|---|---|---|---|
entries | LogEntry[] | — | Log entries with time, level, unit, and message fields. |
import { LogViewer } from "@solarius/onset";
import type { LogEntry } from "@solarius/onset";Kanban
KanbanBoard, KanbanColumn, and KanbanCard form a drag-and-drop board. Cards are draggable between columns via HTML drag-and-drop. Each KanbanColumn receives dropped cards through onDropCard.
| Prop | Type | Default | Description |
|---|---|---|---|
title | ReactNode | — | Column heading. |
count | number | — | Mono count next to the title. |
meta | ReactNode | — | Right-aligned header meta. |
onDropCard | (cardId: string, index: number) => void | — | Card drop handler. Omit to make a no-drop column. |
footer | ReactNode | — | Pinned under the card list. |
import { KanbanBoard, KanbanColumn, KanbanCard } from "@solarius/onset";
<KanbanBoard>
<KanbanColumn
title="Backlog"
count={items.length}
onDropCard={(cardId, index) => moveCard(cardId, "backlog", index)}
>
{items.map((item) => (
<KanbanCard key={item.id} id={item.id} title={item.title} />
))}
</KanbanColumn>
</KanbanBoard>;Text & media
Truncate
Truncate supports line clamping, middle ellipsis, and tooltips for clipped text. Use Text truncate for a single trailing ellipsis. See Truncate for props.
Image
An <img> that reserves its layout box before loading, shows a placeholder while loading, and renders a fallback when the URL fails. It lazy-loads by default. Full props on its page.
import { Truncate, Image } from "@solarius/onset";
<Truncate tooltip>{row.message}</Truncate>
<Image src={asset.url} alt={asset.name} ratio={16 / 9} rounded="md" />Other
Pagination / PageButton
Numbered pager built on PageButton; pair with TableFooter for the standard table footer.
| Prop | Type | Default | Description |
|---|---|---|---|
page | number | — | Controlled 1-based page. |
defaultPage | number | 1 | Initial uncontrolled page. |
pageCount | number | — | Total pages. |
onChange | (page: number) => void | — | Page change handler. |
maxButtons | number | 7 | Max numbered buttons before collapsing to ellipses. |
Timeline / TimelineItem
Timeline displays ordered events with optional title, meta, time, description, detail, and actions slots. It accepts items or TimelineItem children, three variants, three densities, and configurable timestamp placement. See Timeline.
ActivityFeed
ActivityFeed displays actor, action, target, and timestamp fields using Timeline rows. Optional day headings use the client timezone after hydration.
import { ActivityFeed } from "@solarius/onset";
import type { ActivityItem } from "@solarius/onset";CommentThread / CommentView / CommentComposer
Threaded comment system with avatars, reactions, badges, replies, and a composer. CommentView renders a single comment with nested replies; CommentComposer provides the text input for new comments and replies. Supports pending (optimistic) posts.
import { CommentThread, CommentView, CommentComposer } from "@solarius/onset";
import type { Comment, CommentReaction } from "@solarius/onset";
const comments: Comment[] = [
{
id: "1",
author: "Alice",
body: "Looks good to me. Ship it.",
time: new Date(),
reactions: [{ emoji: "🚀", count: 2, reacted: true }],
replies: [
{ id: "2", author: "Bob", body: "Agreed, let's go.", time: new Date() },
],
},
];
<CommentThread
comments={comments}
onReply={(parentId, body) => createReply(parentId, body)}
onReact={(commentId, emoji) => toggleReaction(commentId, emoji)}
/>;