- Introduction
- Getting Started
- Components
- Layout and Structure
- Styling Guidelines
- Interactive Elements
- Accessibility
- Best Practices
- Website UI Components
Ink is a powerful library for building command-line interfaces (CLIs) with a focus on creating beautiful and interactive terminal applications. This documentation provides comprehensive guidance on using Ink's UI components and features effectively.
npm install inkimport React from 'react';
import {render, Text} from 'ink';
const App = () => <Text>Hello World</Text>;
render(<App />);The fundamental building block for displaying text in Ink applications.
import {Text} from 'ink';
// Basic usage
<Text>Regular text</Text>
// Styled text
<Text color="green">Colored text</Text>
<Text bold>Bold text</Text>Used for layout and positioning of elements.
import {Box} from 'ink';
<Box margin={1} padding={2}>
<Text>Content inside a box</Text>
</Box>Handles user input in interactive applications.
import {useInput} from 'ink';
useInput((input, key) => {
// Handle input here
});Ink uses a flexbox-based layout system:
<Box flexDirection="column">
<Box>Row 1</Box>
<Box>Row 2</Box>
</Box>- Margin and padding support
- Flexible alignment options
- Responsive layouts
// Text colors
<Text color="red">Error message</Text>
<Text color="green">Success message</Text>
<Text color="#ff0000">Custom color</Text>
// Background colors
<Text backgroundColor="blue">Highlighted text</Text><Text bold>Bold text</Text>
<Text italic>Italic text</Text>
<Text underline>Underlined text</Text>
<Text inverse>Inverse colors</Text>import {Spinner} from 'ink';
<Spinner type="dots" />import {Progress} from 'ink';
<Progress value={0.5} />import {Select} from 'ink-select-input';
const items = [
{label: 'Option 1', value: '1'},
{label: 'Option 2', value: '2'}
];
<Select items={items} onSelect={handleSelect} />- Use semantic components
- Provide clear feedback
- Support keyboard navigation
- Use appropriate color contrast
useInput((input, key) => {
if (key.return) {
// Handle Enter key
}
if (key.escape) {
// Handle Escape key
}
});- Minimize re-renders
- Use memoization when appropriate
- Optimize large lists
try {
// Your code
} catch (error) {
<Text color="red">{error.message}</Text>
}import {render} from 'ink-testing-library';
test('renders correctly', () => {
const {lastFrame} = render(<App />);
expect(lastFrame()).toContain('Expected output');
});import {Box, Text} from 'ink';
const Navbar = () => (
<Box borderStyle="single" padding={1}>
<Text bold>Home</Text>
<Text> | </Text>
<Text>Documentation</Text>
<Text> | </Text>
<Text>Examples</Text>
</Box>
);const Card = ({title, content}) => (
<Box
flexDirection="column"
borderStyle="round"
padding={1}
marginBottom={1}
>
<Text bold>{title}</Text>
<Text>{content}</Text>
</Box>
);Ink components automatically adjust to terminal width:
<Box flexDirection="row" flexWrap="wrap">
<Box width={process.stdout.columns >= 80 ? '50%' : '100%'}>
<Text>Content adjusts based on terminal size</Text>
</Box>
</Box>import {TextInput} from 'ink-text-input';
const Form = () => {
const [value, setValue] = useState('');
return (
<Box flexDirection="column">
<TextInput
value={value}
onChange={setValue}
placeholder="Enter your text"
/>
</Box>
);
};const Modal = ({isVisible, onClose, children}) => {
if (!isVisible) return null;
return (
<Box
flexDirection="column"
borderStyle="double"
padding={1}
>
{children}
<Text>Press ESC to close</Text>
</Box>
);
};const theme = {
primary: 'blue',
secondary: 'green',
error: 'red',
success: 'green',
warning: 'yellow'
};
const StyledButton = ({variant, children}) => (
<Text color={theme[variant]}>{children}</Text>
);const LoadingState = () => (
<Box>
<Spinner />
<Text> Loading content...</Text>
</Box>
);class ErrorBoundary extends React.Component {
state = { hasError: false };
static getDerivedStateFromError(error) {
return { hasError: true };
}
render() {
if (this.state.hasError) {
return <Text color="red">Something went wrong!</Text>;
}
return this.props.children;
}
}import {useEffect, useState} from 'react';
import {Text, Box} from 'ink';
const FadeIn = ({children}) => {
const [visible, setVisible] = useState(false);
useEffect(() => {
setVisible(true);
}, []);
if (!visible) return null;
return children;
};While traditional SEO isn't applicable to CLI applications, you can implement metadata for your CLI help menus:
const AppMetadata = {
name: 'Your CLI App',
version: '1.0.0',
description: 'A beautiful CLI application',
commands: {
help: 'Display help menu',
version: 'Display version information'
}
};