├── .gitattributes ├── .github ├── dependabot.yml └── workflows │ ├── check-pr.yml │ ├── npm-ci.yml │ └── rust-ci.yml ├── .gitignore ├── .husky ├── post-checkout ├── post-commit ├── post-merge └── pre-push ├── .markdownlint.yaml ├── .mise.toml ├── .node-version ├── .prettierrc ├── .rustfmt.toml ├── .vscode └── settings.json ├── Cargo.lock ├── Cargo.toml ├── LICENSE.md ├── NOTICES ├── README.md ├── astro.config.mjs ├── bacon.toml ├── code ├── concepts │ └── the-elm-architecture │ │ ├── Cargo.toml │ │ └── src │ │ └── main.rs ├── examples │ └── ratatui-examples │ │ ├── Cargo.toml │ │ ├── README.md │ │ ├── examples │ │ ├── README.md │ │ ├── async.rs │ │ ├── barchart-grouped.rs │ │ ├── barchart.rs │ │ ├── block.rs │ │ ├── calendar.rs │ │ ├── canvas.rs │ │ ├── chart.rs │ │ ├── colors.rs │ │ ├── colors_rgb.rs │ │ ├── constraint-explorer.rs │ │ ├── constraints.rs │ │ ├── custom_widget.rs │ │ ├── demo │ │ │ ├── app.rs │ │ │ ├── crossterm.rs │ │ │ ├── main.rs │ │ │ ├── termion.rs │ │ │ ├── termwiz.rs │ │ │ └── ui.rs │ │ ├── demo2 │ │ │ ├── app.rs │ │ │ ├── colors.rs │ │ │ ├── destroy.rs │ │ │ ├── main.rs │ │ │ ├── tabs.rs │ │ │ ├── tabs │ │ │ │ ├── about.rs │ │ │ │ ├── email.rs │ │ │ │ ├── recipe.rs │ │ │ │ ├── traceroute.rs │ │ │ │ └── weather.rs │ │ │ └── theme.rs │ │ ├── docsrs.rs │ │ ├── flex.rs │ │ ├── gauge.rs │ │ ├── hello_world.rs │ │ ├── hyperlink.rs │ │ ├── inline.rs │ │ ├── layout.rs │ │ ├── line_gauge.rs │ │ ├── list.rs │ │ ├── minimal.rs │ │ ├── modifiers.rs │ │ ├── panic.rs │ │ ├── paragraph.rs │ │ ├── popup.rs │ │ ├── ratatui-logo.rs │ │ ├── scrollbar.rs │ │ ├── sparkline.rs │ │ ├── table.rs │ │ ├── tabs.rs │ │ ├── tracing.rs │ │ ├── user_input.rs │ │ ├── vhs │ │ │ ├── barchart-grouped.tape │ │ │ ├── barchart.tape │ │ │ ├── block.tape │ │ │ ├── calendar.tape │ │ │ ├── canvas.tape │ │ │ ├── chart.tape │ │ │ ├── colors.tape │ │ │ ├── colors_rgb.tape │ │ │ ├── constraint-explorer.tape │ │ │ ├── constraints.tape │ │ │ ├── custom_widget.tape │ │ │ ├── demo.tape │ │ │ ├── demo2-destroy.tape │ │ │ ├── demo2-social.tape │ │ │ ├── demo2.tape │ │ │ ├── docsrs.tape │ │ │ ├── flex.tape │ │ │ ├── gauge.tape │ │ │ ├── generate.bash │ │ │ ├── hello_world.tape │ │ │ ├── hyperlink.tape │ │ │ ├── inline.tape │ │ │ ├── layout.tape │ │ │ ├── line_gauge.tape │ │ │ ├── list.tape │ │ │ ├── minimal.tape │ │ │ ├── modifiers.tape │ │ │ ├── panic.tape │ │ │ ├── paragraph.tape │ │ │ ├── popup.tape │ │ │ ├── ratatui-logo.tape │ │ │ ├── scrollbar.tape │ │ │ ├── sparkline.tape │ │ │ ├── table.tape │ │ │ ├── tabs.tape │ │ │ ├── tracing.tape │ │ │ └── user_input.tape │ │ └── widget_impl.rs │ │ └── src │ │ └── lib.rs ├── recipes │ ├── how-to-collapse-borders │ │ ├── Cargo.toml │ │ ├── problem.tape │ │ ├── solution.tape │ │ └── src │ │ │ └── bin │ │ │ ├── problem.rs │ │ │ └── solution.rs │ ├── how-to-color_eyre │ │ ├── Cargo.toml │ │ ├── demo.tape │ │ ├── error-full.tape │ │ ├── error.tape │ │ ├── panic-full.tape │ │ ├── panic.tape │ │ ├── quit.tape │ │ └── src │ │ │ ├── main.rs │ │ │ └── tui.rs │ ├── how-to-misc │ │ ├── Cargo.toml │ │ ├── README.md │ │ └── src │ │ │ ├── layout.rs │ │ │ └── lib.rs │ ├── how-to-overwrite-regions │ │ ├── Cargo.toml │ │ ├── problem.tape │ │ ├── solution.tape │ │ └── src │ │ │ └── bin │ │ │ ├── problem.rs │ │ │ └── solution.rs │ ├── how-to-panic-hooks │ │ ├── Cargo.toml │ │ └── src │ │ │ └── bin │ │ │ ├── crossterm.rs │ │ │ └── termion.rs │ └── how-to-spawn-vim │ │ ├── Cargo.toml │ │ └── src │ │ └── main.rs ├── showcase │ ├── widget-showcase-third-party │ │ ├── README.md │ │ ├── csvlens.tape │ │ ├── throbber-widgets-tui.tape │ │ ├── tui-nodes.tape │ │ ├── tui-textarea.tape │ │ ├── tui-tree-widget.tape │ │ └── tui-widget-list.tape │ └── widget-showcase │ │ ├── Cargo.toml │ │ ├── README.md │ │ ├── bar_chart.tape │ │ ├── block.tape │ │ ├── calendar.tape │ │ ├── canvas.tape │ │ ├── chart.tape │ │ ├── gauge.tape │ │ ├── line_gauge.tape │ │ ├── list.tape │ │ ├── paragraph.tape │ │ ├── scrollbar.tape │ │ ├── sparkline.tape │ │ ├── src │ │ ├── examples.rs │ │ ├── examples │ │ │ ├── bar_chart.rs │ │ │ ├── block.rs │ │ │ ├── calendar.rs │ │ │ ├── canvas.rs │ │ │ ├── chart.rs │ │ │ ├── gauge.rs │ │ │ ├── line_gauge.rs │ │ │ ├── list.rs │ │ │ ├── paragraph.rs │ │ │ ├── scrollbar.rs │ │ │ ├── sparkline.rs │ │ │ ├── table.rs │ │ │ └── tabs.rs │ │ ├── main.rs │ │ └── tui.rs │ │ ├── table.tape │ │ └── tabs.tape ├── templates │ └── async-template-counter │ │ ├── .config │ │ └── config.json5 │ │ ├── .envrc │ │ ├── .gitignore │ │ ├── .rustfmt.toml │ │ ├── Cargo.toml │ │ ├── LICENSE │ │ ├── README.md │ │ ├── build.rs │ │ ├── rust-toolchain.toml │ │ └── src │ │ ├── action.rs │ │ ├── app.rs │ │ ├── cli.rs │ │ ├── components.rs │ │ ├── components │ │ ├── fps.rs │ │ └── home.rs │ │ ├── config.rs │ │ ├── main.rs │ │ ├── tui.rs │ │ └── utils.rs └── tutorials │ ├── counter-app-basic │ ├── Cargo.toml │ ├── basic-app-error.tape │ ├── basic-app.tape │ └── src │ │ └── main.rs │ ├── counter-app-error-handling │ ├── Cargo.toml │ ├── error-full.tape │ ├── error.tape │ ├── generate-demos.sh │ ├── panic-full.tape │ ├── panic.tape │ └── src │ │ ├── main.rs │ │ └── tui.rs │ ├── hello-ratatui.png │ ├── hello-ratatui.tape │ ├── hello-ratatui │ ├── .github │ │ ├── dependabot.yml │ │ └── workflows │ │ │ └── ci.yml │ ├── Cargo.toml │ ├── LICENSE │ ├── README.md │ └── src │ │ └── main.rs │ ├── hello.gif │ ├── json-editor │ ├── .cz.toml │ ├── Cargo.toml │ ├── demo.tape │ ├── shell.nix │ └── src │ │ ├── app.rs │ │ ├── main.rs │ │ └── ui.rs │ ├── quickstart-ratatui │ ├── Cargo.toml │ └── src │ │ └── main.rs │ ├── ratatui-counter-app │ ├── .gitignore │ ├── Cargo.toml │ ├── LICENSE │ └── src │ │ ├── app.rs │ │ ├── event.rs │ │ ├── main.rs │ │ ├── tui.rs │ │ ├── ui.rs │ │ └── update.rs │ ├── ratatui-counter-async-app │ ├── Cargo.toml │ └── src │ │ ├── main.rs │ │ └── tui.rs │ └── ratatui-stopwatch-app │ ├── Cargo.toml │ └── src │ └── main.rs ├── package-lock.json ├── package.json ├── public ├── csvlens.gif ├── favicon-32.png └── ratatui-og.png ├── src ├── assets │ ├── hero-dark.png │ ├── hero-dark.xcf │ ├── hero-light.png │ ├── hero-light.xcf │ ├── logo-dark.png │ ├── logo-light.png │ ├── logo.xcf │ ├── ratatui-animation.gif │ ├── ratatui.png │ └── ratatui.webp ├── components │ ├── Head.astro │ ├── Header.astro │ ├── LinkBadge.astro │ ├── fluid-grid.astro │ ├── media-card.astro │ ├── youtube-card.astro │ └── youtube-grid.astro ├── content │ ├── config.ts │ └── docs │ │ ├── concepts │ │ ├── application-patterns │ │ │ ├── component-architecture.md │ │ │ ├── flux-architecture.md │ │ │ ├── index.md │ │ │ └── the-elm-architecture.md │ │ ├── backends │ │ │ ├── alternate-screen.md │ │ │ ├── comparison.md │ │ │ ├── index.md │ │ │ ├── mouse-capture.md │ │ │ └── raw-mode.md │ │ ├── builder-lite-pattern.md │ │ ├── event-handling.md │ │ ├── index.md │ │ ├── layout.md │ │ ├── rendering │ │ │ ├── index.md │ │ │ └── under-the-hood.md │ │ ├── storing-state.md │ │ └── widgets.md │ │ ├── developer-guide │ │ ├── git-guide.md │ │ ├── github-update.png │ │ ├── index.md │ │ ├── ratatui.md │ │ └── website.mdx │ │ ├── examples │ │ ├── Apps │ │ │ ├── constraints.gif │ │ │ ├── demo.gif │ │ │ ├── demo.md │ │ │ ├── demo2-about.png │ │ │ ├── demo2-destroy.gif │ │ │ ├── demo2-email.png │ │ │ ├── demo2-recipe.png │ │ │ ├── demo2-social.gif │ │ │ ├── demo2-trace.png │ │ │ ├── demo2-weather.png │ │ │ ├── demo2.gif │ │ │ ├── demo2.md │ │ │ ├── docsrs-hello.png │ │ │ ├── docsrs-layout.png │ │ │ ├── docsrs-styling.png │ │ │ ├── docsrs.gif │ │ │ ├── docsrs.md │ │ │ ├── hello_world.gif │ │ │ ├── hello_world.md │ │ │ ├── index.mdx │ │ │ ├── inline.gif │ │ │ ├── inline.md │ │ │ ├── minimal.gif │ │ │ ├── minimal.md │ │ │ ├── panic.gif │ │ │ ├── panic.md │ │ │ ├── popup.gif │ │ │ ├── popup.md │ │ │ ├── ratatui-logo.gif │ │ │ ├── ratatui-logo.md │ │ │ ├── user_input.gif │ │ │ └── user_input.md │ │ ├── Layout │ │ │ ├── constraint-explorer.gif │ │ │ ├── constraint-explorer.md │ │ │ ├── constraints.gif │ │ │ ├── constraints.md │ │ │ ├── flex.gif │ │ │ ├── flex.md │ │ │ ├── index.mdx │ │ │ ├── layout.gif │ │ │ └── layout.md │ │ ├── Style │ │ │ ├── colors.gif │ │ │ ├── colors.md │ │ │ ├── colors_rgb.gif │ │ │ ├── colors_rgb.md │ │ │ ├── colors_rgb.mov │ │ │ ├── colors_rgb.png │ │ │ ├── index.mdx │ │ │ ├── modifiers.gif │ │ │ └── modifiers.md │ │ ├── Widgets │ │ │ ├── barchart.gif │ │ │ ├── barchart.md │ │ │ ├── block.gif │ │ │ ├── block.md │ │ │ ├── calendar.gif │ │ │ ├── calendar.md │ │ │ ├── canvas.gif │ │ │ ├── canvas.md │ │ │ ├── chart.gif │ │ │ ├── chart.md │ │ │ ├── custom_widget.gif │ │ │ ├── custom_widget.md │ │ │ ├── gauge.gif │ │ │ ├── gauge.md │ │ │ ├── index.mdx │ │ │ ├── line_gauge.gif │ │ │ ├── list.gif │ │ │ ├── list.md │ │ │ ├── paragraph.gif │ │ │ ├── paragraph.md │ │ │ ├── scrollbar.gif │ │ │ ├── scrollbar.md │ │ │ ├── sparkline.gif │ │ │ ├── sparkline.md │ │ │ ├── table.gif │ │ │ ├── table.md │ │ │ ├── tabs.gif │ │ │ └── tabs.md │ │ └── index.mdx │ │ ├── faq.md │ │ ├── highlights │ │ ├── constraint-explorer.gif │ │ ├── index.md │ │ ├── v0.21.md │ │ ├── v0.22.md │ │ ├── v0.23.md │ │ ├── v0.24.md │ │ ├── v0.25.md │ │ ├── v0.26.2.md │ │ ├── v0.26.3.md │ │ ├── v0.26.md │ │ ├── v0.27.md │ │ ├── v0.28.md │ │ └── v0.29.md │ │ ├── index.mdx │ │ ├── installation │ │ ├── feature-flags.md │ │ └── index.md │ │ ├── recipes │ │ ├── apps │ │ │ ├── better-panic.md │ │ │ ├── cli-arguments.md │ │ │ ├── color-eyre.md │ │ │ ├── color-eyre │ │ │ │ ├── demo.gif │ │ │ │ ├── error-full.gif │ │ │ │ ├── error-full.png │ │ │ │ ├── error.gif │ │ │ │ ├── error.png │ │ │ │ ├── panic-full.gif │ │ │ │ ├── panic-full.png │ │ │ │ ├── panic.gif │ │ │ │ ├── panic.png │ │ │ │ ├── quit.gif │ │ │ │ └── quit.png │ │ │ ├── config-directories.md │ │ │ ├── index.md │ │ │ ├── log-with-tracing.md │ │ │ ├── migrate-from-tui-rs.md │ │ │ ├── panic-hooks.md │ │ │ ├── release-your-app.md │ │ │ ├── spawn-vim.md │ │ │ └── terminal-and-event-handler.md │ │ ├── index.md │ │ ├── layout │ │ │ ├── center-a-widget.md │ │ │ ├── collapse-borders.md │ │ │ ├── dynamic.md │ │ │ └── index.md │ │ ├── render │ │ │ ├── display-text.md │ │ │ ├── index.md │ │ │ ├── overwrite-regions.md │ │ │ └── style-text.md │ │ ├── testing │ │ │ └── snapshots.md │ │ └── widgets │ │ │ ├── block.md │ │ │ ├── custom.md │ │ │ ├── index.md │ │ │ └── paragraph.md │ │ ├── references.md │ │ ├── showcase │ │ ├── apps.md │ │ ├── index.mdx │ │ ├── third-party-widgets.mdx │ │ ├── third-party-widgets │ │ │ ├── throbber-widgets-tui.gif │ │ │ ├── tui-big-text.png │ │ │ ├── tui-logger.png │ │ │ ├── tui-menu.png │ │ │ ├── tui-nodes.gif │ │ │ ├── tui-term.gif │ │ │ ├── tui-textarea.gif │ │ │ ├── tui-treeview.gif │ │ │ └── tui-widget-list.gif │ │ ├── widgets.mdx │ │ └── widgets │ │ │ ├── bar_chart.gif │ │ │ ├── bar_chart.png │ │ │ ├── block.gif │ │ │ ├── block.png │ │ │ ├── calendar.gif │ │ │ ├── calendar.png │ │ │ ├── canvas.png │ │ │ ├── chart.gif │ │ │ ├── chart.png │ │ │ ├── gauge.gif │ │ │ ├── gauge.png │ │ │ ├── line_gauge.gif │ │ │ ├── line_gauge.png │ │ │ ├── list.png │ │ │ ├── paragraph.gif │ │ │ ├── paragraph.png │ │ │ ├── scrollbar.gif │ │ │ ├── scrollbar.png │ │ │ ├── sparkline.gif │ │ │ ├── sparkline.png │ │ │ ├── table.gif │ │ │ ├── table.png │ │ │ ├── tabs.gif │ │ │ ├── tabs.png │ │ │ ├── throbber-widgets-tui.gif │ │ │ ├── tui-big-text.png │ │ │ ├── tui-nodes.gif │ │ │ ├── tui-term.gif │ │ │ ├── tui-textarea.gif │ │ │ ├── tui-treeview.gif │ │ │ └── tui-widget-list.gif │ │ ├── templates │ │ ├── component │ │ │ ├── action-rs.md │ │ │ ├── app-rs.md │ │ │ ├── components-home-rs.md │ │ │ ├── components-rs.md │ │ │ ├── config-rs.md │ │ │ ├── index.md │ │ │ ├── main-rs.md │ │ │ ├── project-structure.md │ │ │ ├── tui-rs.md │ │ │ └── utils-rs.md │ │ └── index.md │ │ └── tutorials │ │ ├── counter-app │ │ ├── _TODO.md │ │ ├── _multiple-files │ │ │ ├── app.md │ │ │ ├── event.md │ │ │ ├── index.md │ │ │ ├── main.md │ │ │ ├── tui.md │ │ │ ├── ui.md │ │ │ └── update.md │ │ ├── _multiple-functions.md │ │ ├── basic-app-error.gif │ │ ├── basic-app-error.png │ │ ├── basic-app.gif │ │ ├── basic-app.md │ │ ├── basic-app.png │ │ ├── error-full.gif │ │ ├── error-full.png │ │ ├── error-handling.md │ │ ├── error.gif │ │ ├── error.png │ │ ├── index.md │ │ ├── panic-full.gif │ │ ├── panic-full.png │ │ ├── panic.gif │ │ └── panic.png │ │ ├── counter-async-app │ │ ├── actions.md │ │ ├── async-event-stream.md │ │ ├── async-increment-decrement.md │ │ ├── conclusion.md │ │ ├── full-async-actions.md │ │ ├── full-async-events.md │ │ ├── index.md │ │ └── sync-increment-decrement.md │ │ ├── hello-ratatui │ │ ├── hello-ratatui.gif │ │ ├── hello-ratatui.png │ │ └── index.md │ │ ├── index.md │ │ ├── json-editor │ │ ├── app.md │ │ ├── closing-thoughts.md │ │ ├── index.md │ │ ├── main.md │ │ ├── ui-editing.md │ │ ├── ui-exit.md │ │ ├── ui-main.md │ │ └── ui.md │ │ └── videos.mdx ├── env.d.ts ├── plugins │ ├── collapsible-frames.mjs │ ├── remark-code-import.test.ts │ └── remark-code-import.ts └── tailwind.css ├── tailwind.config.mjs ├── tsconfig.json ├── typos.toml └── vitest.config.ts /.gitattributes: -------------------------------------------------------------------------------- 1 | *.png filter=lfs diff=lfs merge=lfs -text 2 | *.gif filter=lfs diff=lfs merge=lfs -text 3 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "github-actions" 9 | directory: "/" 10 | schedule: 11 | interval: "weekly" 12 | - package-ecosystem: "npm" 13 | directory: "/" 14 | schedule: 15 | interval: "weekly" 16 | groups: 17 | npm-dependencies: 18 | patterns: ["*"] 19 | - package-ecosystem: "cargo" 20 | directory: "/" 21 | schedule: 22 | interval: "weekly" 23 | groups: 24 | cargo-dependencies: 25 | patterns: ["*"] 26 | -------------------------------------------------------------------------------- /.github/workflows/check-pr.yml: -------------------------------------------------------------------------------- 1 | name: Check PR 2 | 3 | on: 4 | pull_request: 5 | branches: 6 | - main 7 | merge_group: 8 | 9 | # ensure that the workflow is only triggered once per PR, subsequent pushes to the PR will cancel 10 | # and restart the workflow. See https://docs.github.com/en/actions/using-jobs/using-concurrency 11 | concurrency: 12 | group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} 13 | cancel-in-progress: true 14 | 15 | jobs: 16 | check-lfs: 17 | runs-on: ubuntu-latest 18 | steps: 19 | - name: Checkout 20 | uses: nschloe/action-cached-lfs-checkout@v1 21 | - name: Get images 22 | run: 23 | find . -regextype posix-awk -regex ".*\.(png|gif)" -type f | cut -d"/" -f2- | sort > 24 | /tmp/images 25 | - name: Get lfs files 26 | run: git lfs ls-files | cut -d" " -f3 | sort > /tmp/lfs-files 27 | - name: Diff 28 | run: diff --color=always /tmp/images /tmp/lfs-files 29 | -------------------------------------------------------------------------------- /.github/workflows/npm-ci.yml: -------------------------------------------------------------------------------- 1 | name: Npm CI 2 | 3 | on: 4 | # Allows you to run this workflow manually from the Actions tab 5 | workflow_dispatch: 6 | push: 7 | branches: 8 | - main 9 | pull_request: 10 | branches: 11 | - main 12 | merge_group: 13 | 14 | # ensure that the workflow is only triggered once per PR, subsequent pushes to the PR will cancel 15 | # and restart the workflow. See https://docs.github.com/en/actions/using-jobs/using-concurrency 16 | concurrency: 17 | group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} 18 | cancel-in-progress: true 19 | 20 | jobs: 21 | check: 22 | runs-on: ubuntu-latest 23 | steps: 24 | - name: Checkout 25 | uses: actions/checkout@v4 26 | - name: Install 27 | run: npm ci 28 | - name: Check 29 | run: npm run astro check 30 | 31 | build: 32 | runs-on: ubuntu-latest 33 | steps: 34 | # We use this action because github counts LFS bandwidth from CI. 35 | # This action caches LFS downloads. 36 | # See https://github.com/actions/checkout/issues/165 37 | # If it ends up using too much bandwidth anyway, just delete this check. 38 | - name: Checkout 39 | uses: nschloe/action-cached-lfs-checkout@v1 40 | - name: Install 41 | run: npm ci 42 | - name: Build 43 | run: npm run astro build 44 | 45 | format: 46 | runs-on: ubuntu-latest 47 | steps: 48 | - name: Checkout 49 | uses: actions/checkout@v4 50 | - name: Install 51 | run: npm ci 52 | - name: Check format 53 | run: npm run format:check 54 | -------------------------------------------------------------------------------- /.github/workflows/rust-ci.yml: -------------------------------------------------------------------------------- 1 | name: Rust CI 2 | 3 | on: 4 | # Allows you to run this workflow manually from the Actions tab 5 | workflow_dispatch: 6 | push: 7 | branches: 8 | - main 9 | pull_request: 10 | branches: 11 | - main 12 | merge_group: 13 | 14 | # ensure that the workflow is only triggered once per PR, subsequent pushes to the PR will cancel 15 | # and restart the workflow. See https://docs.github.com/en/actions/using-jobs/using-concurrency 16 | concurrency: 17 | group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} 18 | cancel-in-progress: true 19 | 20 | jobs: 21 | fmt: 22 | runs-on: ubuntu-latest 23 | steps: 24 | - name: Checkout 25 | uses: actions/checkout@v4 26 | - name: Install Rust nightly 27 | uses: dtolnay/rust-toolchain@stable 28 | with: 29 | components: rustfmt 30 | 31 | - name: Check formatting 32 | run: cargo fmt --all --check 33 | 34 | typos: 35 | runs-on: ubuntu-latest 36 | steps: 37 | - name: Checkout 38 | uses: actions/checkout@v4 39 | - name: Check typos 40 | uses: crate-ci/typos@master 41 | 42 | clippy: 43 | runs-on: ubuntu-latest 44 | steps: 45 | - name: Checkout 46 | uses: actions/checkout@v4 47 | - name: Install Rust stable 48 | uses: dtolnay/rust-toolchain@stable 49 | with: 50 | components: clippy 51 | 52 | - name: Run cargo clippy 53 | run: cargo clippy -- -D warnings 54 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # build output 2 | dist/ 3 | # generated types 4 | .astro/ 5 | 6 | # dependencies 7 | node_modules/ 8 | 9 | # logs 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | pnpm-debug.log* 14 | 15 | # environment variables 16 | .env 17 | .env.production 18 | 19 | # macOS-specific files 20 | .DS_Store 21 | 22 | code/**/target 23 | target 24 | -------------------------------------------------------------------------------- /.husky/post-checkout: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | command -v git-lfs >/dev/null 2>&1 || { echo >&2 "\nThis repository is configured for Git LFS but 'git-lfs' was not found on your path. If you no longer wish to use Git LFS, remove this hook by deleting the 'post-checkout' file in the hooks directory (set by 'core.hookspath'; usually '.git/hooks').\n"; exit 2; } 3 | git lfs post-checkout "$@" 4 | -------------------------------------------------------------------------------- /.husky/post-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | command -v git-lfs >/dev/null 2>&1 || { echo >&2 "\nThis repository is configured for Git LFS but 'git-lfs' was not found on your path. If you no longer wish to use Git LFS, remove this hook by deleting the 'post-commit' file in the hooks directory (set by 'core.hookspath'; usually '.git/hooks').\n"; exit 2; } 3 | git lfs post-commit "$@" 4 | -------------------------------------------------------------------------------- /.husky/post-merge: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | command -v git-lfs >/dev/null 2>&1 || { echo >&2 "\nThis repository is configured for Git LFS but 'git-lfs' was not found on your path. If you no longer wish to use Git LFS, remove this hook by deleting the 'post-merge' file in the hooks directory (set by 'core.hookspath'; usually '.git/hooks').\n"; exit 2; } 3 | git lfs post-merge "$@" 4 | -------------------------------------------------------------------------------- /.husky/pre-push: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | command -v git-lfs >/dev/null 2>&1 || { echo >&2 "\nThis repository is configured for Git LFS but 'git-lfs' was not found on your path. If you no longer wish to use Git LFS, remove this hook by deleting the 'pre-push' file in the hooks directory (set by 'core.hookspath'; usually '.git/hooks').\n"; exit 2; } 3 | git lfs pre-push "$@" 4 | -------------------------------------------------------------------------------- /.markdownlint.yaml: -------------------------------------------------------------------------------- 1 | # SUMMARY.md uses h1 to indicate the section title 2 | # See https://github.com/DavidAnson/markdownlint/blob/main/doc/md025.md 3 | single-h1: false 4 | line-length: 5 | line_length: 100 6 | code_blocks: false # we have some blocks that show the output of commands that are long 7 | 8 | # SUMMARY.md uses empty links to show table of contents items that are not yet implemented 9 | no-empty-links: false 10 | 11 | no-inline-html: 12 | allowed_elements: 13 | - img # we display the logo using an img tag, so it can be floated beside the text 14 | - iframe # for youtube vids 15 | - div # for example output 16 | - p # for example output 17 | - span # for example output 18 | - details 19 | - summary 20 | -------------------------------------------------------------------------------- /.mise.toml: -------------------------------------------------------------------------------- 1 | [tools] 2 | node = "22" 3 | -------------------------------------------------------------------------------- /.node-version: -------------------------------------------------------------------------------- 1 | 22.12.0 2 | -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "useTabs": false, 3 | "quoteProps": "preserve", 4 | "singleQuote": false, 5 | "trailingComma": "all", 6 | "printWidth": 100, 7 | "tabWidth": 2, 8 | "bracketSameLine": false, 9 | "bracketSpacing": true, 10 | "proseWrap": "always", 11 | "plugins": [ 12 | "prettier-plugin-astro", 13 | "prettier-plugin-svelte", 14 | "prettier-plugin-organize-imports", 15 | "prettier-plugin-tailwindcss" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /.rustfmt.toml: -------------------------------------------------------------------------------- 1 | # While it's tempting to add our own stylistic choices here, for the most part we use the defaults 2 | # rather than configuring specific values. This is because the defaults are generally fairly good, 3 | # and they will align with what people see in the wild. We should only add config options if they 4 | # make the code more readable, and if they are available in rust stable. 5 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.defaultFormatter": "esbenp.prettier-vscode", 3 | "[mdx]": { 4 | "editor.defaultFormatter": "esbenp.prettier-vscode" 5 | }, 6 | "[javascript]": { 7 | "editor.defaultFormatter": "esbenp.prettier-vscode" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | # See https://doc.rust-lang.org/cargo/reference/workspaces.html 2 | [workspace] 3 | members = [ 4 | "code/examples/*", 5 | "code/recipes/*", 6 | "code/showcase/*", 7 | "code/tutorials/*", 8 | ] 9 | exclude = [ 10 | "code/showcase/widget-showcase-third-party", # only contains VHS tape files 11 | ] 12 | resolver = "2" 13 | 14 | [workspace.package] 15 | version = "0.0.0" 16 | authors = ["The Ratatui Developers"] 17 | description = "Sample code for the Ratatui book" 18 | documentation = "https://docs.rs/ratatui/latest/ratatui/" 19 | repository = "https://github.com/ratatui/ratatui" 20 | keywords = ["tui", "terminal", "dashboard"] 21 | license = "MIT" 22 | edition = "2021" 23 | rust-version = "1.74.0" 24 | publish = false 25 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # The MIT License 2 | 3 | Copyright (c) 2023 Ratatui Developers 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and 6 | associated documentation files (the "Software"), to deal in the Software without restriction, 7 | including without limitation the rights to use, copy, modify, merge, publish, distribute, 8 | sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all copies or substantial 12 | portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT 15 | NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 16 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES 17 | OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | -------------------------------------------------------------------------------- /NOTICES: -------------------------------------------------------------------------------- 1 | # NOTICES 2 | 3 | This file contains a list of open source components used in this project 4 | 5 | ## Starlight 6 | 7 | Components copied from are MIT licensed. 8 | 9 | MIT License 10 | 11 | Copyright (c) 2023 [Astro contributors](https://github.com/withastro/starlight/graphs/contributors) 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in all 21 | copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 28 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 29 | SOFTWARE. 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Ratatui Website 2 | 3 | ratatui logo 4 | 5 | This is the website for [Ratatui](https://github.com/ratatui/ratatui), a Rust crate for cooking up 6 | rich Terminal User Interfaces. 7 | 8 | [![License](https://img.shields.io/crates/l/ratatui?style=for-the-badge)](./LICENSE.md) 9 | [![Read the documentation](https://img.shields.io/badge/Read-Documentation-blue?style=for-the-badge)](https://ratatui.rs/) 10 | [![Discord](https://img.shields.io/discord/1070692720437383208?label=discord&logo=discord&style=for-the-badge)](https://discord.gg/pMCEU9hNEj) 11 | 12 | To read this content online, visit: 13 | 14 | 15 | 16 | To build and run the site locally: 17 | 18 | ```shell 19 | git clone https://github.com/ratatui/ratatui-website/ 20 | cd ratatui-website 21 | 22 | git lfs install 23 | git lfs pull 24 | 25 | npm install 26 | npm run dev 27 | ``` 28 | 29 | Feel free to make contributions and submit a PR if you'd like to improve the documentation. 30 | -------------------------------------------------------------------------------- /code/concepts/the-elm-architecture/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "the-elm-architecture" 3 | version.workspace = true 4 | authors.workspace = true 5 | description.workspace = true 6 | documentation.workspace = true 7 | repository.workspace = true 8 | keywords.workspace = true 9 | license.workspace = true 10 | edition.workspace = true 11 | rust-version.workspace = true 12 | publish.workspace = true 13 | 14 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 15 | 16 | [dependencies] 17 | color-eyre = "0.6.3" 18 | ratatui = "0.28.1" 19 | -------------------------------------------------------------------------------- /code/examples/ratatui-examples/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "ratatui-examples" 3 | version.workspace = true 4 | authors.workspace = true 5 | description.workspace = true 6 | documentation.workspace = true 7 | repository.workspace = true 8 | keywords.workspace = true 9 | license.workspace = true 10 | edition.workspace = true 11 | rust-version.workspace = true 12 | publish.workspace = true 13 | 14 | [features] 15 | default = ["crossterm"] 16 | crossterm = ["ratatui/crossterm"] 17 | termion = ["ratatui/termion"] 18 | termwiz = ["ratatui/termwiz"] 19 | unstable-widget-ref = ["ratatui/unstable-widget-ref"] 20 | 21 | [dependencies] 22 | crossterm = "0.28.1" 23 | ratatui = { version = "0.29.0", features = ["widget-calendar"] } 24 | 25 | [dev-dependencies] 26 | anyhow = "1.0.97" 27 | argh = "0.1.13" 28 | better-panic = "0.3.0" 29 | color-eyre = "0.6.2" 30 | criterion = { version = "0.5.1", features = ["html_reports"] } 31 | derive_builder = "0.20.2" 32 | fakeit = "1.1" 33 | font8x8 = "0.3.1" 34 | futures = "0.3.31" 35 | indoc = "2" 36 | octocrab = "0.44.0" 37 | palette = "0.7.3" 38 | pretty_assertions = "1.4.1" 39 | rand = "0.9.0" 40 | rand_chacha = "0.9.0" 41 | rstest = "0.25.0" 42 | serde_json = "1.0.140" 43 | itertools = "0.14" 44 | strum = { version = "0.27.1", features = ["derive"] } 45 | time = { version = "0.3.41", features = ["local-offset"] } 46 | tokio = { version = "1.44.1" } 47 | tracing = "0.1.41" 48 | tracing-subscriber = "0.3.19" 49 | tracing-appender = "0.2.3" 50 | unicode-width = "0.2" 51 | 52 | [[example]] 53 | name = "widget_impl" 54 | required-features = ["unstable-widget-ref"] 55 | -------------------------------------------------------------------------------- /code/examples/ratatui-examples/README.md: -------------------------------------------------------------------------------- 1 | # Ratatui Examples 2 | 3 | Note: Edits to the examples in this folder will be overwritten on each release. To update these 4 | examples, do so in the main [Ratatui](https://github.com/ratatui/ratatui) repo. 5 | 6 | This folder contains a copy of the examples from the latest release version of Ratatui. It is 7 | generated using directly from using git 8 | read-tree as suggested by a 9 | [stackoverflow answer](https://stackoverflow.com/questions/23937436/add-subdirectory-of-remote-repo-with-git-subtree): 10 | 11 | ```shell 12 | git remote add --fetch --track latest --no-tags ratatui https://github.com/ratatui/ratatui.git 13 | git merge --strategy ours --no-commit ratatui/latest --allow-unrelated-histories --squash 14 | git read-tree --prefix=code/ratatui-examples/examples/ -u ratatui/latest:examples 15 | git commit -m 'Add ratatui examples' 16 | ``` 17 | 18 | To update the examples in the future: 19 | 20 | ```shell 21 | # This first command should only need to be run once 22 | git remote add --fetch --track latest --no-tags ratatui https://github.com/ratatui/ratatui.git 23 | 24 | git merge --strategy ours --no-commit ratatui/latest --squash 25 | git rm -rf code/ratatui-examples/examples 26 | git read-tree --prefix=code/ratatui-examples/examples/ -u ratatui/latest:examples 27 | git commit -m 'Update examples' 28 | ``` 29 | -------------------------------------------------------------------------------- /code/examples/ratatui-examples/examples/demo2/tabs.rs: -------------------------------------------------------------------------------- 1 | mod about; 2 | mod email; 3 | mod recipe; 4 | mod traceroute; 5 | mod weather; 6 | 7 | pub use about::AboutTab; 8 | pub use email::EmailTab; 9 | pub use recipe::RecipeTab; 10 | pub use traceroute::TracerouteTab; 11 | pub use weather::WeatherTab; 12 | -------------------------------------------------------------------------------- /code/examples/ratatui-examples/examples/vhs/barchart-grouped.tape: -------------------------------------------------------------------------------- 1 | # This is a vhs script. See https://github.com/charmbracelet/vhs for more info. 2 | # To run this script, install vhs and run `vhs ./examples/barchart.tape` 3 | Output "target/barchart-grouped.gif" 4 | Set Theme "Aardvark Blue" 5 | Set Width 1200 6 | Set Height 1000 7 | Hide 8 | Type "cargo run --example=barchart-grouped" 9 | Enter 10 | Sleep 1s 11 | Show 12 | Sleep 1s 13 | -------------------------------------------------------------------------------- /code/examples/ratatui-examples/examples/vhs/barchart.tape: -------------------------------------------------------------------------------- 1 | # This is a vhs script. See https://github.com/charmbracelet/vhs for more info. 2 | # To run this script, install vhs and run `vhs ./examples/barchart.tape` 3 | Output "target/barchart.gif" 4 | Set Theme "Aardvark Blue" 5 | Set Width 1200 6 | Set Height 600 7 | Hide 8 | Type "cargo run --example=barchart" 9 | Enter 10 | Sleep 1s 11 | Show 12 | Sleep 1s 13 | -------------------------------------------------------------------------------- /code/examples/ratatui-examples/examples/vhs/block.tape: -------------------------------------------------------------------------------- 1 | # This is a vhs script. See https://github.com/charmbracelet/vhs for more info. 2 | # To run this script, install vhs and run `vhs ./examples/block.tape` 3 | Output "target/block.gif" 4 | Set Theme "Aardvark Blue" 5 | Set Width 1200 6 | Set Height 1200 7 | Hide 8 | Type "cargo run --example=block" 9 | Enter 10 | Sleep 2s 11 | Show 12 | Sleep 2s 13 | -------------------------------------------------------------------------------- /code/examples/ratatui-examples/examples/vhs/calendar.tape: -------------------------------------------------------------------------------- 1 | # This is a vhs script. See https://github.com/charmbracelet/vhs for more info. 2 | # To run this script, install vhs and run `vhs ./examples/calendar.tape` 3 | Output "target/calendar.gif" 4 | Set Theme "Aardvark Blue" 5 | Set Width 1200 6 | Set Height 800 7 | Hide 8 | Type "cargo run --example=calendar --features=crossterm,widget-calendar" 9 | Enter 10 | Sleep 3s 11 | Show 12 | Sleep 5s 13 | -------------------------------------------------------------------------------- /code/examples/ratatui-examples/examples/vhs/canvas.tape: -------------------------------------------------------------------------------- 1 | # This is a vhs script. See https://github.com/charmbracelet/vhs for more info. 2 | # To run this script, install vhs and run `vhs ./examples/canvas.tape` 3 | Output "target/canvas.gif" 4 | Set Theme "Aardvark Blue" 5 | Set FontSize 12 6 | Set Width 1200 7 | Set Height 800 8 | Hide 9 | Type "cargo run --example=canvas --features=crossterm" 10 | Enter 11 | Sleep 2s 12 | Show 13 | Sleep 30s 14 | -------------------------------------------------------------------------------- /code/examples/ratatui-examples/examples/vhs/chart.tape: -------------------------------------------------------------------------------- 1 | # This is a vhs script. See https://github.com/charmbracelet/vhs for more info. 2 | # To run this script, install vhs and run `vhs ./examples/chart.tape` 3 | Output "target/chart.gif" 4 | Set Theme "Aardvark Blue" 5 | Set Width 1200 6 | Set Height 800 7 | Hide 8 | Type "cargo run --example=chart --features=crossterm" 9 | Enter 10 | Sleep 1s 11 | Show 12 | Sleep 5s 13 | -------------------------------------------------------------------------------- /code/examples/ratatui-examples/examples/vhs/colors.tape: -------------------------------------------------------------------------------- 1 | # This is a vhs script. See https://github.com/charmbracelet/vhs for more info. 2 | # To run this script, install vhs and run `vhs ./examples/colors.tape` 3 | Output "target/colors.gif" 4 | Set Theme "Aardvark Blue" 5 | Set Width 1200 6 | Set Height 1410 7 | Hide 8 | Type "cargo run --example=colors --features=crossterm" 9 | Enter 10 | Sleep 2s 11 | Show 12 | Sleep 1s 13 | -------------------------------------------------------------------------------- /code/examples/ratatui-examples/examples/vhs/colors_rgb.tape: -------------------------------------------------------------------------------- 1 | # This is a vhs script. See https://github.com/charmbracelet/vhs for more info. 2 | # To run this script, install vhs and run `vhs ./examples/colors_rgb.tape` 3 | 4 | # note that this script sometimes results in the gif having screen tearing 5 | # issues. I'm not sure why, but it's not a problem with the library. 6 | Output "target/colors_rgb.gif" 7 | Set Theme "Aardvark Blue" 8 | Set Width 1200 9 | Set Height 1200 10 | 11 | # unsure if these help the screen tearing issue, but they don't hurt 12 | Set Framerate 60 13 | Set CursorBlink false 14 | 15 | Hide 16 | Type "cargo run --example=colors_rgb --features=crossterm --release" 17 | Enter 18 | Sleep 2s 19 | # Screenshot "target/colors_rgb.png" 20 | Show 21 | Sleep 10s 22 | -------------------------------------------------------------------------------- /code/examples/ratatui-examples/examples/vhs/constraint-explorer.tape: -------------------------------------------------------------------------------- 1 | # This is a vhs script. See https://github.com/charmbracelet/vhs for more info. 2 | # To run this script, install vhs and run `vhs ./examples/constraint-explorer.tape` 3 | Output "target/constraint-explorer.gif" 4 | Set Theme "Aardvark Blue" 5 | Set FontSize 18 6 | Set Width 1200 7 | Set Height 950 8 | Hide 9 | Type "cargo run --example=constraint-explorer --features=crossterm" 10 | Enter 11 | Sleep 2s 12 | Show 13 | Set TypingSpeed 2s 14 | Type "1" 15 | Type "2" 16 | Right 17 | Type "4" 18 | Type "5" 19 | Up 20 | Up 21 | Down 22 | Down 23 | Right 24 | Set TypingSpeed 0.5s 25 | Type "++++++++" 26 | Type "--------" 27 | Type "aaa" 28 | Sleep 2s 29 | Type "xxx" 30 | Hide 31 | -------------------------------------------------------------------------------- /code/examples/ratatui-examples/examples/vhs/constraints.tape: -------------------------------------------------------------------------------- 1 | # This is a vhs script. See https://github.com/charmbracelet/vhs for more info. 2 | # To run this script, install vhs and run `vhs ./examples/constraints.tape` 3 | Output "target/constraints.gif" 4 | Set Theme "Aardvark Blue" 5 | Set FontSize 18 6 | Set Width 1200 7 | Set Height 700 8 | Hide 9 | Type "cargo run --example=constraints --features=crossterm" 10 | Enter 11 | Sleep 2s 12 | Show 13 | Sleep 5s 14 | Right @5s 7 15 | -------------------------------------------------------------------------------- /code/examples/ratatui-examples/examples/vhs/custom_widget.tape: -------------------------------------------------------------------------------- 1 | # This is a vhs script. See https://github.com/charmbracelet/vhs for more info. 2 | # To run this script, install vhs and run `vhs ./examples/custom_widget.tape` 3 | Output "target/custom_widget.gif" 4 | Set Theme "Aardvark Blue" 5 | Set Width 760 6 | Set Height 260 7 | Hide 8 | Type "cargo run --example=custom_widget --features=crossterm" 9 | Enter 10 | Sleep 2s 11 | Show 12 | Sleep 1s 13 | Set TypingSpeed 0.7s 14 | Right 15 | Right 16 | Space 17 | Space 18 | Left 19 | Space 20 | Left 21 | Space 22 | -------------------------------------------------------------------------------- /code/examples/ratatui-examples/examples/vhs/demo.tape: -------------------------------------------------------------------------------- 1 | # This is a vhs script. See https://github.com/charmbracelet/vhs for more info. 2 | # To run this script, install vhs and run `vhs ./examples/demo.tape` 3 | Output "target/demo.gif" 4 | Set Theme "Aardvark Blue" 5 | Set Width 1200 6 | Set Height 1200 7 | Set PlaybackSpeed 0.5 8 | Hide 9 | Type "cargo run --example demo" 10 | Enter 11 | Sleep 2s 12 | Show 13 | Sleep 1s 14 | Down@1s 12 15 | Right 16 | Sleep 4s 17 | Right 18 | Sleep 4s 19 | -------------------------------------------------------------------------------- /code/examples/ratatui-examples/examples/vhs/demo2-destroy.tape: -------------------------------------------------------------------------------- 1 | # This is a vhs script. See https://github.com/charmbracelet/vhs for more info. 2 | # To run this script, install vhs and run `vhs ./examples/demo2-destroy.tape` 3 | # NOTE: Requires VHS 0.6.1 or later for Screenshot support 4 | Output "target/demo2-destroy.gif" 5 | Set Theme "Aardvark Blue" 6 | # The reason for this strange size is that the social preview image for this 7 | # demo is 1280x64 with 80 pixels of padding on each side. We want a version 8 | # without the padding for README.md, etc. 9 | Set Width 1120 10 | Set Height 480 11 | Set Padding 0 12 | Hide 13 | Type "cargo run --example demo2 --features crossterm,palette,widget-calendar" 14 | Enter 15 | Sleep 2s 16 | Show 17 | Type "d" 18 | Sleep 20s 19 | -------------------------------------------------------------------------------- /code/examples/ratatui-examples/examples/vhs/demo2-social.tape: -------------------------------------------------------------------------------- 1 | # This is a vhs script. See https://github.com/charmbracelet/vhs for more info. 2 | # To run this script, install vhs and run `vhs ./examples/demo2-social.tape` 3 | 4 | Output "target/demo2-social.gif" 5 | Set Theme "Aardvark Blue" 6 | # Github social preview size (1280x640 with 80px padding) and must be < 1MB 7 | # This puts some constraints on the amount of interactivity we can do. 8 | Set Width 1280 9 | Set Height 640 10 | Set Padding 80 11 | Hide 12 | Type "cargo run --example demo2 --features crossterm,widget-calendar" 13 | Enter 14 | Sleep 2s 15 | Show 16 | # About screen 17 | Sleep 3.5s 18 | Down # Red eye 19 | Sleep 0.4s 20 | Down # black eye 21 | Sleep 1s 22 | Tab 23 | # Recipe 24 | Sleep 1s 25 | Set TypingSpeed 500ms 26 | Down 7 27 | Sleep 1s 28 | Tab 29 | # Email 30 | Sleep 2s 31 | Down 4 32 | Sleep 2s 33 | Tab 34 | # Trace route 35 | Sleep 1s 36 | Set TypingSpeed 200ms 37 | Down 10 38 | Sleep 2s 39 | Tab 40 | # Weather 41 | Set TypingSpeed 100ms 42 | Down 40 43 | Sleep 2s 44 | -------------------------------------------------------------------------------- /code/examples/ratatui-examples/examples/vhs/demo2.tape: -------------------------------------------------------------------------------- 1 | # This is a vhs script. See https://github.com/charmbracelet/vhs for more info. 2 | # To run this script, install vhs and run `vhs ./examples/demo2.tape` 3 | # NOTE: Requires VHS 0.6.1 or later for Screenshot support 4 | Output "target/demo2.gif" 5 | Set Theme "Aardvark Blue" 6 | # The reason for this strange size is that the social preview image for this 7 | # demo is 1280x64 with 80 pixels of padding on each side. We want a version 8 | # without the padding for README.md, etc. 9 | Set Width 1120 10 | Set Height 480 11 | Set Padding 0 12 | Hide 13 | Type "cargo run --example demo2 --features crossterm,widget-calendar" 14 | Enter 15 | Sleep 2s 16 | Show 17 | # About screen 18 | Screenshot "target/demo2-about.png" 19 | Sleep 3.5s 20 | Down # Red eye 21 | Sleep 0.4s 22 | Down # black eye 23 | Sleep 1s 24 | Tab 25 | # Recipe 26 | Screenshot "target/demo2-recipe.png" 27 | Sleep 1s 28 | Set TypingSpeed 500ms 29 | Down 7 30 | Sleep 1s 31 | Tab 32 | # Email 33 | Screenshot "target/demo2-email.png" 34 | Sleep 2s 35 | Down 4 36 | Sleep 2s 37 | Tab 38 | # Trace route 39 | Screenshot "target/demo2-trace.png" 40 | Sleep 1s 41 | Set TypingSpeed 200ms 42 | Down 10 43 | Sleep 2s 44 | Tab 45 | # Weather 46 | Screenshot "target/demo2-weather.png" 47 | Set TypingSpeed 100ms 48 | Down 40 49 | Sleep 2s 50 | -------------------------------------------------------------------------------- /code/examples/ratatui-examples/examples/vhs/docsrs.tape: -------------------------------------------------------------------------------- 1 | # This is a vhs script. See https://github.com/charmbracelet/vhs for more info. 2 | # To run this script, install vhs and run `vhs ./examples/docsrs.tape` 3 | # NOTE: Requires VHS 0.6.1 or later for Screenshot support 4 | Output "target/docsrs.gif" 5 | Set Theme "Aardvark Blue" 6 | # The reason for this strange size is that the social preview image for this 7 | # demo is 1280x64 with 80 pixels of padding on each side. We want a version 8 | # without the padding for README.md, etc. 9 | Set Width 640 10 | Set Height 160 11 | Set Padding 0 12 | Hide 13 | Type "cargo run --example docsrs --features crossterm" 14 | Enter 15 | Sleep 2s 16 | Show 17 | Sleep 1s 18 | Screenshot "target/docsrs-hello.png" 19 | Sleep 1s 20 | Hide 21 | Type "q" 22 | Type "cargo run --example docsrs --features crossterm -- layout" 23 | Enter 24 | Sleep 2s 25 | Show 26 | Sleep 1s 27 | Screenshot "target/docsrs-layout.png" 28 | Sleep 1s 29 | Hide 30 | Type "q" 31 | Type "cargo run --example docsrs --features crossterm -- styling" 32 | Enter 33 | Sleep 2s 34 | Show 35 | Sleep 1s 36 | Screenshot "target/docsrs-styling.png" 37 | Sleep 1s 38 | Hide 39 | Type "q" 40 | -------------------------------------------------------------------------------- /code/examples/ratatui-examples/examples/vhs/flex.tape: -------------------------------------------------------------------------------- 1 | # This is a vhs script. See https://github.com/charmbracelet/vhs for more info. 2 | # To run this script, install vhs and run `vhs ./examples/flex.tape` 3 | Output "target/flex.gif" 4 | Set Theme "Aardvark Blue" 5 | Set Width 1200 6 | Set Height 1410 7 | Hide 8 | Type "cargo run --example=flex --features=crossterm" 9 | Enter 10 | Sleep 2s 11 | Show 12 | Sleep 2s 13 | Right @5s 7 14 | Sleep 2s 15 | Left 7 16 | Sleep 2s 17 | Down @200ms 50 18 | -------------------------------------------------------------------------------- /code/examples/ratatui-examples/examples/vhs/gauge.tape: -------------------------------------------------------------------------------- 1 | # This is a vhs script. See https://github.com/charmbracelet/vhs for more info. 2 | # To run this script, install vhs and run `vhs ./examples/gauge.tape` 3 | Output "target/gauge.gif" 4 | Set Theme "Aardvark Blue" 5 | Set Width 1200 6 | Set Height 850 7 | Hide 8 | Type "cargo run --example=gauge --features=crossterm" 9 | Enter 10 | Sleep 2s 11 | Show 12 | Sleep 2s 13 | Enter 1 14 | Sleep 15s 15 | -------------------------------------------------------------------------------- /code/examples/ratatui-examples/examples/vhs/hello_world.tape: -------------------------------------------------------------------------------- 1 | # This is a vhs script. See https://github.com/charmbracelet/vhs for more info. 2 | # To run this script, install vhs and run `vhs ./examples/hello_world.tape` 3 | Output "target/hello_world.gif" 4 | Set Theme "Aardvark Blue" 5 | Set Width 1200 6 | Set Height 200 7 | Hide 8 | Type "cargo run --example=hello_world --features=crossterm" 9 | Enter 10 | Sleep 1s 11 | Show 12 | Sleep 5s 13 | -------------------------------------------------------------------------------- /code/examples/ratatui-examples/examples/vhs/hyperlink.tape: -------------------------------------------------------------------------------- 1 | # This is a vhs script. See https://github.com/charmbracelet/vhs for more info. 2 | # To run this script, install vhs and run `vhs ./examples/hyperlink.tape` 3 | Output "target/hyperlink.gif" 4 | Set Theme "Aardvark Blue" 5 | Set Width 1200 6 | Set Height 200 7 | Hide 8 | Type "cargo run --example=hyperlink --features=crossterm,unstable-widget-ref" 9 | Enter 10 | Sleep 3s 11 | Show 12 | Sleep 1s 13 | Hide 14 | Type "q" 15 | 16 | -------------------------------------------------------------------------------- /code/examples/ratatui-examples/examples/vhs/inline.tape: -------------------------------------------------------------------------------- 1 | # This is a vhs script. See https://github.com/charmbracelet/vhs for more info. 2 | # To run this script, install vhs and run `vhs ./examples/inline.tape` 3 | Output "target/inline.gif" 4 | Set Theme "Aardvark Blue" 5 | Set Width 1200 6 | Set Height 600 7 | Type "cargo run --example=inline --features=crossterm" 8 | Enter 9 | Sleep 20s 10 | -------------------------------------------------------------------------------- /code/examples/ratatui-examples/examples/vhs/layout.tape: -------------------------------------------------------------------------------- 1 | # This is a vhs script. See https://github.com/charmbracelet/vhs for more info. 2 | # To run this script, install vhs and run `vhs ./examples/layout.tape` 3 | Output "target/layout.gif" 4 | Set Theme "Aardvark Blue" 5 | Set Width 1200 6 | Set Height 1410 7 | Hide 8 | Type "cargo run --example=layout --features=crossterm" 9 | Enter 10 | Sleep 1s 11 | Show 12 | Sleep 2s 13 | -------------------------------------------------------------------------------- /code/examples/ratatui-examples/examples/vhs/line_gauge.tape: -------------------------------------------------------------------------------- 1 | # This is a vhs script. See https://github.com/charmbracelet/vhs for more info. 2 | # To run this script, install vhs and run `vhs ./examples/line_gauge.tape` 3 | Output "target/line_gauge.gif" 4 | Set Theme "Aardvark Blue" 5 | Set Width 1200 6 | Set Height 850 7 | Hide 8 | Type "cargo run --example=line_gauge --features=crossterm" 9 | Enter 10 | Sleep 2s 11 | Show 12 | Sleep 2s 13 | Enter 1 14 | Sleep 15s 15 | -------------------------------------------------------------------------------- /code/examples/ratatui-examples/examples/vhs/list.tape: -------------------------------------------------------------------------------- 1 | # This is a vhs script. See https://github.com/charmbracelet/vhs for more info. 2 | # To run this script, install vhs and run `vhs ./examples/list.tape` 3 | Output "target/list.gif" 4 | Set Theme "Aardvark Blue" 5 | Set Width 1200 6 | Set Height 612 7 | Hide 8 | Type "cargo run --example=list --features=crossterm" 9 | Enter 10 | Sleep 10s 11 | Show 12 | Sleep 2s 13 | Down@1.5s 3 14 | Right@1.5s 1 15 | Sleep 1.5s 16 | Down@1.5s 3 17 | Sleep 1.5s 18 | Up@1s 1 19 | Sleep 1s 20 | Right@1.5s 1 21 | Sleep 1.5s 22 | Up@1s 4 23 | Left@1s 1 24 | Sleep 2s 25 | -------------------------------------------------------------------------------- /code/examples/ratatui-examples/examples/vhs/minimal.tape: -------------------------------------------------------------------------------- 1 | # This is a vhs script. See https://github.com/charmbracelet/vhs for more info. 2 | # To run this script, install vhs and run `vhs ./examples/minimal.tape` 3 | Output "target/minimal.gif" 4 | Set Theme "Aardvark Blue" 5 | Set Width 1200 6 | Set Height 200 7 | Hide 8 | Type "cargo run --example=minimal --features=crossterm" 9 | Enter 10 | Sleep 1s 11 | Show 12 | Sleep 5s 13 | -------------------------------------------------------------------------------- /code/examples/ratatui-examples/examples/vhs/modifiers.tape: -------------------------------------------------------------------------------- 1 | # This is a vhs script. See https://github.com/charmbracelet/vhs for more info. 2 | # To run this script, install vhs and run `vhs ./examples/modifiers.tape` 3 | Output "target/modifiers.gif" 4 | Set Theme "Aardvark Blue" 5 | Set Width 1200 6 | Set Height 1460 7 | Hide 8 | Type "cargo run --example=modifiers --features=crossterm" 9 | Enter 10 | Sleep 2s 11 | Show 12 | Sleep 1s 13 | -------------------------------------------------------------------------------- /code/examples/ratatui-examples/examples/vhs/panic.tape: -------------------------------------------------------------------------------- 1 | # This is a vhs script. See https://github.com/charmbracelet/vhs for more info. 2 | # To run this script, install vhs and run `vhs ./examples/panic.tape` 3 | Output "target/panic.gif" 4 | Set Theme "Aardvark Blue" 5 | Set Width 1200 6 | Set Height 600 7 | Type "cargo run --example=panic --features=crossterm" 8 | Enter 9 | Sleep 5s 10 | Type p 11 | Sleep 2s 12 | Type reset 13 | Enter 14 | Type "cargo run --example=panic --features=crossterm" 15 | Enter 16 | Sleep 2s 17 | Type e 18 | Sleep 2s 19 | Type p 20 | Sleep 5s 21 | -------------------------------------------------------------------------------- /code/examples/ratatui-examples/examples/vhs/paragraph.tape: -------------------------------------------------------------------------------- 1 | # This is a vhs script. See https://github.com/charmbracelet/vhs for more info. 2 | # To run this script, install vhs and run `vhs ./examples/paragraph.tape` 3 | Output "target/paragraph.gif" 4 | Set Theme "Aardvark Blue" 5 | Set Width 1200 6 | Set Height 1800 7 | Hide 8 | Type "cargo run --example=paragraph --features=crossterm" 9 | Enter 10 | Sleep 1s 11 | Show 12 | Sleep 5s 13 | -------------------------------------------------------------------------------- /code/examples/ratatui-examples/examples/vhs/popup.tape: -------------------------------------------------------------------------------- 1 | # This is a vhs script. See https://github.com/charmbracelet/vhs for more info. 2 | # To run this script, install vhs and run `vhs ./examples/popup.tape` 3 | Output "target/popup.gif" 4 | Set Theme "Aardvark Blue" 5 | Set Width 1200 6 | Set Height 600 7 | Hide 8 | Type "cargo run --example=popup --features=crossterm" 9 | Enter 10 | Sleep 1s 11 | Show 12 | Sleep 2s 13 | Type p 14 | Sleep 2s 15 | Type p 16 | Sleep 5s 17 | -------------------------------------------------------------------------------- /code/examples/ratatui-examples/examples/vhs/ratatui-logo.tape: -------------------------------------------------------------------------------- 1 | # This is a vhs script. See https://github.com/charmbracelet/vhs for more info. 2 | # To run this script, install vhs and run `vhs ./examples/ratatui-logo.tape` 3 | Output "target/ratatui-logo.gif" 4 | Set Theme "Aardvark Blue" 5 | Set Width 550 6 | Set Height 220 7 | Hide 8 | Type "cargo run --example=ratatui-logo --features=crossterm" 9 | Enter 10 | Sleep 2s 11 | Show 12 | Sleep 2s 13 | Hide 14 | Escape 15 | -------------------------------------------------------------------------------- /code/examples/ratatui-examples/examples/vhs/scrollbar.tape: -------------------------------------------------------------------------------- 1 | # This is a vhs script. See https://github.com/charmbracelet/vhs for more info. 2 | # To run this script, install vhs and run `vhs ./examples/scrollbar.tape` 3 | Output "target/scrollbar.gif" 4 | Set Theme "Aardvark Blue" 5 | Set Width 1200 6 | Set Height 1200 7 | Hide 8 | Type "cargo run --example=scrollbar --features=crossterm" 9 | Enter 10 | Sleep 1s 11 | Show 12 | Sleep 5s 13 | -------------------------------------------------------------------------------- /code/examples/ratatui-examples/examples/vhs/sparkline.tape: -------------------------------------------------------------------------------- 1 | # This is a vhs script. See https://github.com/charmbracelet/vhs for more info. 2 | # To run this script, install vhs and run `vhs ./examples/sparkline.tape` 3 | Output "target/sparkline.gif" 4 | Set Theme "Aardvark Blue" 5 | Set Width 1200 6 | Set Height 600 7 | Hide 8 | Type "cargo run --example=sparkline --features=crossterm" 9 | Enter 10 | Sleep 1s 11 | Show 12 | Sleep 5s 13 | -------------------------------------------------------------------------------- /code/examples/ratatui-examples/examples/vhs/table.tape: -------------------------------------------------------------------------------- 1 | # This is a vhs script. See https://github.com/charmbracelet/vhs for more info. 2 | # To run this script, install vhs and run `vhs ./examples/table.tape` 3 | Output "target/table.gif" 4 | Set Theme "Aardvark Blue" 5 | Set Width 1400 6 | Set Height 768 7 | Hide 8 | Type "cargo run --example=table --features=crossterm" 9 | Enter 10 | Sleep 1s 11 | Show 12 | Sleep 2s 13 | Set TypingSpeed 1s 14 | Down 3 15 | Up 6 16 | Sleep 1s 17 | Down 3 18 | Sleep 1s 19 | Right 1 20 | Sleep 1s 21 | Right 1 22 | Sleep 1s 23 | Right 1 24 | Sleep 1s 25 | Right 1 26 | Sleep 2s 27 | -------------------------------------------------------------------------------- /code/examples/ratatui-examples/examples/vhs/tabs.tape: -------------------------------------------------------------------------------- 1 | # This is a vhs script. See https://github.com/charmbracelet/vhs for more info. 2 | # To run this script, install vhs and run `vhs ./examples/tabs.tape` 3 | Output "target/tabs.gif" 4 | Set Theme "Aardvark Blue" 5 | Set Width 1200 6 | Set Height 368 7 | Hide 8 | Type "cargo run --example=tabs --features=crossterm" 9 | Enter 10 | Sleep 2s 11 | Show 12 | Sleep 1s 13 | Right@2.5s 3 14 | Left@2.5s 3 15 | Sleep 2s 16 | -------------------------------------------------------------------------------- /code/examples/ratatui-examples/examples/vhs/tracing.tape: -------------------------------------------------------------------------------- 1 | # This is a vhs script. See https://github.com/charmbracelet/vhs for more info. 2 | # To run this script, install vhs and run `vhs ./examples/tracing.tape` 3 | Output "target/tracing.gif" 4 | Set Theme "Aardvark Blue" 5 | Set Width 1200 6 | Set Height 800 7 | Type "RUST_LOG=trace cargo run --example=tracing" Enter 8 | Sleep 1s 9 | Type @100ms "jjjjq" 10 | Sleep 1s 11 | Type "cat tracing.log" Enter 12 | Sleep 10s 13 | -------------------------------------------------------------------------------- /code/examples/ratatui-examples/examples/vhs/user_input.tape: -------------------------------------------------------------------------------- 1 | # This is a vhs script. See https://github.com/charmbracelet/vhs for more info. 2 | # To run this script, install vhs and run `vhs ./examples/user_input.tape` 3 | Output "target/user_input.gif" 4 | Set Theme "Aardvark Blue" 5 | Set Width 1200 6 | Set Height 600 7 | Hide 8 | Type "cargo run --example=user_input --features=crossterm" 9 | Enter 10 | Sleep 1s 11 | Show 12 | Sleep 2s 13 | Type e 14 | Sleep 1s 15 | Type "Hello, world!" 16 | Enter 17 | Sleep 2s 18 | Backspace 13 19 | Sleep 1s 20 | Type "Goodbye, world!" 21 | Enter 22 | Sleep 5s 23 | -------------------------------------------------------------------------------- /code/examples/ratatui-examples/src/lib.rs: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /code/recipes/how-to-collapse-borders/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "how-to-collapse-borders" 3 | version.workspace = true 4 | authors.workspace = true 5 | description.workspace = true 6 | documentation.workspace = true 7 | repository.workspace = true 8 | keywords.workspace = true 9 | license.workspace = true 10 | edition.workspace = true 11 | rust-version.workspace = true 12 | publish.workspace = true 13 | 14 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 15 | 16 | [dependencies] 17 | color-eyre = "0.6.3" 18 | crossterm = "0.28.1" 19 | ratatui = "0.29.0" 20 | -------------------------------------------------------------------------------- /code/recipes/how-to-collapse-borders/problem.tape: -------------------------------------------------------------------------------- 1 | # A VHS tape. See https://github.com/charmbracelet/vhs 2 | Output collapse-borders-problem.gif 3 | Set Theme "Aardvark Blue" 4 | Set Width 800 5 | Set Height 450 6 | Type "cargo run --bin problem" 7 | Enter 8 | Sleep 2s 9 | Screenshot collapse-borders-problem.png 10 | Sleep 1s 11 | Type q 12 | Sleep 2s 13 | -------------------------------------------------------------------------------- /code/recipes/how-to-collapse-borders/solution.tape: -------------------------------------------------------------------------------- 1 | # A VHS tape. See https://github.com/charmbracelet/vhs 2 | Output collapse-borders-solution.gif 3 | Set Theme "Aardvark Blue" 4 | Set Width 800 5 | Set Height 450 6 | Type "cargo run --bin solution" 7 | Enter 8 | Sleep 2s 9 | Screenshot collapse-borders-solution.png 10 | Sleep 1s 11 | Type q 12 | Sleep 2s 13 | -------------------------------------------------------------------------------- /code/recipes/how-to-collapse-borders/src/bin/problem.rs: -------------------------------------------------------------------------------- 1 | use std::time::Duration; 2 | 3 | use color_eyre::Result; 4 | use crossterm::event::{self, Event}; 5 | use ratatui::{ 6 | layout::{Constraint, Layout}, 7 | widgets::Block, 8 | DefaultTerminal, Frame, 9 | }; 10 | 11 | fn main() -> Result<()> { 12 | color_eyre::install()?; 13 | let terminal = ratatui::init(); 14 | let result = run(terminal); 15 | ratatui::restore(); 16 | result 17 | } 18 | 19 | fn run(mut terminal: DefaultTerminal) -> Result<()> { 20 | loop { 21 | terminal.draw(draw)?; 22 | if key_pressed()? { 23 | return Ok(()); 24 | } 25 | } 26 | } 27 | 28 | fn key_pressed() -> Result { 29 | Ok(event::poll(Duration::from_millis(16))? && matches!(event::read()?, Event::Key(_))) 30 | } 31 | 32 | // ANCHOR: draw 33 | fn draw(frame: &mut Frame) { 34 | // create a layout that splits the screen into 2 equal columns and the right column 35 | // into 2 equal rows 36 | let [left, right] = Layout::horizontal([Constraint::Fill(1); 2]).areas(frame.area()); 37 | let [top_right, bottom_right] = Layout::vertical([Constraint::Fill(1); 2]).areas(right); 38 | 39 | frame.render_widget(Block::bordered().title("Left Block"), left); 40 | frame.render_widget(Block::bordered().title("Top Right Block"), top_right); 41 | frame.render_widget(Block::bordered().title("Bottom Right Block"), bottom_right); 42 | } 43 | // ANCHOR_END: draw 44 | -------------------------------------------------------------------------------- /code/recipes/how-to-color_eyre/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "how-to-color_eyre" 3 | version.workspace = true 4 | authors.workspace = true 5 | description.workspace = true 6 | documentation.workspace = true 7 | repository.workspace = true 8 | keywords.workspace = true 9 | license.workspace = true 10 | edition.workspace = true 11 | rust-version.workspace = true 12 | publish.workspace = true 13 | 14 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 15 | 16 | # ANCHOR: dependencies 17 | [dependencies] 18 | color-eyre = { version = "0.6.3" } 19 | ratatui = "0.29.0" 20 | # ANCHOR_END: dependencies 21 | -------------------------------------------------------------------------------- /code/recipes/how-to-color_eyre/demo.tape: -------------------------------------------------------------------------------- 1 | # A VHS tape. See https://github.com/charmbracelet/vhs 2 | Output "../../src/content/docs/how-to/develop-apps/color-eyre/demo.gif" 3 | Set Theme "Aardvark Blue" 4 | Set Width 1200 5 | Set Height 800 6 | Type "cargo run" Enter 7 | Sleep 2s 8 | Type "q" 9 | Sleep 2s 10 | Type "cargo run" Enter 11 | Sleep 2s 12 | Type "p" 13 | Sleep 2s 14 | Type "cargo run" Enter 15 | Sleep 2s 16 | Type "e" 17 | Sleep 2s 18 | -------------------------------------------------------------------------------- /code/recipes/how-to-color_eyre/error-full.tape: -------------------------------------------------------------------------------- 1 | # A VHS tape. See https://github.com/charmbracelet/vhs 2 | Output "../../src/content/docs/how-to/develop-apps/color-eyre/error-full.gif" 3 | Set Theme "Aardvark Blue" 4 | Set Width 1280 5 | Set Height 1350 6 | Type "RUST_BACKTRACE=full cargo run" Enter 7 | Sleep 2s 8 | Type "e" 9 | Sleep 1s 10 | Screenshot "../../src/content/docs/how-to/develop-apps/color-eyre/error-full.png" 11 | Sleep 2s 12 | -------------------------------------------------------------------------------- /code/recipes/how-to-color_eyre/error.tape: -------------------------------------------------------------------------------- 1 | # A VHS tape. See https://github.com/charmbracelet/vhs 2 | Output "../../src/content/docs/how-to/develop-apps/color-eyre/error.gif" 3 | Set Theme "Aardvark Blue" 4 | Set Width 1280 5 | Set Height 450 6 | Type "cargo run" Enter 7 | Sleep 2s 8 | Type "e" 9 | Screenshot "../../src/content/docs/how-to/develop-apps/color-eyre/error.png" 10 | Sleep 2s 11 | -------------------------------------------------------------------------------- /code/recipes/how-to-color_eyre/panic-full.tape: -------------------------------------------------------------------------------- 1 | # A VHS tape. See https://github.com/charmbracelet/vhs 2 | Output "../../src/content/docs/how-to/develop-apps/color-eyre/panic-full.gif" 3 | Set Theme "Aardvark Blue" 4 | Set Width 1280 5 | Set Height 900 6 | Type "RUST_BACKTRACE=full cargo run" Enter 7 | Sleep 2s 8 | Type "p" 9 | Sleep 1s 10 | Screenshot "../../src/content/docs/how-to/develop-apps/color-eyre/panic-full.png" 11 | Sleep 2s 12 | -------------------------------------------------------------------------------- /code/recipes/how-to-color_eyre/panic.tape: -------------------------------------------------------------------------------- 1 | # A VHS tape. See https://github.com/charmbracelet/vhs 2 | Output "../../src/content/docs/how-to/develop-apps/color-eyre/panic.gif" 3 | Set Theme "Aardvark Blue" 4 | Set Width 1280 5 | Set Height 450 6 | Type "cargo run" Enter 7 | Sleep 2s 8 | Type "p" 9 | Screenshot "../../src/content/docs/how-to/develop-apps/color-eyre/panic.png" 10 | Sleep 2s 11 | -------------------------------------------------------------------------------- /code/recipes/how-to-color_eyre/quit.tape: -------------------------------------------------------------------------------- 1 | # A VHS tape. See https://github.com/charmbracelet/vhs 2 | Output "../../src/content/docs/how-to/develop-apps/color-eyre/quit.gif" 3 | Set Theme "Aardvark Blue" 4 | Set Width 1280 5 | Set Height 300 6 | Type "cargo run" Enter 7 | Sleep 2s 8 | Type "q" 9 | Screenshot "../../src/content/docs/how-to/develop-apps/color-eyre/quit.png" 10 | Sleep 2s 11 | -------------------------------------------------------------------------------- /code/recipes/how-to-color_eyre/src/tui.rs: -------------------------------------------------------------------------------- 1 | use std::io::{self, stdout, Stdout}; 2 | 3 | use ratatui::{ 4 | backend::CrosstermBackend, 5 | crossterm::{ 6 | execute, 7 | terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}, 8 | }, 9 | Terminal, 10 | }; 11 | 12 | // ANCHOR: init 13 | /// Initialize the terminal 14 | pub fn init() -> io::Result>> { 15 | execute!(stdout(), EnterAlternateScreen)?; 16 | enable_raw_mode()?; 17 | set_panic_hook(); 18 | Terminal::new(CrosstermBackend::new(stdout())) 19 | } 20 | 21 | fn set_panic_hook() { 22 | let hook = std::panic::take_hook(); 23 | std::panic::set_hook(Box::new(move |panic_info| { 24 | let _ = restore(); // ignore any errors as we are already failing 25 | hook(panic_info); 26 | })); 27 | } 28 | // ANCHOR_END: init 29 | 30 | // ANCHOR: restore 31 | /// Restore the terminal to its original state 32 | pub fn restore() -> io::Result<()> { 33 | execute!(stdout(), LeaveAlternateScreen)?; 34 | disable_raw_mode()?; 35 | Ok(()) 36 | } 37 | // ANCHOR_END: restore 38 | -------------------------------------------------------------------------------- /code/recipes/how-to-misc/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "recipes" 3 | version.workspace = true 4 | authors.workspace = true 5 | description.workspace = true 6 | documentation.workspace = true 7 | repository.workspace = true 8 | keywords.workspace = true 9 | license.workspace = true 10 | edition.workspace = true 11 | rust-version.workspace = true 12 | publish.workspace = true 13 | 14 | [dependencies] 15 | ratatui = "0.29.0" 16 | -------------------------------------------------------------------------------- /code/recipes/how-to-misc/README.md: -------------------------------------------------------------------------------- 1 | # Recipes 2 | 3 | Generic code for the [recipes](https://ratatui.rs/recipes/) section of the website. 4 | -------------------------------------------------------------------------------- /code/recipes/how-to-misc/src/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod layout; 2 | -------------------------------------------------------------------------------- /code/recipes/how-to-overwrite-regions/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "how-to-overwrite-regions" 3 | version.workspace = true 4 | authors.workspace = true 5 | description.workspace = true 6 | documentation.workspace = true 7 | repository.workspace = true 8 | keywords.workspace = true 9 | license.workspace = true 10 | edition.workspace = true 11 | rust-version.workspace = true 12 | publish.workspace = true 13 | 14 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 15 | 16 | [dependencies] 17 | color-eyre = "0.6.3" 18 | derive_setters = "0.1.6" 19 | lipsum = "0.9.1" 20 | ratatui = "0.29.0" 21 | -------------------------------------------------------------------------------- /code/recipes/how-to-overwrite-regions/problem.tape: -------------------------------------------------------------------------------- 1 | # A VHS tape. See https://github.com/charmbracelet/vhs 2 | Output overwrite-regions-problem.gif 3 | Set Theme "Aardvark Blue" 4 | Set Width 800 5 | Set Height 450 6 | Hide 7 | Type "cargo run --bin problem" 8 | Enter 9 | Sleep 2s 10 | Show 11 | Screenshot overwrite-regions-problem.png 12 | Sleep 1s 13 | Hide 14 | Type q 15 | Sleep 2s 16 | -------------------------------------------------------------------------------- /code/recipes/how-to-overwrite-regions/solution.tape: -------------------------------------------------------------------------------- 1 | # A VHS tape. See https://github.com/charmbracelet/vhs 2 | Output overwrite-regions-solution.gif 3 | Set Theme "Aardvark Blue" 4 | Set Width 800 5 | Set Height 450 6 | Hide 7 | Type "cargo run --bin solution" 8 | Enter 9 | Sleep 2s 10 | Show 11 | Screenshot overwrite-regions-solution.png 12 | Sleep 1s 13 | Hide 14 | Type q 15 | Sleep 2s 16 | -------------------------------------------------------------------------------- /code/recipes/how-to-panic-hooks/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "how-to-panic-hooks" 3 | version.workspace = true 4 | authors.workspace = true 5 | description.workspace = true 6 | documentation.workspace = true 7 | repository.workspace = true 8 | keywords.workspace = true 9 | license.workspace = true 10 | edition.workspace = true 11 | rust-version.workspace = true 12 | publish.workspace = true 13 | 14 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 15 | 16 | [dependencies] 17 | ratatui = "0.29.0" 18 | 19 | [[bin]] 20 | name = "crossterm" 21 | required-features = ["ratatui/crossterm"] 22 | 23 | [[bin]] 24 | name = "termion" 25 | required-features = ["ratatui/termion"] 26 | -------------------------------------------------------------------------------- /code/recipes/how-to-panic-hooks/src/bin/crossterm.rs: -------------------------------------------------------------------------------- 1 | use std::{ 2 | io::{self, stdout}, 3 | panic::{set_hook, take_hook}, 4 | thread::sleep, 5 | time::Duration, 6 | }; 7 | 8 | use ratatui::{ 9 | backend::{Backend, CrosstermBackend}, 10 | crossterm::{ 11 | execute, 12 | terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}, 13 | }, 14 | text::Span, 15 | Terminal, 16 | }; 17 | 18 | // ANCHOR: main 19 | pub fn main() -> io::Result<()> { 20 | init_panic_hook(); 21 | let mut tui = init_tui()?; 22 | tui.draw(|frame| frame.render_widget(Span::from("Hello, world!"), frame.area()))?; 23 | sleep(Duration::from_secs(1)); 24 | panic!("This is a panic!"); 25 | } 26 | // ANCHOR_END: main 27 | 28 | pub fn init_panic_hook() { 29 | let original_hook = take_hook(); 30 | set_hook(Box::new(move |panic_info| { 31 | // intentionally ignore errors here since we're already in a panic 32 | let _ = restore_tui(); 33 | original_hook(panic_info); 34 | })); 35 | } 36 | 37 | pub fn init_tui() -> io::Result> { 38 | enable_raw_mode()?; 39 | execute!(stdout(), EnterAlternateScreen)?; 40 | Terminal::new(CrosstermBackend::new(stdout())) 41 | } 42 | 43 | pub fn restore_tui() -> io::Result<()> { 44 | disable_raw_mode()?; 45 | execute!(stdout(), LeaveAlternateScreen)?; 46 | Ok(()) 47 | } 48 | -------------------------------------------------------------------------------- /code/recipes/how-to-panic-hooks/src/bin/termion.rs: -------------------------------------------------------------------------------- 1 | use std::{ 2 | io::{self, stdout, Write}, 3 | panic::{set_hook, take_hook}, 4 | thread::sleep, 5 | time::Duration, 6 | }; 7 | 8 | use ratatui::{ 9 | backend::{Backend, TermionBackend}, 10 | termion::{ 11 | raw::IntoRawMode, 12 | screen::{ToAlternateScreen, ToMainScreen}, 13 | }, 14 | text::Span, 15 | Terminal, 16 | }; 17 | 18 | pub fn main() -> io::Result<()> { 19 | init_panic_hook()?; 20 | let mut tui = init_tui()?; 21 | tui.draw(|frame| frame.render_widget(Span::from("Hello, world!"), frame.area()))?; 22 | sleep(Duration::from_secs(1)); 23 | panic!("This is a panic!"); 24 | } 25 | 26 | pub fn init_panic_hook() -> io::Result<()> { 27 | let raw_output = stdout().into_raw_mode()?; 28 | raw_output.suspend_raw_mode()?; 29 | 30 | let original_hook = take_hook(); 31 | set_hook(Box::new(move |panic_info| { 32 | // intentionally ignore errors here since we're already in a panic 33 | let _ = raw_output.suspend_raw_mode(); 34 | let _ = restore_tui(); 35 | original_hook(panic_info); 36 | })); 37 | Ok(()) 38 | } 39 | 40 | pub fn init_tui() -> io::Result> { 41 | let mut stdout = stdout().into_raw_mode()?; 42 | write!(stdout, "{}", ToAlternateScreen)?; 43 | stdout.flush()?; 44 | Terminal::new(TermionBackend::new(stdout)) 45 | } 46 | 47 | pub fn restore_tui() -> io::Result<()> { 48 | write!(stdout(), "{}", ToMainScreen)?; 49 | stdout().flush()?; 50 | Ok(()) 51 | } 52 | -------------------------------------------------------------------------------- /code/recipes/how-to-spawn-vim/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "how-to-spawn-vim" 3 | version.workspace = true 4 | edition.workspace = true 5 | authors.workspace = true 6 | license.workspace = true 7 | publish.workspace = true 8 | 9 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 10 | 11 | [dependencies] 12 | ratatui = "0.29.0" 13 | -------------------------------------------------------------------------------- /code/showcase/widget-showcase-third-party/README.md: -------------------------------------------------------------------------------- 1 | # Third party widget showcase 2 | 3 | This folder has [VHS] tape files to create gifs for the [Widget Showcase]. To run them, install VHS 4 | from main (the theme and screenshot commands are not yet released). 5 | 6 | ```shell 7 | go install vhs@main 8 | ``` 9 | 10 | Then run the tape. 11 | 12 | ```shell 13 | ~/go/bin/vhs tapefile.tape 14 | ``` 15 | 16 | Then copy the resulting gif over to `/src/content/docs/showcase/widgets/` and update 17 | `src/content/docs/showcase/widgets/index.mdx` 18 | 19 | Generally, try to avoid making animation super-frantic, and leave enough pauses for people to read 20 | the text before it changes. If animation doesn't help the understanding of the way the widget works, 21 | consider using a static image instead (use the `Screenshot` command in VHS to generate a `PNG`). We 22 | use [git-lfs] to store the images in the repo to avoid repo bloat. 23 | 24 | [VHS]: https://github.com/charmbracelet/vhs 25 | [Widget Showcase]: https://ratatui.rs/showcase/widgets/#third-party-widgets 26 | [git-lfs]: https://git-lfs.com/ 27 | -------------------------------------------------------------------------------- /code/showcase/widget-showcase-third-party/csvlens.tape: -------------------------------------------------------------------------------- 1 | # A VHS tape. See https://github.com/charmbracelet/vhs 2 | 3 | # Assumes you have installed csvlens https://github.com/YS-L/csvlens 4 | # and grabbed a file named pokemon.csv (e.g. https://gist.github.com/armgilles/194bcff35001e7eb53a2a8b441e8b2c6) 5 | # (should be in ~/tmp/pokemon.csv) 6 | Output "csvlens.gif" 7 | Set Theme "Aardvark Blue" 8 | Set Width 1200 9 | Set Height 800 10 | Hide 11 | Type "csvlens ~/tmp/pokemon.csv" Enter 12 | Sleep 2s 13 | Show 14 | Sleep 2s 15 | Down @0.2s 23 16 | Sleep 2s 17 | Type @0.3s "/Flying" 18 | Sleep 2s 19 | Enter @2s 20 | Type @0.5s "nnnnnnn" 21 | Sleep 2s 22 | Type @0.3s "&Bug" 23 | Sleep 2s 24 | Enter @2s 25 | Down @0.5s 7 26 | Sleep 2s 27 | Type @0.3s "*Name|Leg" 28 | Sleep 2s 29 | Enter @2s 30 | Sleep 2s 31 | Hide 32 | Type "q" -------------------------------------------------------------------------------- /code/showcase/widget-showcase-third-party/throbber-widgets-tui.tape: -------------------------------------------------------------------------------- 1 | # A VHS tape. See https://github.com/charmbracelet/vhs 2 | 3 | # for running against the throbber-widgets-tui git repo https://github.com/arkbig/throbber-widgets-tui 4 | Output "throbber-widgets-tui.gif" 5 | Set Theme "Aardvark Blue" 6 | Set Width 1200 7 | Set Height 350 8 | Hide 9 | Type "cargo run --example demo" Enter 10 | Sleep 4s 11 | Show 12 | Sleep 2s 13 | -------------------------------------------------------------------------------- /code/showcase/widget-showcase-third-party/tui-nodes.tape: -------------------------------------------------------------------------------- 1 | # A VHS tape. See https://github.com/charmbracelet/vhs 2 | 3 | # for running against the tui-tree-widget git repo https://git.sr.ht/~jaxter184/tui-nodes 4 | Output "tui-nodes.gif" 5 | Set Theme "Aardvark Blue" 6 | Set Width 1200 7 | Set Height 400 8 | Set CursorBlink false 9 | Hide 10 | Type "cargo run --example tiny" Enter 11 | Sleep 4s 12 | Show 13 | Sleep 2s -------------------------------------------------------------------------------- /code/showcase/widget-showcase-third-party/tui-textarea.tape: -------------------------------------------------------------------------------- 1 | # A VHS tape. See https://github.com/charmbracelet/vhs 2 | 3 | # for running against the tui-textarea git repo https://github.com/rhysd/tui-textarea 4 | Output "tui-textarea.gif" 5 | Set Theme "Aardvark Blue" 6 | Set Width 1200 7 | Set Height 450 8 | Hide 9 | Type "cargo run --example editor --features search -- README.md" Enter 10 | Sleep 4s 11 | Show 12 | Down @200ms 10 13 | Sleep 2s 14 | Type "This is a demo of the tui-textarea crate." Enter 15 | Sleep 2s 16 | Ctrl+G 17 | Type "term.draw" 18 | Sleep 2s 19 | Enter 20 | Sleep 2s 21 | Down @200ms 10 22 | Sleep 2s 23 | Down @200ms 10 24 | Sleep 2s 25 | -------------------------------------------------------------------------------- /code/showcase/widget-showcase-third-party/tui-tree-widget.tape: -------------------------------------------------------------------------------- 1 | # A VHS tape. See https://github.com/charmbracelet/vhs 2 | 3 | # for running against the tui-tree-widget git repo https://github.com/EdJoPaTo/tui-rs-tree-widget 4 | Output "tui-tree-widget.gif" 5 | Set Theme "Aardvark Blue" 6 | Set Width 1200 7 | Set Height 450 8 | Hide 9 | Type "cargo run --example example" Enter 10 | Sleep 4s 11 | Set TypingSpeed 200ms 12 | Show 13 | Down 2 14 | Right @1s 15 | Down 2 16 | Right @1s 17 | Down 2 18 | Left @1s 5 19 | Sleep 2s 20 | -------------------------------------------------------------------------------- /code/showcase/widget-showcase-third-party/tui-widget-list.tape: -------------------------------------------------------------------------------- 1 | # A VHS tape. See https://github.com/charmbracelet/vhs 2 | 3 | # for running against the tui-tree-widget git repo https://github.com/EdJoPaTo/tui-rs-tree-widget 4 | Output "tui-widget-list.gif" 5 | Set Theme "Aardvark Blue" 6 | Set Width 1200 7 | Set Height 450 8 | Hide 9 | Type "cargo run --example demo" Enter 10 | Sleep 4s 11 | Show 12 | Down @1s 7 13 | Sleep 2s -------------------------------------------------------------------------------- /code/showcase/widget-showcase/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "widget-showcase" 3 | version.workspace = true 4 | authors.workspace = true 5 | description.workspace = true 6 | documentation.workspace = true 7 | repository.workspace = true 8 | keywords.workspace = true 9 | license.workspace = true 10 | edition.workspace = true 11 | rust-version.workspace = true 12 | publish.workspace = true 13 | 14 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 15 | 16 | [dependencies] 17 | clap = { version = "4.5.34", features = ["derive"] } 18 | color-eyre = "0.6.3" 19 | ratatui = { version = "0.29.0", features = ["all-widgets"] } 20 | time = "0.3.41" 21 | lipsum = "0.9.1" 22 | textwrap = "0.16.2" 23 | -------------------------------------------------------------------------------- /code/showcase/widget-showcase/README.md: -------------------------------------------------------------------------------- 1 | # Widget Showcase 2 | 3 | The purpose of this project is to create small single examples for display at 4 | . Contributions welcome! 5 | 6 | It's encourage to make examples of third party widgets too using this project, though if they are 7 | more advanced than the ones already in this repo (i.e. require anything beyond just rendering), you 8 | may need to add another binary to the source project. 9 | 10 | ## Contributing 11 | 12 | To add each widget: 13 | 14 | - Add a widget to `enum Widget` in [main.rs](./src/main.rs) 15 | - Add a new module to [examples.rs](./src/examples.rs) 16 | - Add a render function to the module 17 | - Call the render function from `render_frame` in `main.rs` 18 | - Create a VHS tape (copy from the existing tapes) and edit the output and screenshot 19 | - Run `~/go/bin/vhs .tape` (Install VHS from main to get the Aardvark Blue theme and the 20 | Screenshot command). 21 | - Add the image to the [widgets showcase](../../../src/content/docs/showcase/widgets.mdx) 22 | 23 | ## Design guidelines 24 | 25 | For each example 26 | 27 | - Make it look nice 28 | - Keep it consistent with the other widgets 29 | - Keep it simple (less is more) - example barchart has 3 items not 20. 30 | - Avoid animation unless necessary (probably) 31 | -------------------------------------------------------------------------------- /code/showcase/widget-showcase/bar_chart.tape: -------------------------------------------------------------------------------- 1 | # A VHS tape. See https://github.com/charmbracelet/vhs 2 | Output "../../src/content/docs/showcase/widgets/bar_chart.gif" 3 | Set Theme "Aardvark Blue" 4 | Set Width 800 5 | Set Height 300 6 | Type "cargo run -- -w bar-chart" Enter 7 | Sleep 2s 8 | Screenshot "../../src/content/docs/showcase/widgets/bar_chart.png" 9 | Sleep 1s -------------------------------------------------------------------------------- /code/showcase/widget-showcase/block.tape: -------------------------------------------------------------------------------- 1 | # A VHS tape. See https://github.com/charmbracelet/vhs 2 | Output "../../src/content/docs/showcase/widgets/block.gif" 3 | Set Theme "Aardvark Blue" 4 | Set Width 800 5 | Set Height 300 6 | Type "cargo run -- -w block" Enter 7 | Sleep 2s 8 | Screenshot "../../src/content/docs/showcase/widgets/block.png" 9 | Sleep 1s -------------------------------------------------------------------------------- /code/showcase/widget-showcase/calendar.tape: -------------------------------------------------------------------------------- 1 | # A VHS tape. See https://github.com/charmbracelet/vhs 2 | Output "../../src/content/docs/showcase/widgets/calendar.gif" 3 | Set Theme "Aardvark Blue" 4 | Set Width 800 5 | Set Height 300 6 | Type "cargo run -- -w calendar" Enter 7 | Sleep 2s 8 | Screenshot "../../src/content/docs/showcase/widgets/calendar.png" 9 | Sleep 1s -------------------------------------------------------------------------------- /code/showcase/widget-showcase/canvas.tape: -------------------------------------------------------------------------------- 1 | # A VHS tape. See https://github.com/charmbracelet/vhs 2 | Output "../../src/content/docs/showcase/widgets/canvas.gif" 3 | Set Theme "Aardvark Blue" 4 | Set Width 800 5 | Set Height 400 6 | Type "cargo run -- -w canvas" Enter 7 | Sleep 2s 8 | Screenshot "../../src/content/docs/showcase/widgets/canvas.png" 9 | Sleep 1s 10 | -------------------------------------------------------------------------------- /code/showcase/widget-showcase/chart.tape: -------------------------------------------------------------------------------- 1 | # A VHS tape. See https://github.com/charmbracelet/vhs 2 | Output "../../src/content/docs/showcase/widgets/chart.gif" 3 | Set Theme "Aardvark Blue" 4 | Set Width 800 5 | Set Height 300 6 | Type "cargo run -- -w chart" Enter 7 | Sleep 2s 8 | Screenshot "../../src/content/docs/showcase/widgets/chart.png" 9 | Sleep 1s -------------------------------------------------------------------------------- /code/showcase/widget-showcase/gauge.tape: -------------------------------------------------------------------------------- 1 | # A VHS tape. See https://github.com/charmbracelet/vhs 2 | Output "../../src/content/docs/showcase/widgets/gauge.gif" 3 | Set Theme "Aardvark Blue" 4 | Set Width 800 5 | Set Height 420 6 | Type "cargo run -- -w gauge" Enter 7 | Sleep 2s 8 | Screenshot "../../src/content/docs/showcase/widgets/gauge.png" 9 | Sleep 1s -------------------------------------------------------------------------------- /code/showcase/widget-showcase/line_gauge.tape: -------------------------------------------------------------------------------- 1 | # A VHS tape. See https://github.com/charmbracelet/vhs 2 | Output "../../src/content/docs/showcase/widgets/line_gauge.gif" 3 | Set Theme "Aardvark Blue" 4 | Set Width 800 5 | Set Height 320 6 | Type "cargo run -- -w line-gauge" Enter 7 | Sleep 2s 8 | Screenshot "../../src/content/docs/showcase/widgets/line_gauge.png" 9 | Sleep 1s -------------------------------------------------------------------------------- /code/showcase/widget-showcase/list.tape: -------------------------------------------------------------------------------- 1 | # A VHS tape. See https://github.com/charmbracelet/vhs 2 | Output "../../src/content/docs/showcase/widgets/list.gif" 3 | Set Theme "Aardvark Blue" 4 | Set Width 800 5 | Set Height 300 6 | Type "cargo run -- -w list" Enter 7 | Sleep 2s 8 | Screenshot "../../src/content/docs/showcase/widgets/list.png" 9 | Sleep 1s 10 | -------------------------------------------------------------------------------- /code/showcase/widget-showcase/paragraph.tape: -------------------------------------------------------------------------------- 1 | # A VHS tape. See https://github.com/charmbracelet/vhs 2 | Output "../../src/content/docs/showcase/widgets/paragraph.gif" 3 | Set Theme "Aardvark Blue" 4 | Set Width 800 5 | Set Height 220 6 | Type "cargo run -- -w paragraph" Enter 7 | Sleep 5s 8 | Screenshot "../../src/content/docs/showcase/widgets/paragraph.png" 9 | Sleep 1s 10 | -------------------------------------------------------------------------------- /code/showcase/widget-showcase/scrollbar.tape: -------------------------------------------------------------------------------- 1 | # A VHS tape. See https://github.com/charmbracelet/vhs 2 | Output "../../../src/content/docs/showcase/widgets/scrollbar.gif" 3 | Set Theme "Aardvark Blue" 4 | Set Width 800 5 | Set Height 450 6 | Type "cargo run -- -w scrollbar" Enter 7 | Sleep 2s 8 | Screenshot "../../../src/content/docs/showcase/widgets/scrollbar.png" 9 | Sleep 1s -------------------------------------------------------------------------------- /code/showcase/widget-showcase/sparkline.tape: -------------------------------------------------------------------------------- 1 | # A VHS tape. See https://github.com/charmbracelet/vhs 2 | Output "../../src/content/docs/showcase/widgets/sparkline.gif" 3 | Set Theme "Aardvark Blue" 4 | Set Width 800 5 | Set Height 300 6 | Type "cargo run -- -w sparkline" Enter 7 | Sleep 2s 8 | Screenshot "../../src/content/docs/showcase/widgets/sparkline.png" 9 | Sleep 1s -------------------------------------------------------------------------------- /code/showcase/widget-showcase/src/examples.rs: -------------------------------------------------------------------------------- 1 | pub mod bar_chart; 2 | pub mod block; 3 | pub mod calendar; 4 | pub mod canvas; 5 | pub mod chart; 6 | pub mod gauge; 7 | pub mod line_gauge; 8 | pub mod list; 9 | pub mod paragraph; 10 | pub mod scrollbar; 11 | pub mod sparkline; 12 | pub mod table; 13 | pub mod tabs; 14 | -------------------------------------------------------------------------------- /code/showcase/widget-showcase/src/examples/bar_chart.rs: -------------------------------------------------------------------------------- 1 | use ratatui::{prelude::*, widgets::*}; 2 | 3 | pub fn render(frame: &mut Frame) { 4 | let data = BarGroup::default().bars(&[ 5 | Bar::default() 6 | .label("Red".into()) 7 | .value(2) 8 | .style(Style::new().red()), 9 | Bar::default() 10 | .label("Green".into()) 11 | .value(7) 12 | .style(Style::new().green()), 13 | Bar::default() 14 | .label("Blue".into()) 15 | .value(11) 16 | .style(Style::new().blue()), 17 | ]); 18 | let vertical = BarChart::default() 19 | .bar_width(5) 20 | .bar_gap(1) 21 | .data(data.clone()); 22 | let horizontal = BarChart::default() 23 | .bar_width(1) 24 | .bar_gap(1) 25 | .data(data) 26 | .direction(Direction::Horizontal); 27 | let layout = Layout::default() 28 | .direction(Direction::Horizontal) 29 | .constraints([Constraint::Length(20), Constraint::Min(0)]) 30 | .split(frame.area()); 31 | frame.render_widget(vertical, layout[0]); 32 | frame.render_widget(horizontal, layout[1]); 33 | } 34 | -------------------------------------------------------------------------------- /code/showcase/widget-showcase/src/examples/block.rs: -------------------------------------------------------------------------------- 1 | use ratatui::{prelude::*, widgets::*}; 2 | 3 | pub fn render(frame: &mut Frame) { 4 | // intentionally mismatched border types to show how they look 5 | let border_set = symbols::border::Set { 6 | top_left: symbols::line::ROUNDED.top_left, 7 | top_right: symbols::line::THICK.top_right, 8 | bottom_left: symbols::line::ROUNDED.bottom_left, 9 | bottom_right: symbols::border::THICK.bottom_right, 10 | vertical_left: symbols::line::ROUNDED.vertical, 11 | vertical_right: symbols::line::THICK.vertical, 12 | horizontal_top: symbols::line::NORMAL.horizontal, 13 | horizontal_bottom: symbols::line::DOUBLE.horizontal, 14 | }; 15 | let block = Block::default() 16 | .title("Left Title".yellow()) 17 | .title(Line::from("Center title".blue()).alignment(Alignment::Center)) 18 | .title(Line::from("Right Title".green()).alignment(Alignment::Right)) 19 | .title_bottom(Line::from("Bottom Center title".blue()).alignment(Alignment::Center)) 20 | .borders(Borders::ALL) 21 | .border_set(border_set) 22 | .border_style(Style::default().fg(Color::Red)); 23 | frame.render_widget( 24 | Paragraph::new("A Block widget that wraps other widgets.".italic()) 25 | .block(block) 26 | .alignment(Alignment::Center) 27 | .wrap(Wrap { trim: true }), 28 | frame.area(), 29 | ); 30 | } 31 | -------------------------------------------------------------------------------- /code/showcase/widget-showcase/src/examples/canvas.rs: -------------------------------------------------------------------------------- 1 | use ratatui::{ 2 | prelude::*, 3 | widgets::canvas::{self, Canvas, Circle, Context, Rectangle}, 4 | }; 5 | 6 | pub fn render(frame: &mut Frame) { 7 | let canvas = Canvas::default() 8 | .x_bounds([0., 40.]) 9 | .y_bounds([0., 20.]) 10 | .paint(draw); 11 | 12 | frame.render_widget(canvas, frame.area()); 13 | } 14 | 15 | fn draw(ctx: &mut Context) { 16 | // Sky 17 | ctx.draw(&canvas::Line { 18 | x1: 0., 19 | y1: 20., 20 | x2: 32.2, 21 | y2: 20., 22 | color: Color::LightBlue, 23 | }); 24 | 25 | // Sun 26 | ctx.draw(&Circle { 27 | x: 39., 28 | y: 19., 29 | radius: 6.2, 30 | color: Color::Yellow, 31 | }); 32 | 33 | // Grass 34 | ctx.draw(&canvas::Line { 35 | x1: 0., 36 | y1: 1., 37 | x2: 40., 38 | y2: 1., 39 | color: Color::Green, 40 | }); 41 | ctx.layer(); 42 | 43 | // Trunk 44 | ctx.draw(&Rectangle { 45 | x: 9.8, 46 | y: 1., 47 | width: 2.2, 48 | height: 7., 49 | color: Color::Rgb(106, 65, 23), 50 | }); 51 | ctx.layer(); 52 | 53 | // Leaves 54 | ctx.draw(&Circle { 55 | x: 11., 56 | y: 11.2, 57 | radius: 3.5, 58 | color: Color::Green, 59 | }) 60 | } 61 | -------------------------------------------------------------------------------- /code/showcase/widget-showcase/src/examples/gauge.rs: -------------------------------------------------------------------------------- 1 | use ratatui::{prelude::*, widgets::Gauge}; 2 | 3 | pub fn render(frame: &mut Frame) { 4 | let layout = Layout::default() 5 | .direction(Direction::Vertical) 6 | .constraints(vec![ 7 | Constraint::Length(1), 8 | Constraint::Min(1), 9 | Constraint::Length(1), 10 | Constraint::Min(1), 11 | Constraint::Length(3), 12 | Constraint::Min(1), 13 | Constraint::Length(3), 14 | Constraint::Min(0), 15 | ]) 16 | .split(frame.area()); 17 | frame.render_widget( 18 | Gauge::default() 19 | .percent(50) 20 | .gauge_style(Style::new().light_red()), 21 | layout[0], 22 | ); 23 | frame.render_widget( 24 | Gauge::default() 25 | .percent(50) 26 | .label("10/20") 27 | .gauge_style(Style::new().light_green().on_green()), 28 | layout[2], 29 | ); 30 | frame.render_widget( 31 | Gauge::default() 32 | .percent(50) 33 | .gauge_style(Style::new().light_blue().on_blue()) 34 | .style(Style::new().fg(Color::White).bg(Color::Blue)), 35 | layout[4], 36 | ); 37 | frame.render_widget( 38 | Gauge::default() 39 | .ratio(0.51) 40 | .label("0.51") 41 | .use_unicode(true) 42 | .gauge_style(Style::new().white().on_dark_gray()) 43 | .style(Style::new().fg(Color::White).bg(Color::Blue)), 44 | layout[6], 45 | ); 46 | } 47 | -------------------------------------------------------------------------------- /code/showcase/widget-showcase/src/examples/list.rs: -------------------------------------------------------------------------------- 1 | use ratatui::{ 2 | prelude::*, 3 | widgets::{HighlightSpacing, List, ListState}, 4 | }; 5 | 6 | pub fn render(frame: &mut Frame) { 7 | let list = List::new([ 8 | Line::from(vec!["✔️ ".green(), "Fork tui-rs 💻".into()]), 9 | Line::from(vec![ 10 | "✔️ ".green(), 11 | "Create a ".into(), 12 | "great".italic(), 13 | " mascot 🐀".into(), 14 | ]), 15 | Line::from(vec!["✔️ ".green(), "Create a website & book 🕮".into()]), 16 | Line::from(vec!["✔️ ".green(), "Celebrate 500th commit ⭐".into()]), 17 | Line::from(vec!["✔️ ".green(), "Celebrate 1000th commit ✨".into()]), 18 | Line::from(vec!["⌛".yellow(), "Release Ratatui 1.0.0 🎉".bold()]), 19 | ]) 20 | .highlight_symbol("» ") 21 | .highlight_spacing(HighlightSpacing::Always); 22 | 23 | let mut state = ListState::default().with_selected(Some(5)); 24 | 25 | frame.render_stateful_widget(list, frame.area(), &mut state); 26 | } 27 | -------------------------------------------------------------------------------- /code/showcase/widget-showcase/src/examples/paragraph.rs: -------------------------------------------------------------------------------- 1 | use ratatui::{prelude::*, widgets::*}; 2 | 3 | pub fn render(frame: &mut Frame) { 4 | let text = vec![ 5 | Line::from("Hello, Ratatui".white().on_blue().italic()), 6 | Line::from("This is a colorful line".red().underlined()), 7 | Line::from("Be bold with your paragraphs".bold()), 8 | ]; 9 | 10 | let paragraph = Paragraph::new(text) 11 | .bold() 12 | .white() 13 | .alignment(Alignment::Center); 14 | 15 | frame.render_widget(paragraph, frame.area()); 16 | } 17 | -------------------------------------------------------------------------------- /code/showcase/widget-showcase/src/examples/sparkline.rs: -------------------------------------------------------------------------------- 1 | use ratatui::{prelude::*, widgets::*}; 2 | 3 | pub fn render(frame: &mut Frame) { 4 | let sparkline = Sparkline::default() 5 | .block(Block::default().title("Sparkline").borders(Borders::ALL)) 6 | .data([ 7 | 35, 40, 44, 49, 52, 55, 58, 59, 60, 60, 59, 57, 55, 52, 48, 44, 39, 34, 29, 24, 19, 15, 8 | 11, 7, 4, 2, 1, 0, 0, 1, 3, 6, 9, 13, 17, 22, 27, 32, 36, 41, 46, 50, 53, 56, 58, 59, 9 | 60, 60, 59, 57, 54, 51, 47, 42, 38, 33, 28, 23, 18, 10 | ]) 11 | .max(62) 12 | .direction(RenderDirection::LeftToRight) 13 | .style(Style::default().yellow()); 14 | 15 | frame.render_widget(sparkline, frame.area()); 16 | } 17 | -------------------------------------------------------------------------------- /code/showcase/widget-showcase/src/examples/tabs.rs: -------------------------------------------------------------------------------- 1 | use ratatui::{prelude::*, widgets::*}; 2 | 3 | pub fn render(frame: &mut Frame) { 4 | let tabs = Tabs::new(vec!["TODO", "IN PROGRESS", "DONE"]) 5 | .block(Block::default().title("Project").borders(Borders::ALL)) 6 | .style(Style::default().white()) 7 | .highlight_style(Style::default().underlined().bold().yellow()) 8 | .select(1) 9 | .divider(symbols::DOT) 10 | .padding(" ", " "); 11 | 12 | frame.render_widget(tabs, frame.area()); 13 | } 14 | -------------------------------------------------------------------------------- /code/showcase/widget-showcase/src/tui.rs: -------------------------------------------------------------------------------- 1 | use std::io::stdout; 2 | 3 | use ratatui::{ 4 | backend::{Backend, CrosstermBackend}, 5 | crossterm::{ 6 | terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}, 7 | ExecutableCommand, 8 | }, 9 | Terminal, 10 | }; 11 | 12 | pub fn init() -> std::io::Result> { 13 | stdout().execute(EnterAlternateScreen)?; 14 | enable_raw_mode()?; 15 | Terminal::new(CrosstermBackend::new(stdout())) 16 | } 17 | 18 | pub fn restore() -> std::io::Result<()> { 19 | stdout().execute(LeaveAlternateScreen)?; 20 | disable_raw_mode()?; 21 | Ok(()) 22 | } 23 | -------------------------------------------------------------------------------- /code/showcase/widget-showcase/table.tape: -------------------------------------------------------------------------------- 1 | # A VHS tape. See https://github.com/charmbracelet/vhs 2 | Output "../../src/content/docs/showcase/widgets/table.gif" 3 | Set Theme "Aardvark Blue" 4 | Set Width 800 5 | Set Height 320 6 | Type "cargo run -- -w table" Enter 7 | Sleep 2s 8 | Screenshot "../../src/content/docs/showcase/widgets/table.png" 9 | Sleep 1s 10 | -------------------------------------------------------------------------------- /code/showcase/widget-showcase/tabs.tape: -------------------------------------------------------------------------------- 1 | # A VHS tape. See https://github.com/charmbracelet/vhs 2 | Output "../../src/content/docs/showcase/widgets/tabs.gif" 3 | Set Theme "Aardvark Blue" 4 | Set Width 600 5 | Set Height 260 6 | Type "cargo run -- -w tabs" Enter 7 | Sleep 5s 8 | Screenshot "../../src/content/docs/showcase/widgets/tabs.png" 9 | Sleep 1s 10 | -------------------------------------------------------------------------------- /code/templates/async-template-counter/.config/config.json5: -------------------------------------------------------------------------------- 1 | { 2 | "keybindings": { 3 | "Home": { 4 | "": "Quit", // Quit the application 5 | "": "ScheduleIncrement", 6 | "": "ScheduleDecrement", 7 | "": "ToggleShowHelp", 8 | "": "EnterInsert", 9 | "": "Quit", // Another way to quit 10 | "": "Quit", // Yet another way to quit 11 | "": "Suspend", // Suspend the application 12 | }, 13 | }, 14 | } 15 | -------------------------------------------------------------------------------- /code/templates/async-template-counter/.envrc: -------------------------------------------------------------------------------- 1 | export RATATUI_COUNTER_CONFIG=`pwd`/.config 2 | export RATATUI_COUNTER_DATA=`pwd`/.data 3 | export RATATUI_COUNTER_LOG_LEVEL=debug 4 | -------------------------------------------------------------------------------- /code/templates/async-template-counter/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /code/templates/async-template-counter/.rustfmt.toml: -------------------------------------------------------------------------------- 1 | max_width = 120 2 | use_small_heuristics = "Max" 3 | match_block_trailing_comma = true 4 | reorder_imports = true 5 | tab_spaces = 2 6 | use_field_init_shorthand = true 7 | use_try_shorthand = true 8 | -------------------------------------------------------------------------------- /code/templates/async-template-counter/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "ratatui-counter" 3 | version = "0.1.0" 4 | edition = "2021" 5 | description = "Counter application with async-template" 6 | authors = ["Dheepak Krishnamurthy"] 7 | 8 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 9 | 10 | [dependencies] 11 | better-panic = "0.3.0" 12 | clap = { version = "4.5.16", features = [ 13 | "std", 14 | "color", 15 | "help", 16 | "usage", 17 | "error-context", 18 | "suggestions", 19 | "derive", 20 | "cargo", 21 | "wrap_help", 22 | "unicode", 23 | "string", 24 | "unstable-styles", 25 | ] } 26 | color-eyre = "0.6.3" 27 | config = "0.14.0" 28 | crossterm = { version = "0.28.1", features = ["serde", "event-stream"] } 29 | derive_deref = "1.1.1" 30 | directories = "5.0.1" 31 | futures = "0.3.30" 32 | human-panic = "2.0.1" 33 | json5 = "0.4.1" 34 | lazy_static = "1.5.0" 35 | libc = "0.2.158" 36 | log = "0.4.22" 37 | pretty_assertions = "1.4.0" 38 | ratatui = { version = "0.28.1", features = ["serde", "macros"] } 39 | serde = { version = "1.0.209", features = ["derive"] } 40 | serde_json = "1.0.127" 41 | signal-hook = "0.3.17" 42 | strip-ansi-escapes = "0.2.0" 43 | strum = { version = "0.26.3", features = ["derive"] } 44 | tokio = { version = "1.39.3", features = ["full"] } 45 | tokio-util = "0.7.11" 46 | tracing = "0.1.37" 47 | tracing-error = "0.2.0" 48 | tracing-subscriber = { version = "0.3.17", features = ["env-filter", "serde"] } 49 | tui-input = { version = "0.10.1", features = ["serde"] } 50 | -------------------------------------------------------------------------------- /code/templates/async-template-counter/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Dheepak Krishnamurthy 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /code/templates/async-template-counter/README.md: -------------------------------------------------------------------------------- 1 | # ratatui-counter 2 | 3 | Counter application with async-template 4 | 5 | ## Run demo 6 | 7 | ```rust 8 | export RATATUI_COUNTER_CONFIG=`pwd`/.config 9 | export RATATUI_COUNTER_DATA=`pwd`/.data 10 | export RATATUI_COUNTER_LOG_LEVEL=debug 11 | 12 | cargo run 13 | ``` 14 | 15 | ![](https://user-images.githubusercontent.com/1813121/271287288-057a0fe9-9f6d-4f8c-963c-ca2725721bdd.gif) 16 | -------------------------------------------------------------------------------- /code/templates/async-template-counter/rust-toolchain.toml: -------------------------------------------------------------------------------- 1 | [toolchain] 2 | channel = "stable" 3 | -------------------------------------------------------------------------------- /code/templates/async-template-counter/src/action.rs: -------------------------------------------------------------------------------- 1 | use std::{fmt, string::ToString}; 2 | 3 | use serde::{ 4 | de::{self, Deserializer, Visitor}, 5 | Deserialize, Serialize, 6 | }; 7 | use strum::Display; 8 | 9 | // ANCHOR: action_enum 10 | #[derive(Debug, Clone, PartialEq, Eq, Serialize, Display, Deserialize)] 11 | pub enum Action { 12 | Tick, 13 | Render, 14 | Resize(u16, u16), 15 | Suspend, 16 | Resume, 17 | Quit, 18 | Refresh, 19 | Error(String), 20 | Help, 21 | ToggleShowHelp, 22 | ScheduleIncrement, 23 | ScheduleDecrement, 24 | Increment(usize), 25 | Decrement(usize), 26 | CompleteInput(String), 27 | EnterNormal, 28 | EnterInsert, 29 | EnterProcessing, 30 | ExitProcessing, 31 | Update, 32 | } 33 | // ANCHOR_END: action_enum 34 | -------------------------------------------------------------------------------- /code/templates/async-template-counter/src/cli.rs: -------------------------------------------------------------------------------- 1 | use std::path::PathBuf; 2 | 3 | use clap::Parser; 4 | 5 | use crate::utils::version; 6 | 7 | #[derive(Parser, Debug)] 8 | #[command(author, version = version(), about)] 9 | pub struct Cli { 10 | #[arg(short, long, value_name = "FLOAT", help = "Tick rate, i.e. number of ticks per second", default_value_t = 1.0)] 11 | pub tick_rate: f64, 12 | 13 | #[arg( 14 | short, 15 | long, 16 | value_name = "FLOAT", 17 | help = "Frame rate, i.e. number of frames per second", 18 | default_value_t = 60.0 19 | )] 20 | pub frame_rate: f64, 21 | } 22 | -------------------------------------------------------------------------------- /code/templates/async-template-counter/src/components.rs: -------------------------------------------------------------------------------- 1 | use color_eyre::eyre::Result; 2 | use ratatui::{ 3 | crossterm::event::{KeyEvent, MouseEvent}, 4 | layout::Rect, 5 | Frame, 6 | }; 7 | use tokio::sync::mpsc::UnboundedSender; 8 | 9 | use crate::{action::Action, config::Config, tui::Event}; 10 | 11 | pub mod fps; 12 | pub mod home; 13 | 14 | // ANCHOR: component 15 | pub trait Component { 16 | #[allow(unused_variables)] 17 | fn register_action_handler(&mut self, tx: UnboundedSender) -> Result<()> { 18 | Ok(()) 19 | } 20 | #[allow(unused_variables)] 21 | fn register_config_handler(&mut self, config: Config) -> Result<()> { 22 | Ok(()) 23 | } 24 | fn init(&mut self) -> Result<()> { 25 | Ok(()) 26 | } 27 | fn handle_events(&mut self, event: Option) -> Result> { 28 | let r = match event { 29 | Some(Event::Key(key_event)) => self.handle_key_events(key_event)?, 30 | Some(Event::Mouse(mouse_event)) => self.handle_mouse_events(mouse_event)?, 31 | _ => None, 32 | }; 33 | Ok(r) 34 | } 35 | #[allow(unused_variables)] 36 | fn handle_key_events(&mut self, key: KeyEvent) -> Result> { 37 | Ok(None) 38 | } 39 | #[allow(unused_variables)] 40 | fn handle_mouse_events(&mut self, mouse: MouseEvent) -> Result> { 41 | Ok(None) 42 | } 43 | #[allow(unused_variables)] 44 | fn update(&mut self, action: Action) -> Result> { 45 | Ok(None) 46 | } 47 | fn draw(&mut self, f: &mut Frame, rect: Rect) -> Result<()>; 48 | } 49 | // ANCHOR_END: component 50 | -------------------------------------------------------------------------------- /code/templates/async-template-counter/src/main.rs: -------------------------------------------------------------------------------- 1 | #![allow(dead_code)] 2 | #![allow(unused_imports)] 3 | #![allow(unused_variables)] 4 | 5 | // ANCHOR: all 6 | pub mod action; 7 | pub mod app; 8 | pub mod cli; 9 | pub mod components; 10 | pub mod config; 11 | pub mod tui; 12 | pub mod utils; 13 | 14 | use clap::Parser; 15 | use cli::Cli; 16 | use color_eyre::eyre::Result; 17 | 18 | use crate::{ 19 | app::App, 20 | utils::{initialize_logging, initialize_panic_handler, version}, 21 | }; 22 | 23 | async fn tokio_main() -> Result<()> { 24 | initialize_logging()?; 25 | 26 | initialize_panic_handler()?; 27 | 28 | let args = Cli::parse(); 29 | let mut app = App::new(args.tick_rate, args.frame_rate)?; 30 | app.run().await?; 31 | 32 | Ok(()) 33 | } 34 | 35 | #[tokio::main] 36 | async fn main() -> Result<()> { 37 | if let Err(e) = tokio_main().await { 38 | eprintln!("{} error: Something went wrong", env!("CARGO_PKG_NAME")); 39 | Err(e) 40 | } else { 41 | Ok(()) 42 | } 43 | } 44 | // ANCHOR_END: all 45 | -------------------------------------------------------------------------------- /code/tutorials/counter-app-basic/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "counter-app-basic" 3 | version.workspace = true 4 | authors.workspace = true 5 | description.workspace = true 6 | documentation.workspace = true 7 | repository.workspace = true 8 | keywords.workspace = true 9 | license.workspace = true 10 | edition.workspace = true 11 | rust-version.workspace = true 12 | publish.workspace = true 13 | 14 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 15 | 16 | # ANCHOR: dependencies 17 | [dependencies] 18 | ratatui = "0.29.0" 19 | crossterm = "0.28.1" 20 | # ANCHOR_END: dependencies 21 | -------------------------------------------------------------------------------- /code/tutorials/counter-app-basic/basic-app-error.tape: -------------------------------------------------------------------------------- 1 | # This requires vhs installed from source for the updated theme and screenshot command 2 | # go install github.com/charmbracelet/vhs@main 3 | Output "../../src/content/docs/tutorials/counter-app/basic-app/basic-app-error.gif" 4 | Set Theme "Aardvark Blue" 5 | Set Width 1200 6 | Set Height 400 7 | Type "cargo run" Enter 8 | Sleep 3s 9 | Set TypingSpeed 500ms 10 | Left 11 | Sleep 1s 12 | Screenshot "../../src/content/docs/tutorials/counter-app/basic-app/basic-app-error.png" 13 | Sleep 1s 14 | -------------------------------------------------------------------------------- /code/tutorials/counter-app-basic/basic-app.tape: -------------------------------------------------------------------------------- 1 | # This requires vhs installed from source for the updated theme and screenshot command 2 | # go install github.com/charmbracelet/vhs@main 3 | Output "../../src/content/docs/tutorials/counter-app/basic-app/basic-app.gif" 4 | Set Theme "Aardvark Blue" 5 | Set Width 1200 6 | Set Height 400 7 | Type "cargo run" Enter 8 | Sleep 3s 9 | Screenshot "../../src/content/docs/tutorials/counter-app/basic-app/basic-app.png" 10 | Set TypingSpeed 500ms 11 | Right 3 12 | Sleep 1s 13 | Left 3 14 | Sleep 2s 15 | Type "q" 16 | Sleep 2s 17 | -------------------------------------------------------------------------------- /code/tutorials/counter-app-error-handling/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "counter-app-error-handling" 3 | version.workspace = true 4 | authors.workspace = true 5 | description.workspace = true 6 | documentation.workspace = true 7 | repository.workspace = true 8 | keywords.workspace = true 9 | license.workspace = true 10 | edition.workspace = true 11 | rust-version.workspace = true 12 | publish.workspace = true 13 | 14 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 15 | 16 | # ANCHOR: dependencies 17 | [dependencies] 18 | color-eyre = "0.6.3" 19 | ratatui = "0.29.0" 20 | # ANCHOR_END: dependencies 21 | -------------------------------------------------------------------------------- /code/tutorials/counter-app-error-handling/error-full.tape: -------------------------------------------------------------------------------- 1 | # This requires vhs installed from source for the updated theme and screenshot command 2 | # go install github.com/charmbracelet/vhs@main 3 | Output "../../src/content/docs/tutorials/counter-app/error-handling/error-full.gif" 4 | Set Theme "Aardvark Blue" 5 | Set Width 1280 6 | Set Height 1850 7 | Type "RUST_BACKTRACE=full cargo run" Enter 8 | Sleep 2s 9 | Right 3 10 | Sleep 3s 11 | Screenshot "../../src/content/docs/tutorials/counter-app/error-handling/error-full.png" 12 | -------------------------------------------------------------------------------- /code/tutorials/counter-app-error-handling/error.tape: -------------------------------------------------------------------------------- 1 | # This requires vhs installed from source for the updated theme and screenshot command 2 | # go install github.com/charmbracelet/vhs@main 3 | Output "../../src/content/docs/tutorials/counter-app/error-handling/error.gif" 4 | Set Theme "Aardvark Blue" 5 | Set Width 1280 6 | Set Height 600 7 | Type "cargo run" Enter 8 | Sleep 2s 9 | Right 3 10 | Sleep 3s 11 | Screenshot "../../src/content/docs/tutorials/counter-app/error-handling/error.png" -------------------------------------------------------------------------------- /code/tutorials/counter-app-error-handling/generate-demos.sh: -------------------------------------------------------------------------------- 1 | #/bin/bash 2 | 3 | for i in *.tape; do 4 | vhs $i 5 | done 6 | rm -f basic-app-*.gif 7 | -------------------------------------------------------------------------------- /code/tutorials/counter-app-error-handling/panic-full.tape: -------------------------------------------------------------------------------- 1 | # This requires vhs installed from source for the updated theme and screenshot command 2 | # go install github.com/charmbracelet/vhs@main 3 | Output "../../src/content/docs/tutorials/counter-app/error-handling/panic-full.gif" 4 | Set Theme "Aardvark Blue" 5 | Set Width 1280 6 | Set Height 1400 7 | Type "RUST_BACKTRACE=full cargo run" Enter 8 | Sleep 2s 9 | Left 10 | Sleep 1s 11 | Screenshot "../../src/content/docs/tutorials/counter-app/error-handling/panic-full.png" 12 | -------------------------------------------------------------------------------- /code/tutorials/counter-app-error-handling/panic.tape: -------------------------------------------------------------------------------- 1 | # This requires vhs installed from source for the updated theme and screenshot command 2 | # go install github.com/charmbracelet/vhs@main 3 | Output "../../src/content/docs/tutorials/counter-app/error-handling/panic.gif" 4 | Set Theme "Aardvark Blue" 5 | Set Width 1280 6 | Set Height 450 7 | Type "cargo run" Enter 8 | Sleep 2s 9 | Left 10 | Sleep 3s 11 | Screenshot "../../src/content/docs/tutorials/counter-app/error-handling/panic.png" 12 | -------------------------------------------------------------------------------- /code/tutorials/counter-app-error-handling/src/tui.rs: -------------------------------------------------------------------------------- 1 | // ANCHOR: all 2 | // ANCHOR: imports 3 | use std::io::{self, stdout, Stdout}; 4 | 5 | use ratatui::{ 6 | backend::CrosstermBackend, 7 | crossterm::{ 8 | execute, 9 | terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}, 10 | }, 11 | Terminal, 12 | }; 13 | // ANCHOR_END: imports 14 | 15 | /// A type alias for the terminal type used in this application 16 | pub type Tui = Terminal>; 17 | 18 | // ANCHOR: init 19 | /// Initialize the terminal 20 | pub fn init() -> io::Result { 21 | execute!(stdout(), EnterAlternateScreen)?; 22 | enable_raw_mode()?; 23 | set_panic_hook(); 24 | Terminal::new(CrosstermBackend::new(stdout())) 25 | } 26 | 27 | fn set_panic_hook() { 28 | let hook = std::panic::take_hook(); 29 | std::panic::set_hook(Box::new(move |panic_info| { 30 | let _ = restore(); // ignore any errors as we are already failing 31 | hook(panic_info); 32 | })); 33 | } 34 | // ANCHOR_END: init 35 | 36 | // ANCHOR: restore 37 | /// Restore the terminal to its original state 38 | pub fn restore() -> io::Result<()> { 39 | execute!(stdout(), LeaveAlternateScreen)?; 40 | disable_raw_mode()?; 41 | Ok(()) 42 | } 43 | // ANCHOR_END: restore 44 | // ANCHOR_END: all 45 | -------------------------------------------------------------------------------- /code/tutorials/hello-ratatui.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:8c90f88829204b1aa62c63fb0fb5021adb3cba92dc94787e3ec0dfc38aa25ffb 3 | size 8355 4 | -------------------------------------------------------------------------------- /code/tutorials/hello-ratatui.tape: -------------------------------------------------------------------------------- 1 | # A VHS tape. See https://github.com/charmbracelet/vhs 2 | Output hello-ratatui.gif 3 | Set Theme "Aardvark Blue" 4 | Set Width 1200 5 | Set Height 450 6 | Type "cargo run -p hello-ratatui" 7 | Enter 8 | Sleep 7s 9 | Screenshot hello-ratatui.png 10 | Sleep 1s 11 | Type q 12 | Sleep 2s 13 | -------------------------------------------------------------------------------- /code/tutorials/hello-ratatui/.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | # Maintain dependencies for Cargo 9 | - package-ecosystem: "cargo" 10 | directory: "/" # Location of package manifests 11 | schedule: 12 | interval: "weekly" 13 | # Maintain dependencies for GitHub Actions 14 | - package-ecosystem: github-actions 15 | directory: "/" 16 | schedule: 17 | interval: weekly 18 | -------------------------------------------------------------------------------- /code/tutorials/hello-ratatui/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "hello-ratatui" 3 | version = "0.1.0" 4 | authors = ["Josh McKinney "] 5 | license = "MIT" 6 | edition = "2021" 7 | 8 | [dependencies] 9 | color-eyre = "0.6.3" 10 | crossterm = "0.28.1" 11 | ratatui = "0.29.0" 12 | -------------------------------------------------------------------------------- /code/tutorials/hello-ratatui/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) Josh McKinney 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /code/tutorials/hello-ratatui/README.md: -------------------------------------------------------------------------------- 1 | # hello-ratatui 2 | 3 | This is a [Ratatui] app generated by the [Hello World template]. 4 | 5 | [Ratatui]: https://ratatui.rs 6 | [Hello World Template]: https://github.com/ratatui/templates/tree/main/hello-world 7 | 8 | ## License 9 | 10 | Copyright (c) Josh McKinney 11 | 12 | This project is licensed under the MIT license ([LICENSE] or ) 13 | 14 | [LICENSE]: ./LICENSE 15 | -------------------------------------------------------------------------------- /code/tutorials/hello-ratatui/src/main.rs: -------------------------------------------------------------------------------- 1 | use color_eyre::Result; 2 | use crossterm::event::{self, Event}; 3 | use ratatui::{DefaultTerminal, Frame}; 4 | 5 | fn main() -> Result<()> { 6 | color_eyre::install()?; 7 | let terminal = ratatui::init(); 8 | let result = run(terminal); 9 | ratatui::restore(); 10 | result 11 | } 12 | 13 | fn run(mut terminal: DefaultTerminal) -> Result<()> { 14 | loop { 15 | terminal.draw(render)?; 16 | if matches!(event::read()?, Event::Key(_)) { 17 | break Ok(()); 18 | } 19 | } 20 | } 21 | 22 | fn render(frame: &mut Frame) { 23 | frame.render_widget("hello world", frame.area()); 24 | } 25 | -------------------------------------------------------------------------------- /code/tutorials/hello.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:365ad70a037fdba27514dfcea090413694d3523e00abc69e1e16b576dcc71eed 3 | size 1845297 4 | -------------------------------------------------------------------------------- /code/tutorials/json-editor/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "json-editor" 3 | version.workspace = true 4 | edition.workspace = true 5 | authors.workspace = true 6 | license.workspace = true 7 | publish.workspace = true 8 | 9 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 10 | 11 | [dependencies] 12 | ratatui = "0.29.0" 13 | serde = { version = "1.0.219", features = ["derive"] } 14 | serde_json = "1.0.140" 15 | -------------------------------------------------------------------------------- /code/tutorials/json-editor/demo.tape: -------------------------------------------------------------------------------- 1 | # A VHS tape. See https://github.com/charmbracelet/vhs 2 | Output demo.gif 3 | Set Width 1600 4 | Set Height 900 5 | 6 | # setup 7 | Hide 8 | Type "cargo run" 9 | Enter 10 | Sleep 10s 11 | 12 | # demo 13 | Show 14 | Sleep 3s 15 | Type e 16 | Type "key" 17 | Sleep 2s 18 | Tab 19 | Type "value" 20 | Sleep 2s 21 | Enter 22 | Sleep 2s 23 | Type q 24 | Sleep 2s 25 | Type y 26 | Sleep 3s 27 | -------------------------------------------------------------------------------- /code/tutorials/json-editor/shell.nix: -------------------------------------------------------------------------------- 1 | # 2 | { pkgs ? import {}}: 3 | 4 | let 5 | rust_overlay = import (builtins.fetchTarball "https://github.com/oxalica/rust-overlay/archive/master.tar.gz"); 6 | pkgs = import { overlays = [ rust_overlay ]; }; 7 | ruststable = (pkgs.rust-bin.stable.latest.default.override { 8 | extensions = [ 9 | "rust-src" 10 | ]; 11 | }); 12 | in 13 | pkgs.mkShell { 14 | buildInputs = with pkgs; [ 15 | ruststable 16 | rust-analyzer 17 | bacon 18 | commitizen 19 | #pkg-config 20 | ]; 21 | } 22 | -------------------------------------------------------------------------------- /code/tutorials/quickstart-ratatui/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "quickstart-ratatui" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | ratatui = "0.29.0" 10 | -------------------------------------------------------------------------------- /code/tutorials/quickstart-ratatui/src/main.rs: -------------------------------------------------------------------------------- 1 | use ratatui::{ 2 | backend::CrosstermBackend, 3 | layout::Margin, 4 | widgets::{Block, Paragraph}, 5 | Terminal, 6 | }; 7 | 8 | fn main() -> Result<(), Box> { 9 | let mut terminal = Terminal::new(CrosstermBackend::new(std::io::stdout()))?; 10 | 11 | terminal.draw(|frame| { 12 | let widget = Paragraph::new("Hello world!") 13 | .centered() 14 | .block(Block::bordered()); 15 | 16 | let area = frame.area().inner(Margin { 17 | horizontal: 2, 18 | vertical: 2, 19 | }); 20 | 21 | frame.render_widget(widget, area); 22 | })?; 23 | 24 | std::thread::sleep(std::time::Duration::from_secs(5)); 25 | 26 | Ok(()) 27 | } 28 | -------------------------------------------------------------------------------- /code/tutorials/ratatui-counter-app/.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /code/tutorials/ratatui-counter-app/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "ratatui-counter-app" 3 | version = "0.1.0" 4 | authors = ["Dheepak Krishnamurthy "] 5 | license = "MIT" 6 | edition = "2021" 7 | publish.workspace = true 8 | 9 | [dependencies] 10 | color-eyre = "0.6.3" 11 | ratatui = "0.29.0" 12 | -------------------------------------------------------------------------------- /code/tutorials/ratatui-counter-app/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2023 Ratatui Developers 2 | 3 | Permission is hereby granted, free of charge, to any 4 | person obtaining a copy of this software and associated 5 | documentation files (the "Software"), to deal in the 6 | Software without restriction, including without 7 | limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software 10 | is furnished to do so, subject to the following 11 | conditions: 12 | 13 | The above copyright notice and this permission notice 14 | shall be included in all copies or substantial portions 15 | of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 18 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 19 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 21 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 24 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 | DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /code/tutorials/ratatui-counter-app/src/main.rs: -------------------------------------------------------------------------------- 1 | // ANCHOR: imports_main 2 | // ANCHOR: declare_mods 3 | /// Application. 4 | pub mod app; 5 | 6 | /// Terminal events handler. 7 | pub mod event; 8 | 9 | /// Widget renderer. 10 | pub mod ui; 11 | 12 | /// Terminal user interface. 13 | pub mod tui; 14 | 15 | /// Application updater. 16 | pub mod update; 17 | // ANCHOR_END: declare_mods 18 | use app::App; 19 | use color_eyre::Result; 20 | use event::{Event, EventHandler}; 21 | use ratatui::{backend::CrosstermBackend, Terminal}; 22 | use tui::Tui; 23 | use update::update; 24 | // ANCHOR_END: imports_main 25 | 26 | // ANCHOR: main 27 | fn main() -> Result<()> { 28 | // Create an application. 29 | let mut app = App::new(); 30 | 31 | // Initialize the terminal user interface. 32 | let backend = CrosstermBackend::new(std::io::stderr()); 33 | let terminal = Terminal::new(backend)?; 34 | let events = EventHandler::new(250); 35 | let mut tui = Tui::new(terminal, events); 36 | tui.enter()?; 37 | 38 | // Start the main loop. 39 | while !app.should_quit { 40 | // Render the user interface. 41 | tui.draw(&mut app)?; 42 | // Handle events. 43 | match tui.events.next()? { 44 | Event::Tick => {} 45 | Event::Key(key_event) => update(&mut app, key_event), 46 | Event::Mouse(_) => {} 47 | Event::Resize(_, _) => {} 48 | }; 49 | } 50 | 51 | // Exit the user interface. 52 | tui.exit()?; 53 | Ok(()) 54 | } 55 | // ANCHOR_END: main 56 | -------------------------------------------------------------------------------- /code/tutorials/ratatui-counter-app/src/ui.rs: -------------------------------------------------------------------------------- 1 | use ratatui::{ 2 | layout::Alignment, 3 | style::{Color, Style}, 4 | widgets::{Block, BorderType, Borders, Paragraph}, 5 | Frame, 6 | }; 7 | 8 | use crate::app::App; 9 | 10 | pub fn render(app: &mut App, frame: &mut Frame) { 11 | frame.render_widget( 12 | Paragraph::new(format!( 13 | " 14 | Press `Esc`, `Ctrl-C` or `q` to stop running.\n\ 15 | Press `j` and `k` to increment and decrement the counter respectively.\n\ 16 | Counter: {} 17 | ", 18 | app.counter 19 | )) 20 | .block( 21 | Block::default() 22 | .title("Counter App") 23 | .title_alignment(Alignment::Center) 24 | .borders(Borders::ALL) 25 | .border_type(BorderType::Rounded), 26 | ) 27 | .style(Style::default().fg(Color::Yellow)) 28 | .alignment(Alignment::Center), 29 | frame.area(), 30 | ) 31 | } 32 | -------------------------------------------------------------------------------- /code/tutorials/ratatui-counter-app/src/update.rs: -------------------------------------------------------------------------------- 1 | use ratatui::crossterm::event::{KeyCode, KeyEvent, KeyModifiers}; 2 | 3 | use crate::app::App; 4 | 5 | pub fn update(app: &mut App, key_event: KeyEvent) { 6 | match key_event.code { 7 | KeyCode::Esc | KeyCode::Char('q') => app.quit(), 8 | KeyCode::Char('c') | KeyCode::Char('C') => { 9 | if key_event.modifiers == KeyModifiers::CONTROL { 10 | app.quit() 11 | } 12 | } 13 | KeyCode::Right | KeyCode::Char('j') => app.increment_counter(), 14 | KeyCode::Left | KeyCode::Char('k') => app.decrement_counter(), 15 | _ => {} 16 | }; 17 | } 18 | -------------------------------------------------------------------------------- /code/tutorials/ratatui-counter-async-app/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "ratatui-counter-async-app" 3 | version.workspace = true 4 | edition.workspace = true 5 | authors.workspace = true 6 | license.workspace = true 7 | publish.workspace = true 8 | 9 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 10 | 11 | [dependencies] 12 | better-panic = "0.3.0" 13 | clap = { version = "4.5.34", features = [ 14 | "derive", 15 | "cargo", 16 | "wrap_help", 17 | "unicode", 18 | "string", 19 | "unstable-styles", 20 | ] } 21 | color-eyre = "0.6.3" 22 | config = "0.15.11" 23 | crossterm = { version = "0.28.1", features = ["serde", "event-stream"] } 24 | derive_deref = "1.1.1" 25 | directories = "6.0.0" 26 | futures = "0.3.31" 27 | human-panic = "2.0.2" 28 | json5 = "0.4.1" 29 | lazy_static = "1.5.0" 30 | libc = "0.2.171" 31 | log = "0.4.27" 32 | pretty_assertions = "1.4.1" 33 | ratatui = { version = "0.29.0", features = ["serde", "macros"] } 34 | serde = { version = "1.0.219", features = ["derive"] } 35 | serde_json = "1.0.140" 36 | signal-hook = "0.3.17" 37 | strip-ansi-escapes = "0.2.1" 38 | tokio = { version = "1.44.1", features = ["full"] } 39 | tokio-util = "0.7.14" 40 | tracing = "0.1.41" 41 | tracing-error = "0.2.1" 42 | tracing-subscriber = { version = "0.3.19", features = ["env-filter", "serde"] } 43 | -------------------------------------------------------------------------------- /code/tutorials/ratatui-stopwatch-app/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "ratatui-stopwatch-app" 3 | version.workspace = true 4 | edition.workspace = true 5 | authors.workspace = true 6 | license.workspace = true 7 | publish.workspace = true 8 | 9 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 10 | 11 | [dependencies] 12 | color-eyre = "0.6.3" 13 | crossterm = { version = "0.28.1", features = ["event-stream"] } 14 | directories = "6.0.0" 15 | futures = "0.3.31" 16 | human-panic = "2.0.2" 17 | itertools = "0.14.0" 18 | libc = "0.2.171" 19 | log = "0.4.27" 20 | ratatui = "0.29.0" 21 | strip-ansi-escapes = "0.2.1" 22 | strum = { version = "0.27.1", features = ["derive"] } 23 | tokio = { version = "1.44.1", features = ["full"] } 24 | tokio-util = "0.7.14" 25 | tui-big-text = "0.7.1" 26 | -------------------------------------------------------------------------------- /public/csvlens.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:e4a95dab039ab6ec2e4cfb42d2f36258157f7cbd93d4a4fb35047336c93cec4f 3 | size 1506265 4 | -------------------------------------------------------------------------------- /public/favicon-32.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:dc7bbc5dac40070826467e0db1e24e4adf8fc3ccca6889a20f613dd0dea7be89 3 | size 416 4 | -------------------------------------------------------------------------------- /public/ratatui-og.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:c61fdfe020a3afb689ebf307a14eadbdc5e53572d16ee98a368668eeb153a55c 3 | size 21716 4 | -------------------------------------------------------------------------------- /src/assets/hero-dark.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:a2f815478b6ccd4efabb98d9822f7ae10b2f82429ddbbbf59c9a11b02f9ab00d 3 | size 10797 4 | -------------------------------------------------------------------------------- /src/assets/hero-dark.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ratatui/ratatui-website/68c730a9a9a245c842f7e2e90781096014f057d1/src/assets/hero-dark.xcf -------------------------------------------------------------------------------- /src/assets/hero-light.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:35747262b739bce66b19840d0f3106334e33972cba1bfed7305647ef682e7dad 3 | size 10552 4 | -------------------------------------------------------------------------------- /src/assets/hero-light.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ratatui/ratatui-website/68c730a9a9a245c842f7e2e90781096014f057d1/src/assets/hero-light.xcf -------------------------------------------------------------------------------- /src/assets/logo-dark.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:1bc803e107b734473174ba3128708231b1bd2d3381c01b2f8a479521feebe158 3 | size 7445 4 | -------------------------------------------------------------------------------- /src/assets/logo-light.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:2579755f70d91631f17c078e092249f1ffdefd949c56dac76ac4d76fe7ffcdbd 3 | size 7453 4 | -------------------------------------------------------------------------------- /src/assets/logo.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ratatui/ratatui-website/68c730a9a9a245c842f7e2e90781096014f057d1/src/assets/logo.xcf -------------------------------------------------------------------------------- /src/assets/ratatui-animation.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:5157ed6aad5b92b151597755252b63948f4a8705dd646dc55bed01164565a521 3 | size 3853745 4 | -------------------------------------------------------------------------------- /src/assets/ratatui.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:735a3e02a47e410d8b66e53e594c9e6e3b84f76a3f647c621b0be509216adb2d 3 | size 117681 4 | -------------------------------------------------------------------------------- /src/assets/ratatui.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ratatui/ratatui-website/68c730a9a9a245c842f7e2e90781096014f057d1/src/assets/ratatui.webp -------------------------------------------------------------------------------- /src/components/Head.astro: -------------------------------------------------------------------------------- 1 | --- 2 | import type { Props } from "@astrojs/starlight/props"; 3 | import Default from "@astrojs/starlight/components/Head.astro"; 4 | --- 5 | 6 | 7 | 8 | 13 | -------------------------------------------------------------------------------- /src/components/fluid-grid.astro: -------------------------------------------------------------------------------- 1 | --- 2 | // source: https://github.com/withastro/starlight/blob/main/docs/src/components/media-card.astro 3 | interface Props { 4 | minColumnWidth?: string; 5 | } 6 | const { minColumnWidth } = Astro.props; 7 | --- 8 | 9 |
10 | 11 | 23 | -------------------------------------------------------------------------------- /src/components/media-card.astro: -------------------------------------------------------------------------------- 1 | --- 2 | // source: https://github.com/withastro/starlight/blob/main/docs/src/components/media-card.astro 3 | interface Props { 4 | href?: string | undefined; 5 | } 6 | const { href } = Astro.props; 7 | const El = href ? "a" : "span"; 8 | --- 9 | 10 |
  • 11 | 12 |
    13 | 14 |
    15 |
  • 16 | 17 | 50 | -------------------------------------------------------------------------------- /src/components/youtube-card.astro: -------------------------------------------------------------------------------- 1 | --- 2 | // source: https://github.com/withastro/starlight/blob/main/docs/src/components/media-card.astro 3 | import { YouTube } from "@astro-community/astro-embed-youtube"; 4 | import MediaCard from "./media-card.astro"; 5 | 6 | export interface Props { 7 | href: string; 8 | title: string; 9 | description?: string; 10 | } 11 | import { marked } from "marked"; 12 | const { href, title, description } = Astro.props; 13 | let description_markdown = marked.parse(description || ""); 14 | --- 15 | 16 | 17 | 18 |
    19 |

    {title}

    20 | {description &&

    } 21 |

    22 |
    23 | 24 | 38 | -------------------------------------------------------------------------------- /src/components/youtube-grid.astro: -------------------------------------------------------------------------------- 1 | --- 2 | // source: https://github.com/withastro/starlight/blob/main/docs/src/components/media-card.astro 3 | import FluidGrid from "./fluid-grid.astro"; 4 | import YoutubeCard, { type Props as CardProps } from "./youtube-card.astro"; 5 | 6 | interface Props { 7 | videos: CardProps[]; 8 | } 9 | --- 10 | 11 | 12 | {Astro.props.videos.map((video) => )} 13 | 14 | -------------------------------------------------------------------------------- /src/content/config.ts: -------------------------------------------------------------------------------- 1 | import { docsSchema } from "@astrojs/starlight/schema"; 2 | import { defineCollection } from "astro:content"; 3 | 4 | export const collections = { 5 | docs: defineCollection({ schema: docsSchema() }), 6 | }; 7 | -------------------------------------------------------------------------------- /src/content/docs/concepts/application-patterns/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Application Patterns 3 | sidebar: 4 | order: 0 5 | --- 6 | 7 | This page covers several patterns one can use for their application and acts as a top-level page for 8 | the following articles where these patterns are explored more in-depth. 9 | 10 | - [The Elm Architecture](./the-elm-architecture/) 11 | - [Component Architecture](./component-architecture/) 12 | - [Flux Architecture](./flux-architecture/) 13 | -------------------------------------------------------------------------------- /src/content/docs/concepts/backends/comparison.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Comparison of Backends 3 | sidebar: 4 | order: 1 5 | label: Comparison 6 | --- 7 | 8 | :::tip[TLDR] 9 | 10 | Choose [Crossterm](https://crates.io/crates/crossterm) for most tasks. 11 | 12 | ::: 13 | 14 | Ratatui interfaces with the terminal emulator through its "backends". These are powerful libraries 15 | that grant `ratatui` the ability to capture keypresses, maneuver the cursor, style the text with 16 | colors and other features. As of now, `ratatui` supports three backends: 17 | 18 | - [Crossterm](https://crates.io/crates/crossterm) 19 | - [Termion](https://crates.io/crates/termion) 20 | - [Termwiz](https://crates.io/crates/termwiz) 21 | 22 | Selecting a backend does influence your project's structure, but the core functionalities remain 23 | consistent across all options. Here's a flowchart that can help you make your decision. 24 | 25 | ```mermaid 26 | graph TD; 27 | Q1[Is the TUI only for Wezterm users?] 28 | Q2[Is Windows compatibility important?] 29 | Q3[Are you familiar with Crossterm?] 30 | Q4[Are you familiar with Termion?] 31 | Crossterm 32 | Termwiz 33 | Termion 34 | 35 | Q1 -->|Yes| Termwiz 36 | Q1 -->|No| Q2 37 | Q2 -->|Yes| Crossterm 38 | Q2 -->|No| Q3 39 | Q3 -->|Yes| Crossterm 40 | Q3 -->|No| Q4 41 | Q4 -->|Yes| Termion 42 | Q4 -->|No| Crossterm 43 | ``` 44 | 45 | Though we try to make sure that all backends are fully-supported, the most commonly-used backend is 46 | Crossterm. If you have no particular reason to use Termion or Termwiz, you will find it easiest to 47 | learn Crossterm simply due to its popularity. 48 | -------------------------------------------------------------------------------- /src/content/docs/concepts/backends/mouse-capture.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Mouse Capture 3 | sidebar: 4 | order: 4 5 | --- 6 | 7 | Mouse capture is a mode where the terminal captures mouse events such as clicks, scrolls, and 8 | movement, and sends them to the application as special sequences or events. This enables the 9 | application to handle and respond to mouse actions, providing a more interactive and graphical user 10 | experience within the terminal. It’s particularly useful for applications like terminal-based games, 11 | text editors, or other programs that require more direct interaction from the user. 12 | 13 | Each backend handles mouse capture differently, with variations in the types of events that can be 14 | captured and how they are represented. As such, the behavior may vary depending on the backend being 15 | used, and developers should consult the specific backend’s documentation to understand how it 16 | implements mouse capture. 17 | -------------------------------------------------------------------------------- /src/content/docs/concepts/backends/raw-mode.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Raw Mode 3 | sidebar: 4 | order: 2 5 | --- 6 | 7 | Raw mode is a mode where the terminal does not perform any processing or handling of the input and 8 | output. This means that features such as echoing input characters, line buffering, and special 9 | character processing (e.g., `CTRL-C` or `SIGINT`) are disabled. This is useful for applications that 10 | want to have complete control over the terminal input and output, processing each keystroke 11 | themselves. 12 | 13 | For example, in raw mode, the terminal will not perform line buffering on the input, so the 14 | application will receive each key press as it is typed, instead of waiting for the user to press 15 | enter. This makes it suitable for real-time applications like text editors, terminal-based games, 16 | and more. 17 | 18 | Each backend handles raw mode differently, so the behavior may vary depending on the backend being 19 | used. Be sure to consult the backend’s specific documentation for exact details on how it implements 20 | raw mode. 21 | 22 | - [`CrosstermBackend`] 23 | - [`TermionBackend`] 24 | - [`TermwizBackend`] 25 | 26 | [`CrosstermBackend`]: https://docs.rs/ratatui/latest/ratatui/backend/struct.CrosstermBackend.html 27 | [`TermionBackend`]: https://docs.rs/ratatui/latest/ratatui/backend/struct.TermionBackend.html 28 | [`TermwizBackend`]: https://docs.rs/ratatui/latest/ratatui/backend/struct.TermwizBackend.html 29 | -------------------------------------------------------------------------------- /src/content/docs/concepts/builder-lite-pattern.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Builder Lite Pattern 3 | --- 4 | 5 | In Ratatui, most widgets (and some other objects) use the [Builder Lite] pattern to set fields. This 6 | allows the object to be created in a single shot with methods that setup how the widget will be 7 | displayed, without having to store the widget in a variable and mutate it. 8 | 9 | The builder lite pattern consumes the `self` parameter of each method and returns a value with the 10 | updated field. An example of this from Paragraph (and any other widget that supports being 11 | automatically wrapped in a block): 12 | 13 | ```rust 14 | #[must_use] 15 | pub fn block(mut self, block: Block<'a>) -> Self { 16 | self.block = Some(block); 17 | self 18 | } 19 | ``` 20 | 21 | Which you might call like: 22 | 23 | ```rust 24 | let paragraph = Paragraph::new("foobar").block(Block::bordered()) 25 | ``` 26 | 27 | If you've reached this page after seeing an error or warning in your app's compilation, then it's 28 | likely that you are calling the setter methods against an object, but not storing or using the 29 | result. This will have no effect on the actual display of the widget and is usually a mistake. 30 | 31 | E.g. the following code: 32 | 33 | ```rust 34 | let text = Text::raw("wrong"); 35 | text.centered(); 36 | ``` 37 | 38 | Should be replaced with: 39 | 40 | ```rust 41 | let text = Text::raw("right").centered(); 42 | ``` 43 | 44 | Or in situations where you want to reuse a widget's setup more than once: 45 | 46 | ```rust 47 | let text = Text::raw("right"); 48 | let centered_text = text.clone().centered(); 49 | let bold_text = text.bold(); 50 | ``` 51 | 52 | [Builder Lite]: https://matklad.github.io/2022/05/29/builder-lite.html 53 | -------------------------------------------------------------------------------- /src/content/docs/concepts/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Concepts 3 | --- 4 | 5 | In this section, we will cover various concepts associated with terminal user interfaces, such as: 6 | 7 | - Rendering 8 | - Layout 9 | - Application patterns 10 | - Backends 11 | - Event handling 12 | -------------------------------------------------------------------------------- /src/content/docs/concepts/storing-state.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Storing Application State 3 | --- 4 | 5 | This page covers several ways that a programmer can store the state of the application. 6 | 7 | ## Single Silo Method 8 | 9 | This is perhaps the easiest method to understand, and works best for small applications that do no 10 | require a large amount of state to be remembered. The idea behind this method is simple: "One struct 11 | for all state", and whenever a component requires knowledge about the state of the application, it 12 | requests a reference to the `app` state. 13 | 14 | This is the method used in the tutorial. 15 | 16 | ### Pros 17 | 18 | This is conceptually very easy to understand. All of your states are stored in one place, and 19 | passing it to sub-components is simple. 20 | 21 | ### Cons 22 | 23 | However, you can tell when your application has outgrown the single silo application state when you 24 | begin to write code like this: 25 | 26 | ```rust 27 | let selected_item = &app.states.history.transacts_list.items[app.states.history.transacts_list.state.selected().unwrap()]; 28 | ``` 29 | 30 | Another downside to this method, is the lack of multithreaded support. If you begin to use multiple 31 | threads that need access to the application state, access to the `app` can become a bottleneck as 32 | `Mutex` and locks get handed around. 33 | -------------------------------------------------------------------------------- /src/content/docs/developer-guide/github-update.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:34932ca1ed4627d397d7765beafe4904c473543669f3ee0e254ffbe47a4b9011 3 | size 39427 4 | -------------------------------------------------------------------------------- /src/content/docs/developer-guide/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Developer Guide 3 | sidebar: 4 | order: 0 5 | --- 6 | 7 | This is the developer guide section for the `ratatui` source code and the `ratatui-book`. 8 | -------------------------------------------------------------------------------- /src/content/docs/examples/Apps/constraints.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:2daefab976c0b18f9486480b013259d3bd47124644487c1a751a5a2f5bf6b066 3 | size 208859 4 | -------------------------------------------------------------------------------- /src/content/docs/examples/Apps/demo.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:5be9bbca4de903f62cb7dbc30c190cc766669f08a9aefc6102a2dfc3e13f08ba 3 | size 3099568 4 | -------------------------------------------------------------------------------- /src/content/docs/examples/Apps/demo.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Demo 3 | --- 4 | 5 | This is the original demo example from the main README. It is available for each of the backends. 6 | 7 | ```shell title=run example 8 | git clone https://github.com/ratatui/ratatui.git --branch latest 9 | cd ratatui 10 | cargo run --example=demo --features=crossterm 11 | cargo run --example=demo --no-default-features --features=termion 12 | cargo run --example=demo --no-default-features --features=termwiz 13 | ``` 14 | 15 | ![demo](demo.gif) 16 | 17 | ```rust title=demo/main.rs 18 | {{ #include @code/examples/ratatui-examples/examples/demo/main.rs }} 19 | ``` 20 | 21 | ```rust title=demo/app.rs 22 | {{ #include @code/examples/ratatui-examples/examples/demo/app.rs }} 23 | ``` 24 | 25 | ```rust title=demo/ui.rs 26 | {{ #include @code/examples/ratatui-examples/examples/demo/ui.rs }} 27 | ``` 28 | 29 | ```rust title=demo/crossterm.rs 30 | {{ #include @code/examples/ratatui-examples/examples/demo/crossterm.rs }} 31 | ``` 32 | 33 | ```rust title=demo/termion.rs 34 | {{ #include @code/examples/ratatui-examples/examples/demo/termion.rs }} 35 | ``` 36 | 37 | ```rust title=demo/termwiz.rs 38 | {{ #include @code/examples/ratatui-examples/examples/demo/termwiz.rs }} 39 | ``` 40 | -------------------------------------------------------------------------------- /src/content/docs/examples/Apps/demo2-about.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:002fc2928b89803800fa886357eabc941fb77d0f61821ace7b967c09dfc76a7b 3 | size 128371 4 | -------------------------------------------------------------------------------- /src/content/docs/examples/Apps/demo2-destroy.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:6171f62e0ff4aae6bb738724e8d036c8e895aadae57e141912872f748862b346 3 | size 12242793 4 | -------------------------------------------------------------------------------- /src/content/docs/examples/Apps/demo2-email.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:2dd7a39f77251dd433bd98c3b1b0dc7d2194abad788a20f9d6e914ed6086f2fe 3 | size 134322 4 | -------------------------------------------------------------------------------- /src/content/docs/examples/Apps/demo2-recipe.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:dbd65a6547899180635967127a337f72e8062baf45d576e02ec7790f16eba444 3 | size 259357 4 | -------------------------------------------------------------------------------- /src/content/docs/examples/Apps/demo2-social.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:60970d1bcd9767e3a3dd8214eb5b498f830a4cb46d788b6b763c93444b23b4a4 3 | size 1082534 4 | -------------------------------------------------------------------------------- /src/content/docs/examples/Apps/demo2-trace.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:aa49445874bc3408781ef099acd90e79dfca9aea5e5b103ac58e07c9abb5a98e 3 | size 136378 4 | -------------------------------------------------------------------------------- /src/content/docs/examples/Apps/demo2-weather.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:a61c164526a054d90afa631bc410471e03d3fa74daf304387147ef1d1a0f7e25 3 | size 130634 4 | -------------------------------------------------------------------------------- /src/content/docs/examples/Apps/demo2.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:f05e6d35b68c7175e99a5ee395aebe7cf835e914c2ae17af6f668bf8991eb541 3 | size 1050734 4 | -------------------------------------------------------------------------------- /src/content/docs/examples/Apps/demo2.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Demo 2 3 | --- 4 | 5 | This is the demo example from the main README and crate page. 6 | 7 | ```shell title=run example 8 | git clone https://github.com/ratatui/ratatui.git --branch latest 9 | cd ratatui 10 | cargo run --example=demo2 --features=crossterm 11 | ``` 12 | 13 | ![demo2](demo2-destroy.gif) 14 | 15 | Source: 16 | -------------------------------------------------------------------------------- /src/content/docs/examples/Apps/docsrs-hello.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:1d756949dbe1634f5e3a588c700160ff1ce71f3564621ee8abfa742b6cee98d5 3 | size 8650 4 | -------------------------------------------------------------------------------- /src/content/docs/examples/Apps/docsrs-layout.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:b7ca9232ad38baff73bbe85a13604bb7ed91e79fdef1821bc4039e79c58f4ff8 3 | size 12024 4 | -------------------------------------------------------------------------------- /src/content/docs/examples/Apps/docsrs-styling.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:b07446a23945252f4a05e6dcf3c6ab1a826d0edbb136bd20e31da00ac7c6bac3 3 | size 22071 4 | -------------------------------------------------------------------------------- /src/content/docs/examples/Apps/docsrs.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:a36b62da7d2c1432276cc336f3c36cd1b969a5d969dc3b585438698fa250ba17 3 | size 30986 4 | -------------------------------------------------------------------------------- /src/content/docs/examples/Apps/docsrs.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Docs.rs 3 | --- 4 | 5 | Several examples used for importing into the main docs.rs page. 6 | 7 | ```shell title=run example 8 | git clone https://github.com/ratatui/ratatui.git --branch latest 9 | cd ratatui 10 | cargo run --example=docsrs --features=crossterm 11 | ``` 12 | 13 | ![docsrs](docsrs.gif) 14 | 15 | ```rust title=docsrs.rs 16 | {{ #include @code/examples/ratatui-examples/examples/docsrs.rs }} 17 | ``` 18 | -------------------------------------------------------------------------------- /src/content/docs/examples/Apps/hello_world.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:fd4014f2774b3963e81e25ae6f40b4e6538b66cc4cbf5c71946cb9b7a8e3a93f 3 | size 12520 4 | -------------------------------------------------------------------------------- /src/content/docs/examples/Apps/hello_world.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Hello World 3 | --- 4 | 5 | Demonstrates a basic hello world app. 6 | 7 | ```shell title=run example 8 | git clone https://github.com/ratatui/ratatui.git --branch latest 9 | cd ratatui 10 | cargo run --example=hello_world --features=crossterm 11 | ``` 12 | 13 | ![hello_world](hello_world.gif) 14 | 15 | ```rust title=hello_world.rs 16 | {{ #include @code/examples/ratatui-examples/examples/hello_world.rs }} 17 | ``` 18 | -------------------------------------------------------------------------------- /src/content/docs/examples/Apps/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: App Examples 3 | --- 4 | 5 | import { Image } from "astro:assets"; 6 | import demoImage from "./demo.gif"; 7 | import demo2Image from "./demo2-destroy.gif"; 8 | import docsrsImage from "./docsrs.gif"; 9 | import helloWorldImage from "./hello_world.gif"; 10 | import inlineImage from "./inline.gif"; 11 | import minimalImage from "./minimal.gif"; 12 | import panicImage from "./panic.gif"; 13 | import popupImage from "./popup.gif"; 14 | import ratatuiLogoImage from "./ratatui-logo.gif"; 15 | import userInputImage from "./user_input.gif"; 16 | 17 | ## [Demo Demo App](./demo) 18 | 19 | ## [Demo2 Demo App](./demo2) 20 | 21 | ## [Docs.rs Docs.rs App](./docsrs) 22 | 23 | ## [Hello World Hello World App](./hello_world) 24 | 25 | ## [Inline Inline App](./inline) 26 | 27 | ## [Minimal Minimal App](./minimal) 28 | 29 | ## [Panic Panic App](./panic) 30 | 31 | ## [Popup Popup App](./popup) 32 | 33 | ## [Ratatui Logo Ratatui Logo App](./ratatui-logo) 34 | 35 | ## [User Input User Input App](./user_input) 36 | -------------------------------------------------------------------------------- /src/content/docs/examples/Apps/inline.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:4fb3c02d66940853f49c4e366eb9f44e0ef952c83c2a158a01e391e3b52d2e0a 3 | size 537724 4 | -------------------------------------------------------------------------------- /src/content/docs/examples/Apps/inline.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Inline Viewport 3 | --- 4 | 5 | Demonstrates the 6 | [`Inline`](https://docs.rs/ratatui/latest/ratatui/enum.Viewport.html#variant.Inline) Viewport. 7 | 8 | ```shell title=run example 9 | git clone https://github.com/ratatui/ratatui.git --branch latest 10 | cd ratatui 11 | cargo run --example=inline --features=crossterm 12 | ``` 13 | 14 | ![inline](inline.gif) 15 | 16 | ```rust title=inline.rs 17 | {{ #include @code/examples/ratatui-examples/examples/inline.rs }} 18 | ``` 19 | -------------------------------------------------------------------------------- /src/content/docs/examples/Apps/minimal.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:ad8d712f62320729a914f9b7815761e81d6e7d913582828fca89634d8037fd3e 3 | size 8670 4 | -------------------------------------------------------------------------------- /src/content/docs/examples/Apps/minimal.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Minimal Hello World 3 | --- 4 | 5 | Demonstrates a minimal hello world 6 | 7 | ```shell title=run example 8 | git clone https://github.com/ratatui/ratatui.git --branch latest 9 | cd ratatui 10 | cargo run --example=minimal --features=crossterm 11 | ``` 12 | 13 | ![minimal](minimal.gif) 14 | 15 | ```rust title=minimal.rs 16 | {{ #include @code/examples/ratatui-examples/examples/minimal.rs }} 17 | ``` 18 | -------------------------------------------------------------------------------- /src/content/docs/examples/Apps/panic.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:2a151ddba63dd62961f68b8006588a65c274eb5b5aa7f62ffb4f57559a3a5240 3 | size 584395 4 | -------------------------------------------------------------------------------- /src/content/docs/examples/Apps/panic.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Panic Hooks 3 | --- 4 | 5 | Demonstrates the setting up panic hooks 6 | 7 | ```shell title=run example 8 | git clone https://github.com/ratatui/ratatui.git --branch latest 9 | cd ratatui 10 | cargo run --example=panic --features=crossterm 11 | ``` 12 | 13 | ![panic](panic.gif) 14 | 15 | ```rust title=panic.rs 16 | {{ #include @code/examples/ratatui-examples/examples/panic.rs }} 17 | ``` 18 | -------------------------------------------------------------------------------- /src/content/docs/examples/Apps/popup.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:c0ca3a4ee4a9a87ec5e72ec25cdcc7a57cde5d5a536750ce9c45d0659084d11b 3 | size 31621 4 | -------------------------------------------------------------------------------- /src/content/docs/examples/Apps/popup.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Popup 3 | --- 4 | 5 | Demonstrates how to render a widget over the top of previously rendered widgets using the 6 | [`Clear`](https://docs.rs/ratatui/latest/ratatui/widgets/struct.Clear.html) widget. 7 | 8 | ```shell title=run example 9 | git clone https://github.com/ratatui/ratatui.git --branch latest 10 | cd ratatui 11 | cargo run --example=popup --features=crossterm 12 | ``` 13 | 14 | ![popup](popup.gif) 15 | 16 | ```rust title=popup.rs 17 | {{ #include @code/examples/ratatui-examples/examples/popup.rs }} 18 | ``` 19 | -------------------------------------------------------------------------------- /src/content/docs/examples/Apps/ratatui-logo.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:5bebb75fa5c43857a5da477b2d7efec74bb39965a6e52645f7beb53da508c69d 3 | size 9127 4 | -------------------------------------------------------------------------------- /src/content/docs/examples/Apps/ratatui-logo.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Ratatui Logo 3 | --- 4 | 5 | A fun example of using half blocks to render graphics. 6 | 7 | ```shell title=run example 8 | git clone https://github.com/ratatui/ratatui.git --branch latest 9 | cd ratatui 10 | cargo run --example=ratatui-logo --features=crossterm 11 | ``` 12 | 13 | ![ratatui-logo](ratatui-logo.gif) 14 | 15 | ```rust title=ratatui-logo.rs 16 | {{ #include @code/examples/ratatui-examples/examples/ratatui-logo.rs }} 17 | ``` 18 | -------------------------------------------------------------------------------- /src/content/docs/examples/Apps/user_input.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:a3047641fe985059938e61621e1f1d406e23b828c1241d1847251fab5b0f918e 3 | size 67366 4 | -------------------------------------------------------------------------------- /src/content/docs/examples/Apps/user_input.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: User Input 3 | --- 4 | 5 | Demonstrates one approach to accepting user input. Source 6 | [user_input.rs](https://github.com/ratatui/ratatui/blob/main/examples/apps/input-form/src/main.rs). 7 | 8 | :::caution 9 | 10 | Consider using [`tui-textarea`](https://crates.io/crates/tui-textarea) or 11 | [`tui-input`](https://crates.io/crates/tui-input) crates for more functional text entry UIs. 12 | 13 | ::: 14 | 15 | ```shell title=run example 16 | git clone https://github.com/ratatui/ratatui.git --branch latest 17 | cd ratatui 18 | cargo run --example=user_input --features=crossterm 19 | ``` 20 | 21 | ![user_input](user_input.gif) 22 | 23 | ```rust title=user_input.rs 24 | {{ #include @code/examples/ratatui-examples/examples/user_input.rs }} 25 | ``` 26 | -------------------------------------------------------------------------------- /src/content/docs/examples/Layout/constraint-explorer.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:86fd3c37b32bc1b52cf337ff3164047476b3be7b5d6a10e6914c2c67cf266723 3 | size 1351442 4 | -------------------------------------------------------------------------------- /src/content/docs/examples/Layout/constraint-explorer.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Constraint Explorer 3 | --- 4 | 5 | The constraint explorer is a utility that can be used to work out the interaction between your 6 | constraints. 7 | 8 | ```shell title=run example 9 | git clone https://github.com/ratatui/ratatui.git --branch latest 10 | cd ratatui 11 | cargo run --example=constraint-explorer --features=crossterm 12 | ``` 13 | 14 | ![constraint-explorer](constraint-explorer.gif) 15 | 16 | ```rust title=constraint-explorer.rs 17 | {{ #include @code/examples/ratatui-examples/examples/constraint-explorer.rs }} 18 | ``` 19 | -------------------------------------------------------------------------------- /src/content/docs/examples/Layout/constraints.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:2daefab976c0b18f9486480b013259d3bd47124644487c1a751a5a2f5bf6b066 3 | size 208859 4 | -------------------------------------------------------------------------------- /src/content/docs/examples/Layout/constraints.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Constraints 3 | --- 4 | 5 | Demonstrates how various 6 | [`Constraint`](https://docs.rs/ratatui/latest/ratatui/layout/enum.Constraint.html)s affect each 7 | other in a layout. 8 | 9 | ```shell title=run example 10 | git clone https://github.com/ratatui/ratatui.git --branch latest 11 | cd ratatui 12 | cargo run --example=constraints --features=crossterm 13 | ``` 14 | 15 | ![constraints](constraints.gif) 16 | 17 | ```rust title=constraints.rs 18 | {{ #include @code/examples/ratatui-examples/examples/constraints.rs }} 19 | ``` 20 | -------------------------------------------------------------------------------- /src/content/docs/examples/Layout/flex.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:b99719ed733a2ac0b8f67984c66bd98f8fb9950528fe78069e291d5d0768654e 3 | size 8833070 4 | -------------------------------------------------------------------------------- /src/content/docs/examples/Layout/flex.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Flex 3 | --- 4 | 5 | Demonstrates the [`flex`](https://docs.rs/ratatui/latest/ratatui/layout/enum.Flex.html) layout 6 | variants. 7 | 8 | ```shell title=run example 9 | git clone https://github.com/ratatui/ratatui.git --branch latest 10 | cd ratatui 11 | cargo run --example=flex --features=crossterm 12 | ``` 13 | 14 | ![flex](flex.gif) 15 | 16 | ```rust title=flex.rs 17 | {{ #include @code/examples/ratatui-examples/examples/flex.rs }} 18 | ``` 19 | -------------------------------------------------------------------------------- /src/content/docs/examples/Layout/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Layout Examples 3 | --- 4 | 5 | import { Image } from "astro:assets"; 6 | import constraintExplorerImage from "./constraint-explorer.gif"; 7 | import constraintsImage from "./constraints.gif"; 8 | import flexImage from "./flex.gif"; 9 | import layoutImage from "./layout.gif"; 10 | 11 | ## [Constraint Explorer Constraint Explorer](./constraint-explorer) 12 | 13 | ## [Constraints Constraints](./constraints) 14 | 15 | ## [Flex Flex](./flex) 16 | 17 | ## [Layout Layout](./layout) 18 | -------------------------------------------------------------------------------- /src/content/docs/examples/Layout/layout.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:499c52e6958a78ce65da180dc9e018af5ddb6641af3acd02f21f9237a1fcf4f7 3 | size 350039 4 | -------------------------------------------------------------------------------- /src/content/docs/examples/Layout/layout.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Layout 3 | --- 4 | 5 | Demonstrates the [`Layout`](https://docs.rs/ratatui/latest/ratatui/layout/struct.Layout.html). 6 | 7 | ```shell title=run example 8 | git clone https://github.com/ratatui/ratatui.git --branch latest 9 | cd ratatui 10 | cargo run --example=layout --features=crossterm 11 | ``` 12 | 13 | ![layout](layout.gif) 14 | 15 | ```rust title=layout.rs 16 | {{ #include @code/examples/ratatui-examples/examples/layout.rs }} 17 | ``` 18 | -------------------------------------------------------------------------------- /src/content/docs/examples/Style/colors.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:5cee41f1bbc99eec4e13c30b4808f71f33cb1d47cc6c6415397986f18bc81cf7 3 | size 551905 4 | -------------------------------------------------------------------------------- /src/content/docs/examples/Style/colors.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Colors 3 | --- 4 | 5 | Demonstrates the available [`Color`](https://docs.rs/ratatui/latest/ratatui/style/enum.Color.html) 6 | options. These can be used in any style field. 7 | 8 | ```shell title=run example 9 | git clone https://github.com/ratatui/ratatui.git --branch latest 10 | cd ratatui 11 | cargo run --example=colors --features=crossterm 12 | ``` 13 | 14 | ![colors](colors.gif) 15 | 16 | ```rust title=colors.rs 17 | {{ #include @code/examples/ratatui-examples/examples/colors.rs }} 18 | ``` 19 | -------------------------------------------------------------------------------- /src/content/docs/examples/Style/colors_rgb.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:6b5b23cf20e8fdc0a2545a59040fcb0c430bbb369b70733aa7440140a6dcd680 3 | size 447716 4 | -------------------------------------------------------------------------------- /src/content/docs/examples/Style/colors_rgb.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Colors (RGB) 3 | --- 4 | 5 | Demonstrates the available RGB 6 | [`Color`](https://docs.rs/ratatui/latest/ratatui/style/enum.Color.html) options. These can be used 7 | in any style field. Source: [colors_rgb.rs](./colors_rgb.rs). Uses a half block technique to render 8 | two square-ish pixels in the space of a single rectangular terminal cell. 9 | 10 | ```shell title=run example 11 | git clone https://github.com/ratatui/ratatui.git --branch latest 12 | cd ratatui 13 | cargo run --example=colors_rgb --features=crossterm 14 | ``` 15 | 16 | 17 | 18 | ![colors_rgb](colors_rgb.gif) 19 | 20 | ```rust title=colors_rgb.rs 21 | {{ #include @code/examples/ratatui-examples/examples/colors_rgb.rs }} 22 | ``` 23 | -------------------------------------------------------------------------------- /src/content/docs/examples/Style/colors_rgb.mov: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ratatui/ratatui-website/68c730a9a9a245c842f7e2e90781096014f057d1/src/content/docs/examples/Style/colors_rgb.mov -------------------------------------------------------------------------------- /src/content/docs/examples/Style/colors_rgb.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:1652f892eaa3288878f5b2608896f2c9ecc3fea27b169fb0cbc5b78fe81fc532 3 | size 94922 4 | -------------------------------------------------------------------------------- /src/content/docs/examples/Style/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Style Examples 3 | --- 4 | 5 | import { Image } from "astro:assets"; 6 | 7 | import colorsImage from "./colors.gif"; 8 | import colorsRgbImage from "./colors_rgb.gif"; 9 | import modifiersImage from "./modifiers.gif"; 10 | 11 | ## [Colors Colors](./colors) 12 | 13 | ## [Colors RGB Colors RGB](./colors_rgb) 14 | 15 | ## [Modifiers Modifiers](./modifiers) 16 | -------------------------------------------------------------------------------- /src/content/docs/examples/Style/modifiers.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:e0fefb904f51b748d69729ab807b87f5ef28ddb8a8e0f0db3eeb7a5d0b7b7f5a 3 | size 359823 4 | -------------------------------------------------------------------------------- /src/content/docs/examples/Style/modifiers.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Modifiers 3 | --- 4 | 5 | Demonstrates the style 6 | [`Modifiers`](https://docs.rs/ratatui/latest/ratatui/style/struct.Modifier.html) 7 | 8 | ```shell title=run example 9 | git clone https://github.com/ratatui/ratatui.git --branch latest 10 | cd ratatui 11 | cargo run --example=modifiers --features=crossterm 12 | ``` 13 | 14 | ![modifiers](modifiers.gif) 15 | 16 | ```rust title=modifiers.rs 17 | {{ #include @code/examples/ratatui-examples/examples/modifiers.rs }} 18 | ``` 19 | -------------------------------------------------------------------------------- /src/content/docs/examples/Widgets/barchart.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:aad2489a598e0fa13cfe335eddbafe947c68c3a5af8f1deae5c4b12b23b0a397 3 | size 274069 4 | -------------------------------------------------------------------------------- /src/content/docs/examples/Widgets/barchart.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Barchart 3 | --- 4 | 5 | Demonstrates the [`BarChart`](https://docs.rs/ratatui/latest/ratatui/widgets/struct.BarChart.html) 6 | widget. 7 | 8 | ```shell title="run example" 9 | git clone https://github.com/ratatui/ratatui.git --branch latest 10 | cd ratatui 11 | cargo run --example=barchart --features=crossterm 12 | ``` 13 | 14 | ![Barchart](barchart.gif) 15 | 16 | ```rust title=barchart.rs 17 | {{ #include @code/examples/ratatui-examples/examples/barchart.rs }} 18 | ``` 19 | -------------------------------------------------------------------------------- /src/content/docs/examples/Widgets/block.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:935a26adb38eb6169aca18022ddb22423ff2d82a5457d266ec01bb3307fde631 3 | size 312736 4 | -------------------------------------------------------------------------------- /src/content/docs/examples/Widgets/block.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Block 3 | --- 4 | 5 | Demonstrates the [`Block`](https://docs.rs/ratatui/latest/ratatui/widgets/block/struct.Block.html) 6 | widget. 7 | 8 | ```shell title=run example 9 | git clone https://github.com/ratatui/ratatui.git --branch latest 10 | cd ratatui 11 | cargo run --example=block --features=crossterm 12 | ``` 13 | 14 | ![Block](block.gif) 15 | 16 | ```rust title=block.rs 17 | {{ #include @code/examples/ratatui-examples/examples/block.rs }} 18 | ``` 19 | -------------------------------------------------------------------------------- /src/content/docs/examples/Widgets/calendar.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:5b03748bbbb16f917b1b786f99a2e29edfab85ef089c7b42c6a01e0781a5ce08 3 | size 178635 4 | -------------------------------------------------------------------------------- /src/content/docs/examples/Widgets/calendar.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Calendar 3 | --- 4 | 5 | Demonstrates the [`Calendar`](https://docs.rs/ratatui/latest/ratatui/widgets/calendar/) widget. 6 | 7 | ```shell title=run example 8 | git clone https://github.com/ratatui/ratatui.git --branch latest 9 | cd ratatui 10 | cargo run --example=calendar --features=crossterm,widget-calendar 11 | ``` 12 | 13 | ![Calendar](calendar.gif) 14 | 15 | ```rust title=calendar.rs 16 | {{ #include @code/examples/ratatui-examples/examples/calendar.rs }} 17 | ``` 18 | -------------------------------------------------------------------------------- /src/content/docs/examples/Widgets/canvas.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:203acd8521ff965add7148f305f333a2edbf95103f97a16ce790827bcd2f8b71 3 | size 1364762 4 | -------------------------------------------------------------------------------- /src/content/docs/examples/Widgets/canvas.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Canvas 3 | --- 4 | 5 | Demonstrates the [`Canvas`](https://docs.rs/ratatui/latest/ratatui/widgets/canvas/index.html) widget 6 | and related shapes in the 7 | [`canvas`](https://docs.rs/ratatui/latest/ratatui/widgets/canvas/index.html) module. 8 | 9 | ```shell title=run example 10 | git clone https://github.com/ratatui/ratatui.git --branch latest 11 | cd ratatui 12 | cargo run --example=canvas --features=crossterm 13 | ``` 14 | 15 | ![canvas](canvas.gif) 16 | 17 | ```rust title=canvas.rs 18 | {{ #include @code/examples/ratatui-examples/examples/canvas.rs }} 19 | ``` 20 | -------------------------------------------------------------------------------- /src/content/docs/examples/Widgets/chart.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:87f79003b4b1a070269c4add0c5cc8554fb26ef2810982567835283f1c81abb6 3 | size 333024 4 | -------------------------------------------------------------------------------- /src/content/docs/examples/Widgets/chart.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Chart 3 | --- 4 | 5 | Demonstrates the [`Chart`](https://docs.rs/ratatui/latest/ratatui/widgets/struct.Chart.html) widget. 6 | 7 | ```shell title=run example 8 | git clone https://github.com/ratatui/ratatui.git --branch latest 9 | cd ratatui 10 | cargo run --example=chart --features=crossterm 11 | ``` 12 | 13 | ![chart](chart.gif) 14 | 15 | ```rust title=chart.rs 16 | {{ #include @code/examples/ratatui-examples/examples/chart.rs }} 17 | ``` 18 | -------------------------------------------------------------------------------- /src/content/docs/examples/Widgets/custom_widget.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:77f28016b8906c1debba27d891b59a86d802b59ec783f8156dd80482959aa923 3 | size 44360 4 | -------------------------------------------------------------------------------- /src/content/docs/examples/Widgets/custom_widget.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Custom Widget 3 | --- 4 | 5 | Demonstrates how to implement the 6 | [`Widget`](https://docs.rs/ratatui/latest/ratatui/widgets/trait.Widget.html) trait. Also shows mouse 7 | interaction. 8 | 9 | ```shell title=run example 10 | git clone https://github.com/ratatui/ratatui.git --branch latest 11 | cd ratatui 12 | cargo run --example=custom_widget --features=crossterm 13 | ``` 14 | 15 | ![custom_widget](custom_widget.gif) 16 | 17 | ```rust title=custom_widget.rs 18 | {{ #include @code/examples/ratatui-examples/examples/custom_widget.rs }} 19 | ``` 20 | -------------------------------------------------------------------------------- /src/content/docs/examples/Widgets/gauge.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:2cac77f8833dfbcb58f03f3c24adb51f2813bc9fc74094b4bdb42f981983f11d 3 | size 243266 4 | -------------------------------------------------------------------------------- /src/content/docs/examples/Widgets/gauge.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Gauge 3 | --- 4 | 5 | Demonstrates the [`Gauge`](https://docs.rs/ratatui/latest/ratatui/widgets/struct.Gauge.html) widget. 6 | 7 | ```shell title=run example 8 | git clone https://github.com/ratatui/ratatui.git --branch latest 9 | cd ratatui 10 | cargo run --example=gauge --features=crossterm 11 | ``` 12 | 13 | ![gauge](gauge.gif) 14 | 15 | ```rust title=gauge.rs 16 | {{ #include @code/examples/ratatui-examples/examples/gauge.rs }} 17 | ``` 18 | -------------------------------------------------------------------------------- /src/content/docs/examples/Widgets/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Widget Examples 3 | --- 4 | 5 | import { Image } from "astro:assets"; 6 | 7 | import barchartImage from "./barchart.gif"; 8 | import blockImage from "./block.gif"; 9 | import calendarImage from "./calendar.gif"; 10 | import canvasImage from "./canvas.gif"; 11 | import chartImage from "./chart.gif"; 12 | import customWidgetImage from "./custom_widget.gif"; 13 | import gaugeImage from "./gauge.gif"; 14 | import listImage from "./list.gif"; 15 | import paragraphImage from "./paragraph.gif"; 16 | import scrollbarImage from "./scrollbar.gif"; 17 | import sparklineImage from "./sparkline.gif"; 18 | import tableImage from "./table.gif"; 19 | import tabsImage from "./tabs.gif"; 20 | 21 | ## [BarChart BarChart](./barchart) 22 | 23 | ## [Block Block](./block) 24 | 25 | ## [Calendar Calendar](./calendar) 26 | 27 | ## [Canvas Canvas](./canvas) 28 | 29 | ## [Chart Chart](./chart) 30 | 31 | ## [Custom Widget Custom Widget](./custom_widget) 32 | 33 | ## [Gauge Gauge](./gauge) 34 | 35 | ## [List List](./list) 36 | 37 | ## [Paragraph Paragraph](./paragraph) 38 | 39 | ## [Scrollbar Scrollbar](./scrollbar) 40 | 41 | ## [Sparkline Sparkline](./sparkline) 42 | 43 | ## [Table Table](./table) 44 | 45 | ## [Tabs Tabs](./tabs) 46 | -------------------------------------------------------------------------------- /src/content/docs/examples/Widgets/line_gauge.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:db204c4bd132be513ca3c85d9b308791b1db0ab6799fdf1e507574f759cd51d4 3 | size 137441 4 | -------------------------------------------------------------------------------- /src/content/docs/examples/Widgets/list.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:f767d91340d12932db7dca369603c33002c12b181e8189fa1bb641bfe32d67a7 3 | size 460292 4 | -------------------------------------------------------------------------------- /src/content/docs/examples/Widgets/list.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: List 3 | --- 4 | 5 | Demonstrates the [`List`](https://docs.rs/ratatui/latest/ratatui/widgets/struct.List.html) widget. 6 | 7 | ```shell title=run example 8 | git clone https://github.com/ratatui/ratatui.git --branch latest 9 | cd ratatui 10 | cargo run --example=list --features=crossterm 11 | ``` 12 | 13 | ![list](list.gif) 14 | 15 | ```rust title=list.rs 16 | {{ #include @code/examples/ratatui-examples/examples/list.rs }} 17 | ``` 18 | -------------------------------------------------------------------------------- /src/content/docs/examples/Widgets/paragraph.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:865e0d04176da9604dbce0478bcf5512a36028aab1e1b9976f8df44f46f5e4bc 3 | size 1319718 4 | -------------------------------------------------------------------------------- /src/content/docs/examples/Widgets/paragraph.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Paragraph 3 | --- 4 | 5 | Demonstrates the [`Paragraph`](https://docs.rs/ratatui/latest/ratatui/widgets/struct.Paragraph.html) 6 | widget. 7 | 8 | ```shell title=run example 9 | git clone https://github.com/ratatui/ratatui.git --branch latest 10 | cd ratatui 11 | cargo run --example=paragraph --features=crossterm 12 | ``` 13 | 14 | ![paragraph](paragraph.gif) 15 | 16 | ```rust title=paragraph.rs 17 | {{ #include @code/examples/ratatui-examples/examples/paragraph.rs }} 18 | ``` 19 | -------------------------------------------------------------------------------- /src/content/docs/examples/Widgets/scrollbar.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:b94e89832d682e343b8961b3d9089635811d3420f08a7b05523ca30e7f92a43d 3 | size 179292 4 | -------------------------------------------------------------------------------- /src/content/docs/examples/Widgets/scrollbar.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Scrollbar 3 | --- 4 | 5 | Demonstrates the [`Scrollbar`](https://docs.rs/ratatui/latest/ratatui/widgets/struct.Scrollbar.html) 6 | widget. 7 | 8 | ```shell title=run example 9 | git clone https://github.com/ratatui/ratatui.git --branch latest 10 | cd ratatui 11 | cargo run --example=scrollbar --features=crossterm 12 | ``` 13 | 14 | ![scrollbar](scrollbar.gif) 15 | 16 | ```rust title=scrollbar.rs 17 | {{ #include @code/examples/ratatui-examples/examples/scrollbar.rs }} 18 | ``` 19 | -------------------------------------------------------------------------------- /src/content/docs/examples/Widgets/sparkline.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:a5d779f810dbfc32d74bac0f6eec3ee61d2be7a33bed96bbdef276fe8c68e821 3 | size 1170951 4 | -------------------------------------------------------------------------------- /src/content/docs/examples/Widgets/sparkline.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Sparkline 3 | --- 4 | 5 | Demonstrates the [`Sparkline`](https://docs.rs/ratatui/latest/ratatui/widgets/struct.Sparkline.html) 6 | widget. 7 | 8 | ```shell title=run example 9 | git clone https://github.com/ratatui/ratatui.git --branch latest 10 | cd ratatui 11 | cargo run --example=sparkline --features=crossterm 12 | ``` 13 | 14 | ![sparkline](sparkline.gif) 15 | 16 | ```rust title=sparkline.rs 17 | {{ #include @code/examples/ratatui-examples/examples/sparkline.rs }} 18 | ``` 19 | -------------------------------------------------------------------------------- /src/content/docs/examples/Widgets/table.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:8dd8ff163e3a900d78f619c0f7d044d0b7faf013a4e0472e588ca41001c6a642 3 | size 771683 4 | -------------------------------------------------------------------------------- /src/content/docs/examples/Widgets/table.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Table 3 | --- 4 | 5 | Demonstrates the [`Table`](https://docs.rs/ratatui/latest/ratatui/widgets/struct.Table.html) widget. 6 | 7 | ```shell title=run example 8 | git clone https://github.com/ratatui/ratatui.git --branch latest 9 | cd ratatui 10 | cargo run --example=table --features=crossterm 11 | ``` 12 | 13 | ![table](table.gif) 14 | 15 | ```rust title=table.rs 16 | {{ #include @code/examples/ratatui-examples/examples/table.rs }} 17 | ``` 18 | -------------------------------------------------------------------------------- /src/content/docs/examples/Widgets/tabs.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:51ed83ea6f23509bd59c21d910a1295f11f3e011569c03f4f7c5901cc6bbbe5e 3 | size 121506 4 | -------------------------------------------------------------------------------- /src/content/docs/examples/Widgets/tabs.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Tabs 3 | --- 4 | 5 | Demonstrates the [`Tabs`](https://docs.rs/ratatui/latest/ratatui/widgets/struct.Tabs.html) widget. 6 | 7 | ```shell title=run example 8 | git clone https://github.com/ratatui/ratatui.git --branch latest 9 | cd ratatui 10 | cargo run --example=tabs --features=crossterm 11 | ``` 12 | 13 | ![tabs](tabs.gif) 14 | 15 | ```rust title=tabs.rs 16 | {{ #include @code/examples/ratatui-examples/examples/tabs.rs }} 17 | ``` 18 | -------------------------------------------------------------------------------- /src/content/docs/examples/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Examples 3 | --- 4 | 5 | import { Image } from "astro:assets"; 6 | 7 | - [Apps](./apps) 8 | - [Layout](./layout) 9 | - [Style](./style) 10 | - [Widgets](./widgets) 11 | -------------------------------------------------------------------------------- /src/content/docs/highlights/constraint-explorer.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:0566995c0ec5221605b2eb687c88a84009181eb54f59ff30bed9abbe7b83f4b9 3 | size 16583304 4 | -------------------------------------------------------------------------------- /src/content/docs/highlights/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Highlights 3 | --- 4 | 5 | This section highlights the main changes in each major release of Ratatui (from v0.21.0 through the 6 | latest version). 7 | 8 | Follow the links in the sidebar to see the full highlights for each version. 9 | -------------------------------------------------------------------------------- /src/content/docs/installation/feature-flags.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Feature Flags 3 | sidebar: 4 | order: 1 5 | --- 6 | 7 | As ratatui grows and evolves, this list may change, so make sure to check the 8 | [main repo](https://github.com/ratatui/ratatui) if you are unsure. 9 | 10 | ## Backend Selection 11 | 12 | For most cases, the default `crossterm` backend is the correct choice. See 13 | [Backends](/concepts/backends/) for more information. However, this can be changed to termion or 14 | termwiz 15 | 16 | ```shell 17 | # Defaults to crossterm 18 | cargo add ratatui 19 | 20 | # For termion, unset the default crossterm feature and select the termion feature 21 | cargo add ratatui --no-default-features --features=termion 22 | cargo add termion 23 | 24 | # For termwiz, unset the default crossterm feature and select the termwiz feature 25 | cargo add ratatui --no-default-features --features=termwiz 26 | cargo add termwiz 27 | ``` 28 | 29 | ## All-Widgets 30 | 31 | This feature enables some extra widgets that are not in `default` to save on compile time. As of 32 | v0.21, the only widget in this feature group is the `calendar` widget, which can be enabled with the 33 | `widget-calendar` feature. 34 | 35 | ```shell 36 | cargo add ratatui --features all-widgets 37 | ``` 38 | 39 | ## Widget-Calendar 40 | 41 | This feature enables the calendar widget, which requires the `time` crate. 42 | 43 | ```shell 44 | cargo add ratatui --features widget-calendar 45 | ``` 46 | 47 | ## Serde 48 | 49 | Enables serialization and deserialization of style and color types using the Serde crate. This is 50 | useful if you want to save themes to a file. 51 | 52 | ```shell 53 | cargo add ratatui --features serde 54 | ``` 55 | -------------------------------------------------------------------------------- /src/content/docs/recipes/apps/color-eyre/demo.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:48c44aa6d91039e9e07e81e1a093a859dfe3667339896f3c7b138ee4b5324dc4 3 | size 445767 4 | -------------------------------------------------------------------------------- /src/content/docs/recipes/apps/color-eyre/error-full.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:b98d9ffd72ea6cf46942ef402cf451f2de0d4c58dd43ba63923ac3f15c0e7df6 3 | size 325168 4 | -------------------------------------------------------------------------------- /src/content/docs/recipes/apps/color-eyre/error-full.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:0980fc9b438d891bb30ff1c1e8f8f10f139e656abf154514b364975f86571098 3 | size 552104 4 | -------------------------------------------------------------------------------- /src/content/docs/recipes/apps/color-eyre/error.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:7db839bcd3d832fe1f2b65e0f3685538b546ebcddc820718f60651dfc68481f0 3 | size 120173 4 | -------------------------------------------------------------------------------- /src/content/docs/recipes/apps/color-eyre/error.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:fb429a69e5600ef56c5f2ce58f7ad360b887ff5459540638f42d7b4ec60b70d5 3 | size 139248 4 | -------------------------------------------------------------------------------- /src/content/docs/recipes/apps/color-eyre/panic-full.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:20c2836759feb69267222c7cd7994fd46dc537d76e0327dba93921d0d6c34fdc 3 | size 315099 4 | -------------------------------------------------------------------------------- /src/content/docs/recipes/apps/color-eyre/panic-full.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:c6d9eca5a9fa3a3d7d2e0fce7efcdf73497f1fe15c3a146d748039244d169ac3 3 | size 399168 4 | -------------------------------------------------------------------------------- /src/content/docs/recipes/apps/color-eyre/panic.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:f2727aa1d0dcfd38269fc59550cb6720f794aa21fd1c248515b1d5547030fe15 3 | size 126050 4 | -------------------------------------------------------------------------------- /src/content/docs/recipes/apps/color-eyre/panic.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:9022e1002970048682b8dc0a7660c555956982d4b880256433de1faed660c8e6 3 | size 150879 4 | -------------------------------------------------------------------------------- /src/content/docs/recipes/apps/color-eyre/quit.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:584a802cebc9f23ca01bae5db1d4680461f955dd0d8aec3047cdd1b93c1cc1f5 3 | size 84934 4 | -------------------------------------------------------------------------------- /src/content/docs/recipes/apps/color-eyre/quit.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:310faa5443924b7cf5ccb7fb461ffe3c886f81bb2bcefe04758aa367ee506353 3 | size 64515 4 | -------------------------------------------------------------------------------- /src/content/docs/recipes/apps/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Develop Applications 3 | sidebar: 4 | order: 0 5 | --- 6 | 7 | This section covers recipes for developing applications: 8 | 9 | - [CLI arguments](./cli-arguments/) 10 | - [Configuration Directories](./config-directories/) 11 | - [Setup Logging with Tracing](./log-with-tracing/) 12 | - [Arrange your App Code](./terminal-and-event-handler/) 13 | - [Setup Panic Hooks](./panic-hooks/) 14 | - [Use Better Panic](./better-panic/) 15 | - [Migrate from TUI-rs](./migrate-from-tui-rs/) 16 | - [Spawn Vim](./spawn-vim/) 17 | - [Releasing Your App](./release-your-app/) 18 | -------------------------------------------------------------------------------- /src/content/docs/recipes/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Recipes 3 | --- 4 | 5 | - [Layout](./layout/): Articles regarding how to layout your application's User Interface including 6 | widgets and nesting blocks 7 | - [Rendering](./render/): Articles related to actually rendering text and widgets to the screen 8 | including how to style and write to the buffer. 9 | - [Widgets](./widgets/): Articles related to using individual widgets suchs as the paragraph, block, 10 | and creating your own custom widget. 11 | - [Testing](./testing/): Articles related to how to test your TUI application. 12 | - [Applications](./apps/): Articles related to developing applications. E.g. how to handle CLI 13 | arguments, tracing, configuration, panics, etc. 14 | -------------------------------------------------------------------------------- /src/content/docs/recipes/layout/dynamic.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Create Dynamic layouts" 3 | sidebar: 4 | order: 1 5 | label: Dynamic Layouts 6 | --- 7 | 8 | With real world applications, the content can often be dynamic. For example, a chat application may 9 | need to resize the chat input area based on the number of incoming messages. To achieve this, you 10 | can generate layouts dynamically: 11 | 12 | ```rust 13 | fn get_layout_based_on_messages(msg_count: usize, f: &Frame) -> Rc<[Rect]> { 14 | let msg_percentage = if msg_count > 50 { 80 } else { 50 }; 15 | 16 | Layout::default() 17 | .direction(Direction::Vertical) 18 | .constraints([ 19 | Constraint::Percentage(msg_percentage), 20 | Constraint::Percentage(100 - msg_percentage), 21 | ]) 22 | .split(f.area()) 23 | } 24 | ``` 25 | 26 | You can even update the layout based on some user input or command: 27 | 28 | ```rust 29 | match action { 30 | Action::IncreaseSize => { 31 | current_percentage += 5; 32 | if current_percentage > 95 { 33 | current_percentage = 95; 34 | } 35 | }, 36 | Action::DecreaseSize => { 37 | current_percentage -= 5; 38 | if current_percentage < 5 { 39 | current_percentage = 5; 40 | } 41 | }, 42 | _ => {} 43 | } 44 | 45 | let chunks = Layout::default() 46 | .direction(Direction::Horizontal) 47 | .constraints([ 48 | Constraint::Percentage(current_percentage), 49 | Constraint::Percentage(100 - current_percentage), 50 | ]) 51 | .split(f.area()); 52 | 53 | ``` 54 | -------------------------------------------------------------------------------- /src/content/docs/recipes/layout/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Recipes: UI Layout" 3 | sidebar: 4 | order: 0 5 | label: UI Layout 6 | --- 7 | 8 | In this section we will cover layout basics and advanced techniques. 9 | 10 | - [Create Dynamic Layouts](./dynamic/) 11 | - [Center a Rect](./center-a-widget/) 12 | - [Collapse Borders](./collapse-borders/) 13 | 14 | ## See Also 15 | 16 | - [Layout Concepts](/concepts/layout) 17 | - [FAQ: How do I avoid panics due to out of range calls on the Buffer?][faq-avoid-panics] 18 | 19 | [faq-avoid-panics]: /faq#how-do-i-avoid-panics-due-to-out-of-range-calls-on-the-buffer 20 | -------------------------------------------------------------------------------- /src/content/docs/recipes/render/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Render UIs 3 | sidebar: 4 | order: 0 5 | --- 6 | 7 | - [Display Text](./display-text/) 8 | - [Style Text](./style-text/) 9 | - [Overwrite regions](./overwrite-regions/) 10 | -------------------------------------------------------------------------------- /src/content/docs/recipes/widgets/block.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Block 3 | sidebar: 4 | order: 1 5 | --- 6 | 7 | The `Block` widget serves as a foundational building block for structuring and framing other 8 | widgets. It's essentially a container that can have borders, a title, and other styling elements to 9 | enhance the aesthetics and structure of your terminal interface. This page provides an in-depth 10 | exploration of the `Block` widget. 11 | 12 | ## Basic Usage 13 | 14 | The simplest use case for a `Block` is to create a container with borders: 15 | 16 | ```rust 17 | let b = Block::default() 18 | .borders(Borders::ALL); 19 | f.render_widget(b, chunks[0]); 20 | ``` 21 | 22 | ## Titles 23 | 24 | A common use case for Block is to give a section of the UI a title or a label: 25 | 26 | ```rust 27 | let b = Block::default() 28 | .title("Header") 29 | .borders(Borders::ALL); 30 | f.render_widget(b, chunks[0]); 31 | ``` 32 | 33 | You can also use the `Line` struct for better positioning or multiple titles. 34 | 35 | ```rust 36 | let b = Block::default() 37 | .title(Line::from("Left Title").left_aligned()) 38 | .title(Line::from("Middle Title").centered()) 39 | .title(Line::from("Right Title").right_aligned()) 40 | .borders(Borders::ALL); 41 | f.render_widget(b, chunks[0]); 42 | ``` 43 | 44 | ## Border style 45 | 46 | Block provides flexibility in both the borders style and type: 47 | 48 | ```rust 49 | let b = Block::default() 50 | .title("Styled Header") 51 | .border_style(Style::default().fg(Color::Magenta)) 52 | .border_type(BorderType::Rounded) 53 | .borders(Borders::ALL); 54 | f.render_widget(b, chunks[0]); 55 | ``` 56 | -------------------------------------------------------------------------------- /src/content/docs/recipes/widgets/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Use Widgets 3 | sidebar: 4 | order: 0 5 | --- 6 | 7 | Widgets are types that implement the [`Widget`] or [`StatefulWidget`] trait which allows 8 | applications to render them to a terminal. 9 | 10 | The following pages document how to use the following widgets: 11 | 12 | - [Block](./block/) 13 | - [Paragraph](./paragraph/) 14 | - [Custom Widgets](./custom/) 15 | 16 | There are more widgets available than just the above list. The crate docs document all the built-in 17 | widgets. See the [`widgets` module] for a list. There are also [Third Party Crates] that implement 18 | more widgets. 19 | 20 | [`Widget`]: https://docs.rs/ratatui/latest/ratatui/widgets/trait.Widget.html 21 | [`StatefulWidget`]: https://docs.rs/ratatui/latest/ratatui/widgets/trait.StatefulWidget.html 22 | [`widgets` module]: https://docs.rs/ratatui/latest/ratatui/widgets/index.html 23 | [Third Party Crates]: /references/#third-party-crates 24 | -------------------------------------------------------------------------------- /src/content/docs/showcase/index.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Showcase 3 | sidebar: 4 | order: 0 5 | --- 6 | 7 | import { Card, CardGrid } from "@astrojs/starlight/components"; 8 | 9 | 10 | 11 |

    Apps built with Ratatui

    12 |
    13 | 14 |

    Built-in widgets for building Ratatui apps

    15 |
    16 | 17 |

    Third party widgets for building Ratatui apps

    18 |
    19 |
    20 | -------------------------------------------------------------------------------- /src/content/docs/showcase/third-party-widgets/throbber-widgets-tui.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:196b64bd16ae3b5e12ebab6f96ed09829bbbaeaf86bdf13453e8a8b34f214ab0 3 | size 120996 4 | -------------------------------------------------------------------------------- /src/content/docs/showcase/third-party-widgets/tui-big-text.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:9fa75eba660acfd09435e74e9491cbc85dab3dc54ba7468f220c63d9d29cde6d 3 | size 20597 4 | -------------------------------------------------------------------------------- /src/content/docs/showcase/third-party-widgets/tui-logger.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:c7c853049b62f488df6b4769de61b6d00c163e5de68bc4d6b23096c55bd5c613 3 | size 901751 4 | -------------------------------------------------------------------------------- /src/content/docs/showcase/third-party-widgets/tui-menu.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:cd7b05e19eed1c4a311126572c23048edc49dd6e2df8d20fb70cf9657b758da3 3 | size 34973 4 | -------------------------------------------------------------------------------- /src/content/docs/showcase/third-party-widgets/tui-nodes.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:da83aacb210376791fe4f737f0e4c99fd256d8595be0b1e469895b5b737119c9 3 | size 19480 4 | -------------------------------------------------------------------------------- /src/content/docs/showcase/third-party-widgets/tui-term.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:0b0b20f398f945f1691d8e0d289e9f745982129c2e6c76128bb87eaf80df6866 3 | size 2298842 4 | -------------------------------------------------------------------------------- /src/content/docs/showcase/third-party-widgets/tui-textarea.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:37d4cc437d165f9fdf251d960a9e65a98caa27da4242185ebfe64b573a40f6ef 3 | size 1633142 4 | -------------------------------------------------------------------------------- /src/content/docs/showcase/third-party-widgets/tui-treeview.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:411635b09eb0e66421b0983bf45b2e9a21945a3ae06730952ac4ccadda26fb17 3 | size 113580 4 | -------------------------------------------------------------------------------- /src/content/docs/showcase/third-party-widgets/tui-widget-list.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:e8a229fa1f821c6ff209c80dfaa9034d25bf33868387257404ba50649b5b97fd 3 | size 220369 4 | -------------------------------------------------------------------------------- /src/content/docs/showcase/widgets/bar_chart.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:f059cee59ab8c41171be7128aa87eaeaaaf1c3f6a636eadc6e01f72d537a6f72 3 | size 96642 4 | -------------------------------------------------------------------------------- /src/content/docs/showcase/widgets/bar_chart.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:982bbd82dc3f1f6af5d36a4da58e84e03b0787bac4731e13e0134c938c4fc1a6 3 | size 21289 4 | -------------------------------------------------------------------------------- /src/content/docs/showcase/widgets/block.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:22a30244204516cdca8fb4916c0c75df72a274c0b971923a447c7f56bfe73dbc 3 | size 102321 4 | -------------------------------------------------------------------------------- /src/content/docs/showcase/widgets/block.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:b0005e209b7c0dd881ad802588d6bda382788cc698cc0ca65d823f6e510880df 3 | size 38493 4 | -------------------------------------------------------------------------------- /src/content/docs/showcase/widgets/calendar.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:7726ea0798f587dbc28a660a19b134b70f7d1ad976d5bc2e17ba5d013c744165 3 | size 108785 4 | -------------------------------------------------------------------------------- /src/content/docs/showcase/widgets/calendar.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:85043d51b5e04970f851afea8c0451fedff3978ba51b795394f87fcbe61d0204 3 | size 50853 4 | -------------------------------------------------------------------------------- /src/content/docs/showcase/widgets/canvas.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:61fbdfa1917a4c5cba9304a7b3b92f9d3bb08344cc4f1be6320c08e57184b8ee 3 | size 22817 4 | -------------------------------------------------------------------------------- /src/content/docs/showcase/widgets/chart.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:fba18d3c840a18ac5ea3c6e748bce33becbf5b99a639765f668e667aa5a3339f 3 | size 141088 4 | -------------------------------------------------------------------------------- /src/content/docs/showcase/widgets/chart.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:e3a0ad21b36257c1eb050219d41b971c75e8f35b1efa56e1047781d6d288c2dd 3 | size 26324 4 | -------------------------------------------------------------------------------- /src/content/docs/showcase/widgets/gauge.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:3ac444c2210076331b56e4c6cfb5b31a7197653e06d065ada8f879acbc454975 3 | size 53872 4 | -------------------------------------------------------------------------------- /src/content/docs/showcase/widgets/gauge.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:6084d6ad18fcba151a52d3e867383cc9cd33530537ba0a7ea95a774176a186df 3 | size 12885 4 | -------------------------------------------------------------------------------- /src/content/docs/showcase/widgets/line_gauge.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:b9548b9bbde6725bb9b909a571b254e557711e03ca8904275c4bdafbdf70a321 3 | size 64652 4 | -------------------------------------------------------------------------------- /src/content/docs/showcase/widgets/line_gauge.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:106a894dfbae550d751b03c81562964d0e0f9a44081ffb5d91383bf09b9dfdab 3 | size 17557 4 | -------------------------------------------------------------------------------- /src/content/docs/showcase/widgets/list.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:8e0b323614d8ede474dfe11f3337ecd0a394428dbe70ec5f0ea3e3f64c71dc33 3 | size 53448 4 | -------------------------------------------------------------------------------- /src/content/docs/showcase/widgets/paragraph.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:e770deaf46710b6ace2a8b913bd5ee7fabc976fa0aa823265e3862df6ebaa3ad 3 | size 60249 4 | -------------------------------------------------------------------------------- /src/content/docs/showcase/widgets/paragraph.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:d600e2d402ef6058084b383edb37ece183b3b92bd606ad4a54fe55ff70a9248f 3 | size 35441 4 | -------------------------------------------------------------------------------- /src/content/docs/showcase/widgets/scrollbar.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:be539d6d66abc5a728cf3da62725530df07dc461b68b5d5153cc3b17dc68ab2f 3 | size 72969 4 | -------------------------------------------------------------------------------- /src/content/docs/showcase/widgets/scrollbar.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:e8a68b4dde5bb723e6afad07d2d5ed78eee9fa46f7f6ecd8b681977c4c9b6e50 3 | size 89126 4 | -------------------------------------------------------------------------------- /src/content/docs/showcase/widgets/sparkline.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:f48653a4f18e63ae29aa48d5bc5b96c8b591a874a5140993c0054894e3d7b1c4 3 | size 38979 4 | -------------------------------------------------------------------------------- /src/content/docs/showcase/widgets/sparkline.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:ea3d89b4284e227c568f5f9017df1419deb96f8494780293b040c9785e9beb25 3 | size 10392 4 | -------------------------------------------------------------------------------- /src/content/docs/showcase/widgets/table.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:e0777a831c6f3f2d2165bb778fca9f6fab71d2e03d7c7a4b9a3860b45ff0f3d8 3 | size 147297 4 | -------------------------------------------------------------------------------- /src/content/docs/showcase/widgets/table.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:1b653bfda17fca9461bb433b91ebd0c652b028755b85364d4aa38ccfad3605ae 3 | size 98747 4 | -------------------------------------------------------------------------------- /src/content/docs/showcase/widgets/tabs.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:9cd9a7f663665fa50f544b5d8f71449831f818103267b218e48b6305aebf464c 3 | size 68852 4 | -------------------------------------------------------------------------------- /src/content/docs/showcase/widgets/tabs.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:c856f5324fa602b809c4cdb6b17e301eb9019fd04f92be7f7ee694661e5c79bc 3 | size 18948 4 | -------------------------------------------------------------------------------- /src/content/docs/showcase/widgets/throbber-widgets-tui.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:196b64bd16ae3b5e12ebab6f96ed09829bbbaeaf86bdf13453e8a8b34f214ab0 3 | size 120996 4 | -------------------------------------------------------------------------------- /src/content/docs/showcase/widgets/tui-big-text.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:9fa75eba660acfd09435e74e9491cbc85dab3dc54ba7468f220c63d9d29cde6d 3 | size 20597 4 | -------------------------------------------------------------------------------- /src/content/docs/showcase/widgets/tui-nodes.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:da83aacb210376791fe4f737f0e4c99fd256d8595be0b1e469895b5b737119c9 3 | size 19480 4 | -------------------------------------------------------------------------------- /src/content/docs/showcase/widgets/tui-term.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:0b0b20f398f945f1691d8e0d289e9f745982129c2e6c76128bb87eaf80df6866 3 | size 2298842 4 | -------------------------------------------------------------------------------- /src/content/docs/showcase/widgets/tui-textarea.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:37d4cc437d165f9fdf251d960a9e65a98caa27da4242185ebfe64b573a40f6ef 3 | size 1633142 4 | -------------------------------------------------------------------------------- /src/content/docs/showcase/widgets/tui-treeview.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:411635b09eb0e66421b0983bf45b2e9a21945a3ae06730952ac4ccadda26fb17 3 | size 113580 4 | -------------------------------------------------------------------------------- /src/content/docs/showcase/widgets/tui-widget-list.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:e8a229fa1f821c6ff209c80dfaa9034d25bf33868387257404ba50649b5b97fd 3 | size 220369 4 | -------------------------------------------------------------------------------- /src/content/docs/templates/component/components-rs.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Components.rs 3 | sidebar: 4 | order: 5 5 | --- 6 | 7 | In `components/mod.rs`, we implement a `trait` called `Component`: 8 | 9 | ```rust 10 | {{#include @code/templates/async-template-counter/src/components.rs:component}} 11 | ``` 12 | 13 | I personally like keeping the functions for `handle_events` (i.e. event -> action mapping), 14 | `dispatch` (i.e. action -> state update mapping) and `render` (i.e. state -> drawing mapping) all in 15 | one file for each component of my application. 16 | 17 | There's also an `init` function that can be used to setup the `Component` when it is loaded. 18 | 19 | The `Home` struct (i.e. the root struct that may hold other `Component`s) will implement the 20 | `Component` trait. We'll have a look at `Home` next. 21 | -------------------------------------------------------------------------------- /src/content/docs/templates/component/main-rs.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Main.rs 3 | sidebar: 4 | order: 2 5 | --- 6 | 7 | In this section, let's just cover the contents of `main.rs`, `build.rs` and `utils.rs`. 8 | 9 | The `main.rs` file is the entry point of the application. Here's the complete `main.rs` file: 10 | 11 | ```rust 12 | {{#include @code/templates/async-template-counter/src/main.rs:all}} 13 | ``` 14 | 15 | In essence, the `main` function creates an instance of `App` and calls `App.run()`, which runs the 16 | "`handle event` -> `update state` -> `draw`" loop. We will talk more about this in a later section. 17 | 18 | This `main.rs` file incorporates some key features that are not necessarily related to `ratatui`, 19 | but in my opinion, essential for any Terminal User Interface (TUI) program: 20 | 21 | - Command Line Argument Parsing (`clap`) 22 | - XDG Base Directory Specification 23 | - Logging 24 | - Panic Handler 25 | 26 | These are described in more detail in the [`utils.rs` section](./08-structure.md). 27 | -------------------------------------------------------------------------------- /src/content/docs/templates/component/project-structure.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Project Structure 3 | sidebar: 4 | order: 1 5 | --- 6 | 7 | The rust files in the `component` project are organized as follows: 8 | 9 | ```bash 10 | $ tree 11 | . 12 | ├── build.rs 13 | └── src 14 | ├── action.rs 15 | ├── components 16 | │ ├── app.rs 17 | │ └── mod.rs 18 | ├── config.rs 19 | ├── main.rs 20 | ├── runner.rs 21 | ├── tui.rs 22 | └── utils.rs 23 | ``` 24 | 25 | Once you have setup the project, you shouldn't need to change the contents of anything outside of 26 | the `components` folder. 27 | 28 | Let's discuss the contents of the files in the `src` folder first, how these contents of these files 29 | interact with each other and why they do what they are doing. 30 | -------------------------------------------------------------------------------- /src/content/docs/templates/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Ratatui Templates 3 | --- 4 | 5 | Ratatui provides [templates] for building apps using [Cargo Generate]. 6 | 7 | To use these, [install Cargo Generate] and then create a new app using the chosen template: 8 | 9 | ```shell 10 | cargo install cargo-generate 11 | cargo generate ratatui/templates 12 | ``` 13 | 14 | [templates]: https://github.com/ratatui/templates 15 | [Cargo Generate]: https://cargo-generate.github.io/cargo-generate/ 16 | [install Cargo Generate]: https://cargo-generate.github.io/cargo-generate/installation.html 17 | -------------------------------------------------------------------------------- /src/content/docs/tutorials/counter-app/_TODO.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: todo for the counter app rewrite 3 | --- 4 | 5 | - Testing app methods (e.g. increment / decrement) 6 | - Adding style (probably not necessary) 7 | - event loop - add a throbber 8 | - event loop - add poll 9 | - event loop - take events out of the loop 10 | -------------------------------------------------------------------------------- /src/content/docs/tutorials/counter-app/_multiple-files/app.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: app.rs 3 | --- 4 | 5 | Let's start with the same `struct` as we had before: 6 | 7 | ```rust 8 | {{#include @code/tutorials/ratatui-counter-app/src/app.rs:application}} 9 | ``` 10 | 11 | We can add additional methods to this `Application` struct: 12 | 13 | ```rust 14 | {{#include @code/tutorials/ratatui-counter-app/src/app.rs:application_impl}} 15 | ``` 16 | 17 | We use the principle of encapsulation to expose an interface to modify the state. In this particular 18 | instance, it may seem like overkill but it is good practice nonetheless. 19 | 20 | The practical advantage of this is that it makes the state changes easy to test. 21 | 22 | ```rust 23 | {{#include @code/tutorials/ratatui-counter-app/src/app.rs:application_test}} 24 | ``` 25 | 26 | :::tip 27 | 28 | You can test a single function by writing out fully qualified module path to the test function, like 29 | so: 30 | 31 | ```bash 32 | cargo test -- app::tests::test_app_increment_counter --nocapture 33 | ``` 34 | 35 | Or even test all functions that start with `test_app_` by doing this: 36 | 37 | ```bash 38 | cargo test -- app::tests::test_app_ --nocapture 39 | ``` 40 | 41 | The `--nocapture` flag prints stdout and stderr to the console, which can help debugging tests. 42 | 43 | ::: 44 | -------------------------------------------------------------------------------- /src/content/docs/tutorials/counter-app/_multiple-files/main.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: main.rs 3 | --- 4 | 5 | Putting it all together, we have the `main.rs` function: 6 | 7 | ```rust 8 | {{#include @code/tutorials/ratatui-counter-app/src/main.rs:imports_main}} 9 | 10 | {{#include @code/tutorials/ratatui-counter-app/src/main.rs:main}} 11 | ``` 12 | 13 | Because we call `tui.events.next()` in a loop, it blocks until there's an event generated. If 14 | there's a key press, the state updates and the UI is refreshed. If there's no key press, a `Tick` 15 | event is generated every 250 milliseconds, which causes the UI to be refreshed. 16 | 17 | This is what it looks like in practice to: 18 | 19 | - Run the TUI 20 | - Wait 2.5 seconds 21 | - Press `j` 5 times 22 | - Wait 2.5 seconds 23 | - Press `k` 5 times 24 | - Wait 2.5 seconds 25 | - Press `q` 26 | 27 | 44 | 45 | ![Counter app demo](https://user-images.githubusercontent.com/1813121/263404720-41bd81a0-4eec-479c-9333-44363a183613.gif) 46 | 47 | You can find the full source code for this multiple files tutorial here: 48 | . 49 | 50 | :::note[Homework] 51 | 52 | Right now, this TUI application will render every time a key is pressed. As an exercise, can you 53 | make this app render only an a predefined tick rate? 54 | 55 | ::: 56 | -------------------------------------------------------------------------------- /src/content/docs/tutorials/counter-app/_multiple-files/ui.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: ui.rs 3 | --- 4 | 5 | Previously we were rendering a `Paragraph` with no styling. 6 | 7 | Let's make some improvements: 8 | 9 | 1. Add a `Block` with a rounded border and the title `"Counter App"`. 10 | 2. Make everything in the Paragraph have a foreground color of `Color::Yellow` 11 | 12 | This is what our code will now look like: 13 | 14 | ```rust 15 | {{#include @code/tutorials/ratatui-counter-app/src/ui.rs}} 16 | ``` 17 | 18 | Keep in mind it won't render until we have written the code for `tui::Frame` 19 | 20 | When rendered, this is what the UI will look like: 21 | 22 | ![Counter app demo](https://user-images.githubusercontent.com/1813121/263155937-d8a8b6f6-97f4-4839-b855-ffd0249c2ae0.png) 23 | -------------------------------------------------------------------------------- /src/content/docs/tutorials/counter-app/_multiple-files/update.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: update.rs 3 | --- 4 | 5 | Finally we have the `update.rs` file. Here, the `update()` function takes in two arguments: 6 | 7 | - `key_event`: This is an event provided by the `crossterm` crate, representing a key press from the 8 | user. 9 | - `app`: A mutable reference to our application's state, represented by the `App` struct. 10 | 11 | ```rust 12 | {{#include @code/tutorials/ratatui-counter-app/src/update.rs}} 13 | ``` 14 | 15 | Note that here we don't have to check that `key_event.kind` is `KeyEventKind::Press` because we 16 | already do that check in [event.rs](../event/) and only send `KeyEventKind::Press` events on the 17 | channel. 18 | 19 | :::note[Homework] 20 | 21 | As an exercise, can you refactor this app to use "The Elm Architecture" principles? 22 | 23 | Check out 24 | [the concepts page on The Elm Architecture](/concepts/application-patterns/the-elm-architecture/) 25 | for reference. 26 | 27 | ::: 28 | -------------------------------------------------------------------------------- /src/content/docs/tutorials/counter-app/basic-app-error.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:8d658aa4cee4e329714f0a1035a6c461d7fc4f2f613bec37fa3ef3e20cbcb468 3 | size 110806 4 | -------------------------------------------------------------------------------- /src/content/docs/tutorials/counter-app/basic-app-error.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:05ab80e03cf174e26e94876cff775a1aa800a04179ad48483183f3f000123a9b 3 | size 87541 4 | -------------------------------------------------------------------------------- /src/content/docs/tutorials/counter-app/basic-app.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:43f6906c3b69c3ad906135c660aa4c9727f0d034efec870815e35cd5089b8017 3 | size 100088 4 | -------------------------------------------------------------------------------- /src/content/docs/tutorials/counter-app/basic-app.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:b4028a29d272e7ffabb217cc570b29e738af4453019d68f56807486560f0171b 3 | size 34772 4 | -------------------------------------------------------------------------------- /src/content/docs/tutorials/counter-app/error-full.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:80945328a476e8defd8c3dcbe9b5b83a10da93bf7dbd8672208ddaebcffb6fd5 3 | size 437648 4 | -------------------------------------------------------------------------------- /src/content/docs/tutorials/counter-app/error-full.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:14249c0769064bbf885fa34a7febeae5269e255d6ec6c7555bb403dbc49cfa85 3 | size 801492 4 | -------------------------------------------------------------------------------- /src/content/docs/tutorials/counter-app/error.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:51e0e7e88308a790de6f95dd30efc5b7dee6abec1cba66cb9433fff8a9adaf5b 3 | size 191237 4 | -------------------------------------------------------------------------------- /src/content/docs/tutorials/counter-app/error.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:bd15691977e835efa385a13aff7f91dc74e2581ce9909852f70c669159422bac 3 | size 129893 4 | -------------------------------------------------------------------------------- /src/content/docs/tutorials/counter-app/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Counter App 3 | sidebar: 4 | order: 0 5 | --- 6 | 7 | The previous [Hello Ratatui] tutorial introduced how to create a simple TUI that displayed some text 8 | and waited for the user to press a key. This tutorial will cover how to handle state and some more 9 | complex interactions. You will build a counter application that allows the user to increment and 10 | decrement a value on the screen. 11 | 12 | When you're finished the application will look like the following: 13 | 14 | ![basic-app demo](./basic-app.png) 15 | 16 | The application will render the counter in a [`Paragraph`] widget. When the user presses the left 17 | and right arrow keys, the application will increment and decrement the value of the counter. 18 | 19 | [Hello Ratatui]: /tutorials/hello-ratatui 20 | [`Paragraph`]: https://docs.rs/ratatui/latest/ratatui/widgets/struct.Paragraph.html 21 | -------------------------------------------------------------------------------- /src/content/docs/tutorials/counter-app/panic-full.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:4882f5b57baf95998f7a84496be630e736c8e8e5d7fa4fcf252af1b478ca799c 3 | size 404865 4 | -------------------------------------------------------------------------------- /src/content/docs/tutorials/counter-app/panic-full.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:7d909eddf2225c465c044ba195534e5ca40f6a237d9b6f5068d7cc2b3a5a1b00 3 | size 704603 4 | -------------------------------------------------------------------------------- /src/content/docs/tutorials/counter-app/panic.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:18b40c40136d59cf4f54bfdadde46f11d23997b1e0500bd4a676f5e5b5cbb1db 3 | size 143029 4 | -------------------------------------------------------------------------------- /src/content/docs/tutorials/counter-app/panic.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:90d5b70be5d368e270d7c0d5c1fb3158f090dd7bdf8fc38d1569ea34fdeba153 3 | size 160450 4 | -------------------------------------------------------------------------------- /src/content/docs/tutorials/counter-async-app/conclusion.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Conclusion 3 | sidebar: 4 | order: 7 5 | --- 6 | 7 | We touched on the basic framework for building an `async` application with Ratatui, namely using 8 | `tokio` and `crossterm`'s async features to create an `Event` and `Action` enum that contain 9 | `Render` variants. We also saw how we could use `tokio` channels to send `Action`s to run domain 10 | specific async operations concurrently. 11 | 12 | There's more information in the documentation for a template that covers setting up a 13 | [`Component` based architecture](/concepts/application-patterns/component-architecture/). 14 | -------------------------------------------------------------------------------- /src/content/docs/tutorials/hello-ratatui/hello-ratatui.gif: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:365ad70a037fdba27514dfcea090413694d3523e00abc69e1e16b576dcc71eed 3 | size 1845297 4 | -------------------------------------------------------------------------------- /src/content/docs/tutorials/hello-ratatui/hello-ratatui.png: -------------------------------------------------------------------------------- 1 | version https://git-lfs.github.com/spec/v1 2 | oid sha256:8c90f88829204b1aa62c63fb0fb5021adb3cba92dc94787e3ec0dfc38aa25ffb 3 | size 8355 4 | -------------------------------------------------------------------------------- /src/content/docs/tutorials/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Tutorials 3 | --- 4 | 5 | - [Hello Ratatui](./hello-ratatui/): This tutorial takes you through the basics of creating a simple 6 | Ratatui application that displays "Hello World". 7 | - [Counter App](./counter-app/): This tutorial will set up the basics of a `ratatui` project by 8 | building a app that displays a counter. 9 | - [JSON Editor](./json-editor/): This tutorial will guide you through setting up a Rust project and 10 | organizing its structure for a `ratatui`-based application to edit json key value pairs. JSON 11 | Editor TUI will provide an interface for users to input key-value pairs, which are then converted 12 | into correct JSON format and printed to stdout. 13 | 14 | :::note 15 | 16 | If you want to jump right into coding yourself, we provide templates for that. See the 17 | [template section](/templates). 18 | We also have some [examples](https://github.com/ratatui/ratatui/tree/main/examples) that might help 19 | you get started on GitHub. 20 | 21 | ::: 22 | 23 | :::note 24 | 25 | You can also check out [videos](/tutorials/videos) created by Ratatui users. 26 | 27 | ::: 28 | -------------------------------------------------------------------------------- /src/content/docs/tutorials/json-editor/closing-thoughts.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Closing Thoughts 3 | sidebar: 4 | order: 7 5 | --- 6 | 7 | This tutorial should get you started with a basic understanding of the flow of a `ratatui` program. 8 | However, this is only _one_ way to create a `ratatui` application. Because `ratatui` is relatively 9 | low level compared to other UI frameworks, almost any application model can be implemented. You can 10 | explore more of these in 11 | [Concepts: Application Patterns](/concepts/application-patterns/the-elm-architecture/) and get some 12 | inspiration for what model will work best for your application. 13 | 14 | ## Finished Files 15 | 16 | You can find the finished project used for the tutorial on 17 | [GitHub](https://github.com/ratatui/ratatui-website/tree/main/code/tutorials/json-editor). The code 18 | is also shown at the bottom of this page. 19 | 20 | You can test this application by yourself by running: 21 | 22 | ```shell 23 | cargo run > test.json 24 | ``` 25 | 26 | and double checking the output. 27 | 28 | ### Main.rs 29 | 30 | ```rust 31 | {{#include @code/tutorials/json-editor/src/main.rs:all}} 32 | ``` 33 | 34 | ### App.rs 35 | 36 | ```rust 37 | {{#include @code/tutorials/json-editor/src/app.rs:all}} 38 | ``` 39 | 40 | ### UI.rs 41 | 42 | ```rust 43 | {{#include @code/tutorials/json-editor/src/ui.rs:all}} 44 | ``` 45 | -------------------------------------------------------------------------------- /src/content/docs/tutorials/json-editor/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: JSON Editor 3 | sidebar: 4 | order: 0 5 | --- 6 | 7 | Now that we have covered some of the basics of a [Hello Ratatui] and [Counter] apps, we are ready to 8 | build and manage something more involved. 9 | 10 | [Hello Ratatui]: /tutorials/hello-ratatui 11 | [Counter]: /tutorials/counter-app 12 | 13 | In this tutorial, we will be creating an application that gives the user a simple interface to enter 14 | key-value pairs, which will be converted and printed to `stdout` in json. The purpose of this 15 | application will be to give the user an interface to create correct json, instead of having to worry 16 | about commas and brackets themselves. 17 | 18 | Here’s a gif of what it will look like if you run this: 19 | 20 | ![Demo](https://vhs.charm.sh/vhs-5VaEPLZP2OlOxPPAIiLqbF.gif) 21 | 22 | ## Initialization 23 | 24 | Go ahead and set up a new rust project with 25 | 26 | ```shell 27 | cargo new ratatui-json-editor 28 | ``` 29 | 30 | and put the following in the `Cargo.toml`: 31 | 32 | ```toml 33 | {{#include @code/tutorials/json-editor/Cargo.toml:10:}} 34 | ``` 35 | 36 | or the latest version of these libraries. 37 | 38 | ## Filestructure 39 | 40 | Now create two files inside of `src/` so it looks like this: 41 | 42 | ``` 43 | src 44 | ├── main.rs 45 | ├── ui.rs 46 | └── app.rs 47 | ``` 48 | 49 | This follows a common approach to small applications in `ratatui`, where we have a state file, a UI 50 | file, and the main file to tie it all together. 51 | -------------------------------------------------------------------------------- /src/content/docs/tutorials/json-editor/ui-exit.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: UI - Exit Popup 3 | sidebar: 4 | order: 6 5 | --- 6 | 7 | We have a way for the user to view their already entered key-value pairs, and we have a way for the 8 | user to enter new ones. The last screen we need to create, is the exit/confirmation screen. 9 | 10 | In this screen, we are asking the user if they want to output the key-value pairs they have entered 11 | in the `stdout` pipe, or close without outputting anything. 12 | 13 | ```rust 14 | {{#include @code/tutorials/json-editor/src/ui.rs:exit_screen}} 15 | ``` 16 | 17 | The only thing in this part that we haven't done before, is use the 18 | [`Clear`](https://docs.rs/ratatui/latest/ratatui/widgets/struct.Clear.html) widget. This is a 19 | special widget that does what the name suggests --- it clears everything in the space it is 20 | rendered. 21 | -------------------------------------------------------------------------------- /src/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | -------------------------------------------------------------------------------- /tailwind.config.mjs: -------------------------------------------------------------------------------- 1 | import starlightPlugin from "@astrojs/starlight-tailwind"; 2 | import colors from "tailwindcss/colors"; 3 | 4 | /** @type {import('tailwindcss').Config} */ 5 | export default { 6 | content: ["./src/**/*.{astro,html,js,jsx,md,mdx,svelte,ts,tsx,vue}"], 7 | theme: { 8 | extend: { 9 | colors: { accent: colors.blue, gray: colors.slate }, 10 | }, 11 | }, 12 | plugins: [require("tailwindcss-animate"), starlightPlugin()], 13 | }; 14 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "astro/tsconfigs/strict", 3 | "compilerOptions": { 4 | "baseUrl": ".", 5 | "paths": { 6 | "@components/*": ["src/components/*"], 7 | "@assets/*": ["src/assets/*"], 8 | "@code/*": ["src/code/*"], 9 | "~/*": ["src/*"] 10 | } 11 | }, 12 | "exclude": ["dist"] 13 | } 14 | -------------------------------------------------------------------------------- /typos.toml: -------------------------------------------------------------------------------- 1 | # configuration for https://github.com/crate-ci/typos 2 | 3 | [default.extend-words] 4 | ratatui = "ratatui" 5 | iterm2 = "iTerm2" 6 | iterm = "iTerm2" 7 | 8 | [type.md] 9 | extend-ignore-re = [ 10 | "\\[[[:xdigit:]]{7}\\]\\(https://github.com/ratatui/ratatui/commit/[[:xdigit:]]{40}\\)", 11 | ] 12 | -------------------------------------------------------------------------------- /vitest.config.ts: -------------------------------------------------------------------------------- 1 | /// 2 | import { getViteConfig } from "astro/config"; 3 | 4 | export default getViteConfig({ 5 | test: { 6 | // Vitest configuration options 7 | }, 8 | }); 9 | --------------------------------------------------------------------------------