diff --git a/Cargo.toml b/Cargo.toml
index a97acfc8..29891bee 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -155,6 +155,11 @@ name = "demo2"
required-features = ["crossterm", "widget-calendar"]
doc-scrape-examples = true
+[[example]]
+name = "docsrs"
+required-features = ["crossterm"]
+doc-scrape-examples = false
+
[[example]]
name = "gauge"
required-features = ["crossterm"]
diff --git a/README.md b/README.md
index 6d0fe3b2..2e0b0cd5 100644
--- a/README.md
+++ b/README.md
@@ -1,142 +1,336 @@
-
-
+
+Table of Contents
+
+- [Ratatui](#ratatui)
+ - [Installation](#installation)
+ - [Introduction](#introduction)
+ - [Other Documentation](#other-documentation)
+ - [Quickstart](#quickstart)
+ - [Status of this fork](#status-of-this-fork)
+ - [Rust version requirements](#rust-version-requirements)
+ - [Widgets](#widgets)
+ - [Built in](#built-in)
+ - [Third\-party libraries, bootstrapping templates and
+ widgets](#third-party-libraries-bootstrapping-templates-and-widgets)
+ - [Apps](#apps)
+ - [Alternatives](#alternatives)
+ - [Acknowledgments](#acknowledgments)
+ - [License](#license)
+
+
+
+
+
+
-[](https://crates.io/crates/ratatui)
-[](./LICENSE) [](https://github.com/ratatui-org/ratatui/actions?query=workflow%3ACI+)
-[](https://docs.rs/crate/ratatui/)
-[](https://deps.rs/repo/github/ratatui-org/ratatui)
-[](https://app.codecov.io/gh/ratatui-org/ratatui)
-[](https://discord.gg/pMCEU9hNEj)
-[](https://matrix.to/#/#ratatui:matrix.org)
-[Documentation](https://docs.rs/ratatui)
-· [Examples](https://github.com/ratatui-org/ratatui/tree/main/examples)
-· [Report a bug](https://github.com/ratatui-org/ratatui/issues/new?labels=bug&projects=&template=bug_report.md)
-· [Request a Feature](https://github.com/ratatui-org/ratatui/issues/new?labels=enhancement&projects=&template=feature_request.md)
+[![Crate Badge]](https://crates.io/crates/ratatui) [![License Badge]](./LICENSE) [![CI
+Badge]](https://github.com/ratatui-org/ratatui/actions?query=workflow%3ACI+) [![Docs
+Badge]](https://docs.rs/crate/ratatui/)
+[![Dependencies Badge]](https://deps.rs/repo/github/ratatui-org/ratatui) [![Codecov
+Badge]](https://app.codecov.io/gh/ratatui-org/ratatui) [![Discord
+Badge]](https://discord.gg/pMCEU9hNEj) [![Matrix
+Badge]](https://matrix.to/#/#ratatui:matrix.org)
+[Documentation](https://docs.rs/ratatui) · [Ratatui Book](https://ratatui.rs) ·
+[Examples](https://github.com/ratatui-org/ratatui/tree/main/examples) · [Report a
+bug](https://github.com/ratatui-org/ratatui/issues/new?labels=bug&projects=&template=bug_report.md)
+· [Request a
+Feature](https://github.com/ratatui-org/ratatui/issues/new?labels=enhancement&projects=&template=feature_request.md)
· [Send a Pull Request](https://github.com/ratatui-org/ratatui/compare)
-
-
# Ratatui
-`ratatui` is a [Rust](https://www.rust-lang.org) library that is all about cooking up terminal user
-interfaces. It is a community fork of the original [tui-rs](https://github.com/fdehau/tui-rs)
-project.
-
-
-Table of Contents
-
-* [Ratatui](#ratatui)
- * [Installation](#installation)
- * [Introduction](#introduction)
- * [Quickstart](#quickstart)
- * [Status of this fork](#status-of-this-fork)
- * [Rust version requirements](#rust-version-requirements)
- * [Documentation](#documentation)
- * [Examples](#examples)
- * [Widgets](#widgets)
- * [Built in](#built-in)
- * [Third\-party libraries, bootstrapping templates and
- widgets](#third-party-libraries-bootstrapping-templates-and-widgets)
- * [Apps](#apps)
- * [Alternatives](#alternatives)
- * [Contributors](#contributors)
- * [Acknowledgments](#acknowledgments)
- * [License](#license)
-
-
+[Ratatui] is a crate for cooking up terminal user interfaces in rust. It is a lightweight
+library that provides a set of widgets and utilities to build complex rust TUIs. Ratatui was
+forked from the [Tui-rs crate] in 2023 in order to continue its development.
## Installation
+Add `ratatui` and `crossterm` as dependencies to your cargo.toml:
+
```shell
-cargo add ratatui --features all-widgets
+cargo add ratatui crossterm
```
-Or modify your `Cargo.toml`
-
-```toml
-[dependencies]
-ratatui = { version = "0.23.0", features = ["all-widgets"]}
-```
+Ratatui uses [Crossterm] by default as it works on most platforms. See the [Installation]
+section of the [Ratatui Book] for more details on how to use other backends ([Termion] /
+[Termwiz]).
## Introduction
-`ratatui` is a terminal UI library that supports multiple backends:
+Ratatui is based on the principle of immediate rendering with intermediate buffers. This means
+that for each frame, your app must render all widgets that are supposed to be part of the UI.
+This is in contrast to the retained mode style of rendering where widgets are updated and then
+automatically redrawn on the next frame. See the [Rendering] section of the [Ratatui Book] for
+more info.
-* [crossterm](https://github.com/crossterm-rs/crossterm) [default]
-* [termion](https://github.com/ticki/termion)
-* [termwiz](https://github.com/wez/wezterm/tree/master/termwiz)
+## Other documentation
-The library is based on the principle of immediate rendering with intermediate buffers. This means
-that at each new frame you should build all widgets that are supposed to be part of the UI. While
-providing a great flexibility for rich and interactive UI, this may introduce overhead for highly
-dynamic content. So, the implementation try to minimize the number of ansi escapes sequences
-generated to draw the updated UI. In practice, given the speed of `Rust` the overhead rather comes
-from the terminal emulator than the library itself.
-
-Moreover, the library does not provide any input handling nor any event system and you may rely on
-the previously cited libraries to achieve such features.
-
-We keep a [CHANGELOG](./CHANGELOG.md) generated by [git-cliff](https://github.com/orhun/git-cliff)
-utilizing [Conventional Commits](https://www.conventionalcommits.org/).
+- [Ratatui Book] - explains the library's concepts and provides step-by-step tutorials
+- [Examples] - a collection of examples that demonstrate how to use the library.
+- [API Documentation] - the full API documentation for the library on docs.rs.
+- [Changelog] - generated by [git-cliff] utilizing [Conventional Commits].
+- [Contributing] - Please read this if you are interested in contributing to the project.
## Quickstart
The following example demonstrates the minimal amount of code necessary to setup a terminal and
render "Hello World!". The full code for this example which contains a little more detail is in
-[hello_world.rs](./examples/hello_world.rs). For more guidance on how to create Ratatui apps, see
-the [Docs](https://docs.rs/ratatui) and [Examples](#examples). There is also a starter template
-available at [rust-tui-template](https://github.com/ratatui-org/rust-tui-template).
+[hello_world.rs]. For more guidance on different ways to structure your application see the
+[Application Patterns] and [Hello World tutorial] sections in the [Ratatui Book] and the various
+[Examples]. There are also several starter templates available:
+
+- [rust-tui-template]
+- [ratatui-async-template] (book and template)
+- [simple-tui-rs]
+
+Every application built with `ratatui` needs to implement the following steps:
+
+- Initialize the terminal
+- A main loop to:
+ - Handle input events
+ - Draw the UI
+- Restore the terminal state
+
+The library contains a [`prelude`] module that re-exports the most commonly used traits and
+types for convenience. Most examples in the documentation will use this instead of showing the
+full path of each type.
+
+### Initialize and restore the terminal
+
+The [`Terminal`] type is the main entry point for any Ratatui application. It is a light
+abstraction over a choice of [`Backend`] implementations that provides functionality to draw
+each frame, clear the screen, hide the cursor, etc. It is parametrized over any type that
+implements the [`Backend`] trait which has implementations for [Crossterm], [Termion] and
+[Termwiz].
+
+Most applications should enter the Alternate Screen when starting and leave it when exiting and
+also enable raw mode to disable line buffering and enable reading key events. See the [`backend`
+module] and the [Backends] section of the [Ratatui Book] for more info.
+
+### Drawing the UI
+
+The drawing logic is delegated to a closure that takes a [`Frame`] instance as argument. The
+[`Frame`] provides the size of the area to draw to and allows the app to render any [`Widget`]
+using the provided [`render_widget`] method. See the [Widgets] section of the [Ratatui Book] for
+more info.
+
+### Handling events
+
+Ratatui does not include any input handling. Instead event handling can be implemented by
+calling backend library methods directly. See the [Handling Events] section of the [Ratatui
+Book] for more info. For example, if you are using [Crossterm], you can use the
+[`crossterm::event`] module to handle events.
+
+### Example
```rust
-fn main() -> Result<(), Box> {
- let mut terminal = setup_terminal()?;
- run(&mut terminal)?;
- restore_terminal(&mut terminal)?;
+use std::io::{self, stdout};
+use crossterm::{
+ event::{self, Event, KeyCode},
+ ExecutableCommand,
+ terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}
+};
+use ratatui::{prelude::*, widgets::*};
+
+fn main() -> io::Result<()> {
+ enable_raw_mode()?;
+ stdout().execute(EnterAlternateScreen)?;
+ let mut terminal = Terminal::new(CrosstermBackend::new(stdout()))?;
+
+ let mut should_quit = false;
+ while !should_quit {
+ terminal.draw(ui)?;
+ should_quit = handle_events()?;
+ }
+
+ disable_raw_mode()?;
+ stdout().execute(LeaveAlternateScreen)?;
Ok(())
}
-fn setup_terminal() -> Result>, Box> {
- let mut stdout = io::stdout();
- enable_raw_mode()?;
- execute!(stdout, EnterAlternateScreen)?;
- Ok(Terminal::new(CrosstermBackend::new(stdout))?)
-}
-
-fn restore_terminal(
- terminal: &mut Terminal>,
-) -> Result<(), Box> {
- disable_raw_mode()?;
- execute!(terminal.backend_mut(), LeaveAlternateScreen,)?;
- Ok(terminal.show_cursor()?)
-}
-
-fn run(terminal: &mut Terminal>) -> Result<(), Box> {
- Ok(loop {
- terminal.draw(|frame| {
- let greeting = Paragraph::new("Hello World!");
- frame.render_widget(greeting, frame.size());
- })?;
- if event::poll(Duration::from_millis(250))? {
- if let Event::Key(key) = event::read()? {
- if KeyCode::Char('q') == key.code {
- break;
- }
+fn handle_events() -> io::Result {
+ if event::poll(std::time::Duration::from_millis(50))? {
+ if let Event::Key(key) = event::read()? {
+ if key.kind == event::KeyEventKind::Press && key.code == KeyCode::Char('q') {
+ return Ok(true);
}
- }
- })
+ }
+ }
+ Ok(false)
+}
+
+fn ui(frame: &mut Frame) {
+ frame.render_widget(
+ Paragraph::new("Hello World!")
+ .block(Block::default().title("Greeting").borders(Borders::ALL)),
+ frame.size(),
+ );
}
```
+Running this example produces the following output:
+
+
+
+## Layout
+
+The library comes with a basic yet useful layout management object called [`Layout`] which
+allows you to split the available space into multiple areas and then render widgets in each
+area. This lets you describe a responsive terminal UI by nesting layouts. See the [Layout]
+section of the [Ratatui Book] for more info.
+
+```rust
+use ratatui::{prelude::*, widgets::*};
+
+fn ui(frame: &mut Frame) {
+ let areas = Layout::default()
+ .direction(Direction::Vertical)
+ .constraints(vec![
+ Constraint::Length(1),
+ Constraint::Min(0),
+ Constraint::Length(1),
+ ])
+ .split(frame.size());
+ frame.render_widget(Paragraph::new("Title Bar"), areas[0]);
+ frame.render_widget(Paragraph::new("Status Bar"), areas[2]);
+
+ let areas = Layout::default()
+ .direction(Direction::Horizontal)
+ .constraints(vec![Constraint::Percentage(50), Constraint::Percentage(50)])
+ .split(areas[1]);
+ frame.render_widget(
+ Block::default().borders(Borders::ALL).title("Left"),
+ areas[0],
+ );
+ frame.render_widget(
+ Block::default().borders(Borders::ALL).title("Right"),
+ areas[1],
+ );
+}
+```
+
+Running this example produces the following output:
+
+
+
+## Text and styling
+
+The [`Text`], [`Line`] and [`Span`] types are the building blocks of the library and are used in
+many places. [`Text`] is a list of [`Line`]s and a [`Line`] is a list of [`Span`]s. A [`Span`]
+is a string with a specific style.
+
+The [`style` module] provides types that represent the various styling options. The most
+important one is [`Style`] which represents the foreground and background colors and the text
+attributes of a [`Span`]. The [`style` module] also provides a [`Stylize`] trait that allows
+short-hand syntax to apply a style to widgets and text. See the [Styling Text] section of the
+[Ratatui Book] for more info.
+
+```rust
+use ratatui::{prelude::*, widgets::*};
+
+fn ui(frame: &mut Frame) {
+ let areas = Layout::default()
+ .direction(Direction::Vertical)
+ .constraints(vec![
+ Constraint::Length(1),
+ Constraint::Length(1),
+ Constraint::Length(1),
+ Constraint::Length(1),
+ Constraint::Min(0),
+ ])
+ .split(frame.size());
+
+ let span1 = Span::raw("Hello ");
+ let span2 = Span::styled(
+ "World",
+ Style::new()
+ .fg(Color::Green)
+ .bg(Color::White)
+ .add_modifier(Modifier::BOLD),
+ );
+ let span3 = "!".red().on_light_yellow().italic();
+
+ let line = Line::from(vec![span1, span2, span3]);
+ let text: Text = Text::from(vec![line]);
+
+ frame.render_widget(Paragraph::new(text), areas[0]);
+ // or using the short-hand syntax and implicit conversions
+ frame.render_widget(
+ Paragraph::new("Hello World!".red().on_white().bold()),
+ areas[1],
+ );
+
+ // to style the whole widget instead of just the text
+ frame.render_widget(
+ Paragraph::new("Hello World!").style(Style::new().red().on_white()),
+ areas[2],
+ );
+ // or using the short-hand syntax
+ frame.render_widget(Paragraph::new("Hello World!").blue().on_yellow(), areas[3]);
+}
+```
+
+Running this example produces the following output:
+
+
+
+[Ratatui Book]: https://ratatui.rs
+[Installation]: https://ratatui.rs/installation.html
+[Rendering]: https://ratatui.rs/concepts/rendering/index.html
+[Application Patterns]: https://ratatui.rs/concepts/application_patterns/index.html
+[Hello World tutorial]: https://ratatui.rs/tutorial/hello_world.html
+[Backends]: https://ratatui.rs/concepts/backends/index.html
+[Widgets]: https://ratatui.rs/how-to/widgets/index.html
+[Handling Events]: https://ratatui.rs/concepts/event_handling.html
+[Layout]: https://ratatui.rs/how-to/layout/index.html
+[Styling Text]: https://ratatui.rs/how-to/render/style-text.html
+[rust-tui-template]: https://github.com/ratatui-org/rust-tui-template
+[ratatui-async-template]: https://ratatui-org.github.io/ratatui-async-template/
+[simple-tui-rs]: https://github.com/pmsanford/simple-tui-rs
+[Examples]: https://github.com/ratatui-org/ratatui/tree/main/examples
+[git-cliff]: https://github.com/orhun/git-cliff
+[Conventional Commits]: https://www.conventionalcommits.org
+[API Documentation]: https://docs.rs/ratatui
+[Changelog]: https://github.com/ratatui-org/ratatui/blob/main/CHANGELOG.md
+[Contributing]: https:://github.com/ratatui-org/ratatui/blob/main/CONTRIBUTING.md
+[`Frame`]: terminal::Frame
+[`render_widget`]: terminal::Frame::render_widget
+[`Widget`]: widgets::Widget
+[`Layout`]: layout::Layout
+[`Text`]: text::Text
+[`Line`]: text::Line
+[`Span`]: text::Span
+[`Style`]: style::Style
+[`style` module]: style
+[`Stylize`]: style::Stylize
+[`Backend`]: backend::Backend
+[`backend` module]: backend
+[`crossterm::event`]: https://docs.rs/crossterm/latest/crossterm/event/index.html
+[Ratatui]: https://ratatui.rs
+[Crossterm]: https://crates.io/crates/crossterm
+[Termion]: https://crates.io/crates/termion
+[Termwiz]: https://crates.io/crates/termwiz
+[Tui-rs crate]: https://crates.io/crates/tui
+[hello_world.rs]: https://github.com/ratatui-org/ratatui/blob/main/examples/hello_world.rs
+[Crate Badge]: https://img.shields.io/crates/v/ratatui?logo=rust&style=flat-square
+[CI Badge]:
+ https://img.shields.io/github/actions/workflow/status/ratatui-org/ratatui/ci.yml?style=flat-square&logo=github
+[Codecov Badge]:
+ https://img.shields.io/codecov/c/github/ratatui-org/ratatui?logo=codecov&style=flat-square&token=BAQ8SOKEST
+[Dependencies Badge]: https://deps.rs/repo/github/ratatui-org/ratatui/status.svg?style=flat-square
+[Discord Badge]:
+ https://img.shields.io/discord/1070692720437383208?label=discord&logo=discord&style=flat-square
+[Docs Badge]: https://img.shields.io/docsrs/ratatui?logo=rust&style=flat-square
+[License Badge]: https://img.shields.io/crates/l/ratatui?style=flat-square
+[Matrix Badge]:
+ https://img.shields.io/matrix/ratatui-general%3Amatrix.org?style=flat-square&logo=matrix&label=Matrix
+
+
+
## Status of this fork
In response to the original maintainer [**Florian Dehau**](https://github.com/fdehau)'s issue
@@ -159,35 +353,6 @@ you are interested in working on a PR or issue opened in the previous repository
Since version 0.23.0, The Minimum Supported Rust Version (MSRV) of `ratatui` is 1.67.0.
-## Documentation
-
-The documentation can be found on [docs.rs.](https://docs.rs/ratatui)
-
-## Examples
-
-The demo shown in the gif above is available on all available backends.
-
-```shell
-# crossterm
-cargo run --example demo
-# termion
-cargo run --example demo --no-default-features --features=termion
-# termwiz
-cargo run --example demo --no-default-features --features=termwiz
-```
-
-The UI code for this is in [examples/demo/ui.rs](./examples/demo/ui.rs) while the application state
-is in [examples/demo/app.rs](./examples/demo/app.rs).
-
-If the user interface contains glyphs that are not displayed correctly by your terminal, you may
-want to run the demo without those symbols:
-
-```shell
-cargo run --example demo --release -- --tick-rate 200 --enhanced-graphics false
-```
-
-More examples are available in the [examples](./examples/) folder.
-
## Widgets
### Built in
@@ -195,21 +360,21 @@ More examples are available in the [examples](./examples/) folder.
The library comes with the following
[widgets](https://docs.rs/ratatui/latest/ratatui/widgets/index.html):
-* [BarChart](https://docs.rs/ratatui/latest/ratatui/widgets/struct.BarChart.html)
-* [Block](https://docs.rs/ratatui/latest/ratatui/widgets/block/struct.Block.html)
-* [Calendar](https://docs.rs/ratatui/latest/ratatui/widgets/calendar/index.html)
-* [Canvas](https://docs.rs/ratatui/latest/ratatui/widgets/canvas/struct.Canvas.html) which allows
+- [BarChart](https://docs.rs/ratatui/latest/ratatui/widgets/struct.BarChart.html)
+- [Block](https://docs.rs/ratatui/latest/ratatui/widgets/block/struct.Block.html)
+- [Calendar](https://docs.rs/ratatui/latest/ratatui/widgets/calendar/index.html)
+- [Canvas](https://docs.rs/ratatui/latest/ratatui/widgets/canvas/struct.Canvas.html) which allows
rendering [points, lines, shapes and a world
map](https://docs.rs/ratatui/latest/ratatui/widgets/canvas/index.html)
-* [Chart](https://docs.rs/ratatui/latest/ratatui/widgets/struct.Chart.html)
-* [Clear](https://docs.rs/ratatui/latest/ratatui/widgets/struct.Clear.html)
-* [Gauge](https://docs.rs/ratatui/latest/ratatui/widgets/struct.Gauge.html)
-* [List](https://docs.rs/ratatui/latest/ratatui/widgets/struct.List.html)
-* [Paragraph](https://docs.rs/ratatui/latest/ratatui/widgets/struct.Paragraph.html)
-* [Scrollbar](https://docs.rs/ratatui/latest/ratatui/widgets/scrollbar/struct.Scrollbar.html)
-* [Sparkline](https://docs.rs/ratatui/latest/ratatui/widgets/struct.Sparkline.html)
-* [Table](https://docs.rs/ratatui/latest/ratatui/widgets/struct.Table.html)
-* [Tabs](https://docs.rs/ratatui/latest/ratatui/widgets/struct.Tabs.html)
+- [Chart](https://docs.rs/ratatui/latest/ratatui/widgets/struct.Chart.html)
+- [Clear](https://docs.rs/ratatui/latest/ratatui/widgets/struct.Clear.html)
+- [Gauge](https://docs.rs/ratatui/latest/ratatui/widgets/struct.Gauge.html)
+- [List](https://docs.rs/ratatui/latest/ratatui/widgets/struct.List.html)
+- [Paragraph](https://docs.rs/ratatui/latest/ratatui/widgets/struct.Paragraph.html)
+- [Scrollbar](https://docs.rs/ratatui/latest/ratatui/widgets/scrollbar/struct.Scrollbar.html)
+- [Sparkline](https://docs.rs/ratatui/latest/ratatui/widgets/struct.Sparkline.html)
+- [Table](https://docs.rs/ratatui/latest/ratatui/widgets/struct.Table.html)
+- [Tabs](https://docs.rs/ratatui/latest/ratatui/widgets/struct.Tabs.html)
Each widget has an associated example which can be found in the [examples](./examples/) folder. Run
each examples with cargo (e.g. to run the gauge example `cargo run --example gauge`), and quit by
@@ -220,31 +385,31 @@ be installed with `cargo install cargo-make`).
### Third-party libraries, bootstrapping templates and widgets
-* [ansi-to-tui](https://github.com/uttarayan21/ansi-to-tui) — Convert ansi colored text to
+- [ansi-to-tui](https://github.com/uttarayan21/ansi-to-tui) — Convert ansi colored text to
`ratatui::text::Text`
-* [color-to-tui](https://github.com/uttarayan21/color-to-tui) — Parse hex colors to
+- [color-to-tui](https://github.com/uttarayan21/color-to-tui) — Parse hex colors to
`ratatui::style::Color`
-* [rust-tui-template](https://github.com/ratatui-org/rust-tui-template) — A template for bootstrapping a
- Rust TUI application with Tui-rs & crossterm
-* [simple-tui-rs](https://github.com/pmsanford/simple-tui-rs) — A simple example tui-rs app
-* [tui-builder](https://github.com/jkelleyrtp/tui-builder) — Batteries-included MVC framework for
+- [rust-tui-template](https://github.com/ratatui-org/rust-tui-template) — A template for
+ bootstrapping a Rust TUI application with Tui-rs & crossterm
+- [simple-tui-rs](https://github.com/pmsanford/simple-tui-rs) — A simple example tui-rs app
+- [tui-builder](https://github.com/jkelleyrtp/tui-builder) — Batteries-included MVC framework for
Tui-rs + Crossterm apps
-* [tui-clap](https://github.com/kegesch/tui-clap-rs) — Use clap-rs together with Tui-rs
-* [tui-log](https://github.com/kegesch/tui-log-rs) — Example of how to use logging with Tui-rs
-* [tui-logger](https://github.com/gin66/tui-logger) — Logger and Widget for Tui-rs
-* [tui-realm](https://github.com/veeso/tui-realm) — Tui-rs framework to build stateful applications
+- [tui-clap](https://github.com/kegesch/tui-clap-rs) — Use clap-rs together with Tui-rs
+- [tui-log](https://github.com/kegesch/tui-log-rs) — Example of how to use logging with Tui-rs
+- [tui-logger](https://github.com/gin66/tui-logger) — Logger and Widget for Tui-rs
+- [tui-realm](https://github.com/veeso/tui-realm) — Tui-rs framework to build stateful applications
with a React/Elm inspired approach
-* [tui-realm-treeview](https://github.com/veeso/tui-realm-treeview) — Treeview component for
+- [tui-realm-treeview](https://github.com/veeso/tui-realm-treeview) — Treeview component for
Tui-realm
-* [tui-rs-tree-widgets](https://github.com/EdJoPaTo/tui-rs-tree-widget): Widget for tree data
+- [tui-rs-tree-widgets](https://github.com/EdJoPaTo/tui-rs-tree-widget): Widget for tree data
structures.
-* [tui-windows](https://github.com/markatk/tui-windows-rs) — Tui-rs abstraction to handle multiple
+- [tui-windows](https://github.com/markatk/tui-windows-rs) — Tui-rs abstraction to handle multiple
windows and their rendering
-* [tui-textarea](https://github.com/rhysd/tui-textarea): Simple yet powerful multi-line text editor
+- [tui-textarea](https://github.com/rhysd/tui-textarea): Simple yet powerful multi-line text editor
widget supporting several key shortcuts, undo/redo, text search, etc.
-* [tui-input](https://github.com/sayanarijit/tui-input): TUI input library supporting multiple
+- [tui-input](https://github.com/sayanarijit/tui-input): TUI input library supporting multiple
backends and tui-rs.
-* [tui-term](https://github.com/a-kenji/tui-term): A pseudoterminal widget library
+- [tui-term](https://github.com/a-kenji/tui-term): A pseudoterminal widget library
that enables the rendering of terminal applications as ratatui widgets.
## Apps
@@ -257,11 +422,6 @@ Check out the list of more than 50 [Apps using
You might want to checkout [Cursive](https://github.com/gyscos/Cursive) for an alternative solution
to build text user interfaces in Rust.
-## Contributors
-
-[](https://github.com/ratatui-org/ratatui/graphs/contributors)
-
## Acknowledgments
Special thanks to [**Pavel Fomchenkov**](https://github.com/nawok) for his work in designing **an
diff --git a/examples/docsrs.rs b/examples/docsrs.rs
new file mode 100644
index 00000000..ab25f2fc
--- /dev/null
+++ b/examples/docsrs.rs
@@ -0,0 +1,126 @@
+use std::io::{self, stdout};
+
+use crossterm::{
+ terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
+ ExecutableCommand,
+};
+use ratatui::{prelude::*, widgets::*};
+
+/// Example code for libr.rs
+///
+/// When cargo-rdme supports doc comments that import from code, this will be imported
+/// rather than copied to the lib.rs file.
+fn main() -> io::Result<()> {
+ let arg = std::env::args().nth(1).unwrap_or_default();
+ enable_raw_mode()?;
+ stdout().execute(EnterAlternateScreen)?;
+ let mut terminal = Terminal::new(CrosstermBackend::new(stdout()))?;
+
+ let mut should_quit = false;
+ while !should_quit {
+ terminal.draw(match arg.as_str() {
+ "hello_world" => hello_world,
+ "layout" => layout,
+ "styling" => styling,
+ _ => hello_world,
+ })?;
+ should_quit = handle_events()?;
+ }
+
+ disable_raw_mode()?;
+ stdout().execute(LeaveAlternateScreen)?;
+ Ok(())
+}
+
+fn hello_world(frame: &mut Frame) {
+ frame.render_widget(
+ Paragraph::new("Hello World!")
+ .block(Block::default().title("Greeting").borders(Borders::ALL)),
+ frame.size(),
+ );
+}
+
+use crossterm::event::{self, Event, KeyCode};
+fn handle_events() -> io::Result {
+ if event::poll(std::time::Duration::from_millis(50))? {
+ if let Event::Key(key) = event::read()? {
+ if key.kind == event::KeyEventKind::Press && key.code == KeyCode::Char('q') {
+ return Ok(true);
+ }
+ }
+ }
+ Ok(false)
+}
+
+fn layout(frame: &mut Frame) {
+ let main_layout = Layout::default()
+ .direction(Direction::Vertical)
+ .constraints(vec![
+ Constraint::Length(1),
+ Constraint::Min(0),
+ Constraint::Length(1),
+ ])
+ .split(frame.size());
+ frame.render_widget(
+ Block::new().borders(Borders::TOP).title("Title Bar"),
+ main_layout[0],
+ );
+ frame.render_widget(
+ Block::new().borders(Borders::TOP).title("Status Bar"),
+ main_layout[2],
+ );
+
+ let inner_layout = Layout::default()
+ .direction(Direction::Horizontal)
+ .constraints(vec![Constraint::Percentage(50), Constraint::Percentage(50)])
+ .split(main_layout[1]);
+ frame.render_widget(
+ Block::default().borders(Borders::ALL).title("Left"),
+ inner_layout[0],
+ );
+ frame.render_widget(
+ Block::default().borders(Borders::ALL).title("Right"),
+ inner_layout[1],
+ );
+}
+
+fn styling(frame: &mut Frame) {
+ let areas = Layout::default()
+ .direction(Direction::Vertical)
+ .constraints(vec![
+ Constraint::Length(1),
+ Constraint::Length(1),
+ Constraint::Length(1),
+ Constraint::Length(1),
+ Constraint::Min(0),
+ ])
+ .split(frame.size());
+
+ let span1 = Span::raw("Hello ");
+ let span2 = Span::styled(
+ "World",
+ Style::new()
+ .fg(Color::Green)
+ .bg(Color::White)
+ .add_modifier(Modifier::BOLD),
+ );
+ let span3 = "!".red().on_light_yellow().italic();
+
+ let line = Line::from(vec![span1, span2, span3]);
+ let text: Text = Text::from(vec![line]);
+
+ frame.render_widget(Paragraph::new(text), areas[0]);
+ // or using the short-hand syntax and implicit conversions
+ frame.render_widget(
+ Paragraph::new("Hello World!".red().on_white().bold()),
+ areas[1],
+ );
+
+ // to style the whole widget instead of just the text
+ frame.render_widget(
+ Paragraph::new("Hello World!").style(Style::new().red().on_white()),
+ areas[2],
+ );
+ // or using the short-hand syntax
+ frame.render_widget(Paragraph::new("Hello World!").blue().on_yellow(), areas[3]);
+}
diff --git a/examples/docsrs.tape b/examples/docsrs.tape
new file mode 100644
index 00000000..f5708d50
--- /dev/null
+++ b/examples/docsrs.tape
@@ -0,0 +1,39 @@
+# This is a vhs script. See https://github.com/charmbracelet/vhs for more info.
+# To run this script, install vhs and run `vhs ./examples/demo.tape`
+# NOTE: Requires VHS 0.6.1 or later for Screenshot support
+Output "target/docsrs.gif"
+Set Theme "OceanicMaterial"
+# The reason for this strange size is that the social preview image for this
+# demo is 1280x64 with 80 pixels of padding on each side. We want a version
+# without the padding for README.md, etc.
+Set Width 640
+Set Height 160
+Set Padding 0
+Hide
+Type "cargo run --example docsrs --features crossterm"
+Enter
+Sleep 2s
+Show
+Sleep 1s
+Screenshot "target/docsrs-hello.png"
+Sleep 1s
+Hide
+Type "q"
+Type "cargo run --example docsrs --features crossterm -- layout"
+Enter
+Sleep 2s
+Show
+Sleep 1s
+Screenshot "target/docsrs-layout.png"
+Sleep 1s
+Hide
+Type "q"
+Type "cargo run --example docsrs --features crossterm -- styling"
+Enter
+Sleep 2s
+Show
+Sleep 1s
+Screenshot "target/docsrs-styling.png"
+Sleep 1s
+Hide
+Type "q"
diff --git a/src/lib.rs b/src/lib.rs
index f192a06b..e609287f 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,180 +1,336 @@
#![forbid(unsafe_code)]
-//! [ratatui](https://github.com/ratatui-org/ratatui) is a library that is all about cooking up terminal user
-//! interfaces (TUIs).
-//!
//! 
-// this is a permalink to https://github.com/ratatui-org/ratatui/blob/images/examples/demo2.gif
//!
-//! # Get started
+//!
//!
-//! ## Adding `ratatui` as a dependency
+//! [![Crate Badge]](https://crates.io/crates/ratatui) [![License Badge]](./LICENSE) [![CI
+//! Badge]](https://github.com/ratatui-org/ratatui/actions?query=workflow%3ACI+) [![Docs
+//! Badge]](https://docs.rs/crate/ratatui/)
+//! [![Dependencies Badge]](https://deps.rs/repo/github/ratatui-org/ratatui) [![Codecov
+//! Badge]](https://app.codecov.io/gh/ratatui-org/ratatui) [![Discord
+//! Badge]](https://discord.gg/pMCEU9hNEj) [![Matrix
+//! Badge]](https://matrix.to/#/#ratatui:matrix.org)
+//! [Documentation](https://docs.rs/ratatui) · [Ratatui Book](https://ratatui.rs) ·
+//! [Examples](https://github.com/ratatui-org/ratatui/tree/main/examples) · [Report a
+//! bug](https://github.com/ratatui-org/ratatui/issues/new?labels=bug&projects=&template=bug_report.md)
+//! · [Request a
+//! Feature](https://github.com/ratatui-org/ratatui/issues/new?labels=enhancement&projects=&template=feature_request.md)
+//! · [Send a Pull Request](https://github.com/ratatui-org/ratatui/compare)
//!
-//! Add the following to your `Cargo.toml`:
-//! ```toml
-//! [dependencies]
-//! crossterm = "0.27"
-//! ratatui = "0.23"
+//!
+//!
+//! # Ratatui
+//!
+//! [Ratatui] is a crate for cooking up terminal user interfaces in rust. It is a lightweight
+//! library that provides a set of widgets and utilities to build complex rust TUIs. Ratatui was
+//! forked from the [Tui-rs crate] in 2023 in order to continue its development.
+//!
+//! ## Installation
+//!
+//! Add `ratatui` and `crossterm` as dependencies to your cargo.toml:
+//!
+//! ```shell
+//! cargo add ratatui crossterm
//! ```
//!
-//! The crate is using the `crossterm` backend by default that works on most platforms. But if for
-//! example you want to use the `termion` backend instead. This can be done by changing your
-//! dependencies specification to the following:
+//! Ratatui uses [Crossterm] by default as it works on most platforms. See the [Installation]
+//! section of the [Ratatui Book] for more details on how to use other backends ([Termion] /
+//! [Termwiz]).
//!
-//! ```toml
-//! [dependencies]
-//! termion = "2.0.1"
-//! ratatui = { version = "0.23", default-features = false, features = ['termion'] }
-//! ```
+//! ## Introduction
//!
-//! The same logic applies for all other available backends.
+//! Ratatui is based on the principle of immediate rendering with intermediate buffers. This means
+//! that for each frame, your app must render all widgets that are supposed to be part of the UI.
+//! This is in contrast to the retained mode style of rendering where widgets are updated and then
+//! automatically redrawn on the next frame. See the [Rendering] section of the [Ratatui Book] for
+//! more info.
//!
-//! ## Creating a `Terminal`
+//! ## Other documentation
//!
-//! Every application using `ratatui` should start by instantiating a `Terminal`. It is a light
-//! abstraction over available backends that provides basic functionalities such as clearing the
-//! screen, hiding the cursor, etc.
+//! - [Ratatui Book] - explains the library's concepts and provides step-by-step tutorials
+//! - [Examples] - a collection of examples that demonstrate how to use the library.
+//! - [API Documentation] - the full API documentation for the library on docs.rs.
+//! - [Changelog] - generated by [git-cliff] utilizing [Conventional Commits].
+//! - [Contributing] - Please read this if you are interested in contributing to the project.
+//!
+//! ## Quickstart
+//!
+//! The following example demonstrates the minimal amount of code necessary to setup a terminal and
+//! render "Hello World!". The full code for this example which contains a little more detail is in
+//! [hello_world.rs]. For more guidance on different ways to structure your application see the
+//! [Application Patterns] and [Hello World tutorial] sections in the [Ratatui Book] and the various
+//! [Examples]. There are also several starter templates available:
+//!
+//! - [rust-tui-template]
+//! - [ratatui-async-template] (book and template)
+//! - [simple-tui-rs]
+//!
+//! Every application built with `ratatui` needs to implement the following steps:
+//!
+//! - Initialize the terminal
+//! - A main loop to:
+//! - Handle input events
+//! - Draw the UI
+//! - Restore the terminal state
+//!
+//! The library contains a [`prelude`] module that re-exports the most commonly used traits and
+//! types for convenience. Most examples in the documentation will use this instead of showing the
+//! full path of each type.
+//!
+//! ### Initialize and restore the terminal
+//!
+//! The [`Terminal`] type is the main entry point for any Ratatui application. It is a light
+//! abstraction over a choice of [`Backend`] implementations that provides functionality to draw
+//! each frame, clear the screen, hide the cursor, etc. It is parametrized over any type that
+//! implements the [`Backend`] trait which has implementations for [Crossterm], [Termion] and
+//! [Termwiz].
+//!
+//! Most applications should enter the Alternate Screen when starting and leave it when exiting and
+//! also enable raw mode to disable line buffering and enable reading key events. See the [`backend`
+//! module] and the [Backends] section of the [Ratatui Book] for more info.
+//!
+//! ### Drawing the UI
+//!
+//! The drawing logic is delegated to a closure that takes a [`Frame`] instance as argument. The
+//! [`Frame`] provides the size of the area to draw to and allows the app to render any [`Widget`]
+//! using the provided [`render_widget`] method. See the [Widgets] section of the [Ratatui Book] for
+//! more info.
+//!
+//! ### Handling events
+//!
+//! Ratatui does not include any input handling. Instead event handling can be implemented by
+//! calling backend library methods directly. See the [Handling Events] section of the [Ratatui
+//! Book] for more info. For example, if you are using [Crossterm], you can use the
+//! [`crossterm::event`] module to handle events.
+//!
+//! ### Example
//!
//! ```rust,no_run
-//! use std::io;
-//! use ratatui::prelude::*;
-//!
-//! fn main() -> Result<(), io::Error> {
-//! let stdout = io::stdout();
-//! let backend = CrosstermBackend::new(stdout);
-//! let mut terminal = Terminal::new(backend)?;
-//! Ok(())
-//! }
-//! ```
-//!
-//! If you had previously chosen `termion` as a backend, the terminal can be created in a similar
-//! way:
-//!
-//! ```rust,ignore
-//! use std::io;
-//! use ratatui::prelude::*;
-//! use termion::raw::IntoRawMode;
-//!
-//! fn main() -> Result<(), io::Error> {
-//! let stdout = io::stdout().into_raw_mode()?;
-//! let backend = TermionBackend::new(stdout);
-//! let mut terminal = Terminal::new(backend)?;
-//! Ok(())
-//! }
-//! ```
-//!
-//! You may also refer to the examples to find out how to create a `Terminal` for each available
-//! backend.
-//!
-//! ## Building a User Interface (UI)
-//!
-//! Every component of your interface will be implementing the `Widget` trait. The library comes
-//! with a predefined set of widgets that should meet most of your use cases. You are also free to
-//! implement your own.
-//!
-//! Each widget follows a builder pattern API providing a default configuration along with methods
-//! to customize them. The widget is then rendered using [`Frame::render_widget`] which takes your
-//! widget instance and an area to draw to.
-//!
-//! The following example renders a block of the size of the terminal:
-//!
-//! ```rust,no_run
-//! use std::{io, thread, time::Duration};
-//! use ratatui::{prelude::*, widgets::*};
+//! use std::io::{self, stdout};
//! use crossterm::{
-//! event::{self, DisableMouseCapture, EnableMouseCapture},
-//! execute,
-//! terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
+//! event::{self, Event, KeyCode},
+//! ExecutableCommand,
+//! terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}
//! };
+//! use ratatui::{prelude::*, widgets::*};
//!
-//! fn main() -> Result<(), io::Error> {
-//! // setup terminal
+//! fn main() -> io::Result<()> {
//! enable_raw_mode()?;
-//! let mut stdout = io::stdout();
-//! execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?;
-//! let backend = CrosstermBackend::new(stdout);
-//! let mut terminal = Terminal::new(backend)?;
+//! stdout().execute(EnterAlternateScreen)?;
+//! let mut terminal = Terminal::new(CrosstermBackend::new(stdout()))?;
//!
-//! terminal.draw(|f| {
-//! let size = f.size();
-//! let block = Block::default()
-//! .title("Block")
-//! .borders(Borders::ALL);
-//! f.render_widget(block, size);
-//! })?;
+//! let mut should_quit = false;
+//! while !should_quit {
+//! terminal.draw(ui)?;
+//! should_quit = handle_events()?;
+//! }
//!
-//! // Start a thread to discard any input events. Without handling events, the
-//! // stdin buffer will fill up, and be read into the shell when the program exits.
-//! thread::spawn(|| loop {
-//! event::read();
-//! });
-//!
-//! thread::sleep(Duration::from_millis(5000));
-//!
-//! // restore terminal
//! disable_raw_mode()?;
-//! execute!(
-//! terminal.backend_mut(),
-//! LeaveAlternateScreen,
-//! DisableMouseCapture
-//! )?;
-//! terminal.show_cursor()?;
-//!
+//! stdout().execute(LeaveAlternateScreen)?;
//! Ok(())
//! }
+//!
+//! fn handle_events() -> io::Result {
+//! if event::poll(std::time::Duration::from_millis(50))? {
+//! if let Event::Key(key) = event::read()? {
+//! if key.kind == event::KeyEventKind::Press && key.code == KeyCode::Char('q') {
+//! return Ok(true);
+//! }
+//! }
+//! }
+//! Ok(false)
+//! }
+//!
+//! fn ui(frame: &mut Frame) {
+//! frame.render_widget(
+//! Paragraph::new("Hello World!")
+//! .block(Block::default().title("Greeting").borders(Borders::ALL)),
+//! frame.size(),
+//! );
+//! }
//! ```
//!
+//! Running this example produces the following output:
+//!
+//! 
+//!
//! ## Layout
//!
-//! The library comes with a basic yet useful layout management object called `Layout`. As you may
-//! see below and in the examples, the library makes heavy use of the builder pattern to provide
-//! full customization. And `Layout` is no exception:
+//! The library comes with a basic yet useful layout management object called [`Layout`] which
+//! allows you to split the available space into multiple areas and then render widgets in each
+//! area. This lets you describe a responsive terminal UI by nesting layouts. See the [Layout]
+//! section of the [Ratatui Book] for more info.
//!
//! ```rust,no_run
//! use ratatui::{prelude::*, widgets::*};
//!
-//! fn ui(f: &mut Frame) {
-//! let chunks = Layout::default()
+//! fn ui(frame: &mut Frame) {
+//! let main_layout = Layout::default()
//! .direction(Direction::Vertical)
-//! .margin(1)
-//! .constraints(
-//! [
-//! Constraint::Percentage(10),
-//! Constraint::Percentage(80),
-//! Constraint::Percentage(10)
-//! ].as_ref()
-//! )
-//! .split(f.size());
-//! let block = Block::default()
-//! .title("Block")
-//! .borders(Borders::ALL);
-//! f.render_widget(block, chunks[0]);
-//! let block = Block::default()
-//! .title("Block 2")
-//! .borders(Borders::ALL);
-//! f.render_widget(block, chunks[1]);
+//! .constraints(vec![
+//! Constraint::Length(1),
+//! Constraint::Min(0),
+//! Constraint::Length(1),
+//! ])
+//! .split(frame.size());
+//! frame.render_widget(
+//! Block::new().borders(Borders::TOP).title("Title Bar"),
+//! main_layout[0],
+//! );
+//! frame.render_widget(
+//! Block::new().borders(Borders::TOP).title("Status Bar"),
+//! main_layout[2],
+//! );
+//!
+//! let inner_layout = Layout::default()
+//! .direction(Direction::Horizontal)
+//! .constraints(vec![Constraint::Percentage(50), Constraint::Percentage(50)])
+//! .split(main_layout[1]);
+//! frame.render_widget(
+//! Block::default().borders(Borders::ALL).title("Left"),
+//! inner_layout[0],
+//! );
+//! frame.render_widget(
+//! Block::default().borders(Borders::ALL).title("Right"),
+//! inner_layout[1],
+//! );
//! }
//! ```
//!
-//! This let you describe responsive terminal UI by nesting layouts. You should note that by default
-//! the computed layout tries to fill the available space completely. So if for any reason you might
-//! need a blank space somewhere, try to pass an additional constraint and don't use the
-//! corresponding area.
+//! Running this example produces the following output:
//!
-//! # Features
+//! 
+//!
+//! ## Text and styling
+//!
+//! The [`Text`], [`Line`] and [`Span`] types are the building blocks of the library and are used in
+//! many places. [`Text`] is a list of [`Line`]s and a [`Line`] is a list of [`Span`]s. A [`Span`]
+//! is a string with a specific style.
+//!
+//! The [`style` module] provides types that represent the various styling options. The most
+//! important one is [`Style`] which represents the foreground and background colors and the text
+//! attributes of a [`Span`]. The [`style` module] also provides a [`Stylize`] trait that allows
+//! short-hand syntax to apply a style to widgets and text. See the [Styling Text] section of the
+//! [Ratatui Book] for more info.
+//!
+//! ```rust,no_run
+//! use ratatui::{prelude::*, widgets::*};
+//!
+//! fn ui(frame: &mut Frame) {
+//! let areas = Layout::default()
+//! .direction(Direction::Vertical)
+//! .constraints(vec![
+//! Constraint::Length(1),
+//! Constraint::Length(1),
+//! Constraint::Length(1),
+//! Constraint::Length(1),
+//! Constraint::Min(0),
+//! ])
+//! .split(frame.size());
+//!
+//! let span1 = Span::raw("Hello ");
+//! let span2 = Span::styled(
+//! "World",
+//! Style::new()
+//! .fg(Color::Green)
+//! .bg(Color::White)
+//! .add_modifier(Modifier::BOLD),
+//! );
+//! let span3 = "!".red().on_light_yellow().italic();
+//!
+//! let line = Line::from(vec![span1, span2, span3]);
+//! let text: Text = Text::from(vec![line]);
+//!
+//! frame.render_widget(Paragraph::new(text), areas[0]);
+//! // or using the short-hand syntax and implicit conversions
+//! frame.render_widget(
+//! Paragraph::new("Hello World!".red().on_white().bold()),
+//! areas[1],
+//! );
+//!
+//! // to style the whole widget instead of just the text
+//! frame.render_widget(
+//! Paragraph::new("Hello World!").style(Style::new().red().on_white()),
+//! areas[2],
+//! );
+//! // or using the short-hand syntax
+//! frame.render_widget(Paragraph::new("Hello World!").blue().on_yellow(), areas[3]);
+//! }
+//! ```
+//!
+//! Running this example produces the following output:
+//!
+//! 
+#![cfg_attr(feature = "document-features", doc = "\n## Features")]
#![cfg_attr(feature = "document-features", doc = document_features::document_features!())]
+#![cfg_attr(
+ feature = "document-features",
+ doc = "[`CrossTermBackend`]: backend::CrosstermBackend"
+)]
+#![cfg_attr(
+ feature = "document-features",
+ doc = "[`TermionBackend`]: backend::TermionBackend"
+)]
+#![cfg_attr(
+ feature = "document-features",
+ doc = "[`TermwizBackend`]: backend::TermwizBackend"
+)]
+#![cfg_attr(
+ feature = "document-features",
+ doc = "[`calendar`]: widgets::calendar::Monthly"
+)]
//!
+//! [Ratatui Book]: https://ratatui.rs
+//! [Installation]: https://ratatui.rs/installation.html
+//! [Rendering]: https://ratatui.rs/concepts/rendering/index.html
+//! [Application Patterns]: https://ratatui.rs/concepts/application_patterns/index.html
+//! [Hello World tutorial]: https://ratatui.rs/tutorial/hello_world.html
+//! [Backends]: https://ratatui.rs/concepts/backends/index.html
+//! [Widgets]: https://ratatui.rs/how-to/widgets/index.html
+//! [Handling Events]: https://ratatui.rs/concepts/event_handling.html
+//! [Layout]: https://ratatui.rs/how-to/layout/index.html
+//! [Styling Text]: https://ratatui.rs/how-to/render/style-text.html
+//! [rust-tui-template]: https://github.com/ratatui-org/rust-tui-template
+//! [ratatui-async-template]: https://ratatui-org.github.io/ratatui-async-template/
+//! [simple-tui-rs]: https://github.com/pmsanford/simple-tui-rs
+//! [Examples]: https://github.com/ratatui-org/ratatui/tree/main/examples
+//! [git-cliff]: https://github.com/orhun/git-cliff
+//! [Conventional Commits]: https://www.conventionalcommits.org
+//! [API Documentation]: https://docs.rs/ratatui
+//! [Changelog]: https://github.com/ratatui-org/ratatui/blob/main/CHANGELOG.md
+//! [Contributing]: https:://github.com/ratatui-org/ratatui/blob/main/CONTRIBUTING.md
+//! [`Frame`]: terminal::Frame
+//! [`render_widget`]: terminal::Frame::render_widget
+//! [`Widget`]: widgets::Widget
//! [`Layout`]: layout::Layout
-//! [`backend`]: backend
-//! [`calendar`]: widgets::calendar
-//! [`CrosstermBackend`]: backend::CrosstermBackend
-//! [`TermionBackend`]: backend::TermionBackend
-//! [`TermwizBackend`]: backend::TermwizBackend
-//! [Crossterm crate]: https://crates.io/crates/crossterm
-//! [Serde crate]: https://crates.io/crates/serde
-//! [Termion crate]: https://crates.io/crates/termion
-//! [Termwiz crate]: https://crates.io/crates/termwiz
-//! [Time crate]: https://crates.io/crates/time
+//! [`Text`]: text::Text
+//! [`Line`]: text::Line
+//! [`Span`]: text::Span
+//! [`Style`]: style::Style
+//! [`style` module]: style
+//! [`Stylize`]: style::Stylize
+//! [`Backend`]: backend::Backend
+//! [`backend` module]: backend
+//! [`crossterm::event`]: https://docs.rs/crossterm/latest/crossterm/event/index.html
+//! [Ratatui]: https://ratatui.rs
+//! [Crossterm]: https://crates.io/crates/crossterm
+//! [Termion]: https://crates.io/crates/termion
+//! [Termwiz]: https://crates.io/crates/termwiz
+//! [Tui-rs crate]: https://crates.io/crates/tui
+//! [hello_world.rs]: https://github.com/ratatui-org/ratatui/blob/main/examples/hello_world.rs
+//! [Crate Badge]: https://img.shields.io/crates/v/ratatui?logo=rust&style=flat-square
+//! [CI Badge]:
+//! https://img.shields.io/github/actions/workflow/status/ratatui-org/ratatui/ci.yml?style=flat-square&logo=github
+//! [Codecov Badge]:
+//! https://img.shields.io/codecov/c/github/ratatui-org/ratatui?logo=codecov&style=flat-square&token=BAQ8SOKEST
+//! [Dependencies Badge]: https://deps.rs/repo/github/ratatui-org/ratatui/status.svg?style=flat-square
+//! [Discord Badge]:
+//! https://img.shields.io/discord/1070692720437383208?label=discord&logo=discord&style=flat-square
+//! [Docs Badge]: https://img.shields.io/docsrs/ratatui?logo=rust&style=flat-square
+//! [License Badge]: https://img.shields.io/crates/l/ratatui?style=flat-square
+//! [Matrix Badge]:
+//! https://img.shields.io/matrix/ratatui-general%3Amatrix.org?style=flat-square&logo=matrix&label=Matrix
// show the feature flags in the generated documentation
#![cfg_attr(docsrs, feature(doc_auto_cfg))]