Components

Reference for all React components in @visulima/tui/react: Box, Text, Cursor, Newline, Spacer, Static, Transform, Spinner, ProgressBar

Components

@visulima/tui exposes Ink-compatible core components plus Ratatat-only additions.

import { Box, Cursor, Newline, ProgressBar, Spacer, Spinner, Static, Text, Transform } from "@visulima/tui/react";

Box

Layout primitive backed by Yoga.

<Box
    flexDirection="row" // row | column | row-reverse | column-reverse
    flexGrow={1}
    flexShrink={1}
    width={40}
    height={10}
    minWidth={10}
    minHeight={4}
    padding={1}
    paddingX={2}
    margin={1}
    gap={1}
    alignItems="center"
    justifyContent="space-between"
    borderStyle="round" // single | double | round | bold | classic | singleDouble | doubleSingle
    borderColor="cyan"
    borderBackgroundColor="blue"
    borderTop={true}
    borderRight={true}
    borderBottom={true}
    borderLeft={true}
>
    {children}
</Box>

Notes:

  • Box defaults to flexDirection="row" unless you set it explicitly.
  • Border side toggles (borderTop, etc.) are supported.
  • Per-side border colors are supported: borderTopColor, borderBottomColor, borderLeftColor, borderRightColor.
  • Per-side border background colors are supported: borderTopBackgroundColor, borderBottomBackgroundColor, borderLeftBackgroundColor, borderRightBackgroundColor.
  • Per-side dim is supported: borderTopDimColor, borderBottomDimColor, borderLeftDimColor, borderRightDimColor.

Text

Renders styled text.

<Text
    color="cyan" // named, #rrggbb, rgb(r,g,b), or ANSI index 0-255
    backgroundColor="blue"
    bold
    italic
    underline
    strikethrough
    dim
    inverse
>
    Hello world
</Text>

dimColor is supported as an Ink-compat alias for dim.

Cursor

Declaratively position the terminal cursor. Two modes are available:

Inline mode (no props)

Place <Cursor /> after a <Text> node. The cursor appears where the preceding text ended, even when text wraps across lines.

<Box>
    <Text>{prompt + value}</Text>
    <Cursor />
</Box>

This is the recommended approach for text inputs. It handles text wrapping, wide characters (CJK, emoji), and multi-line output automatically because the cursor position is derived from the actual rendered text output.

For editable text with a cursor position in the middle:

<Box>
    <Text>{value.slice(0, cursorPos)}</Text>
    <Cursor />
    <Text>{value.slice(cursorPos)}</Text>
</Box>

Anchor mode

Pass anchorRef and/or x/y to position the cursor relative to another element's content origin.

const ref = useRef(null);

<Box ref={ref}>
    <Text>{content}</Text>
</Box>
<Cursor anchorRef={ref} x={5} y={1} />
PropTypeDefault
anchorRefRefObject<DOMElement/null>parent node
xnumber0
ynumber0

Notes:

  • <Cursor> must not be rendered inside <Text>.
  • If multiple <Cursor> components are rendered, the last one controls the terminal cursor.
  • If anchorRef is set but unresolved, the cursor is hidden for that frame.
  • See also useCursor() for imperative cursor control (e.g. IME support).

Newline

<Newline />
<Newline count={2} />

Spacer

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

Static

Append-only region for completed items and log lines.

<Static items={completedTasks}>
    {(task) => (
        <Box key={task.id}>
            <Text color="green">✓ {task.name}</Text>
        </Box>
    )}
</Static>

Static only appends new tail items from items.

Transform

Applies a transform function to the collected text output of its subtree.

<Transform transform={(s) => s.toUpperCase()}>
    <Text>hello world</Text>
</Transform>

Spinner (Ratatat-only)

<Spinner />
<Spinner color="cyan" />
<Spinner frames={["-", "\\", "|", "/"]} interval={100} />

Props (plus all Text props):

PropTypeDefault
framesstring[]Braille frames
intervalnumber80

ProgressBar (Ratatat-only)

<ProgressBar value={42} />
<ProgressBar value={downloaded} max={total} width={30} color="green" />
<ProgressBar value={50} showPercentage={false} />

Props (plus all Text props):

PropTypeDefault
valuenumberrequired
maxnumber100
widthnumber20
completeCharstring'█'
incompleteCharstring'░'
bracketbooleantrue
showPercentagebooleantrue
Support

Contribute to our work and keep us going

Community is the heart of open source. The success of our packages wouldn't be possible without the incredible contributions of users, testers, and developers who collaborate with us every day.Want to get involved? Here are some tips on how you can make a meaningful impact on our open source projects.

Ready to help us out?

Be sure to check out the package's contribution guidelines first. They'll walk you through the process on how to properly submit an issue or pull request to our repositories.

Submit a pull request

Found something to improve? Fork the repo, make your changes, and open a PR. We review every contribution and provide feedback to help you get merged.

Good first issues

Simple issues suited for people new to open source development, and often a good place to start working on a package.
View good first issues