React for CLI - build interactive command-line interfaces using React components and Flexbox layouts
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Essential components for building terminal layouts using Flexbox-style positioning, text rendering with styling options, and specialized layout utilities.
The essential layout component for building terminal UIs, equivalent to <div style="display: flex"> in the browser.
/**
* Primary layout container component with Flexbox support
* @param props - Layout and styling properties
* @param children - Child components to render inside the box
*/
function Box(props: BoxProps & { children?: ReactNode }): JSX.Element;
interface BoxProps {
// Position and display
position?: "absolute" | "relative";
display?: "flex" | "none";
overflow?: "visible" | "hidden";
overflowX?: "visible" | "hidden";
overflowY?: "visible" | "hidden";
// Flexbox layout
flexDirection?: "row" | "column" | "row-reverse" | "column-reverse"; // default: "row"
flexWrap?: "nowrap" | "wrap" | "wrap-reverse"; // default: "nowrap"
flexGrow?: number; // default: 0
flexShrink?: number; // default: 1
flexBasis?: number | string;
justifyContent?: "flex-start" | "flex-end" | "center" | "space-between" | "space-around" | "space-evenly";
alignItems?: "flex-start" | "center" | "flex-end" | "stretch";
alignSelf?: "flex-start" | "center" | "flex-end" | "auto";
// Dimensions
width?: number | string; // number = characters, string = percentage
height?: number | string; // number = lines, string = percentage
minWidth?: number | string;
minHeight?: number | string;
// Spacing
margin?: number;
marginX?: number; // horizontal margin
marginY?: number; // vertical margin
marginTop?: number;
marginBottom?: number;
marginLeft?: number;
marginRight?: number;
padding?: number;
paddingX?: number; // horizontal padding
paddingY?: number; // vertical padding
paddingTop?: number;
paddingBottom?: number;
paddingLeft?: number;
paddingRight?: number;
gap?: number; // gap between children
columnGap?: number; // gap between columns
rowGap?: number; // gap between rows
// Borders
borderStyle?: string; // border style from cli-boxes
borderTop?: boolean; // default: true
borderBottom?: boolean; // default: true
borderLeft?: boolean; // default: true
borderRight?: boolean; // default: true
borderColor?: string;
borderTopColor?: string;
borderBottomColor?: string;
borderLeftColor?: string;
borderRightColor?: string;
borderDimColor?: boolean;
borderTopDimColor?: boolean;
borderBottomDimColor?: boolean;
borderLeftDimColor?: boolean;
borderRightDimColor?: boolean;
}Usage Examples:
import React from "react";
import { render, Box, Text } from "ink";
// Basic layout
function BasicLayout() {
return (
<Box flexDirection="column">
<Box>
<Text>Header</Text>
</Box>
<Box flexGrow={1}>
<Text>Content</Text>
</Box>
</Box>
);
}
// Centered content
function CenteredBox() {
return (
<Box justifyContent="center" alignItems="center" width={40} height={10}>
<Text>Centered text</Text>
</Box>
);
}
// With borders and styling
function StyledBox() {
return (
<Box
borderStyle="round"
borderColor="blue"
padding={2}
margin={1}
>
<Text>Bordered content</Text>
</Box>
);
}Component for displaying and styling text with color, formatting, and text wrapping options.
/**
* Text display component with comprehensive styling support
* @param props - Text styling and content properties
*/
function Text(props: TextProps & { children?: ReactNode }): JSX.Element;
interface TextProps {
/**
* Text color using chalk color names or hex values
*/
color?: string;
/**
* Background color using chalk color names or hex values
*/
backgroundColor?: string;
/**
* Dim the text color (emit less light)
* @default false
*/
dimColor?: boolean;
/**
* Make text bold
* @default false
*/
bold?: boolean;
/**
* Make text italic
* @default false
*/
italic?: boolean;
/**
* Underline text
* @default false
*/
underline?: boolean;
/**
* Strike through text
* @default false
*/
strikethrough?: boolean;
/**
* Inverse background and foreground colors
* @default false
*/
inverse?: boolean;
/**
* Text wrapping behavior when width exceeds container
* @default "wrap"
*/
wrap?: "wrap" | "truncate-end" | "truncate" | "truncate-start" | "truncate-middle" | "end" | "middle";
}Usage Examples:
import React from "react";
import { render, Box, Text } from "ink";
// Styled text
function StyledText() {
return (
<Box flexDirection="column">
<Text color="red" bold>Error: Something went wrong</Text>
<Text color="green">✓ Success message</Text>
<Text color="blue" italic>Information text</Text>
<Text backgroundColor="yellow" color="black">Highlighted</Text>
<Text dimColor>Dimmed text</Text>
<Text underline>Underlined text</Text>
<Text strikethrough>Crossed out</Text>
</Box>
);
}
// Text wrapping
function WrappedText() {
return (
<Box width={20}>
<Text wrap="wrap">
This is a long text that will wrap to multiple lines
</Text>
</Box>
);
}
// Truncated text
function TruncatedText() {
return (
<Box width={15}>
<Text wrap="truncate-end">
This text will be truncated...
</Text>
</Box>
);
}Component that permanently renders output above everything else, useful for logs or completed tasks.
/**
* Renders items permanently above other output
* @param props - Static rendering configuration
*/
function Static<T>(props: StaticProps<T>): JSX.Element;
interface StaticProps<T> {
/**
* Array of items to render using the render function
*/
items: T[];
/**
* Styles to apply to container (Box styles)
*/
style?: Styles;
/**
* Function to render each item in the items array
* @param item - Current item being rendered
* @param index - Index of the item in the array
* @returns React node for the item
*/
children: (item: T, index: number) => ReactNode;
}Usage Examples:
import React, { useState, useEffect } from "react";
import { render, Box, Text, Static } from "ink";
interface LogEntry {
message: string;
timestamp: Date;
type: "info" | "error" | "success";
}
function LogViewer() {
const [logs, setLogs] = useState<LogEntry[]>([]);
const [currentTask, setCurrentTask] = useState("Processing...");
useEffect(() => {
// Simulate adding log entries
const interval = setInterval(() => {
setLogs(prev => [...prev, {
message: `Task ${prev.length + 1} completed`,
timestamp: new Date(),
type: "success"
}]);
}, 1000);
return () => clearInterval(interval);
}, []);
return (
<Box flexDirection="column">
<Static items={logs}>
{(log, index) => (
<Box key={index}>
<Text color={log.type === "error" ? "red" : "green"}>
[{log.timestamp.toTimeString()}] {log.message}
</Text>
</Box>
)}
</Static>
<Box>
<Text>Current: {currentTask}</Text>
</Box>
</Box>
);
}Component for transforming string representation of child components before output.
/**
* Transform string output of child components
* @param props - Transform configuration
*/
function Transform(props: TransformProps): JSX.Element;
interface TransformProps {
/**
* Function to transform the rendered string output
* @param children - String representation of child components
* @param index - Transform index (for multiple transforms)
* @returns Transformed string
*/
transform: (children: string, index: number) => string;
children?: ReactNode;
}Usage Examples:
import React from "react";
import { render, Box, Text, Transform } from "ink";
import gradient from "gradient-string";
// Apply gradient effect
function GradientText() {
return (
<Transform transform={(output) => gradient.rainbow(output)}>
<Text>Rainbow gradient text</Text>
</Transform>
);
}
// Add prefix to output
function PrefixedOutput() {
return (
<Transform transform={(output) => `>>> ${output}`}>
<Box flexDirection="column">
<Text>Line 1</Text>
<Text>Line 2</Text>
</Box>
</Transform>
);
}Component for inserting newline characters, must be used within Text components.
/**
* Insert newline characters
* @param props - Newline configuration
*/
function Newline(props: NewlineProps): JSX.Element;
interface NewlineProps {
/**
* Number of newlines to insert
* @default 1
*/
count?: number;
}Usage Examples:
import React from "react";
import { render, Text, Newline } from "ink";
function MultilineText() {
return (
<Text>
First line
<Newline />
Second line
<Newline count={2} />
Line after double newline
</Text>
);
}Flexible space component that expands along the major axis of its containing layout.
/**
* Flexible space that fills available space
* Note: Spacer accepts no props and simply renders a Box with flexGrow={1}
*/
function Spacer(): JSX.Element;Usage Examples:
import React from "react";
import { render, Box, Text, Spacer } from "ink";
// Right-aligned text
function RightAligned() {
return (
<Box>
<Spacer />
<Text>Right aligned</Text>
</Box>
);
}
// Space between elements
function SpaceBetween() {
return (
<Box>
<Text>Left</Text>
<Spacer />
<Text>Right</Text>
</Box>
);
}
// Vertical spacing
function VerticalSpacing() {
return (
<Box flexDirection="column" height={10}>
<Text>Top</Text>
<Spacer />
<Text>Bottom</Text>
</Box>
);
}