docs: tweak readme (#1419)

Fixes: <https://github.com/ratatui/ratatui/issues/1417>
This commit is contained in:
Josh McKinney 2024-10-15 03:00:03 -07:00 committed by GitHub
parent 6db16d67fc
commit 4728f0e68b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 243 additions and 204 deletions

229
README.md
View file

@ -2,14 +2,13 @@
<summary>Table of Contents</summary> <summary>Table of Contents</summary>
- [Ratatui](#ratatui) - [Ratatui](#ratatui)
- [Installation](#installation) - [Quick Start](#quickstart)
- [Introduction](#introduction)
- [Other documentation](#other-documentation) - [Other documentation](#other-documentation)
- [Introduction](#introduction)
- [Quickstart](#quickstart) - [Quickstart](#quickstart)
- [Initialize and restore the terminal](#initialize-and-restore-the-terminal) - [Initialize and restore the terminal](#initialize-and-restore-the-terminal)
- [Drawing the UI](#drawing-the-ui) - [Drawing the UI](#drawing-the-ui)
- [Handling events](#handling-events) - [Handling events](#handling-events)
- [Example](#example)
- [Layout](#layout) - [Layout](#layout)
- [Text and styling](#text-and-styling) - [Text and styling](#text-and-styling)
- [Status of this fork](#status-of-this-fork) - [Status of this fork](#status-of-this-fork)
@ -45,28 +44,42 @@ Badge]][GitHub Sponsors]<br> [![Discord Badge]][Discord Server] [![Matrix Badge]
lightweight library that provides a set of widgets and utilities to build complex Rust TUIs. 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. Ratatui was forked from the [tui-rs] crate in 2023 in order to continue its development.
## Installation ## Quickstart
Add `ratatui` as a dependency to your cargo.toml: Add `ratatui` and `crossterm` as dependencies to your cargo.toml:
```shell ```shell
cargo add ratatui cargo add ratatui crossterm
``` ```
Ratatui uses [Crossterm] by default as it works on most platforms. See the [Installation] Then you can create a simple "Hello World" application:
section of the [Ratatui Website] for more details on how to use other backends ([Termion] /
[Termwiz]).
## Introduction ```rust
use crossterm::event::{self, Event};
use ratatui::{text::Text, Frame};
Ratatui is based on the principle of immediate rendering with intermediate buffers. This means fn main() {
that for each frame, your app must render all widgets that are supposed to be part of the UI. let mut terminal = ratatui::init();
This is in contrast to the retained mode style of rendering where widgets are updated and then loop {
automatically redrawn on the next frame. See the [Rendering] section of the [Ratatui Website] terminal.draw(draw).expect("failed to draw frame");
for more info. if matches!(event::read().expect("failed to read event"), Event::Key(_)) {
break;
}
}
ratatui::restore();
}
You can also watch the [FOSDEM 2024 talk] about Ratatui which gives a brief introduction to fn draw(frame: &mut Frame) {
terminal user interfaces and showcases the features of Ratatui, along with a hello world demo. let text = Text::raw("Hello World!");
frame.render_widget(text, frame.area());
}
```
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.
## Other documentation ## Other documentation
@ -78,46 +91,82 @@ terminal user interfaces and showcases the features of Ratatui, along with a hel
- [Changelog] - generated by [git-cliff] utilizing [Conventional Commits]. - [Changelog] - generated by [git-cliff] utilizing [Conventional Commits].
- [Breaking Changes] - a list of breaking changes in the library. - [Breaking Changes] - a list of breaking changes in the library.
## Quickstart 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.
The following example demonstrates the minimal amount of code necessary to setup a terminal and ## Introduction
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 Ratatui is based on the principle of immediate rendering with intermediate buffers. This means
the [Application Patterns] and [Hello World tutorial] sections in the [Ratatui Website] and the that for each frame, your app must render all widgets that are supposed to be part of the UI.
various [Examples]. There are also several starter templates available in the [templates] This is in contrast to the retained mode style of rendering where widgets are updated and then
repository. automatically redrawn on the next frame. See the [Rendering] section of the [Ratatui Website]
for more info.
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]).
Every application built with `ratatui` needs to implement the following steps: Every application built with `ratatui` needs to implement the following steps:
- Initialize the terminal - Initialize the terminal
- A main loop to: - A main loop that:
- Handle input events - Draws the UI
- Draw the UI - Handles input events
- Restore the terminal state - 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 ### Initialize and restore the terminal
The [`Terminal`] type is the main entry point for any Ratatui application. It is a light The [`Terminal`] type is the main entry point for any Ratatui application. It is generic over a
abstraction over a choice of [`Backend`] implementations that provides functionality to draw a choice of [`Backend`] implementations that each provide functionality to draw frames, clear
each frame, clear the screen, hide the cursor, etc. It is parametrized over any type that the screen, hide the cursor, etc. There are backend implementations for [Crossterm], [Termion]
implements the [`Backend`] trait which has implementations for [Crossterm], [Termion] and and [Termwiz].
[Termwiz].
Most applications should enter the Alternate Screen when starting and leave it when exiting and The simplest way to initialize the terminal is to use the [`init`] function which returns a
also enable raw mode to disable line buffering and enable reading key events. See the [`backend` [`DefaultTerminal`] instance with the default options, enters the Alternate Screen and Raw mode
module] and the [Backends] section of the [Ratatui Website] for more info. and sets up a panic hook that restores the terminal in case of panic. This instance can then be
used to draw frames and interact with the terminal state. (The [`DefaultTerminal`] instance is a
type alias for a terminal with the [`crossterm`] backend.) The [`restore`] function restores the
terminal to its original state.
```rust
fn main() -> std::io::Result<()> {
let mut terminal = ratatui::init();
let result = run(&mut terminal);
ratatui::restore();
result
}
```
See the [`backend` module] and the [Backends] section of the [Ratatui Website] for more info on
the alternate screen and raw mode.
### Drawing the UI ### Drawing the UI
The drawing logic is delegated to a closure that takes a [`Frame`] instance as argument. The Drawing the UI is done by calling the [`Terminal::draw`] method on the terminal instance. This
[`Frame`] provides the size of the area to draw to and allows the app to render any [`Widget`] method takes a closure that is called with a [`Frame`] instance. The [`Frame`] provides the size
using the provided [`render_widget`] method. After this closure returns, a diff is performed and of the area to draw to and allows the app to render any [`Widget`] using the provided
only the changes are drawn to the terminal. See the [Widgets] section of the [Ratatui Website] [`render_widget`] method. After this closure returns, a diff is performed and only the changes
for more info. are drawn to the terminal. See the [Widgets] section of the [Ratatui Website] for more info.
The closure passed to the [`Terminal::draw`] method should handle the rendering of a full frame.
```rust
use ratatui::{Frame, widgets::Paragraph};
fn run(terminal: &mut ratatui::DefaultTerminal) -> std::io::Result<()> {
loop {
terminal.draw(|frame| draw(frame))?;
if handle_events()? {
break Ok(());
}
}
}
fn draw(frame: &mut Frame) {
let text = Paragraph::new("Hello World!");
frame.render_widget(text, frame.area());
}
```
### Handling events ### Handling events
@ -126,63 +175,23 @@ calling backend library methods directly. See the [Handling Events] section of t
Website] for more info. For example, if you are using [Crossterm], you can use the Website] for more info. For example, if you are using [Crossterm], you can use the
[`crossterm::event`] module to handle events. [`crossterm::event`] module to handle events.
### Example
```rust ```rust
use std::io::{self, stdout}; use crossterm::event::{self, Event, KeyCode, KeyEvent, KeyEventKind};
use ratatui::{ fn handle_events() -> std::io::Result<bool> {
backend::CrosstermBackend, match event::read()? {
crossterm::{ Event::Key(key) if key.kind == KeyEventKind::Press => match key.code {
event::{self, Event, KeyCode}, KeyCode::Char('q') => return Ok(true),
terminal::{ // handle other key events
disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen, _ => {}
}, },
ExecutableCommand, // handle other events
}, _ => {}
widgets::{Block, Paragraph},
Frame, Terminal,
};
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<bool> {
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) Ok(false)
} }
fn ui(frame: &mut Frame) {
frame.render_widget(
Paragraph::new("Hello World!").block(Block::bordered().title("Greeting")),
frame.area(),
);
}
``` ```
Running this example produces the following output:
![docsrs-hello]
## Layout ## Layout
The library comes with a basic yet useful layout management object called [`Layout`] which The library comes with a basic yet useful layout management object called [`Layout`] which
@ -197,16 +206,13 @@ use ratatui::{
Frame, Frame,
}; };
fn ui(frame: &mut Frame) { fn draw(frame: &mut Frame) {
let [title_area, main_area, status_area] = Layout::vertical([ use Constraint::{Fill, Length, Min};
Constraint::Length(1),
Constraint::Min(0), let vertical = Layout::vertical([Length(1), Min(0),Length(1)]);
Constraint::Length(1), let [title_area, main_area, status_area] = vertical.areas(frame.area());
]) let horizontal = Layout::horizontal([Fill(1); 2]);
.areas(frame.area()); let [left_area, right_area] = horizontal.areas(main_area);
let [left_area, right_area] =
Layout::horizontal([Constraint::Percentage(50), Constraint::Percentage(50)])
.areas(main_area);
frame.render_widget(Block::bordered().title("Title Bar"), title_area); frame.render_widget(Block::bordered().title("Title Bar"), title_area);
frame.render_widget(Block::bordered().title("Status Bar"), status_area); frame.render_widget(Block::bordered().title("Status Bar"), status_area);
@ -217,7 +223,13 @@ fn ui(frame: &mut Frame) {
Running this example produces the following output: Running this example produces the following output:
![docsrs-layout] ```text
Title Bar───────────────────────────────────
┌Left────────────────┐┌Right───────────────┐
│ ││ │
└────────────────────┘└────────────────────┘
Status Bar──────────────────────────────────
```
## Text and styling ## Text and styling
@ -240,7 +252,7 @@ use ratatui::{
Frame, Frame,
}; };
fn ui(frame: &mut Frame) { fn draw(frame: &mut Frame) {
let areas = Layout::vertical([Constraint::Length(1); 4]).split(frame.area()); let areas = Layout::vertical([Constraint::Length(1); 4]).split(frame.area());
let line = Line::from(vec![ let line = Line::from(vec![
@ -270,10 +282,6 @@ fn ui(frame: &mut Frame) {
} }
``` ```
Running this example produces the following output:
![docsrs-styling]
[Ratatui Website]: https://ratatui.rs/ [Ratatui Website]: https://ratatui.rs/
[Installation]: https://ratatui.rs/installation/ [Installation]: https://ratatui.rs/installation/
[Rendering]: https://ratatui.rs/concepts/rendering/ [Rendering]: https://ratatui.rs/concepts/rendering/
@ -296,9 +304,6 @@ Running this example produces the following output:
[Contributing]: https://github.com/ratatui/ratatui/blob/main/CONTRIBUTING.md [Contributing]: https://github.com/ratatui/ratatui/blob/main/CONTRIBUTING.md
[Breaking Changes]: https://github.com/ratatui/ratatui/blob/main/BREAKING-CHANGES.md [Breaking Changes]: https://github.com/ratatui/ratatui/blob/main/BREAKING-CHANGES.md
[FOSDEM 2024 talk]: https://www.youtube.com/watch?v=NU0q6NOLJ20 [FOSDEM 2024 talk]: https://www.youtube.com/watch?v=NU0q6NOLJ20
[docsrs-hello]: https://github.com/ratatui/ratatui/blob/c3c3c289b1eb8d562afb1931adb4dc719cd48490/examples/docsrs-hello.png?raw=true
[docsrs-layout]: https://github.com/ratatui/ratatui/blob/c3c3c289b1eb8d562afb1931adb4dc719cd48490/examples/docsrs-layout.png?raw=true
[docsrs-styling]: https://github.com/ratatui/ratatui/blob/c3c3c289b1eb8d562afb1931adb4dc719cd48490/examples/docsrs-styling.png?raw=true
[`Frame`]: terminal::Frame [`Frame`]: terminal::Frame
[`render_widget`]: terminal::Frame::render_widget [`render_widget`]: terminal::Frame::render_widget
[`Widget`]: widgets::Widget [`Widget`]: widgets::Widget

View file

@ -14,4 +14,5 @@ allowed-duplicate-crates = [
"windows_x86_64_gnu", "windows_x86_64_gnu",
"windows_x86_64_gnullvm", "windows_x86_64_gnullvm",
"windows_x86_64_msvc", "windows_x86_64_msvc",
"unicode-width",
] ]

View file

@ -20,21 +20,21 @@
//! [examples]: https://github.com/ratatui/ratatui/blob/main/examples //! [examples]: https://github.com/ratatui/ratatui/blob/main/examples
//! [examples readme]: https://github.com/ratatui/ratatui/blob/main/examples/README.md //! [examples readme]: https://github.com/ratatui/ratatui/blob/main/examples/README.md
use ratatui::{ use crossterm::event::{self, Event};
crossterm::event::{self, Event}, use ratatui::{text::Text, Frame};
text::Text,
Frame,
};
fn main() { fn main() {
let mut terminal = ratatui::init(); let mut terminal = ratatui::init();
loop { loop {
terminal terminal.draw(draw).expect("failed to draw frame");
.draw(|frame: &mut Frame| frame.render_widget(Text::raw("Hello World!"), frame.area()))
.expect("failed to draw frame");
if matches!(event::read().expect("failed to read event"), Event::Key(_)) { if matches!(event::read().expect("failed to read event"), Event::Key(_)) {
break; break;
} }
} }
ratatui::restore(); ratatui::restore();
} }
fn draw(frame: &mut Frame) {
let text = Text::raw("Hello World!");
frame.render_widget(text, frame.area());
}

View file

@ -18,28 +18,42 @@
//! lightweight library that provides a set of widgets and utilities to build complex Rust TUIs. //! 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. //! Ratatui was forked from the [tui-rs] crate in 2023 in order to continue its development.
//! //!
//! ## Installation //! ## Quickstart
//! //!
//! Add `ratatui` as a dependency to your cargo.toml: //! Add `ratatui` and `crossterm` as dependencies to your cargo.toml:
//! //!
//! ```shell //! ```shell
//! cargo add ratatui //! cargo add ratatui crossterm
//! ``` //! ```
//! //!
//! Ratatui uses [Crossterm] by default as it works on most platforms. See the [Installation] //! Then you can create a simple "Hello World" application:
//! section of the [Ratatui Website] for more details on how to use other backends ([Termion] /
//! [Termwiz]).
//! //!
//! ## Introduction //! ```rust,no_run
//! use crossterm::event::{self, Event};
//! use ratatui::{text::Text, Frame};
//! //!
//! Ratatui is based on the principle of immediate rendering with intermediate buffers. This means //! fn main() {
//! that for each frame, your app must render all widgets that are supposed to be part of the UI. //! let mut terminal = ratatui::init();
//! This is in contrast to the retained mode style of rendering where widgets are updated and then //! loop {
//! automatically redrawn on the next frame. See the [Rendering] section of the [Ratatui Website] //! terminal.draw(draw).expect("failed to draw frame");
//! for more info. //! if matches!(event::read().expect("failed to read event"), Event::Key(_)) {
//! break;
//! }
//! }
//! ratatui::restore();
//! }
//! //!
//! You can also watch the [FOSDEM 2024 talk] about Ratatui which gives a brief introduction to //! fn draw(frame: &mut Frame) {
//! terminal user interfaces and showcases the features of Ratatui, along with a hello world demo. //! let text = Text::raw("Hello World!");
//! frame.render_widget(text, frame.area());
//! }
//! ```
//!
//! 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.
//! //!
//! ## Other documentation //! ## Other documentation
//! //!
@ -51,46 +65,84 @@
//! - [Changelog] - generated by [git-cliff] utilizing [Conventional Commits]. //! - [Changelog] - generated by [git-cliff] utilizing [Conventional Commits].
//! - [Breaking Changes] - a list of breaking changes in the library. //! - [Breaking Changes] - a list of breaking changes in the library.
//! //!
//! ## Quickstart //! 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.
//! //!
//! The following example demonstrates the minimal amount of code necessary to setup a terminal and //! ## Introduction
//! 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 //! Ratatui is based on the principle of immediate rendering with intermediate buffers. This means
//! the [Application Patterns] and [Hello World tutorial] sections in the [Ratatui Website] and the //! that for each frame, your app must render all widgets that are supposed to be part of the UI.
//! various [Examples]. There are also several starter templates available in the [templates] //! This is in contrast to the retained mode style of rendering where widgets are updated and then
//! repository. //! automatically redrawn on the next frame. See the [Rendering] section of the [Ratatui Website]
//! for more info.
//!
//! 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]).
//! //!
//! Every application built with `ratatui` needs to implement the following steps: //! Every application built with `ratatui` needs to implement the following steps:
//! //!
//! - Initialize the terminal //! - Initialize the terminal
//! - A main loop to: //! - A main loop that:
//! - Handle input events //! - Draws the UI
//! - Draw the UI //! - Handles input events
//! - Restore the terminal state //! - 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 //! ### Initialize and restore the terminal
//! //!
//! The [`Terminal`] type is the main entry point for any Ratatui application. It is a light //! The [`Terminal`] type is the main entry point for any Ratatui application. It is generic over a
//! abstraction over a choice of [`Backend`] implementations that provides functionality to draw //! a choice of [`Backend`] implementations that each provide functionality to draw frames, clear
//! each frame, clear the screen, hide the cursor, etc. It is parametrized over any type that //! the screen, hide the cursor, etc. There are backend implementations for [Crossterm], [Termion]
//! implements the [`Backend`] trait which has implementations for [Crossterm], [Termion] and //! and [Termwiz].
//! [Termwiz].
//! //!
//! Most applications should enter the Alternate Screen when starting and leave it when exiting and //! The simplest way to initialize the terminal is to use the [`init`] function which returns a
//! also enable raw mode to disable line buffering and enable reading key events. See the [`backend` //! [`DefaultTerminal`] instance with the default options, enters the Alternate Screen and Raw mode
//! module] and the [Backends] section of the [Ratatui Website] for more info. //! and sets up a panic hook that restores the terminal in case of panic. This instance can then be
//! used to draw frames and interact with the terminal state. (The [`DefaultTerminal`] instance is a
//! type alias for a terminal with the [`crossterm`] backend.) The [`restore`] function restores the
//! terminal to its original state.
//!
//! ```rust,no_run
//! fn main() -> std::io::Result<()> {
//! let mut terminal = ratatui::init();
//! let result = run(&mut terminal);
//! ratatui::restore();
//! result
//! }
//! # fn run(terminal: &mut ratatui::DefaultTerminal) -> std::io::Result<()> { Ok(()) }
//! ```
//!
//! See the [`backend` module] and the [Backends] section of the [Ratatui Website] for more info on
//! the alternate screen and raw mode.
//! //!
//! ### Drawing the UI //! ### Drawing the UI
//! //!
//! The drawing logic is delegated to a closure that takes a [`Frame`] instance as argument. The //! Drawing the UI is done by calling the [`Terminal::draw`] method on the terminal instance. This
//! [`Frame`] provides the size of the area to draw to and allows the app to render any [`Widget`] //! method takes a closure that is called with a [`Frame`] instance. The [`Frame`] provides the size
//! using the provided [`render_widget`] method. After this closure returns, a diff is performed and //! of the area to draw to and allows the app to render any [`Widget`] using the provided
//! only the changes are drawn to the terminal. See the [Widgets] section of the [Ratatui Website] //! [`render_widget`] method. After this closure returns, a diff is performed and only the changes
//! for more info. //! are drawn to the terminal. See the [Widgets] section of the [Ratatui Website] for more info.
//!
//! The closure passed to the [`Terminal::draw`] method should handle the rendering of a full frame.
//!
//! ```rust,no_run
//! use ratatui::{widgets::Paragraph, Frame};
//!
//! fn run(terminal: &mut ratatui::DefaultTerminal) -> std::io::Result<()> {
//! loop {
//! terminal.draw(|frame| draw(frame))?;
//! if handle_events()? {
//! break Ok(());
//! }
//! }
//! }
//!
//! fn draw(frame: &mut Frame) {
//! let text = Paragraph::new("Hello World!");
//! frame.render_widget(text, frame.area());
//! }
//! # fn handle_events() -> std::io::Result<bool> { Ok(false) }
//! ```
//! //!
//! ### Handling events //! ### Handling events
//! //!
@ -99,38 +151,23 @@
//! Website] for more info. For example, if you are using [Crossterm], you can use the //! Website] for more info. For example, if you are using [Crossterm], you can use the
//! [`crossterm::event`] module to handle events. //! [`crossterm::event`] module to handle events.
//! //!
//! ### Example
//!
//! ```rust,no_run //! ```rust,no_run
//! use ratatui::{ //! use crossterm::event::{self, Event, KeyCode, KeyEvent, KeyEventKind};
//! crossterm::event::{self, Event, KeyCode, KeyEventKind},
//! widgets::{Block, Paragraph},
//! };
//! //!
//! fn main() -> std::io::Result<()> { //! fn handle_events() -> std::io::Result<bool> {
//! let mut terminal = ratatui::init(); //! match event::read()? {
//! loop { //! Event::Key(key) if key.kind == KeyEventKind::Press => match key.code {
//! terminal.draw(|frame| { //! KeyCode::Char('q') => return Ok(true),
//! frame.render_widget( //! // handle other key events
//! Paragraph::new("Hello World!").block(Block::bordered().title("Greeting")), //! _ => {}
//! frame.area(), //! },
//! ); //! // handle other events
//! })?; //! _ => {}
//! if let Event::Key(key) = event::read()? {
//! if key.kind == KeyEventKind::Press && key.code == KeyCode::Char('q') {
//! break;
//! } //! }
//! } //! Ok(false)
//! }
//! ratatui::restore();
//! Ok(())
//! } //! }
//! ``` //! ```
//! //!
//! Running this example produces the following output:
//!
//! ![docsrs-hello]
//!
//! ## Layout //! ## Layout
//! //!
//! The library comes with a basic yet useful layout management object called [`Layout`] which //! The library comes with a basic yet useful layout management object called [`Layout`] which
@ -146,15 +183,12 @@
//! }; //! };
//! //!
//! fn draw(frame: &mut Frame) { //! fn draw(frame: &mut Frame) {
//! let [title_area, main_area, status_area] = Layout::vertical([ //! use Constraint::{Fill, Length, Min};
//! Constraint::Length(1), //!
//! Constraint::Min(0), //! let vertical = Layout::vertical([Length(1), Min(0), Length(1)]);
//! Constraint::Length(1), //! let [title_area, main_area, status_area] = vertical.areas(frame.area());
//! ]) //! let horizontal = Layout::horizontal([Fill(1); 2]);
//! .areas(frame.area()); //! let [left_area, right_area] = horizontal.areas(main_area);
//! let [left_area, right_area] =
//! Layout::horizontal([Constraint::Percentage(50), Constraint::Percentage(50)])
//! .areas(main_area);
//! //!
//! frame.render_widget(Block::bordered().title("Title Bar"), title_area); //! frame.render_widget(Block::bordered().title("Title Bar"), title_area);
//! frame.render_widget(Block::bordered().title("Status Bar"), status_area); //! frame.render_widget(Block::bordered().title("Status Bar"), status_area);
@ -165,7 +199,13 @@
//! //!
//! Running this example produces the following output: //! Running this example produces the following output:
//! //!
//! ![docsrs-layout] //! ```text
//! Title Bar───────────────────────────────────
//! ┌Left────────────────┐┌Right───────────────┐
//! │ ││ │
//! └────────────────────┘└────────────────────┘
//! Status Bar──────────────────────────────────
//! ```
//! //!
//! ## Text and styling //! ## Text and styling
//! //!
@ -217,10 +257,6 @@
//! frame.render_widget(paragraph, areas[3]); //! frame.render_widget(paragraph, 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 = "\n## Features")]
#![cfg_attr(feature = "document-features", doc = document_features::document_features!())] #![cfg_attr(feature = "document-features", doc = document_features::document_features!())]
//! //!
@ -246,9 +282,6 @@
//! [Contributing]: https://github.com/ratatui/ratatui/blob/main/CONTRIBUTING.md //! [Contributing]: https://github.com/ratatui/ratatui/blob/main/CONTRIBUTING.md
//! [Breaking Changes]: https://github.com/ratatui/ratatui/blob/main/BREAKING-CHANGES.md //! [Breaking Changes]: https://github.com/ratatui/ratatui/blob/main/BREAKING-CHANGES.md
//! [FOSDEM 2024 talk]: https://www.youtube.com/watch?v=NU0q6NOLJ20 //! [FOSDEM 2024 talk]: https://www.youtube.com/watch?v=NU0q6NOLJ20
//! [docsrs-hello]: https://github.com/ratatui/ratatui/blob/c3c3c289b1eb8d562afb1931adb4dc719cd48490/examples/docsrs-hello.png?raw=true
//! [docsrs-layout]: https://github.com/ratatui/ratatui/blob/c3c3c289b1eb8d562afb1931adb4dc719cd48490/examples/docsrs-layout.png?raw=true
//! [docsrs-styling]: https://github.com/ratatui/ratatui/blob/c3c3c289b1eb8d562afb1931adb4dc719cd48490/examples/docsrs-styling.png?raw=true
//! [`Frame`]: terminal::Frame //! [`Frame`]: terminal::Frame
//! [`render_widget`]: terminal::Frame::render_widget //! [`render_widget`]: terminal::Frame::render_widget
//! [`Widget`]: widgets::Widget //! [`Widget`]: widgets::Widget