docs: improve Block docs (#1953)
Co-authored-by: Jagoda Estera Ślązak <128227338+j-g00da@users.noreply.github.com>
This commit is contained in:
@@ -22,87 +22,194 @@ use crate::borders::{BorderType, Borders};
|
||||
|
||||
mod padding;
|
||||
|
||||
/// Base widget to be used to display a box border around all other built-in widgets.
|
||||
/// A widget that renders borders, titles, and padding around other widgets.
|
||||
///
|
||||
/// The borders can be configured with [`Block::borders`] and others. A block can have multiple
|
||||
/// titles using [`Block::title`]. It can also be [styled](Block::style) and
|
||||
/// [padded](Block::padding).
|
||||
/// A `Block` is a foundational widget that creates visual containers by drawing borders around an
|
||||
/// area. It serves as a wrapper or frame for other widgets, providing structure and visual
|
||||
/// separation in terminal UIs. Most built-in widgets in Ratatui use a pattern where they accept an
|
||||
/// optional `Block` parameter that wraps the widget's content.
|
||||
///
|
||||
/// You can call the title methods multiple times to add multiple titles. Each title will be
|
||||
/// rendered with a single space separating titles that are in the same position or alignment. When
|
||||
/// both centered and non-centered titles are rendered, the centered space is calculated based on
|
||||
/// the full width of the block, rather than the leftover width.
|
||||
/// When a widget renders with a block, the widget's style is applied first, then the block's style,
|
||||
/// and finally the widget's content is rendered within the inner area calculated by the block. This
|
||||
/// layered approach allows for flexible styling where the block can provide background colors,
|
||||
/// borders, and padding while the inner widget handles its own content styling.
|
||||
///
|
||||
/// Titles are not rendered in the corners of the block unless there is no border on that edge. If
|
||||
/// the block is too small and multiple titles overlap, the border may get cut off at a corner.
|
||||
/// Multiple blocks can be nested within each other. The [`Block::inner`] method calculates the area
|
||||
/// available for content after accounting for borders, titles, and padding, making it easy to nest
|
||||
/// blocks or position widgets within a block's boundaries.
|
||||
///
|
||||
/// # Constructor Methods
|
||||
///
|
||||
/// - [`Block::new`] - Creates a block with no borders or padding
|
||||
/// - [`Block::bordered`] - Creates a block with all borders enabled
|
||||
///
|
||||
/// # Border Configuration
|
||||
///
|
||||
/// - [`Block::borders`] - Specifies which borders to display
|
||||
/// - [`Block::border_style`] - Sets the style of the borders
|
||||
/// - [`Block::border_type`] - Sets border symbols (single, double, thick, rounded, etc.)
|
||||
/// - [`Block::border_set`] - Sets custom border symbols as a [`border::Set`]
|
||||
/// - [`Block::merge_borders`] - Controls how borders merge with adjacent blocks
|
||||
///
|
||||
/// # Title Configuration
|
||||
///
|
||||
/// - [`Block::title`] - Adds a title to the block
|
||||
/// - [`Block::title_top`] - Adds a title to the top of the block
|
||||
/// - [`Block::title_bottom`] - Adds a title to the bottom of the block
|
||||
/// - [`Block::title_alignment`] - Sets default alignment for all titles
|
||||
/// - [`Block::title_style`] - Sets the style for all titles
|
||||
/// - [`Block::title_position`] - Sets default position for titles
|
||||
///
|
||||
/// # Styling and Layout
|
||||
///
|
||||
/// - [`Block::style`] - Sets the base style of the block
|
||||
/// - [`Block::padding`] - Adds internal padding within the borders
|
||||
/// - [`Block::inner`] - Calculates the inner area available for content
|
||||
///
|
||||
/// # Title Behavior
|
||||
///
|
||||
/// You can add multiple titles to a block, and they will be rendered with spaces separating titles
|
||||
/// that share the same position or alignment. When both centered and non-centered titles exist, the
|
||||
/// centered space is calculated based on the full width of the block.
|
||||
///
|
||||
/// Titles are set using the `.title`, `.title_top`, and `.title_bottom` methods. These methods
|
||||
/// accept a string or any type that can be converted into a [`Line`], such as a string slice,
|
||||
/// `String`, or a vector of [`Span`]s. To control the alignment of a title (left, center, right),
|
||||
/// pass a `Line` with the desired alignment, e.g. `Line::from("Title").centered()`.
|
||||
///
|
||||
/// By default, `.title` places the title at the top of the block, but you can use `.title_top` or
|
||||
/// `.title_bottom` to explicitly set the position. The default alignment for all titles can be set
|
||||
/// with [`Block::title_alignment`], and the default position for all titles can be set with
|
||||
/// [`Block::title_position`].
|
||||
///
|
||||
/// Note that prior to `v0.30.0`, the `block::Title` struct was used to create titles. This struct
|
||||
/// has been removed. The new recommended approach is to use [`Line`] with a specific alignment for
|
||||
/// the title's content and the [`Block::title_top`] and [`Block::title_bottom`] methods for
|
||||
/// positioning.
|
||||
///
|
||||
/// Titles avoid being rendered in corners when borders are present, but will align to edges when no
|
||||
/// border exists on that side:
|
||||
///
|
||||
/// ```plain
|
||||
/// ┌With at least a left border───
|
||||
///
|
||||
/// Without left border───
|
||||
/// ```
|
||||
/// # Constructor methods
|
||||
///
|
||||
/// - [`Block::new`] creates a new [`Block`] with no border or paddings.
|
||||
/// - [`Block::bordered`] Create a new block with all borders shown.
|
||||
/// # Nesting Widgets with `inner`
|
||||
///
|
||||
/// # Setter methods
|
||||
/// The [`Block::inner`] method computes the area inside the block after accounting for borders,
|
||||
/// titles, and padding. This allows you to nest widgets inside a block by rendering the block
|
||||
/// first, then rendering other widgets in the returned inner area.
|
||||
///
|
||||
/// These methods are fluent setters. They return a new [`Block`] with the specified property set.
|
||||
/// For example, you can nest a block inside another block:
|
||||
///
|
||||
/// - [`Block::borders`] Defines which borders to display.
|
||||
/// - [`Block::border_style`] Defines the style of the borders.
|
||||
/// - [`Block::border_type`] Sets the symbols used to display the border (e.g. single line, double
|
||||
/// line, thick or rounded borders).
|
||||
/// - [`Block::border_set`] Sets the symbols used to display the border as a [`border::Set`].
|
||||
/// - [`Block::merge_borders`] Sets the block's [`MergeStrategy`] for overlapping characters.
|
||||
/// - [`Block::padding`] Defines the padding inside a [`Block`].
|
||||
/// - [`Block::style`] Sets the base style of the widget.
|
||||
/// - [`Block::title`] Adds a title to the block.
|
||||
/// - [`Block::title_alignment`] Sets the default [`Alignment`] for all block titles.
|
||||
/// - [`Block::title_style`] Applies the style to all titles.
|
||||
/// - [`Block::title_top`] Adds a title to the top of the block.
|
||||
/// - [`Block::title_bottom`] Adds a title to the bottom of the block.
|
||||
/// - [`Block::title_position`] Adds a title to the block.
|
||||
/// ```
|
||||
/// use ratatui::Frame;
|
||||
/// use ratatui::widgets::Block;
|
||||
///
|
||||
/// # Other Methods
|
||||
/// - [`Block::inner`] Compute the inner area of a block based on its border visibility rules.
|
||||
/// # fn render_nested_block(frame: &mut Frame) {
|
||||
/// let outer_block = Block::bordered().title("Outer");
|
||||
/// let inner_block = Block::bordered().title("Inner");
|
||||
///
|
||||
/// [`Style`]s are applied first to the entire block, then to the borders, and finally to the
|
||||
/// titles. If the block is used as a container for another widget, the inner widget can also be
|
||||
/// styled. See [`Style`] for more information on how merging styles works.
|
||||
/// let outer_area = frame.area();
|
||||
/// let inner_area = outer_block.inner(outer_area);
|
||||
///
|
||||
/// frame.render_widget(outer_block, outer_area);
|
||||
/// frame.render_widget(inner_block, inner_area);
|
||||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// You can also use the standard [`Layout`] functionality to further subdivide the inner area and
|
||||
/// lay out multiple widgets inside a block.
|
||||
///
|
||||
/// # Integration with Other Widgets
|
||||
///
|
||||
/// Most widgets in Ratatui accept a block parameter. For example, [`Paragraph`], [`List`],
|
||||
/// [`Table`], and other widgets can be wrapped with a block:
|
||||
///
|
||||
/// ```
|
||||
/// use ratatui::widgets::{Block, Paragraph};
|
||||
///
|
||||
/// let paragraph = Paragraph::new("Hello, world!").block(Block::bordered().title("My Paragraph"));
|
||||
/// ```
|
||||
///
|
||||
/// This pattern allows widgets to focus on their content while blocks handle the visual framing.
|
||||
///
|
||||
/// # Styling
|
||||
///
|
||||
/// Styles are applied in a specific order: first the block's base style, then border styles, then
|
||||
/// title styles, and finally any content widget styles. This layered approach allows for flexible
|
||||
/// styling where outer styles provide defaults that inner styles can override.
|
||||
///
|
||||
/// `Block` implements [`Stylize`](ratatui_core::style::Stylize), allowing you to use style
|
||||
/// shorthand methods:
|
||||
///
|
||||
/// ```
|
||||
/// use ratatui::style::Stylize;
|
||||
/// use ratatui::widgets::Block;
|
||||
///
|
||||
/// let block = Block::bordered().red().on_white().bold();
|
||||
/// ```
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use ratatui::style::{Color, Style};
|
||||
/// use ratatui::widgets::{Block, BorderType, Borders};
|
||||
/// Create a simple bordered block:
|
||||
///
|
||||
/// Block::new()
|
||||
/// ```
|
||||
/// use ratatui::widgets::Block;
|
||||
///
|
||||
/// let block = Block::bordered().title("My Block");
|
||||
/// ```
|
||||
///
|
||||
/// Create a block with custom border styling:
|
||||
///
|
||||
/// ```
|
||||
/// use ratatui::style::{Color, Style, Stylize};
|
||||
/// use ratatui::widgets::{Block, BorderType};
|
||||
///
|
||||
/// let block = Block::bordered()
|
||||
/// .title("Styled Block")
|
||||
/// .border_type(BorderType::Rounded)
|
||||
/// .borders(Borders::LEFT | Borders::RIGHT)
|
||||
/// .border_style(Style::default().fg(Color::White))
|
||||
/// .style(Style::default().bg(Color::Black))
|
||||
/// .title("Block");
|
||||
/// .border_style(Style::new().cyan())
|
||||
/// .style(Style::new().on_black());
|
||||
/// ```
|
||||
///
|
||||
/// You may also use multiple titles like in the following:
|
||||
/// ```
|
||||
/// use ratatui::widgets::{Block, TitlePosition};
|
||||
/// Use a block to wrap another widget:
|
||||
///
|
||||
/// Block::new().title("Title 1").title_bottom("Title 2");
|
||||
/// ```
|
||||
/// use ratatui::widgets::{Block, Paragraph};
|
||||
///
|
||||
/// let paragraph = Paragraph::new("Hello, world!").block(Block::bordered().title("Greeting"));
|
||||
/// ```
|
||||
///
|
||||
/// You can also pass it as parameters of another widget so that the block surrounds them:
|
||||
/// ```
|
||||
/// use ratatui::widgets::{Block, Borders, List};
|
||||
/// Add multiple titles with different alignments:
|
||||
///
|
||||
/// let surrounding_block = Block::default()
|
||||
/// .borders(Borders::ALL)
|
||||
/// .title("Here is a list of items");
|
||||
/// let items = ["Item 1", "Item 2", "Item 3"];
|
||||
/// let list = List::new(items).block(surrounding_block);
|
||||
/// ```
|
||||
/// use ratatui::text::Line;
|
||||
/// use ratatui::widgets::Block;
|
||||
///
|
||||
/// let block = Block::bordered()
|
||||
/// .title_top(Line::from("Left").left_aligned())
|
||||
/// .title_top(Line::from("Center").centered())
|
||||
/// .title_top(Line::from("Right").right_aligned())
|
||||
/// .title_bottom("Status: OK");
|
||||
/// ```
|
||||
///
|
||||
/// # See Also
|
||||
///
|
||||
/// - [Block recipe] - Visual examples and common patterns (on the ratatui website)
|
||||
/// - [Collapse borders recipe] - Techniques for creating seamless layouts (on the ratatui website)
|
||||
/// - [`MergeStrategy`] - Controls how borders merge with adjacent elements
|
||||
///
|
||||
/// [Block recipe]: https://ratatui.rs/recipes/widgets/block/
|
||||
/// [Collapse borders recipe]: https://ratatui.rs/recipes/layout/collapse-borders/
|
||||
/// [`Paragraph`]: crate::paragraph::Paragraph
|
||||
/// [`Span`]: ratatui_core::text::Span
|
||||
/// [`Table`]: crate::table::Table
|
||||
/// [`Stylize`]: ratatui_core::style::Stylize
|
||||
/// [`List`]: crate::list::List
|
||||
/// [`Layout`]: ratatui_core::layout::Layout
|
||||
#[derive(Debug, Default, Clone, Eq, PartialEq, Hash)]
|
||||
pub struct Block<'a> {
|
||||
/// List of titles
|
||||
@@ -137,10 +244,10 @@ pub struct Block<'a> {
|
||||
/// ```
|
||||
/// use ratatui::widgets::{Block, TitlePosition};
|
||||
///
|
||||
/// Block::new()
|
||||
/// Block::bordered()
|
||||
/// .title_position(TitlePosition::Top)
|
||||
/// .title("Top Title");
|
||||
/// Block::new()
|
||||
/// Block::bordered()
|
||||
/// .title_position(TitlePosition::Bottom)
|
||||
/// .title("Bottom Title");
|
||||
/// ```
|
||||
@@ -183,7 +290,11 @@ impl<'a> Block<'a> {
|
||||
block
|
||||
}
|
||||
|
||||
/// Adds a title to the block.
|
||||
/// Adds a title to the block using the default position.
|
||||
///
|
||||
/// The position of the title is determined by the `title_position` field of the block, which
|
||||
/// defaults to `Top`. This can be changed using the [`Block::title_position`] method. For
|
||||
/// explicit positioning, use [`Block::title_top`] or [`Block::title_bottom`].
|
||||
///
|
||||
/// The `title` function allows you to add a title to the block. You can call this function
|
||||
/// multiple times to add multiple titles.
|
||||
@@ -222,9 +333,9 @@ impl<'a> Block<'a> {
|
||||
/// - Two titles with the same alignment (notice the left titles are separated)
|
||||
/// ```
|
||||
/// use ratatui::text::Line;
|
||||
/// use ratatui::widgets::{Block, Borders};
|
||||
/// use ratatui::widgets::Block;
|
||||
///
|
||||
/// Block::new()
|
||||
/// Block::bordered()
|
||||
/// .title("Title")
|
||||
/// .title(Line::from("Left").left_aligned())
|
||||
/// .title(Line::from("Right").right_aligned())
|
||||
@@ -343,7 +454,7 @@ impl<'a> Block<'a> {
|
||||
/// use ratatui::text::Line;
|
||||
/// use ratatui::widgets::Block;
|
||||
///
|
||||
/// Block::new()
|
||||
/// Block::bordered()
|
||||
/// .title_alignment(Alignment::Center)
|
||||
/// // This title won't be aligned in the center
|
||||
/// .title(Line::from("right").right_aligned())
|
||||
@@ -360,16 +471,18 @@ impl<'a> Block<'a> {
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// This example positions all titles on the bottom except the "top" title which explicitly sets
|
||||
/// [`TitlePosition::Top`].
|
||||
/// This example positions all titles on the bottom by default. The "top" title explicitly sets
|
||||
/// its position to `Top`, so it is not affected. The "foo" and "bar" titles will be positioned
|
||||
/// at the bottom.
|
||||
///
|
||||
/// ```
|
||||
/// use ratatui::widgets::{Block, TitlePosition};
|
||||
///
|
||||
/// Block::new()
|
||||
/// Block::bordered()
|
||||
/// .title_position(TitlePosition::Bottom)
|
||||
/// .title_top("top")
|
||||
/// .title("foo")
|
||||
/// .title("bar");
|
||||
/// .title("foo") // will be at the bottom
|
||||
/// .title_top("top") // will be at the top
|
||||
/// .title("bar"); // will be at the bottom
|
||||
/// ```
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub const fn title_position(mut self, position: TitlePosition) -> Self {
|
||||
@@ -543,9 +656,8 @@ impl<'a> Block<'a> {
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets the block's [`MergeStrategy`] for overlapping characters.
|
||||
/// Sets the block's [`MergeStrategy`] for overlapping characters, defaulting to [`Replace`].
|
||||
///
|
||||
/// Defaults to [`Replace`], which completely replaces the previously rendered character.
|
||||
/// Changing the strategy to [`Exact`] or [`Fuzzy`] collapses border characters that intersect
|
||||
/// with any previously rendered borders.
|
||||
///
|
||||
@@ -591,7 +703,7 @@ impl<'a> Block<'a> {
|
||||
self
|
||||
}
|
||||
|
||||
/// Compute the inner area of a block based on its border visibility rules.
|
||||
/// Computes the inner area of a block after subtracting space for borders, titles, and padding.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
||||
Reference in New Issue
Block a user