commit d8b622860ca3e37930c66ea2c7d2d1d6aba51597 Author: Priec Date: Mon Jun 1 20:01:15 2026 +0200 website created diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ad7c24f --- /dev/null +++ b/.gitignore @@ -0,0 +1,30 @@ +# Build artifacts +bin/ +node_modules/ +dist/ +*.min.css +*.min.js + +# Editor +.vscode/ +.idea/ +*.swp +.DS_Store + +# OS +Thumbs.db + +# Logs +*.log +npm-debug.log* + +# Env +.env +.env.local + +# Cache +.cache/ +.parcel-cache/ + +# Generated +static/css/site.compiled.css diff --git a/404.html b/404.html new file mode 100644 index 0000000..7871b2e --- /dev/null +++ b/404.html @@ -0,0 +1,77 @@ + + + + + + + + 404 — page not found · tui-pages + + + + + + + + + + + + + + + + + + +
+
+  ┌──────────────────────────────────────────┐
+  │                                          │
+  │   error: route not found                 │
+  │   errno  404                             │
+  │                                          │
+  └──────────────────────────────────────────┘
+    
+ +

+ 404 +

+

+ That route doesn't exist. Maybe the page moved, or the link is stale. +

+ + + +

+ hint: try cargo add tui-pages +

+
+ + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..206aa66 --- /dev/null +++ b/Makefile @@ -0,0 +1,32 @@ +.PHONY: help serve size validate clean + +help: ## Show this help + @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | \ + awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-12s\033[0m %s\n", $$1, $$2}' + +serve: ## Start a local static server on :8000 + @command -v python3 >/dev/null 2>&1 && \ + python3 -m http.server 8000 || \ + (command -v npx >/dev/null 2>&1 && npx --yes http-server -p 8000) || \ + echo "Install python3 or node to serve locally." + +size: ## Report file sizes + @echo "HTML:" + @find . -maxdepth 2 -name "*.html" -printf " %-30p %s bytes\n" + @echo + @echo "CSS:" + @find static/css -name "*.css" -printf " %-30p %s bytes\n" + @echo + @echo "Images (svg):" + @find static/img -name "*.svg" -printf " %-30p %s bytes\n" + +validate: ## Quick HTML sanity check (counts opening vs closing tags) + @for f in *.html; do \ + open=$(grep -oE '<[a-zA-Z][a-zA-Z0-9-]*' "$$f" | grep -vE '^<(br|hr|img|input|meta|link|source|area|base|col|embed|param|track|wbr|!--)' | sed 's/^` and the DaisyUI +``, and ensure `/static/css/site.css` is loaded last in ``. + +## File layout + +``` +tui-pages-web/ +├── index.html # landing page +├── examples.html # examples gallery +├── 404.html # not found +├── robots.txt # search engine hints +├── sitemap.xml # sitemap +├── static/ +│ ├── css/ +│ │ └── site.css # our custom layer (small) +│ ├── img/ +│ │ ├── favicon.svg +│ │ ├── logo.svg +│ │ ├── og-image.svg +│ │ ├── terminal-default.svg +│ │ ├── terminal-canvas.svg +│ │ └── terminal-keybindings.svg +│ └── demos/ # (empty — drop asciinema .cast files here) +├── content/ # (empty — markdown for blog/changelog later) +├── Makefile +├── .gitignore +└── README.md +``` + +## Adding an asciinema demo to the hero + +The hero currently shows a static SVG terminal mockup. To replace it with a +real asciinema recording: + +1. Record one of the examples: + + ```bash + cd ../komp_ac/tui-pages/examples/default + asciinema rec ../../tui-pages-web/static/demos/intro.cast + # ... run the app for a few seconds, hit ctrl-d to stop + ``` + +2. In `index.html`, replace the hero terminal block with: + + ```html +
+ +
+ ``` + +3. Add the asciinema player to the ``: + + ```html + + + ``` + +## License + +The website source is MIT-licensed. The terminal mockup SVGs in `static/img/` +are hand-drawn and original. The crate itself is at +. diff --git a/examples.html b/examples.html new file mode 100644 index 0000000..aacfd5d --- /dev/null +++ b/examples.html @@ -0,0 +1,330 @@ + + + + + + + + + + Examples — tui-pages + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + +
+ +
+ +
+ + +
+
+ +

Examples

+

+ Three apps in the box. +

+

+ Each example is a standalone cargo project under examples/ in the repo. Clone, run, read, fork. +

+
+
+ + +
+
+
+
+
+
+ examples/default TUI screenshot +
+
+
+ +
+
+ basic + no features +
+

examples/default

+

+ A multi-page app with a focusable list, page navigation, and quit. The minimal end-to-end example — the one to read first to understand the architecture. +

+ +

Run it

+
+ cargo run --example default + +
+ +

What it shows

+
    +
  • Multi-page routing with register_page
  • +
  • Focus list with movement (j k)
  • +
  • Default keymaps in action
  • +
  • Clean Runtime::run() loop
  • +
+ + + Read source + + +
+
+
+
+ + +
+
+
+
+
+
+ examples/canvas TUI screenshot +
+
+
+ +
+
+ canvas + +ratatui +
+

examples/canvas

+

+ A login form with validated inputs, a submit button, and a canvas-owned keymap. Demonstrates the canvas feature flag: GUI renderers, suggestions, cursor style, validation, computed fields, textareas, and text inputs. +

+ +

Run it

+
+ cargo run --example canvas --features canvas + +
+ +

What it shows

+
    +
  • Field-level focus with tab / shift+tab
  • +
  • Cursor style + blinking caret from canvas
  • +
  • Submit button as a focusable element
  • +
  • Validation wiring (sketch in examples/canvas)
  • +
+ + + Read source + + +
+
+
+
+ + +
+
+
+
+
+
+ examples/keybindings TUI screenshot +
+
+
+ +
+
+ dialog + +ratatui +
+

examples/keybindings

+

+ A modal showing all keybindings, opened with ?. Demonstrates the built-in dialog feature: content and result types, plus a ratatui renderer. +

+ +

Run it

+
+ cargo run --example keybindings --features dialog + +
+ +

What it shows

+
    +
  • Modal lifecycle: open, focus, close
  • +
  • Background app dimmed behind the modal
  • +
  • Custom keymaps rendered with the kbd widget
  • +
  • Dialog::Keybindings content type
  • +
+ + + Read source + + +
+
+
+
+ + +
+
+

Build your own.

+

+ The book walks you from cargo new to a working multi-page app. Or read the API reference and dive in. +

+ +
+
+
+ + +
+
+
+

© 2026 Filip Riečický. Released under the MIT License.

+

crafted with htmx + alpine + tailwind

+
+
+
+ + + + diff --git a/index.html b/index.html new file mode 100644 index 0000000..a36d52a --- /dev/null +++ b/index.html @@ -0,0 +1,712 @@ + + + + + + + + + + tui-pages — a framework for building TUIs in Rust + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Skip to content + + +
+ + + +
+ +
+
+ +
+ + +
+
+
+
+
+ + + v0.7.2 + · + MIT + · + on crates.io + + + +

+ A framework for
+ building TUIs in Rust +

+ +

+ tui-pages gives you a pre-programmed focus manager, input pipeline, keymaps, and page navigation on top of ratatui. Stop rewriting the same architecture for every project. +

+ + + + +
+ + + + cargo add tui-pages + +
+ +

or: cargo install tui-pages-cli

+
+ + +
+
+
+
+ Screenshot of the examples/default TUI app built with tui-pages +
+

examples/default · cargo run

+
+
+
+
+
+ + +
+
+
+
+
Version
+
0.7.2
+
+
+
License
+
MIT
+
+
+
Features
+
3 opt-in
+
+
+
Renderers
+
agnostic
+
+
+
+
+ + +
+
+
+

What's inside

+

+ Everything a multi-page TUI needs, already wired up. +

+

+ The crate separates the framework from your pages. You assign element IDs to a list, the framework handles the rest: focus, movement, keymaps, modal dialogs, and page navigation. +

+
+ +
+ +
+
+ +
+

Focus Manager

+

+ One global focus model. Be dumb — tell the manager what to focus, don't do it yourself. The system inside it handles library-vs-page focus conflicts. +

+
+ + +
+
+ +
+

Input Pipeline

+

+ Map type-safe Command::Save to a key chord. KeyEvents are flushed into the pipeline; you never write key matching by hand. +

+
+ + +
+
+ +
+

Page Navigation

+

+ Pages are first-class. Move between them, swap state, render any way you want. The runtime stays out of your way. +

+
+ + +
+
+ +
+

Default Keymaps

+

+ Vim-style j k gg movement and VS Code-style navigation come pre-wired. Override or extend per page. +

+
+ + +
+
+ +
+

Canvas integration

+

+ One feature flag. Enables GUI renderers, suggestions, cursor style, validation, computed fields, textareas, text inputs, and a canvas-owned keymap. +

+
+ + +
+
+ +
+

Modal Dialog

+

+ Built-in dialog with content and result types plus a ratatui renderer. Enable it, write the content, you're done. +

+
+
+
+
+ + +
+
+
+

How it works

+

+ A primitive list, a pipeline, and an executor. +

+

+ Imagine 0..n element IDs. You're at ID 1 and want to move next, so you go to 2. That's the whole abstraction. Everything else is built on top of it. +

+
+ +
    +
  1. +
    + 01 +

    KeyEvent

    +
    +

    A key binding like "ctrl+s" or a plain letter is flushed into the input pipeline.

    +
  2. +
  3. +
    + 02 +

    InputPipeline

    +
    +

    Maps a key chord to a type-safe Command::Save.

    +
  4. +
  5. +
    + 03 +

    Orchestrator

    +
    +

    Decides where the request goes. jMovement::Down → FocusManager.

    +
  6. +
  7. +
    + 04 +

    Executor

    +
    +

    Calls the page's function. Login page logs you in. The page owns its own logic.

    +
  8. +
+
+
+ + +
+
+
+

Show me the code

+

+ Three lines of focus, three lines of pages. +

+

+ Define a page with an element list, register keymaps, run the loop. The framework handles focus, movement, and routing. +

+
+ +
+ +
+ + + + +
+ + +
+ + +
+
use tui_pages::prelude::*;
+
+fn main() -> Result<(), Box<dyn std::error::Error>> {
+    // 1. Build the runtime with default keymaps and a terminal.
+    let mut rt = Runtime::new(Terminal::default())?;
+
+    // 2. Register pages. Each page owns its own focus list and logic.
+    rt.register_page("login",   pages::login::build());
+    rt.register_page("home",    pages::home::build());
+    rt.register_page("settings",pages::settings::build());
+
+    // 3. Run the main loop. Framework handles focus, movement, and routing.
+    rt.run()
+}
+
+
+ +
+
[package]
+name = "my-tui"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
+tui-pages  = "0.7"
+ratatui    = "0.29"   # only if you enable the `canvas` or `dialog` feature
+crossterm  = "0.28"
+
+# Pick what you need:
+# tui-pages = { version = "0.7", features = ["canvas"] }  # +ratatui, GUI surfaces
+# tui-pages = { version = "0.7", features = ["dialog"] }  # +ratatui, built-in dialog
+# tui-pages = { version = "0.7", features = ["serde"] }   # +serde on input/mode types
+
+
+ +
+
use tui_pages::prelude::*;
+
+/// A page is just a focus list + a render fn + an executor.
+pub fn build() -> Page {
+    Page::new("login", render, executor)
+        // Elements are 0..n. The framework moves through them for you.
+        .with_elements(|s| s
+            .input("username")
+            .input("password")
+            .button("submit"))
+        .with_focus(0)
+}
+
+fn render(f: &mut Frame, area: Rect, focus: &Focus) {
+    // Your ratatui render. The focus index is handed to you.
+    let focused = focus.current();
+    // ... draw inputs and the button, highlight `focused`
+}
+
+fn executor(cmd: Command, focus: &mut Focus, state: &mut State) -> Outcome {
+    match cmd {
+        Command::Submit => state.navigate("home"),
+        _ => Outcome::Next,
+    }
+}
+
+
+ +
+
use tui_pages::prelude::*;
+
+/// Map key chords to type-safe commands. Override defaults or add your own.
+pub fn keymaps() -> KeyMap {
+    KeyMap::new()
+        .bind("j",     Command::Move(Movement::Down))
+        .bind("k",     Command::Move(Movement::Up))
+        .bind("gg",    Command::Move(Movement::Top))
+        .bind("G",     Command::Move(Movement::Bottom))
+        .bind("enter", Command::Submit)
+        .bind("ctrl+s", Command::Save)
+        .bind("?",     Command::OpenDialog(Dialog::Keybindings))
+        .bind("q",     Command::Quit)
+}
+
+
+
+
+
+
+ + +
+ +
+ + +
+
+
+

Why

+

+ The architecture you've already written, generalized. +

+
+ +
+
+

// what most TUI code looks like

+
let mut app = App::new();
+loop {
+    app.handle_event(event);
+    app.focus.update();
+    app.ui.draw(&mut app);
+    // shared &mut references
+    // everywhere
+    // god object strikes again
+}
+
+
+

// what tui-pages looks like

+
let mut rt = Runtime::new(terminal)?;
+rt.register_page("home",    pages::home::build());
+rt.register_page("login",   pages::login::build());
+rt.register_page("settings",pages::settings::build());
+rt.run()  // framework handles the rest
+
+
+
+
+ + +
+
+

+ Build your first TUI page in the next five minutes. +

+

+ The book walks you from cargo new to a working multi-page app. Or read the API reference and dive in. +

+ +
+
+
+ + + + + + + + diff --git a/robots.txt b/robots.txt new file mode 100644 index 0000000..4b0b647 --- /dev/null +++ b/robots.txt @@ -0,0 +1,4 @@ +User-agent: * +Allow: / + +Sitemap: https://tui-pages.dev/sitemap.xml diff --git a/sitemap.xml b/sitemap.xml new file mode 100644 index 0000000..502b36c --- /dev/null +++ b/sitemap.xml @@ -0,0 +1,13 @@ + + + + https://tui-pages.dev/ + weekly + 1.0 + + + https://tui-pages.dev/examples.html + weekly + 0.9 + + diff --git a/static/css/site.css b/static/css/site.css new file mode 100644 index 0000000..524cb34 --- /dev/null +++ b/static/css/site.css @@ -0,0 +1,266 @@ +/* ========================================================================== + tui-pages website — custom layer on top of Tailwind + DaisyUI + Loaded AFTER Tailwind Play CDN compiles and DaisyUI prebuilt. + Keep this small. Tailwind utility classes do the heavy lifting. + ========================================================================== */ + +/* ---------- Smooth scroll, native feel ----------------------------------- */ +html { + scroll-behavior: smooth; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + text-rendering: optimizeLegibility; +} + +@media (prefers-reduced-motion: reduce) { + html { scroll-behavior: auto; } + *, *::before, *::after { + animation-duration: 0.001ms !important; + animation-iteration-count: 1 !important; + transition-duration: 0.001ms !important; + } +} + +/* ---------- Theme (default to dark) -------------------------------------- */ +:root { + color-scheme: dark light; + --tp-accent: #b7410e; + --tp-accent-fg: #fff5f0; + --tp-grid-line: rgba(63, 63, 70, 0.35); + --tp-hero-from: #0b0b0f; + --tp-hero-to: #18181b; +} + +:root[data-theme="light"] { + --tp-accent: #93330c; + --tp-accent-fg: #fff5f0; + --tp-grid-line: rgba(228, 228, 231, 0.7); + --tp-hero-from: #fafafa; + --tp-hero-to: #f4f4f5; +} + +/* ---------- Body --------------------------------------------------------- */ +body { + font-family: 'Inter', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif; + font-feature-settings: 'cv11', 'ss01', 'ss03'; +} + +/* ---------- View Transitions (progressive enhancement) ------------------ */ +@supports (view-transition-name: foo) { + ::view-transition-old(root), + ::view-transition-new(root) { + animation-duration: 220ms; + } +} + +/* ---------- Hero --------------------------------------------------------- */ +.tp-hero { + background: + radial-gradient(ellipse 80% 50% at 50% 0%, rgba(183, 65, 14, 0.15), transparent 70%), + linear-gradient(180deg, var(--tp-hero-from) 0%, var(--tp-hero-to) 100%); + position: relative; + isolation: isolate; +} + +.tp-hero::before { + content: ""; + position: absolute; + inset: 0; + background-image: + linear-gradient(var(--tp-grid-line) 1px, transparent 1px), + linear-gradient(90deg, var(--tp-grid-line) 1px, transparent 1px); + background-size: 56px 56px; + background-position: -1px -1px; + -webkit-mask-image: radial-gradient(ellipse 60% 50% at 50% 0%, #000 30%, transparent 80%); + mask-image: radial-gradient(ellipse 60% 50% at 50% 0%, #000 30%, transparent 80%); + pointer-events: none; + z-index: -1; +} + +/* Subtle floating code lines in the hero, behind the content */ +.tp-hero-glow { + position: absolute; + inset: 0; + pointer-events: none; + z-index: -1; + opacity: 0.6; + background: + radial-gradient(circle at 15% 30%, rgba(183, 65, 14, 0.08), transparent 35%), + radial-gradient(circle at 85% 70%, rgba(126, 231, 135, 0.05), transparent 35%); +} + +/* ---------- Cursor caret animation --------------------------------------- */ +@keyframes tp-blink { + 0%, 49% { opacity: 1; } + 50%, 100% { opacity: 0; } +} +.tp-cursor { + display: inline-block; + width: 0.55em; + height: 1em; + background: var(--tp-accent); + margin-left: 0.15em; + vertical-align: -0.12em; + animation: tp-blink 1.1s steps(1) infinite; +} + +/* ---------- Soft float for the hero terminal ----------------------------- */ +@keyframes tp-float { + 0%, 100% { transform: translateY(0); } + 50% { transform: translateY(-6px); } +} +.tp-float { + animation: tp-float 6s ease-in-out infinite; +} + +/* ---------- Glass nav ---------------------------------------------------- */ +.tp-nav { + background: rgba(9, 9, 11, 0.65); + backdrop-filter: saturate(160%) blur(12px); + -webkit-backdrop-filter: saturate(160%) blur(12px); + border-bottom: 1px solid rgba(63, 63, 70, 0.4); +} +:root[data-theme="light"] .tp-nav { + background: rgba(255, 255, 255, 0.7); + border-bottom-color: rgba(228, 228, 231, 0.7); +} + +/* ---------- Feature cards ------------------------------------------------ */ +.tp-card { + position: relative; + background: rgba(24, 24, 27, 0.5); + border: 1px solid rgba(63, 63, 70, 0.5); + border-radius: 1rem; + padding: 1.5rem; + transition: border-color 200ms ease, transform 200ms ease, background 200ms ease; +} +.tp-card:hover { + border-color: rgba(183, 65, 14, 0.6); + background: rgba(24, 24, 27, 0.75); + transform: translateY(-2px); +} +:root[data-theme="light"] .tp-card { + background: rgba(255, 255, 255, 0.6); + border-color: rgba(228, 228, 231, 0.8); +} +:root[data-theme="light"] .tp-card:hover { + background: rgba(255, 255, 255, 0.9); + border-color: rgba(183, 65, 14, 0.4); +} + +.tp-card-icon { + display: inline-flex; + align-items: center; + justify-content: center; + width: 2.5rem; + height: 2.5rem; + border-radius: 0.75rem; + background: rgba(183, 65, 14, 0.12); + color: var(--tp-accent); + border: 1px solid rgba(183, 65, 14, 0.25); + margin-bottom: 1rem; +} + +/* ---------- Code blocks (kitchen sink — hljs + custom) ------------------ */ +.tp-code { + font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace; + font-size: 0.85rem; + line-height: 1.6; + tab-size: 4; +} +.tp-code pre { + background: #0b0b0f; + border: 1px solid rgba(63, 63, 70, 0.5); + border-radius: 0.75rem; + padding: 1.25rem 1.5rem; + overflow-x: auto; + margin: 0; +} +.tp-code pre code.hljs { + background: transparent; + padding: 0; +} + +/* ---------- Inline kbd --------------------------------------------------- */ +.tp-kbd { + display: inline-flex; + align-items: center; + padding: 0.15rem 0.5rem; + font-family: 'JetBrains Mono', ui-monospace, monospace; + font-size: 0.75rem; + font-weight: 500; + border: 1px solid rgba(63, 63, 70, 0.7); + border-bottom-width: 2px; + border-radius: 0.375rem; + background: rgba(39, 39, 42, 0.6); + color: #f4f4f5; + line-height: 1; +} +:root[data-theme="light"] .tp-kbd { + background: #fff; + color: #18181b; + border-color: #d4d4d8; +} + +/* ---------- Terminal window wrapper -------------------------------------- */ +.tp-terminal { + position: relative; + border-radius: 0.875rem; + background: #0b0b0f; + box-shadow: + 0 1px 0 rgba(255, 255, 255, 0.04) inset, + 0 30px 60px -20px rgba(0, 0, 0, 0.6), + 0 18px 36px -18px rgba(0, 0, 0, 0.5); + overflow: hidden; + border: 1px solid rgba(63, 63, 70, 0.4); +} +.tp-terminal::after { + content: ""; + position: absolute; + inset: 0; + pointer-events: none; + border-radius: inherit; + box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.03); +} + +/* ---------- Selection --------------------------------------------------- */ +::selection { + background: var(--tp-accent); + color: var(--tp-accent-fg); +} + +/* ---------- Focus ring -------------------------------------------------- */ +:focus-visible { + outline: 2px solid var(--tp-accent); + outline-offset: 2px; + border-radius: 0.25rem; +} + +/* ---------- Scrollbar (subtle) ----------------------------------------- */ +::-webkit-scrollbar { width: 10px; height: 10px; } +::-webkit-scrollbar-track { background: transparent; } +::-webkit-scrollbar-thumb { + background: rgba(63, 63, 70, 0.6); + border-radius: 999px; + border: 2px solid transparent; + background-clip: padding-box; +} +::-webkit-scrollbar-thumb:hover { background-color: rgba(82, 82, 91, 0.8); background-clip: padding-box; } + +/* ---------- No-FOUC theme flash ----------------------------------------- */ +html:not([data-theme]) body { background: #09090b; } +:root[data-theme="light"] body { background: #fafafa; } + +/* ---------- Alpine x-cloak (prevents flash of un-initialised content) --- */ +[x-cloak] { display: none !important; } + +/* ---------- DaisyUI overrides for our theme ----------------------------- */ +/* Bring DaisyUI's primary to our accent so .btn-primary etc. look on-brand. */ +[data-theme="night"] { + --p: 28 70% 36%; + --pc: 0 0% 100%; + --b1: 240 5% 8%; + --b2: 240 4% 12%; + --b3: 240 4% 16%; + --bc: 0 0% 96%; +} diff --git a/static/img/favicon.svg b/static/img/favicon.svg new file mode 100644 index 0000000..ae83750 --- /dev/null +++ b/static/img/favicon.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/static/img/logo.svg b/static/img/logo.svg new file mode 100644 index 0000000..8f4417f --- /dev/null +++ b/static/img/logo.svg @@ -0,0 +1,11 @@ + + + tui-pages + + + + + diff --git a/static/img/og-image.svg b/static/img/og-image.svg new file mode 100644 index 0000000..7dcfcb1 --- /dev/null +++ b/static/img/og-image.svg @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + tui-pages + + + + + A framework for + + + building TUIs in Rust. + + + + Pre-programmed focus, keymaps, and page navigation. + + + Stop rewriting the same architecture for every project. + + + + + $ cargo add tui-pages + + diff --git a/static/img/terminal-canvas.svg b/static/img/terminal-canvas.svg new file mode 100644 index 0000000..3bf6814 --- /dev/null +++ b/static/img/terminal-canvas.svg @@ -0,0 +1,52 @@ + + + + + + + + + + + + + examples/canvas — login page + + Sign in + Use Tab to move between fields. Enter to submit. + + USERNAME + + filip + + + + + PASSWORD + + •••••••••••• + + + Sign in + esc · cancel + + + tab next · shift+tab prev · enter submit + canvas feature enabled + diff --git a/static/img/terminal-default.svg b/static/img/terminal-default.svg new file mode 100644 index 0000000..8bba8f0 --- /dev/null +++ b/static/img/terminal-default.svg @@ -0,0 +1,57 @@ + + + + + + + + + + + + + examples/default — cargo run + + Pages: + + Home + Settings + About + Quit + + + + Home + Choose a section to open. + + + + + + ▸ Dashboard + enter + + Accounts + Transactions + Reports + Settings + + + + ↑↓ move · enter select · q quit + tui-pages v0.7.2 + diff --git a/static/img/terminal-keybindings.svg b/static/img/terminal-keybindings.svg new file mode 100644 index 0000000..8b3bc39 --- /dev/null +++ b/static/img/terminal-keybindings.svg @@ -0,0 +1,71 @@ + + + + + + + + + + + + + examples/keybindings — modal open + + + ▸ Accounts + Transactions + Reports + Settings + Press ? for help + + + + Keybindings + + + MOVEMENT + + j + move down + + + k + move up + + + gg + top of list + + ACTIONS + + enter + select + + + / + search + + + ctrl+s + save + + + press esc to close + + + esc close · ? toggle this dialog + dialog feature enabled +