TermuiX 1.1.0
dotnet add package TermuiX --version 1.1.0
NuGet\Install-Package TermuiX -Version 1.1.0
<PackageReference Include="TermuiX" Version="1.1.0" />
<PackageVersion Include="TermuiX" Version="1.1.0" />
<PackageReference Include="TermuiX" />
paket add TermuiX --version 1.1.0
#r "nuget: TermuiX, 1.1.0"
#:package TermuiX@1.1.0
#addin nuget:?package=TermuiX&version=1.1.0
#tool nuget:?package=TermuiX&version=1.1.0
TermuiX
A modern, declarative terminal UI framework for .NET 9.0 and .NET 10.0 that brings XML-based UI definition to the console.
Why TermuiX?
TermuiX offers a unique approach to terminal UI development:
- Zero Dependencies - Pure .NET implementation with no external dependencies or native bindings
- Declarative UI - Define your interface in XML, similar to web development or XAML
- Simple Rendering Model - Straightforward render loop - call
Render()when ready, no complex state management - Pure C# - No need to learn platform-specific APIs or deal with interop complexities
- Cross-Platform - Works on any platform that supports .NET 9.0/10.0 and ANSI terminals
- AOT Compatible - Full support for Native AOT compilation for minimal deployment size and fast startup
- Extensible - Register custom widgets and components for reusable UI patterns
Perfect for building dashboards, TUI tools, interactive CLIs, and terminal-based applications.
Features
- Declarative XML-based UI - Define your terminal UI using familiar XML syntax
- Rich Widget Set - Comprehensive collection of interactive widgets with disabled state support
- Event-Driven Architecture - Clean event handling for user interactions
- Flexible Styling - Support for colors, borders, text styles (bold, italic, underline, strikethrough)
- Advanced Layout - Positioned and scrollable containers with padding support
- Keyboard Navigation - Built-in Tab/Shift+Tab navigation and custom keyboard shortcuts
- Multi-line Support - Tables and inputs with multi-line text capabilities
- Unicode & Emoji Support - Full support for emojis, East Asian characters, and wide Unicode characters
- Custom Widgets - Register your own widget types and reusable components in XML
- Widget Cloning - Deep and shallow cloning support for all widgets
Available Widgets
Interactive Widgets
- Button - Clickable buttons with customizable styling and focus states
- Input - Single-line and multi-line text input with password mode
- Checkbox - Toggle checkboxes with checked/unchecked states
- RadioButton - Mutually exclusive radio button groups
- Slider - Adjustable value slider with min/max/step configuration
Display Widgets
- Text - Static or dynamic text with various alignments and styles
- Table - Multi-row, multi-column tables with borders and text styling
- Chart - Line charts with multiple data series and legends
- ProgressBar - Progress indicators and marquee animations
- Line - Horizontal and vertical separator lines
- Container - Layout containers with optional borders and scrolling
Installation
dotnet add package TermuiX
Quick Start
using System.Threading;
using TermuiX.Widgets;
var xml = """
<Container Width="100%" Height="100%" BackgroundColor="DarkBlue">
<Text PositionX="2ch" PositionY="1ch"
ForegroundColor="Yellow"
Style="Bold">
Welcome to TermuiX!
</Text>
<Button Name="myButton" PositionX="2ch" PositionY="3ch"
BorderColor="White" TextColor="Cyan"
RoundedCorners="true">
Click Me
</Button>
</Container>
""";
// Initialize and load UI
var termui = TermuiX.TermuiX.Init();
termui.LoadXml(xml);
// Get widget reference and attach event
var button = termui.GetWidget<Button>("myButton");
if (button is not null)
{
bool running = true;
button.Click += (sender, e) => running = false;
try
{
while (running)
{
termui.Render();
Thread.Sleep(16); // 60 FPS
}
}
finally
{
TermuiX.TermuiX.DeInit();
}
}
Usage Examples
Creating a Form
<Container Width="100%" Height="100%" BackgroundColor="DarkBlue">
<Container PositionX="5ch" PositionY="5ch" Width="32ch" Height="3ch"
BorderStyle="Single" RoundedCorners="true">
<Input Name="nameInput" PositionX="0ch" PositionY="0ch"
Width="30ch" Height="1ch"
Placeholder="Enter your name..."
FocusBackgroundColor="DarkBlue"
FocusForegroundColor="White" />
</Container>
<Checkbox Name="agreeCheckbox" PositionX="5ch" PositionY="9ch" />
<Text PositionX="7ch" PositionY="9ch">I agree to the terms</Text>
<Button Name="submitButton" PositionX="5ch" PositionY="11ch"
RoundedCorners="true">Submit</Button>
</Container>
Creating a Table
<Table Name="dataTable" PositionX="5ch" PositionY="5ch"
BorderStyle="Single" BorderColor="White"
RoundedCorners="true">
<TableRow>
<TableCell Style="Bold">Name</TableCell>
<TableCell Style="Bold">Age</TableCell>
<TableCell Style="Bold">City</TableCell>
</TableRow>
<TableRow>
<TableCell>Alice</TableCell>
<TableCell>25</TableCell>
<TableCell>New York</TableCell>
</TableRow>
<TableRow>
<TableCell>Bob</TableCell>
<TableCell>30</TableCell>
<TableCell>London</TableCell>
</TableRow>
</Table>
Creating a Chart
var chart = termui.GetWidget<Chart>("salesChart");
if (chart is not null)
{
var series1 = new ChartDataSeries
{
Label = "Product A",
Color = ConsoleColor.Green,
Data = [10, 15, 13, 17, 22, 28, 35, 42]
};
chart.AddSeries(series1);
chart.XLabels = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug"];
}
Widget Properties
Common Properties
All widgets support these common properties:
Name- Unique identifier for retrieving widgets viaGetWidget<T>()PositionX,PositionY- Position in characters (e.g., "10ch")Width,Height- Dimensions in characters or percentage (e.g., "50ch", "100%")PaddingLeft,PaddingRight,PaddingTop,PaddingBottom- Padding in charactersForegroundColor,BackgroundColor- Standard console colorsFocusForegroundColor,FocusBackgroundColor- Colors when focusedVisible- Show/hide widgetCanFocus- Enable/disable focus capability
Container-Specific
BorderStyle-Single,Double, orNoneBorderColor- Border colorRoundedCorners- Enable rounded corners (single border only)Scrollable- Enable scrolling for overflow content
Input-Specific
Placeholder- Placeholder textIsPassword- Hide input charactersMultiline- Enable multi-line inputValue- Current text value
Text Styles
Normal- Regular textBold- Bold text (Unicode mathematical alphanumeric symbols)Italic- Italic text (Unicode mathematical alphanumeric symbols)BoldItalic- Combined bold and italicUnderline- Underlined textStrikethrough- Text with strikethrough
Event Handling
Button Click Events
button.Click += (sender, e) =>
{
Console.WriteLine("Button clicked!");
};
Input Events
input.TextChanged += (sender, e) =>
{
Console.WriteLine($"New value: {input.Value}");
};
input.EnterPressed += (sender, e) =>
{
Console.WriteLine("Enter key pressed!");
};
Checkbox Events
checkbox.CheckedChanged += (sender, e) =>
{
Console.WriteLine($"Checked: {checkbox.Checked}");
};
RadioButton Events
radioButton.SelectionChanged += (sender, e) =>
{
Console.WriteLine($"Selected: {radioButton.Selected}");
};
Slider Events
slider.ValueChanged += (sender, newValue) =>
{
Console.WriteLine($"Value: {newValue}");
};
Keyboard Shortcuts
termui.Shortcut += (sender, key) =>
{
if (key.Key == ConsoleKey.S) // Ctrl+S
{
// Handle save shortcut
}
};
Advanced Features
Modal Dialogs
Create modal dialogs by toggling container visibility:
var mainPage = termui.GetWidget<Container>("mainPage");
var confirmModal = termui.GetWidget<Container>("confirmModal");
// Show modal
mainPage.Visible = false;
confirmModal.Visible = true;
termui.SetFocus(modalYesButton);
Scrollable Containers
<Container Width="30ch" Height="10ch" Scrollable="true">
<RadioButton Name="option1" PositionX="2ch" PositionY="2ch" />
<RadioButton Name="option2" PositionX="2ch" PositionY="3ch" />
</Container>
Use Page Up/Page Down or Ctrl+Page Up/Page Down to scroll.
Dynamic Updates
// Update text dynamically
outputText.Content = "Updated message!";
// Update progress bar
progressBar.Value = 0.75; // 75%
// Update slider
volumeSlider.Value = 50;
Console State Management
TermuiX automatically manages console state:
// Initialize - clears screen, hides cursor
var termui = TermuiX.TermuiX.Init();
// DeInit - restores cursor, clears screen, resets colors
TermuiX.TermuiX.DeInit();
Ctrl+C Handling
Ctrl+C automatically calls DeInit() to restore console state. You can control this behavior:
// Disable automatic exit on Ctrl+C
TermuiX.TermuiX.AllowCancelKeyExit = false;
Border Styles
TermuiX supports multiple border styles:
- Single - Single-line borders (┌─┐│└┘)
- Double - Double-line borders (╔═╗║╚╝)
- RoundedCorners - Rounded corners with single borders (╭─╮│╰╯)
<Container BorderStyle="Single" RoundedCorners="true">
</Container>
Requirements
- .NET 9.0 or .NET 10.0
- Terminal with Unicode support
- Terminal with ANSI color support
What's New in v1.1.0
Custom Widget & Component Registration
Register your own widget types and reusable components directly in the XML parser:
// Register a custom widget
termui.RegisterWidget("CustomButton", attrs =>
{
var text = attrs.GetValueOrDefault("Text", "Default");
return new CustomButton(text);
});
// Register a reusable component
var fileExplorer = new FileExplorer(termui);
termui.RegisterComponent("FileExplorer", attrs =>
{
var width = attrs.GetValueOrDefault("Width", "100%");
return fileExplorer.BuildXml();
});
fileExplorer.Initialize();
// Use in XML
// <CustomButton Text="Click Me" />
// <FileExplorer Width="80%" Height="90%" />
Emoji & Unicode Support
Full support for emojis, East Asian characters (CJK), and all wide Unicode characters with proper display width calculation:
<Text>Hello 👋 World! 你好世界</Text>
<Button>Save 💾</Button>
Disabled State for All Interactive Widgets
All interactive widgets now support disabled states with customizable colors:
<Button Name="submitBtn" Disabled="true"
DisabledForegroundColor="Gray"
DisabledBackgroundColor="DarkGray">
Submit
</Button>
<Input Disabled="true" DisabledForegroundColor="DarkGray" />
<Checkbox Disabled="true" />
<RadioButton Disabled="true" />
<Slider Disabled="true" />
.NET 10.0 & AOT Support
- Multi-targeting for .NET 9.0 and .NET 10.0
- Full Native AOT compatibility for minimal deployment size
- Enabled AOT analyzer for build-time warnings
New FileManager Sample
Complete file explorer implementation demonstrating:
- Two-column layout with file properties
- Navigation with history (back/forward buttons)
- File operations (copy, move, delete, rename)
- Confirmation dialogs
- Filter and sort functionality
- Custom component registration
Framework Improvements
- Auto-scroll to keep focused widgets visible
- Better rendering of wide characters and emojis
- Improved layout calculations with scrollbar awareness
- Enhanced clipboard support in Input widget
- Better multiline navigation with proper rune handling
Additional Features
Reusable Components
Create reusable UI components by adding XML strings dynamically to containers:
var container = termui.GetWidget<Container>("myContainer");
string cardComponent = """
<Container Width="30ch" Height="5ch" BorderStyle="Single" BorderColor="White">
<Text PositionX="1ch" PositionY="1ch">Card Title</Text>
</Container>
""";
container.Add(cardComponent); // Components are automatically cloned
Negative Positioning
Use negative positions to place widgets off-screen or create animated transitions:
<Container PositionX="-50ch" PositionY="0ch" Width="40ch" Height="100%">
</Container>
// Animate position changes
sidebar.PositionX = $"{currentPosition}ch";
Widget Cloning
All widgets support deep and shallow cloning:
var originalButton = termui.GetWidget<Button>("myButton");
var clonedButton = originalButton.Clone(deep: true); // Deep clone with children
Samples
Check out the included samples:
- TermuiX.Demo - Comprehensive demo with forms, charts, modals, and more
- TermuiX.Demo2 - Table widget demonstration with multi-line text
- TermuiX.Demo3 - Animated sidebar with burger menu using negative positioning
- TermuiX.Demo4 - Component model demonstration with dynamic widget addition
- TermuiX.Demo5 - Auto-scroll messenger with programmatic scroll control
- TermuiX.FileManager - Full-featured file explorer with custom component registration
Run samples:
cd samples/TermuiX.Demo
dotnet run
cd samples/TermuiX.Demo2
dotnet run
cd samples/TermuiX.Demo3
dotnet run
cd samples/TermuiX.Demo4
dotnet run
cd samples/TermuiX.Demo5
dotnet run
cd samples/TermuiX.FileManager
dotnet run
License
MIT License - see LICENSE file for details
Contributing
Contributions are welcome! Please feel free to submit issues and pull requests.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- No dependencies.
-
net9.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.