Core Components

April 6, 2026 ยท View on GitHub

Fundamental building blocks for layout and text rendering.

Core

Box

Flexbox container -- the primary layout primitive. Arranges children vertically (default) or horizontally with full flexbox semantics, CSS Grid support, borders, padding, margin, and background color.

PropTypeDefaultDescription
childrenReactNode--Child elements
flexDirection"column" | "row" | "column-reverse" | "row-reverse""column"Primary axis direction
flexnumber--Shorthand for flex-grow
flexGrownumber--How much to grow relative to siblings
flexShrinknumber--How much to shrink relative to siblings
flexBasisnumber--Initial size before grow/shrink
flexWrap"nowrap" | "wrap" | "wrap-reverse""nowrap"Whether children wrap
gapnumber--Space between children (both axes)
columnGapnumber--Horizontal gap between children
rowGapnumber--Vertical gap between children
alignItems"flex-start" | "center" | "flex-end" | "stretch""stretch"Cross-axis alignment
alignSelf"auto" | "flex-start" | "center" | "flex-end" | "stretch""auto"Override parent alignItems
justifyContent"flex-start" | "center" | "flex-end" | "space-between" | "space-around" | "space-evenly""flex-start"Main-axis alignment
widthnumber | \${number}%``--Explicit width
heightnumber | \${number}%``--Explicit height
minWidthnumber--Minimum width
maxWidthnumber--Maximum width
minHeightnumber--Minimum height
maxHeightnumber--Maximum height
overflow"visible" | "hidden" | "scroll""visible"Content overflow behavior
overflowX"visible" | "hidden" | "scroll"--Horizontal overflow
overflowY"visible" | "hidden" | "scroll"--Vertical overflow
display"flex" | "grid" | "none""flex"Display mode
position"relative" | "absolute""relative"Positioning mode
topnumber--Offset from top (absolute positioning)
leftnumber--Offset from left (absolute positioning)
rightnumber--Offset from right (absolute positioning)
bottomnumber--Offset from bottom (absolute positioning)
paddingnumber--Padding on all sides
paddingXnumber--Horizontal padding
paddingYnumber--Vertical padding
paddingTopnumber--Top padding
paddingBottomnumber--Bottom padding
paddingLeftnumber--Left padding
paddingRightnumber--Right padding
marginnumber--Margin on all sides
marginXnumber--Horizontal margin
marginYnumber--Vertical margin
marginTopnumber--Top margin
marginBottomnumber--Bottom margin
marginLeftnumber--Left margin
marginRightnumber--Right margin
borderStyle"single" | "double" | "round" | "bold" | "classic"--Border style
borderColorstring | number--Border color
borderTopbooleantrueShow top border
borderBottombooleantrueShow bottom border
borderLeftbooleantrueShow left border
borderRightbooleantrueShow right border
borderDimColorboolean--Dim all borders
backgroundColorstring | number--Background color
opaqueboolean--Fill background even in empty cells
stickyboolean--Stick to top of ScrollView
stickyChildrenboolean--Enable sticky for children
userSelectboolean--Allow text selection
aria-labelstring--Accessibility label
aria-hiddenboolean--Hide from accessibility tree
backgroundBackgroundProp--Background pattern painted into the buffer before children. Accepts preset ("dots", "grid", "crosshatch") or full BackgroundPattern object for gradients, watermarks, animation.

Basic: Two-column layout

import { Box, Text } from "@orchetron/storm";

<Box flexDirection="row" gap={2} padding={1} borderStyle="round" borderColor="#82AAFF">
  <Box width={20}>
    <Text bold>Sidebar</Text>
  </Box>
  <Box flex={1}>
    <Text>Main content</Text>
  </Box>
</Box>

Background patterns

<Box background="dots">
  <Text>Content on dot pattern</Text>
</Box>

<Box background={{ type: "gradient", gradient: ["#1a1b26", "#82AAFF"] }}>
  <Text>Gradient background</Text>
</Box>

Advanced: Grid layout with nested containers

<Box display="flex" flexDirection="column" height="100%">
  <Box borderStyle="double" borderColor="#82AAFF" padding={1}>
    <Text bold color="#82AAFF">Header</Text>
  </Box>
  <Box flexDirection="row" flex={1} gap={1}>
    <Box width={30} borderStyle="single" borderColor="#505050" paddingX={1}>
      <Text bold>Navigation</Text>
    </Box>
    <Box flex={1} padding={1}>
      <Text>Content area with flex grow</Text>
    </Box>
    <Box width={25} borderStyle="single" borderColor="#505050" paddingX={1}>
      <Text bold>Details</Text>
    </Box>
  </Box>
  <Box borderStyle="single" borderColor="#505050" paddingX={1}>
    <Text dim>Status bar</Text>
  </Box>
</Box>

Text

Styled text with color, weight, and formatting. Supports inline nesting for mixed styles within a line. Text wraps by default.

PropTypeDefaultDescription
childrenReactNode--Text content or nested Text elements
colorstring | number--Foreground color (hex, named, or 256-color index)
bgColorstring | number--Background color
backgroundColorstring | number--Alias for bgColor
boldbooleanfalseBold weight
dimbooleanfalseDim/faint rendering
dimColorbooleanfalseAlias for dim
italicbooleanfalseItalic style
underlinebooleanfalseUnderline decoration
strikethroughbooleanfalseStrikethrough decoration
inversebooleanfalseSwap foreground and background
wrap"wrap" | "truncate" | "truncate-start" | "truncate-end" | "truncate-middle""wrap"Text overflow behavior
align"left" | "center" | "right""left"Text alignment (adds a wrapper Box)
aria-labelstring--Accessibility label
aria-hiddenboolean--Hide from accessibility tree

Basic: Styled inline text

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

<Text color="#82AAFF" bold>
  Hello <Text underline>world</Text>
</Text>

Advanced: Mixed formatting with truncation

<Text>
  <Text color="#34D399" bold>SUCCESS</Text>
  <Text dim> | </Text>
  <Text color="#D4D4D4">Operation completed in </Text>
  <Text color="#FBBF24" bold>42ms</Text>
</Text>

<Text wrap="truncate-middle" color="#808080">
  /very/long/path/to/some/deeply/nested/file/in/project/src/components/Widget.tsx
</Text>

ScrollView

Scrollable container with hit-tested mouse scroll, keyboard navigation, optional scrollbar, stick-to-bottom, and automatic windowing for large child counts.

PropTypeDefaultDescription
childrenReactNode--Scrollable content
stickToBottombooleanfalseAuto-scroll when new content is added at bottom
scrollSpeednumber3Lines per mouse scroll tick
scrollStateRefMutableRefObject<ScrollState>--Ref to access scroll state imperatively
onScroll(scrollTop: number) => void--Called on scroll position change
scrollbarThumbColorstring | number--Scrollbar thumb color
scrollbarTrackColorstring | number--Scrollbar track color
scrollbarCharstring--Custom scrollbar thumb character
scrollbarTrackCharstring--Custom scrollbar track character
maxRenderChildrennumber500Max children before windowing activates
itemHeightnumber1Estimated child height for windowing calculations
stickyboolean--Enable sticky positioning
stickyChildrenboolean--Enable sticky for children
Plus all Box layout propswidth, height, flex, padding*, margin*, borderStyle, etc.

Basic: Chat log with stick-to-bottom

import { ScrollView, Text } from "@orchetron/storm";

<ScrollView flex={1} stickToBottom scrollbarThumbColor="#82AAFF">
  {messages.map((msg) => (
    <Text key={msg.id}>{msg.text}</Text>
  ))}
</ScrollView>

Advanced: Controlled scroll with imperative access

import { ScrollView, Box, Text, Button } from "@orchetron/storm";
import { useRef } from "react";
import type { ScrollState } from "@orchetron/storm";

function LogViewer({ entries }: { entries: string[] }) {
  const scrollState = useRef<ScrollState | null>(null);

  return (
    <Box flexDirection="column" height={20}>
      <ScrollView
        flex={1}
        scrollStateRef={scrollState}
        stickToBottom={false}
        scrollbarThumbColor="#82AAFF"
        scrollbarTrackColor="#1E1E1E"
        borderStyle="single"
        borderColor="#505050"
        onScroll={(top) => console.log("scroll:", top)}
        maxRenderChildren={200}
        itemHeight={1}
      >
        {entries.map((entry, i) => (
          <Text key={i} color={entry.startsWith("ERROR") ? "#F87171" : "#D4D4D4"}>
            {entry}
          </Text>
        ))}
      </ScrollView>
      <Button label="Jump to bottom" onPress={() => scrollState.current?.scrollToBottom()} />
    </Box>
  );
}

See Common Pitfalls for height constraint requirements.


Overlay

Positioned overlay rendered on top of all other content. Overlays are painted in a second pass, overwriting cells from the normal element tree.

PropTypeDefaultDescription
childrenReactNode--Overlay content
visiblebooleantrueWhether overlay is shown
position"center" | "bottom" | "top" | "center-left" | "center-right""center"Screen position
widthnumber | \${number}%``--Overlay width
heightnumber--Overlay height
minWidthnumber--Minimum width
maxWidthnumber--Maximum width
minHeightnumber--Minimum height
maxHeightnumber--Maximum height
borderStyle"single" | "double" | "round" | "bold" | "classic"--Border style
borderColorstring | number--Border color
paddingnumber--Padding on all sides
paddingXnumber--Horizontal padding
paddingYnumber--Vertical padding

Basic: Centered notification

import { Overlay, Text } from "@orchetron/storm";

<Overlay visible={showNotification} position="center" borderStyle="round" borderColor="#82AAFF" padding={2}>
  <Text bold>Operation complete!</Text>
</Overlay>

Advanced: Bottom-positioned status overlay

<Overlay visible={true} position="bottom" width={60} borderStyle="single" borderColor="#FBBF24" paddingX={2}>
  <Text color="#FBBF24" bold>WARNING</Text>
  <Text> Connection unstable. Retrying in {countdown}s...</Text>
</Overlay>

Spacer

Flexible space that expands to fill available room. Equivalent to a Box with flex={1}. Takes no props and no children.

PropTypeDefaultDescription
(none)Spacer takes no props

Basic: Push items apart

import { Box, Text, Spacer } from "@orchetron/storm";

<Box flexDirection="row">
  <Text bold>Left</Text>
  <Spacer />
  <Text dim>Right</Text>
</Box>

Advanced: Header with centered title

<Box flexDirection="row" paddingX={1}>
  <Text color="#82AAFF">storm v2.1</Text>
  <Spacer />
  <Text bold>Dashboard</Text>
  <Spacer />
  <Text dim>Ctrl+Q quit</Text>
</Box>


Back to Components