Skip to content

Popup

Demonstrates how to render a widget over the top of previously rendered widgets using the Clear widget. Source popup.rs.

run
git clone https://github.com/ratatui/ratatui.git --branch latest
cd ratatui
cargo run -p popup

popup

main.rs
//! A Ratatui example that demonstrates how to handle popups.
//! See also:
//! - <https://github.com/joshka/tui-popup> and
//! - <https://github.com/sephiroth74/tui-confirm-dialog>
//!
//! This example runs with the Ratatui library code in the branch that you are currently
//! reading. See the [`latest`] branch for the code which works with the most recent Ratatui
//! release.
//!
//! [`latest`]: https://github.com/ratatui/ratatui/tree/latest
use color_eyre::Result;
use crossterm::event::{self, KeyCode};
use ratatui::layout::{Constraint, Layout};
use ratatui::style::Stylize;
use ratatui::text::Line;
use ratatui::widgets::{Block, Clear, Paragraph};
use ratatui::Frame;
fn main() -> Result<()> {
color_eyre::install()?;
// This flag will be toggled when the user presses 'p'. This could be stored in an app struct
// if you have more state to manage than just this flag.
let mut show_popup = false;
ratatui::run(|terminal| loop {
terminal.draw(|frame| render(frame, show_popup))?;
if let Some(key) = event::read()?.as_key_press_event() {
match key.code {
KeyCode::Char('q') => return Ok(()),
KeyCode::Char('p') => show_popup = !show_popup,
_ => {}
}
}
})
}
fn render(frame: &mut Frame, show_popup: bool) {
let area = frame.area();
let layout = Layout::vertical([Constraint::Length(1), Constraint::Fill(1)]);
let [instructions, content] = area.layout(&layout);
frame.render_widget(
Line::from("Press 'p' to toggle popup, 'q' to quit").centered(),
instructions,
);
frame.render_widget(Block::bordered().title("Content").on_blue(), content);
if show_popup {
let popup_block = Block::bordered().title("Popup");
let centered_area = area.centered(Constraint::Percentage(60), Constraint::Percentage(20));
// clears out any background in the area before rendering the popup
frame.render_widget(Clear, centered_area);
let paragraph = Paragraph::new("Lorem ipsum").block(popup_block);
frame.render_widget(paragraph, centered_area);
// another solution is to use the inner area of the block
// let inner_area = popup_block.inner(centered_area);
// frame.render_widget(your_widget, inner_area);
}
}