Data Components

April 3, 2026 ยท View on GitHub

Components for displaying structured data, tables, trees, and lists.

Data

Table

Bordered table with headers, auto-sized columns, optional zebra striping, and row virtualization for large datasets.

PropTypeDefaultDescription
columnsTableColumn[]--Column definitions (required)
dataRecord<string, string | number>[]--Row data (required)
headerColorstring | numbercolors.brand.primaryHeader text color
stripebooleanfalseAlternate row background
maxVisibleRowsnumber100Max rows before virtualization
scrollOffsetnumber0Current scroll position
onScrollChange(offset: number) => void--Called when scroll offset changes
Plus container propsborderStyle, borderColor, padding*, width, margin*

TableColumn type:

PropertyTypeDefaultDescription
keystring--Data field key
headerstring--Column header text
widthnumberAutoFixed column width
align"left" | "center" | "right""left"Cell alignment

Basic: Simple data table

import { Table } from "@orchetron/storm";

<Table
  columns={[
    { key: "name", header: "Name", width: 20 },
    { key: "status", header: "Status", width: 10, align: "center" },
    { key: "count", header: "Count", width: 8, align: "right" },
  ]}
  data={[
    { name: "Alpha", status: "Active", count: 42 },
    { name: "Beta", status: "Paused", count: 7 },
  ]}
/>

Advanced: Striped table with custom styling

<Table
  columns={[
    { key: "id", header: "ID", width: 6, align: "right" },
    { key: "endpoint", header: "Endpoint", width: 30 },
    { key: "method", header: "Method", width: 8 },
    { key: "latency", header: "Latency", width: 10, align: "right" },
    { key: "status", header: "Status", width: 8, align: "center" },
  ]}
  data={apiRequests}
  stripe
  headerColor="#82AAFF"
  borderStyle="round"
  borderColor="#505050"
  maxVisibleRows={20}
  scrollOffset={scrollPos}
  onScrollChange={setScrollPos}
/>

DataGrid

Interactive data grid with keyboard navigation, sorting, row selection, and virtualization. Up/Down navigate rows, Left/Right navigate columns, Enter on header sorts, Enter on row selects.

PropTypeDefaultDescription
columnsDataGridColumn[]--Column definitions (required)
rowsArray<Record<string, string | number>>--Row data (required)
selectedRownumber--Index of selected row
onSelect(rowIndex: number) => void--Called on row selection
sortColumnstring--Currently sorted column key
sortDirection"asc" | "desc"--Current sort direction
onSort(column: string) => void--Called when header is activated
isFocusedbooleantrueWhether grid captures input
headerColorstring | numbercolors.brand.primaryHeader text color
selectedColorstring | numbercolors.brand.lightSelected row color
maxVisibleRowsnumber100Max rows before virtualization
onScrollChange(offset: number) => void--Called when scroll offset changes
aria-labelstring--Accessibility label
Plus container propsborderStyle, borderColor, padding*, width, margin*

Basic: Sortable grid

import { DataGrid } from "@orchetron/storm";

<DataGrid
  columns={[
    { key: "name", label: "Name", width: 20 },
    { key: "size", label: "Size", width: 10, align: "right" },
  ]}
  rows={files}
  sortColumn={sortCol}
  sortDirection={sortDir}
  onSort={handleSort}
/>

Advanced: Interactive file browser

<DataGrid
  columns={[
    { key: "icon", label: "", width: 2 },
    { key: "name", label: "Name", width: 30 },
    { key: "size", label: "Size", width: 12, align: "right" },
    { key: "modified", label: "Modified", width: 20 },
    { key: "perms", label: "Permissions", width: 12, align: "center" },
  ]}
  rows={directoryContents}
  selectedRow={selectedIdx}
  onSelect={(idx) => openFile(directoryContents[idx])}
  sortColumn={sortCol}
  sortDirection={sortDir}
  onSort={toggleSort}
  headerColor="#82AAFF"
  selectedColor="#22D3EE"
  borderStyle="single"
  borderColor="#505050"
  maxVisibleRows={25}
/>

Tree

Hierarchical tree with expand/collapse indicators. Renders nodes with indentation and triangular markers.

PropTypeDefaultDescription
nodesTreeNode[]--Tree node array (required)
onToggle(key: string) => void--Called when a node is toggled
colorstring | number--Indicator color

TreeNode type:

PropertyTypeDefaultDescription
keystring--Unique node identifier
labelstring--Display label
childrenTreeNode[]--Child nodes
expandedboolean--Whether children are visible

Basic: Simple tree

import { Tree } from "@orchetron/storm";

<Tree
  nodes={[
    { key: "src", label: "src/", expanded: true, children: [
      { key: "index", label: "index.ts" },
      { key: "utils", label: "utils.ts" },
    ]},
    { key: "pkg", label: "package.json" },
  ]}
  onToggle={handleToggle}
/>

Advanced: Dynamic tree with toggle state

function FileTree({ rootNodes }: { rootNodes: TreeNode[] }) {
  const [nodes, setNodes] = useState(rootNodes);

  const handleToggle = (key: string) => {
    setNodes(toggleNode(nodes, key)); // Your toggle helper
  };

  return (
    <Box borderStyle="single" borderColor="#505050" padding={1}>
      <Tree nodes={nodes} onToggle={handleToggle} color="#82AAFF" />
    </Box>
  );
}

DirectoryTree

Filesystem tree browser with expand/collapse, tree connectors, and keyboard navigation.

PropTypeDefaultDescription
rootPathstring--Root directory path
onSelect(path: string) => void--File/dir selection callback
showHiddenboolean--Show hidden files (dotfiles)
showFilesboolean--Show files (not just directories)
fileColorstring | number--File name color
dirColorstring | number--Directory name color
isFocusedboolean--Enable keyboard navigation
renderEntry(entry, state) => ReactNode--Custom entry renderer
<DirectoryTree rootPath="/src" onSelect={openFile} showFiles isFocused />

ListView

Scrollable list with highlight cursor, selectable items, virtual scrolling, and overflow indicators.

PropTypeDefaultDescription
itemsreadonly ListViewItem[]--List items (required)
selectedKeystring--Currently selected item key
onSelect(key: string) => void--Called on Enter
onHighlight(key: string) => void--Called when highlight moves
maxVisiblenumber10Max visible items before scrolling
highlightColorstring | numbercolors.brand.primaryHighlight indicator color
isFocusedbooleantrueWhether list captures input
emptyMessagestring"No items"Text shown when items is empty
Plus container propsborderStyle, borderColor, padding*, width, margin*

ListViewItem type:

PropertyTypeDescription
keystringUnique identifier
labelstringDisplay text
descriptionstringOptional secondary text
iconstringOptional icon prefix

Basic: Simple selectable list

import { ListView } from "@orchetron/storm";

<ListView
  items={[
    { key: "1", label: "Create new project" },
    { key: "2", label: "Open existing project" },
    { key: "3", label: "Import from Git" },
  ]}
  onSelect={handleAction}
/>

Advanced: List with descriptions and icons

<ListView
  items={[
    { key: "ts", label: "TypeScript", description: "Strict typed JavaScript", icon: "TS" },
    { key: "rs", label: "Rust", description: "Systems programming", icon: "RS" },
    { key: "py", label: "Python", description: "General purpose scripting", icon: "PY" },
    { key: "go", label: "Go", description: "Concurrent systems language", icon: "GO" },
  ]}
  selectedKey={selected}
  onSelect={setSelected}
  onHighlight={(key) => showPreview(key)}
  maxVisible={8}
  highlightColor="#82AAFF"
  borderStyle="round"
  borderColor="#505050"
/>

VirtualList

Efficiently renders large lists by only materializing visible items plus an overscan buffer. Supports keyboard and mouse scroll navigation.

PropTypeDefaultDescription
itemsreadonly T[]--All list items
renderItem(item: T, index: number) => ReactNode--Render function per item
itemHeightnumber1Row height per item
heightnumber--Viewport height in rows
widthnumber | string--Viewport width
keyExtractor(item, index) => string--Unique key function
onSelect(item, index) => void--Called on Enter
isFocusedbooleantrueEnable keyboard/mouse input
selectedIndexnumber--Controlled selected index
emptyMessagestring"No items"Text shown when list is empty

Compound API: VirtualList.Root, VirtualList.Item.

<VirtualList
  items={Array.from({ length: 10000 }, (_, i) => `Item ${i}`)}
  renderItem={(item) => <Text>{item}</Text>}
  height={20}
  onSelect={(item) => console.log(item)}
/>

DiffView

Inline unified diff viewer with colored lines, gutter line numbers, hunk navigation (n/N), word-level highlighting, and collapsible context.

PropTypeDefaultDescription
diffstring--Raw unified diff string
linesDiffLine[]--Pre-parsed diff lines
showLineNumbersbooleantrueShow gutter line numbers
contextLinesnumberallLines of context around changes
addedColorstringgreenColor for added lines
removedColorstringredColor for removed lines
isFocusedbooleanfalseEnable keyboard navigation
filePathstring--File path header
wordDiffbooleanfalseWord-level diff highlighting
<DiffView diff={gitDiffOutput} isFocused wordDiff contextLines={3} />

InlineDiff

Side-by-side single-line diff display. Shows removed characters in red strikethrough and added characters in green bold.

PropTypeDefaultDescription
beforestring--Original text
afterstring--Changed text
colorstring--Base text color
<InlineDiff before="hello world" after="hello there" />

Calendar

Month calendar view with keyboard navigation, date range highlighting, and disabled dates.

PropTypeDefaultDescription
yearnumber--Year to display
monthnumber--Month (1-12)
selectedDaynumber--Currently selected day
onSelect(day: number) => void--Day selection callback
onMonthChange(year, month) => void--Month navigation callback
selectedColorstring | numberbrand primarySelected day color
todayDateautoOverride today highlight
isFocusedbooleantrueEnable keyboard navigation
rangeStartDate--Start of highlight range
rangeEndDate--End of highlight range
disabledDates(date: Date) => boolean--Predicate for disabled dates
weekStartsOn0 | 10Week start: 0=Sunday, 1=Monday
<Calendar year={2026} month={3} selectedDay={15} onSelect={setDay} />

Pretty

JSON/object pretty-printer with syntax coloring and collapsible nodes.

PropTypeDefaultDescription
dataunknown--Data to display
indentnumber2Indentation width
colorbooleantrueEnable syntax coloring
maxDepthnumber5Maximum nesting depth
interactivebooleanfalseEnable collapse/expand with Enter/Space
isFocusedbooleanfalseWhether focused for keyboard navigation
searchQuerystring--Highlight matching text (case-insensitive)
renderValue(value, path, depth) => ReactNode | null--Custom value renderer

Compound API: Pretty.Root, Pretty.Node.

<Pretty data={{ name: "Storm", version: 1, features: ["fast", "reactive"] }} interactive isFocused />

Back to Components