//! ![Demo](https://github.com/ratatui-org/ratatui/blob/1d39444e3dea6f309cf9035be2417ac711c1abc9/examples/demo2-destroy.gif?raw=true) //! //!
//! //! [![Crate Badge]][Crate] [![Docs Badge]][API Docs] [![CI Badge]][CI Workflow] [![Deps.rs //! Badge]][Deps.rs]
[![Codecov Badge]][Codecov] [![License Badge]](./LICENSE) [![Sponsors //! Badge]][GitHub Sponsors]
[![Discord Badge]][Discord Server] [![Matrix Badge]][Matrix] //! [![Forum Badge]][Forum]
//! //! [Ratatui Website] · [API Docs] · [Examples] · [Changelog] · [Breaking Changes]
//! [Contributing] · [Report a bug] · [Request a Feature] · [Create a Pull Request] //! //!
//! //! # Ratatui //! //! [Ratatui][Ratatui Website] 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` as a dependency to your cargo.toml: //! //! ```shell //! cargo add ratatui //! ``` //! //! Ratatui uses [Crossterm] by default as it works on most platforms. See the [Installation] //! section of the [Ratatui Website] for more details on how to use other backends ([Termion] / //! [Termwiz]). //! //! ## Introduction //! //! 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 Website] //! for more info. //! //! You can also watch the [FOSDEM 2024 talk] about Ratatui which gives a brief introduction to //! terminal user interfaces and showcases the features of Ratatui, along with a hello world demo. //! //! ## Other documentation //! //! - [Ratatui Website] - explains the library's concepts and provides step-by-step tutorials //! - [Ratatui Forum][Forum] - a place to ask questions and discuss the library //! - [API Docs] - the full API documentation for the library on docs.rs. //! - [Examples] - a collection of examples that demonstrate how to use the library. //! - [Contributing] - Please read this if you are interested in contributing to the project. //! - [Changelog] - generated by [git-cliff] utilizing [Conventional Commits]. //! - [Breaking Changes] - a list of breaking changes in the library. //! //! ## 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 //! the [Examples] directory. For more guidance on different ways to structure your application see //! the [Application Patterns] and [Hello World tutorial] sections in the [Ratatui Website] and the //! various [Examples]. There are also several starter templates available in the [templates] //! repository. //! //! 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 Website] 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. After this closure returns, a diff is performed and //! only the changes are drawn to the terminal. See the [Widgets] section of the [Ratatui Website] //! 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 //! Website] 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::{self, stdout}; //! //! use ratatui::{ //! crossterm::{ //! event::{self, Event, KeyCode}, //! terminal::{ //! disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen, //! }, //! ExecutableCommand, //! }, //! 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 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::bordered().title("Greeting")), //! frame.size(), //! ); //! } //! ``` //! //! Running this example produces the following output: //! //! ![docsrs-hello] //! //! ## 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 Website] for more info. //! //! ```rust,no_run //! use ratatui::{prelude::*, widgets::*}; //! //! fn ui(frame: &mut Frame) { //! let main_layout = Layout::new( //! Direction::Vertical, //! [ //! 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::new( //! Direction::Horizontal, //! [Constraint::Percentage(50), Constraint::Percentage(50)], //! ) //! .split(main_layout[1]); //! frame.render_widget(Block::bordered().title("Left"), inner_layout[0]); //! frame.render_widget(Block::bordered().title("Right"), inner_layout[1]); //! } //! ``` //! //! Running this example produces the following output: //! //! ![docsrs-layout] //! //! ## 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 Website] for more info. //! //! ```rust,no_run //! use ratatui::{prelude::*, widgets::*}; //! //! fn ui(frame: &mut Frame) { //! let areas = Layout::new( //! Direction::Vertical, //! [ //! 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: //! //! ![docsrs-styling] #![cfg_attr(feature = "document-features", doc = "\n## Features")] #![cfg_attr(feature = "document-features", doc = document_features::document_features!())] //! //! [Ratatui Website]: https://ratatui.rs/ //! [Installation]: https://ratatui.rs/installation/ //! [Rendering]: https://ratatui.rs/concepts/rendering/ //! [Application Patterns]: https://ratatui.rs/concepts/application-patterns/ //! [Hello World tutorial]: https://ratatui.rs/tutorials/hello-world/ //! [Backends]: https://ratatui.rs/concepts/backends/ //! [Widgets]: https://ratatui.rs/how-to/widgets/ //! [Handling Events]: https://ratatui.rs/concepts/event-handling/ //! [Layout]: https://ratatui.rs/how-to/layout/ //! [Styling Text]: https://ratatui.rs/how-to/render/style-text/ //! [templates]: https://github.com/ratatui-org/templates/ //! [Examples]: https://github.com/ratatui-org/ratatui/tree/main/examples/README.md //! [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 //! [Create a Pull Request]: https://github.com/ratatui-org/ratatui/compare //! [git-cliff]: https://git-cliff.org //! [Conventional Commits]: https://www.conventionalcommits.org //! [API Docs]: 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 //! [Breaking Changes]: https://github.com/ratatui-org/ratatui/blob/main/BREAKING-CHANGES.md //! [FOSDEM 2024 talk]: https://www.youtube.com/watch?v=NU0q6NOLJ20 //! [docsrs-hello]: https://github.com/ratatui-org/ratatui/blob/c3c3c289b1eb8d562afb1931adb4dc719cd48490/examples/docsrs-hello.png?raw=true //! [docsrs-layout]: https://github.com/ratatui-org/ratatui/blob/c3c3c289b1eb8d562afb1931adb4dc719cd48490/examples/docsrs-layout.png?raw=true //! [docsrs-styling]: https://github.com/ratatui-org/ratatui/blob/c3c3c289b1eb8d562afb1931adb4dc719cd48490/examples/docsrs-styling.png?raw=true //! [`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 //! [Crate]: https://crates.io/crates/ratatui //! [Crossterm]: https://crates.io/crates/crossterm //! [Termion]: https://crates.io/crates/termion //! [Termwiz]: https://crates.io/crates/termwiz //! [tui-rs]: https://crates.io/crates/tui //! [GitHub Sponsors]: https://github.com/sponsors/ratatui-org //! [Crate Badge]: https://img.shields.io/crates/v/ratatui?logo=rust&style=flat-square&logoColor=E05D44&color=E05D44 //! [License Badge]: https://img.shields.io/crates/l/ratatui?style=flat-square&color=1370D3 //! [CI Badge]: https://img.shields.io/github/actions/workflow/status/ratatui-org/ratatui/ci.yml?style=flat-square&logo=github //! [CI Workflow]: https://github.com/ratatui-org/ratatui/actions/workflows/ci.yml //! [Codecov Badge]: https://img.shields.io/codecov/c/github/ratatui-org/ratatui?logo=codecov&style=flat-square&token=BAQ8SOKEST&color=C43AC3&logoColor=C43AC3 //! [Codecov]: https://app.codecov.io/gh/ratatui-org/ratatui //! [Deps.rs Badge]: https://deps.rs/repo/github/ratatui-org/ratatui/status.svg?style=flat-square //! [Deps.rs]: https://deps.rs/repo/github/ratatui-org/ratatui //! [Discord Badge]: https://img.shields.io/discord/1070692720437383208?label=discord&logo=discord&style=flat-square&color=1370D3&logoColor=1370D3 //! [Discord Server]: https://discord.gg/pMCEU9hNEj //! [Docs Badge]: https://img.shields.io/docsrs/ratatui?logo=rust&style=flat-square&logoColor=E05D44 //! [Matrix Badge]: https://img.shields.io/matrix/ratatui-general%3Amatrix.org?style=flat-square&logo=matrix&label=Matrix&color=C43AC3 //! [Matrix]: https://matrix.to/#/#ratatui:matrix.org //! [Forum Badge]: https://img.shields.io/discourse/likes?server=https%3A%2F%2Fforum.ratatui.rs&style=flat-square&logo=discourse&label=forum&color=C43AC3 //! [Forum]: https://forum.ratatui.rs //! [Sponsors Badge]: https://img.shields.io/github/sponsors/ratatui-org?logo=github&style=flat-square&color=1370D3 // show the feature flags in the generated documentation #![cfg_attr(docsrs, feature(doc_auto_cfg))] #![doc( html_logo_url = "https://raw.githubusercontent.com/ratatui-org/ratatui/main/assets/logo.png", html_favicon_url = "https://raw.githubusercontent.com/ratatui-org/ratatui/main/assets/favicon.ico" )] /// re-export the `crossterm` crate so that users don't have to add it as a dependency #[cfg(feature = "crossterm")] pub use crossterm; #[doc(inline)] pub use terminal::{CompletedFrame, Frame, Terminal, TerminalOptions, Viewport}; /// re-export the `termion` crate so that users don't have to add it as a dependency #[cfg(feature = "termion")] pub use termion; /// re-export the `termwiz` crate so that users don't have to add it as a dependency #[cfg(feature = "termwiz")] pub use termwiz; pub mod backend; pub mod buffer; pub mod layout; pub mod prelude; pub mod style; pub mod symbols; pub mod terminal; pub mod text; pub mod widgets;