gridland
Core Concepts

Intrinsic Elements

The built-in JSX tags box, text, input, select that Gridland renders to a cell grid instead of the DOM

In a normal React app, JSX tags like <div>, <span>, and <button> compile to DOM elements. In Gridland, you use a different set of tags <box>, <text>, <input>, <select>, and a few others that compile to cell grid primitives, not DOM. They're drawn to an HTML5 <canvas> in the browser and to real stdout in a terminal, never to the document tree.

Primitives
?

Run demo

Terminal
bunx @gridland/demo primitives
Terminal
curl -fsSL https://raw.githubusercontent.com/thoughtfulllc/gridland/main/scripts/run-demo.sh | bash -s primitives

These are JSX intrinsic elements, not DOM elements. <box> renders to the canvas cell grid, not to an HTML <div>. They only work inside a <TUI> wrapper.

Files that use intrinsic elements must start with // @ts-nocheck at the very top. The JSX type definitions for <box>, <text>, etc. conflict with React's default DOM types, and TypeScript will reject the file without this directive. This is a known limitation of the OpenTUI JSX integration.

All primitives accept pointer event handlers (onClick, onMouseOver, onMouseScroll, and eight others). See the Pointer Events reference for the complete handler list and event payload shape.

<box>

A container element with flexbox layout support.

Box example
<box
  flexDirection="column"
  padding={1}
  border
  borderStyle="rounded"
  borderColor="#5e81ac"
  backgroundColor="#2e3440"
>
  {children}
</box>

Box Props

PropTypeDescription
flexDirection"row" | "column"Layout direction
paddingnumberPadding in cells
marginnumberMargin in cells
borderbooleanShow border
borderStyle"single" | "rounded" | "double" | "heavy" | "dashed"Border style
borderColorstringBorder color (hex)
backgroundColorstringBackground color (hex)
titlestringBorder title text
titleAlignment"left" | "center" | "right"Title position
flexGrownumberFlex grow factor
flexShrinknumberFlex shrink factor
widthnumber | stringWidth in cells or percentage
heightnumber | stringHeight in cells or percentage
gapnumberGap between children

<text>

Renders styled text content.

Text example
<text fg="#a3be8c" bold>
  Hello World
</text>

Text Props

PropTypeDescription
fgstringForeground color (hex)
bgstringBackground color (hex)
boldbooleanBold text
italicbooleanItalic text
underlinebooleanUnderlined text
dimbooleanDimmed text

<input>

A text input field.

<input> is terminal-only. It is backed by OpenTUI's Zig-FFI EditBuffer and will crash with a resolveRenderLib error if rendered inside <TUI> in the browser (docs site, @gridland/web, any canvas runtime). Use TextInput from @/components/ui/text-input in browser demos — it provides the same behavior with a pure-JS implementation.

Input example
<input
  placeholder="Type here..."
  onInput={(value) => console.log(value)}
  onSubmit={(value) => console.log("Submitted:", value)}
/>

<select>

A selection list.

Select example
<select
  options={[
    { label: "Option A", value: "a" },
    { label: "Option B", value: "b" },
  ]}
  onChange={(index, option) => console.log(option)}
/>

<scrollbox>

A scrollable container.

Scrollbox example
<scrollbox height={10}>
  {/* Content taller than 10 rows will scroll */}
</scrollbox>

<code>

Syntax-highlighted code block.

Code example
<code content="const x = 42" filetype="typescript" />

<markdown>

Rendered markdown content.

Markdown example
<markdown content="# Hello\n\nThis is **bold** text." />