Home

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" />

Deno Deno doc

Simple Deno module that allows easy creation of Terminal User Interfaces.

πŸ”© Features

πŸ–₯️ OS Support

Operating systemLinuxmacOSWindowsΒΉWSL
Baseβœ”οΈβœ”οΈβœ”οΈβœ”οΈ
Keyboard supportβœ”οΈβœ”οΈβœ”οΈβœ”οΈ
Mouse supportβœ”οΈβœ”οΈβœ”οΈβœ”οΈ
Required permissionsnonenonenonenone

ΒΉ - 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

  1. 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
  1. 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);
  1. 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;
});
  1. 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.