nocterm 0.1.0
nocterm: ^0.1.0 copied to clipboard
A Flutter-like framework for terminal UIs.
A powerful, Flutter-inspired Terminal User Interface framework with Riverpod state management for building beautiful command-line applications in Dart.
โจ Features #
- ๐ฏ Flutter-like API - Familiar component-based architecture that mirrors Flutter's design patterns
- ๐ฅ Hot Reload - Instant UI updates during development for rapid iteration
- ๐จ Rich Styling - Full color support, borders, padding, and text styling
- โก Reactive State - Riverpod integration plus built-in
StatefulComponent
andsetState()
- ๐ญ Mouse Support - Full mouse interaction including wheel scrolling and click events
- โจ๏ธ Input Handling - Comprehensive keyboard event system with focus management
- ๐ Flexible Layouts - Row, Column, Stack, ConstrainedBox, and overlay-based layouts
- ๐ Rich Text - Markdown rendering with formatted text, lists, and code blocks
- ๐งช Testing Framework - Flutter-style testing utilities for TUI components
- ๐ Cross-Platform - Works seamlessly on Windows, macOS, and Linux
๐ฆ Project Status #
โ ๏ธ Early Experimental Version (0.1.0)
This framework is in active development. APIs may change significantly in future releases and breaking bugs are still present.
๐ฆ Installation #
Add nocterm
to your pubspec.yaml
:
dependencies:
nocterm: ^0.1.0
๐ Quick Start #
import 'package:nocterm/nocterm.dart';
void main() {
runApp(const Counter());
}
class Counter extends StatefulComponent {
const Counter({super.key});
@override
State<Counter> createState() => _CounterState();
}
class _CounterState extends State<Counter> {
int _count = 0;
@override
Component build(BuildContext context) {
return Focusable(
focused: true,
onKeyEvent: (event) {
if (event.logicalKey == LogicalKey.space) {
setState(() => _count++);
return true;
}
return false;
},
child: Container(
decoration: BoxDecoration(
border: BoxBorder.all(color: Colors.gray),
),
margin: EdgeInsets.all(8),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Counter: $_count'),
SizedBox(height: 1),
Text('Press SPACE to increment', style: TextStyle(color: Colors.gray)),
],
),
),
);
}
}
๐ฅ Hot Reload #
Experience Flutter-like hot reload in your terminal applications:
// Run with hot reload enabled
// Your UI updates instantly as you save changes!
dart --enable-vm-service example/your_app.dart
๐จ Rich Components #
Layout #
- โ Basic - Column, Row, Expanded, Container, Decoration
- โ Advanced - Stack, ConstrainedBox, Overlay system
- โ Scrollable - ListView, ScrollView with mouse wheel support
- โ Positioning - Align, Center, Padding, Margin
Input & Interaction #
- โ TextField - Multi-line input with enhanced cursor styles
- โ Focusable - Keyboard event handling and focus management
- โ Mouse Support - Click and wheel events
Display #
- โ Text - Rich text, markdown rendering, text wrapping
- โ Progress - Progress bars and indicators
- โ Divider - Horizontal and vertical dividers
- โ Terminal - xTerm embedding for subprocess integration
State Management #
- โ Riverpod - Full reactive state management
- โ StatefulComponent - Built-in setState pattern
๐งช Testing #
Write tests for your TUI components:
import 'package:test/test.dart';
import 'package:nocterm/nocterm.dart';
void main() {
test('component renders correctly', () async {
await testNocterm(
'my component test',
(tester) async {
await tester.pumpComponent(
Text('Hello, TUI!', style: TextStyle(color: Colors.green))
);
expect(tester.terminalState, containsText('Hello, TUI!'));
expect(tester.terminalState, hasStyledText(
'Hello, TUI!',
style: TextStyle(color: Colors.green),
));
},
debugPrintAfterPump: true, // See visual output during testing
);
});
test('handles keyboard input', () async {
await testTui(
'keyboard test',
(tester) async {
await tester.pumpComponent(MyInteractiveComponent());
await tester.sendKey(LogicalKey.enter);
expect(tester.terminalState, containsText('Enter pressed!'));
},
);
});
}
๐ License #
This project is licensed under the MIT License - see the LICENSE file for details.
๐ Acknowledgments #
Made with ๐