⌨️ Tui

Deno mascot made as ASCII art

Deno Deno doc

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 --unstable --allow-ffiΒ³ none

ΒΉ - WSL is a heavily recommended way to run Tui on Windows, if you need to stick to clean Windows, please consider using Windows Terminal.

Β² - If unicode characters are displayed incorrectly type chcp 65001 into the console to change active console code page to use UTF-8 encoding.

Β³ - Related to this issue, in order to recognize all pressed keys (including arrows etc.) on Windows Tui uses C:\Windows\System32\msvcrt.dll to read pressed keys via _getch function, see code here.

πŸŽ“ Get started

  1. Create Tui instance
import { crayon } from "https://deno.land/x/crayon@3.3.2/mod.ts";
import { Canvas, Tui } from "https://deno.land/x/tui@version/mod.ts";

const tui = new Tui({
  style: crayon.bgBlue,
  canvas: new Canvas({
    refreshRate: 1000 / 60, // Run in 60FPS
    stdout: Deno.stdout,
  }),
});

tui.dispatch(); // Close Tui on CTRL+C
  1. Enable interaction using keyboard and mouse
import { handleKeyboardControls, handleKeypresses, handleMouseControls } from "https://deno.land/x/tui@version/mod.ts";

...

handleKeypresses(tui);
handleMouseControls(tui);
handleKeyboardControls(tui);
  1. Add some components
import { ButtonComponent } from "https://deno.land/x/tui@version/src/components/mod.ts";

...

let value = 0;
const button = new ButtonComponent({
  tui,
  theme: {
    base: crayon.bgRed,
    focused: crayon.bgLightRed,
    active: crayon.bgYellow,
  },
  rectangle: {
    column: 15,
    row: 3,
    height: 5,
    width: 10,
  },
  label: String(value),
});

button.on("stateChange", () => {
  if (button.state !== "active") return;
  button.label = String(++value);
})
  1. Run Tui
...

tui.run();

🀝 Contributing

Tui is open for any contributions.
If you feel like you can enhance this project - please open an issue and/or pull request.
Code should be well document and easy to follow what's going on.

This project follows conventional commits spec.
If your pull request's code could introduce understandability trouble, please add comments to it.

πŸ“ Licensing

This project is available under MIT License conditions.