konsole 0.1.0
konsole: ^0.1.0 copied to clipboard
A smol & light-lightweight TUI library for Dart.
Konsole - A lightweight TUI framework for Dart 🎯 #
A modern, feature-rich terminal UI framework for Dart. Build interactive command-line interfaces with ease using a component-based architecture.
Konsole provides a simple yet powerful way to create terminal applications with rich UI components like boxes, buttons, spinners, and more.
Example #
Example #
Basic Components Demo |
Interactive Components |
TUI Counter App with Konsole |
|
- 🎨 Rich component library - Buttons, boxes, spinners, text labels, and more
- 📊 Flexible layout system - Use rows and columns for intuitive layouts
- 🎯 Focus management - Tab navigation between interactive elements
- 🌈 ANSI color support - Full terminal color customization
- ⌨️ Input handling - Process keyboard input from your users
- 🔄 Update loop - Automatic rendering with animation support
Installation #
Add Konsole to your pubspec.yaml:
dependencies:
konsole: ^1.0.0
Then run:
dart pub get
Core Concepts #
Konsole is built around a few simple concepts:
- Components: UI elements like Button, Text, Box
- Layouts: Row and Column components for organizing elements
- Application: The main Konsole class that manages components and rendering
- Input Handling: Each component can respond to user input
Components #
Basic Components #
| Component | Description |
|---|---|
Text |
Simple text display with color support |
Button |
Interactive button with callback support |
Box |
Container with border and optional title |
Spinner |
Animated loading indicator with multiple styles |
More to come.
Layout Components #
| Component | Description |
|---|---|
Row |
Horizontal layout container |
Column |
Vertical layout container |
Usage #
Simple Example #
import 'package:konsole/konsole.dart';
void main() {
final app = Konsole();
app.add(Text.success("Hello Konsole!"));
app.run();
}
Text Styles Example #
See example/components/texts.dart for a full showcase of all text styles and extension methods:
import 'package:konsole/konsole.dart';
void main() {
final examples = [
Text('Default Text'),
Text.success('Success Text'),
Text.error('Error Text'),
Text.warning('Warning Text'),
Text.info('Info Text'),
Text.muted('Muted Text'),
Text.highlight('Highlight Text'),
Text.title('Title Text'),
Text.subtitle('Subtitle Text'),
Text.accent('Accent Text'),
Text('Bold Text').bold(),
Text('Italic Text').italic(),
Text('Underline Text').underline(),
Text('Custom Color').withColor(KonsoleColors.magenta),
Text('Custom BG').withBackgroundColor(KonsoleColors.bgCyan),
Text('Right Aligned', alignment: TextAlignment.right, maxWidth: 30),
Text('Center Aligned', alignment: TextAlignment.center, maxWidth: 30),
Text(
'Wrapped text example that is long enough to demonstrate word wrapping.',
maxWidth: 20,
wordWrap: true,
),
Text('With Prefix', prefix: '>> '),
Text('With Suffix', suffix: ' <<'),
];
final app = Konsole();
app.add(Column(examples));
app.run();
}
Interactive Counter Example #
See example/apps/konsole_example.dart for a full-featured interactive demo with counter, spinners, and more.
Complex Layout Example #
import 'package:konsole/konsole.dart';
class Counter extends KonsoleComponent {
int value;
String fgColor;
String? bgColor;
int totalWidth;
Counter({
this.value = 0,
this.fgColor = KonsoleColors.white,
this.bgColor,
this.totalWidth = 20,
super.marginHorizontal,
super.marginVertical,
}) : super(width: totalWidth, height: 1) {
focusable = true;
}
@override
String render() {
String text = 'Counter: $value';
text =
text.length > totalWidth
? text.substring(0, totalWidth)
: text.padRight(totalWidth);
return Ansi.color(text, fg: fgColor, bgColor: bgColor);
}
@override
void handleInput(String input) {
if (focused) {
if (input == '\x1B[A') value++;
if (input == '\x1B[B') value--;
}
}
}
void main() {
final app = Konsole();
final counter = Counter(fgColor: KonsoleColors.red, totalWidth: 35);
final counterBox = Column([
counter,
Column([
Button(
'Up',
fgColor: KonsoleColors.magenta,
onPressed: () => counter.value++,
customWidth: 10,
),
Button(
'Down',
fgColor: KonsoleColors.yellow,
onPressed: () => counter.value--,
customWidth: 10,
),
]),
]);
app.add(
Row([
counterBox,
Column([
Spinner.line(fgColor: KonsoleColors.cyan),
Spinner.dot(fgColor: KonsoleColors.yellow),
Spinner.box(fgColor: KonsoleColors.magenta),
Spinner(fgColor: KonsoleColors.blue),
]),
]),
);
app.run();
}
Component Details #
Text #
Display styled text with color and formatting support:
Text.success("Success!");
Text.error("Error!");
Text.warning("Warning!");
Text.info("Info");
Text.muted("Muted");
Text.highlight("Highlight");
Text.title("Title");
Text.subtitle("Subtitle");
Text.accent("Accent");
// Use extension methods for chaining styles
Text("Bold").bold();
Text("Italic").italic();
Text("Underline").underline();
Text("Custom Color").withColor(KonsoleColors.magenta);
Text("Custom BG").withBackgroundColor(KonsoleColors.bgCyan);
Text("Right Aligned", alignment: TextAlignment.right, maxWidth: 30);
Text("Center Aligned", alignment: TextAlignment.center, maxWidth: 30);
Text("Wrapped text example that is long enough to demonstrate word wrapping.", maxWidth: 20, wordWrap: true);
Text("With Prefix", prefix: '>> ');
Text("With Suffix", suffix: ' <<');
Button #
Interactive button that can respond to user input:
Button(
"Click Me",
fgColor: KonsoleColors.white,
bgColor: KonsoleColors.bgBlue,
onPressed: () => print("Button clicked!"),
)
Box #
Container with border and optional title:
Box(
Text("Content inside box"),
title: "Box Title",
fgColor: KonsoleColors.cyan,
)
Spinner #
Animated loading indicators with multiple styles:
// Default spinner '⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'
Spinner(fgColor: KonsoleColors.blue)
// Dot-style spinner '.', '..', '...', '....'
Spinner.dot(fgColor: KonsoleColors.yellow)
// Line-style spinner
Spinner.line(fgColor: KonsoleColors.cyan)
// Box-style spinner '□', '■', '▣', '▢'
Spinner.box(fgColor: KonsoleColors.magenta)
Counter #
Interactive numeric counter:
See example/apps/counter.dart for a full implementation.
Key Navigation #
Tab: Move focus between interactive componentsEnter: Activate focused buttonsUp/Down Arrow: Interact with counter componentsq: Quit the application
Color Support #
Konsole provides built-in ANSI color constants:
// Foreground colors
KonsoleColors.black
KonsoleColors.red
KonsoleColors.green
KonsoleColors.yellow
KonsoleColors.blue
KonsoleColors.magenta
KonsoleColors.cyan
KonsoleColors.white
// Background colors
KonsoleColors.bgBlack
KonsoleColors.bgRed
KonsoleColors.bgGreen
KonsoleColors.bgYellow
KonsoleColors.bgBlue
KonsoleColors.bgMagenta
KonsoleColors.bgCyan
KonsoleColors.bgWhite
Creating Custom Components #
Extend the KonsoleComponent class to create your own components:
class MyCustomComponent extends KonsoleComponent {
MyCustomComponent({super.marginHorizontal, super.marginVertical}) : super(width: 10, height: 1);
@override
String render() {
return "My custom component";
}
@override
void handleInput(String input) {
// Handle input here
}
@override
void update(double dt) {
// Update state here
}
}
Layout System #
Konsole uses a simple but powerful layout system with two main layout components:
- Row: Horizontal layout that arranges components from left to right
- Column: Vertical layout that arranges components from top to bottom
Both layout components support margins:
// Horizontal layout with margin
Row([component1, component2], marginHorizontal: 2, marginVertical: 1)
// Vertical layout with margin
Column([component1, component2], marginHorizontal: 2, marginVertical: 1)
Each component can also have its own margins:
Text("Hello", marginHorizontal: 2, marginVertical: 1)
License #
This project is licensed under the MIT License - see the LICENSE file for details.
Contributing #
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request