Important
This repo has been consolidated into https://github.com/tui-widgets. All future work will happen there. The crate will remain available as tui-big-text, but this repo is now archived.
A popup widget for Ratatui
The popup widget is a simple widget that renders a popup in the center of the screen.
use ratatui::prelude::*;
use tui_popup::Popup;
fn render_popup(frame: &mut Frame) {
let popup = Popup::new("tui-popup demo", "Press any key to exit")
.style(Style::new().white().on_blue());
frame.render_widget(&popup, frame.size());
}
The widget supports storing the position of the popup in PopupState. This is experimental and the exact api for this will likely change.
use ratatui::prelude::*;
use tui_popup::Popup;
fn render_stateful_popup(frame: &mut Frame, popup_state: &mut PopupState) {
let popup = Popup::new("tui-popup demo", "Press any key to exit")
.style(Style::new().white().on_blue());
frame.render_stateful_widget_ref(popup, frame.size(), popup_state);
}
fn move_up(popup_state: &mut PopupState) {
popup_state.move_by(0, -1);
}
The popup can automatically handle being moved around by the mouse, by passing in the column and row of Mouse Up / Down / Drag events. The current implemntation of this checks whether the click is in the first row of the popup, otherwise ignores the event.
match event.read()? {
Event::Mouse(event) => {
match event.kind {
event::MouseEventKind::Down(MouseButton::Left) => {
popup_state.mouse_down(event.column, event.row)
}
event::MouseEventKind::Up(MouseButton::Left) => {
popup_state.mouse_up(event.column, event.row);
}
event::MouseEventKind::Drag(MouseButton::Left) => {
popup_state.mouse_drag(event.column, event.row);
}
_ => {}
};
}
// -- snip --
}
The popup also supports rendering arbitrary widgets by implementing SizedWidgetRef (or wrapping them
with the provided SizedWrapper). This makes it possible to support wrapping and scrolling in using a
Paragraph
widget, or scrolling any amount of widgets using
tui-scrollview.
let lines: Text = (0..10).map(|i| Span::raw(format!("Line {}", i))).collect();
let paragraph = Paragraph::new(lines).scroll((scroll, 0));
let sized_paragraph = SizedWrapper {
inner: paragraph,
width: 21,
height: 5,
};
let popup = Popup::new("scroll: ↑/↓ quit: Esc", sized_paragraph)
.style(Style::new().white().on_blue());
frame.render_widget_ref(popup, area);
- automatically centers
- automatically sizes to content
- style popup
- move the popup (using state)
- handle mouse events for dragging
- move to position
- resize
- set border set / style
- add close button
- add nicer styling of header etc.
- configure text wrapping in body to conform to a specific size