Awesome
β¨οΈ Tui
<img src="https://raw.githubusercontent.com/Im-Beast/deno_tui/main/docs/logo-transparent.png" align="right" width="250" height="250" alt="Deno mascot made as ASCII art" />Simple Deno module that allows easy creation of Terminal User Interfaces.
π© Features
- π° Ease of use
- ποΈβπ¨οΈ Reactivity
- ποΈ No dependencies
- π Decent documentation
- π¦ Multiple ready-to-use components
- π¨ Styling framework agnostic
- This means you can use whatever terminal styling module you want
- ποΈ Crayon is recommended but not imposed as it greatly integrates with Tui
- πͺΆ Relatively lightweight
π₯οΈ OS Support
Operating system | Linux | macOS | WindowsΒΉ | WSL |
---|---|---|---|---|
Base | βοΈ | βοΈ | βοΈ | βοΈ |
Keyboard support | βοΈ | βοΈ | βοΈ | βοΈ |
Mouse support | βοΈ | βοΈ | βοΈ | βοΈ |
Required permissions | none | none | none | none |
ΒΉ - If unicode characters are displayed incorrectly type chcp 65001
into the console to change active console code
page to use UTF-8 encoding.
π Get started
Replace {version} with relevant module versions
- Create Tui instance
import { crayon } from "https://deno.land/x/crayon@$MODULE_VERSION/mod.ts";
import { Canvas, Tui } from "https://deno.land/x/tui@$MODULE_VERSION/mod.ts";
const tui = new Tui({
style: crayon.bgBlack, // Make background black
refreshRate: 1000 / 60, // Run in 60FPS
});
tui.dispatch(); // Close Tui on CTRL+C
- Enable interaction using keyboard and mouse
import { handleInput, handleKeyboardControls, handleMouseControls } from "https://deno.land/x/tui@$MODULE_VERSION/mod.ts";
...
handleInput(tui);
handleMouseControls(tui);
handleKeyboardControls(tui);
- Add some components
import { Button } from "https://deno.land/x/tui@$MODULE_VERSION/src/components/mod.ts";
import { Signal, Computed } from "https://deno.land/x/tui@$MODULE_VERSION/mod.ts";
...
// Create signal to make number automatically reactive
const number = new Signal(0);
const button = new Button({
parent: tui,
zIndex: 0,
label: {
text: new Computed(() => number.value.toString()), // cast number to string
},
theme: {
base: crayon.bgRed,
focused: crayon.bgLightRed,
active: crayon.bgYellow,
},
rectangle: {
column: 1,
row: 1,
height: 5,
width: 10,
},
});
// If button is active (pressed) make number bigger by one
button.state.when("active", (state) => {
++number.value;
});
// Listen to mousePress event
button.on("mousePress", ({ drag, movementX, movementY }) => {
if (!drag) return;
// Use peek() to get signal's value when it happens outside of Signal/Computed/Effect
const rectangle = button.rectangle.peek();
// Move button by how much mouse has moved while dragging it
rectangle.column += movementX;
rectangle.row += movementY;
});
- Run Tui
...
tui.run();
π€ Contributing
Tui is open for any contributions. <br /> If you feel like you can enhance this project - please open an issue and/or pull request. <br /> Code should be well document and easy to follow what's going on.
This project follows conventional commits spec. <br /> If your pull request's code can be hard to understand, please add comments to it.
π Licensing
This project is available under MIT License conditions.