mirror of
https://github.com/ratatui-org/ratatui
synced 2024-11-21 20:23:11 +00:00
chore: move widgets into ratatui-widgets crate (#1474)
All the widgets now live in their own ratatui-widgets crate, but are re-exported in the main ratatui crate. This makes it easier to use portions of the ratatui library and is part of the effort to modularize Part of: #1388 --------- Co-authored-by: Orhun Parmaksız <orhun@archlinux.org> Co-authored-by: Orhun Parmaksız <orhunparmaksiz@gmail.com>
This commit is contained in:
parent
9f90f7495f
commit
e7085e3a3e
44 changed files with 773 additions and 511 deletions
22
Cargo.lock
generated
22
Cargo.lock
generated
|
@ -2089,7 +2089,6 @@ name = "ratatui"
|
|||
version = "0.29.0"
|
||||
dependencies = [
|
||||
"argh",
|
||||
"bitflags 2.6.0",
|
||||
"color-eyre",
|
||||
"criterion",
|
||||
"crossterm",
|
||||
|
@ -2106,6 +2105,7 @@ dependencies = [
|
|||
"rand 0.8.5",
|
||||
"rand_chacha 0.3.1",
|
||||
"ratatui-core",
|
||||
"ratatui-widgets",
|
||||
"rstest",
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
@ -2117,7 +2117,6 @@ dependencies = [
|
|||
"tracing",
|
||||
"tracing-appender",
|
||||
"tracing-subscriber",
|
||||
"unicode-segmentation",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
|
@ -2144,6 +2143,25 @@ dependencies = [
|
|||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ratatui-widgets"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"indoc",
|
||||
"instability",
|
||||
"itertools 0.13.0",
|
||||
"pretty_assertions",
|
||||
"ratatui",
|
||||
"ratatui-core",
|
||||
"rstest",
|
||||
"serde",
|
||||
"strum",
|
||||
"time",
|
||||
"unicode-segmentation",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.10.0"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
[workspace]
|
||||
resolver = "2"
|
||||
members = ["ratatui", "ratatui-core", "xtask"]
|
||||
default-members = ["ratatui", "ratatui-core"]
|
||||
members = ["ratatui", "ratatui-core", "ratatui-widgets", "xtask"]
|
||||
default-members = ["ratatui", "ratatui-core", "ratatui-widgets"]
|
||||
|
||||
[workspace.package]
|
||||
authors = ["Florian Dehau <work@fdehau.com>", "The Ratatui Developers"]
|
||||
|
@ -29,7 +29,9 @@ indoc = "2.0.5"
|
|||
instability = "0.3.1"
|
||||
itertools = "0.13.0"
|
||||
pretty_assertions = "1.4.1"
|
||||
ratatui = { path = "ratatui" }
|
||||
ratatui-core = { path = "ratatui-core" }
|
||||
ratatui-widgets = { path = "ratatui-widgets" }
|
||||
rstest = "0.23.0"
|
||||
serde = { version = "1.0.214", features = ["derive"] }
|
||||
strum = { version = "0.26.3", features = ["derive"] }
|
||||
|
|
|
@ -27,7 +27,8 @@ cargo add ratatui-core
|
|||
|
||||
## Contributing
|
||||
|
||||
We welcome contributions from the community! Please see our [CONTRIBUTING](../CONTRIBUTING.md) guide for more details on how to get involved.
|
||||
We welcome contributions from the community! Please see our [CONTRIBUTING](../CONTRIBUTING.md) guide
|
||||
for more details on how to get involved.
|
||||
|
||||
## License
|
||||
|
||||
|
|
104
ratatui-widgets/Cargo.toml
Normal file
104
ratatui-widgets/Cargo.toml
Normal file
|
@ -0,0 +1,104 @@
|
|||
[package]
|
||||
name = "ratatui-widgets"
|
||||
description = "A collection of Ratatui widgets for building terminal user interfaces."
|
||||
version = "0.3.0"
|
||||
authors.workspace = true
|
||||
documentation.workspace = true
|
||||
repository.workspace = true
|
||||
homepage.workspace = true
|
||||
keywords.workspace = true
|
||||
categories.workspace = true
|
||||
license.workspace = true
|
||||
exclude.workspace = true
|
||||
edition.workspace = true
|
||||
rust-version.workspace = true
|
||||
|
||||
[features]
|
||||
## enables serialization and deserialization of style and color types using the [`serde`] crate.
|
||||
## This is useful if you want to save themes to a file.
|
||||
serde = ["dep:serde", "ratatui-core/serde"]
|
||||
|
||||
#! Widgets that add dependencies are gated behind feature flags to prevent unused transitive
|
||||
#! dependencies. The available features are:
|
||||
|
||||
## enables all widgets.
|
||||
all-widgets = ["calendar"]
|
||||
|
||||
## enables the [`calendar`](widgets::calendar) widget module and adds a dependency on [`time`].
|
||||
calendar = ["dep:time"]
|
||||
|
||||
## Enable all unstable features.
|
||||
unstable = ["unstable-rendered-line-info", "unstable-widget-ref"]
|
||||
|
||||
## enables the [`WidgetRef`] and [`StatefulWidgetRef`] traits which are experimental and may change
|
||||
## in the future.
|
||||
unstable-widget-ref = ["ratatui-core/unstable-widget-ref"]
|
||||
|
||||
## Enables the [`Paragraph::line_count`](widgets::Paragraph::line_count)
|
||||
## [`Paragraph::line_width`](widgets::Paragraph::line_width) methods
|
||||
## which are experimental and may change in the future.
|
||||
## See [Issue 293](https://github.com/ratatui/ratatui/issues/293) for more details.
|
||||
unstable-rendered-line-info = []
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
rustdoc-args = ["--cfg", "docsrs"]
|
||||
|
||||
[dependencies]
|
||||
bitflags.workspace = true
|
||||
itertools.workspace = true
|
||||
indoc.workspace = true
|
||||
instability.workspace = true
|
||||
ratatui-core = { workspace = true }
|
||||
strum.workspace = true
|
||||
time = { version = "0.3.11", optional = true, features = ["local-offset"] }
|
||||
unicode-segmentation.workspace = true
|
||||
unicode-width.workspace = true
|
||||
serde = { workspace = true, optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
rstest.workspace = true
|
||||
pretty_assertions.workspace = true
|
||||
ratatui.workspace = true
|
||||
|
||||
[lints.rust]
|
||||
unsafe_code = "forbid"
|
||||
|
||||
[lints.clippy]
|
||||
cargo = { level = "warn", priority = -1 }
|
||||
pedantic = { level = "warn", priority = -1 }
|
||||
cast_possible_truncation = "allow"
|
||||
cast_possible_wrap = "allow"
|
||||
cast_precision_loss = "allow"
|
||||
cast_sign_loss = "allow"
|
||||
missing_errors_doc = "allow"
|
||||
missing_panics_doc = "allow"
|
||||
module_name_repetitions = "allow"
|
||||
must_use_candidate = "allow"
|
||||
|
||||
# we often split up a module into multiple files with the main type in a file named after the
|
||||
# module, so we want to allow this pattern
|
||||
module_inception = "allow"
|
||||
|
||||
# nursery or restricted
|
||||
as_underscore = "warn"
|
||||
deref_by_slicing = "warn"
|
||||
else_if_without_else = "warn"
|
||||
empty_line_after_doc_comments = "warn"
|
||||
equatable_if_let = "warn"
|
||||
fn_to_numeric_cast_any = "warn"
|
||||
format_push_string = "warn"
|
||||
map_err_ignore = "warn"
|
||||
missing_const_for_fn = "warn"
|
||||
mixed_read_write_in_expression = "warn"
|
||||
mod_module_files = "warn"
|
||||
needless_pass_by_ref_mut = "warn"
|
||||
needless_raw_strings = "warn"
|
||||
or_fun_call = "warn"
|
||||
redundant_type_annotations = "warn"
|
||||
rest_pat_in_fully_bound_structs = "warn"
|
||||
string_lit_chars_any = "warn"
|
||||
string_slice = "warn"
|
||||
string_to_string = "warn"
|
||||
unnecessary_self_imports = "warn"
|
||||
use_self = "warn"
|
76
ratatui-widgets/README.md
Normal file
76
ratatui-widgets/README.md
Normal file
|
@ -0,0 +1,76 @@
|
|||
# Ratatui-widgets
|
||||
|
||||
<!-- DO NOT EDIT THIS FILE DIRECTLY, EDIT lib.rs AND THEN RUN cargo rdme to update this file -->
|
||||
<!-- cargo-rdme start -->
|
||||
|
||||
Ratatui-widgets contains all the widgets that were previously part of the Ratatui crate. It is
|
||||
meant to be used in conjunction with the [Ratatui] crate, which provides the core functionality
|
||||
for building terminal user interfaces.
|
||||
|
||||
[Ratatui]: https://crates.io/crates/ratatui
|
||||
|
||||
Most applications shouldn't need to depend directly on Ratatui-widgets, as all the Ratatui crate
|
||||
re-exports all the widgets from this crate. However, if you are building a widget library that
|
||||
internally uses Ratatui widgets, or if you prefer finer grained dependencies, you may want to
|
||||
depend on this crate rather than transitively through the Ratatui crate.
|
||||
|
||||
Previously, a crate named `Ratatui-widgets` was published with some formative ideas about an
|
||||
eventual Ratatui framework. That crate is now move to [tui-framework-experiment], pending a new
|
||||
name.
|
||||
|
||||
[tui-framework-experiment]: https://crates.io/crates/tui-framework-experiment
|
||||
|
||||
## Installation
|
||||
|
||||
Run the following command to add this crate to your project:
|
||||
|
||||
```sh
|
||||
cargo add ratatui-widgets
|
||||
```
|
||||
|
||||
## Available Widgets
|
||||
|
||||
- [`BarChart`]: displays multiple datasets as bars with optional grouping.
|
||||
- [`Block`]: a basic widget that draws a block with optional borders, titles, and styles.
|
||||
- [`calendar::Monthly`]: displays a single month.
|
||||
- [`Canvas`]: draws arbitrary shapes using drawing characters.
|
||||
- [`Chart`]: displays multiple datasets as lines or scatter graphs.
|
||||
- [`Clear`]: clears the area it occupies. Useful to render over previously drawn widgets.
|
||||
- [`Gauge`]: displays progress percentage using block characters.
|
||||
- [`LineGauge`]: displays progress as a line.
|
||||
- [`List`]: displays a list of items and allows selection.
|
||||
- [`RatatuiLogo`]: displays the Ratatui logo.
|
||||
- [`Paragraph`]: displays a paragraph of optionally styled and wrapped text.
|
||||
- [`Scrollbar`]: displays a scrollbar.
|
||||
- [`Sparkline`]: displays a single dataset as a sparkline.
|
||||
- [`Table`]: displays multiple rows and columns in a grid and allows selection.
|
||||
- [`Tabs`]: displays a tab bar and allows selection.
|
||||
|
||||
[`BarChart`]: https://docs.rs/ratatui-widgets/latest/ratatui_widgets/barchart/struct.BarChart.html
|
||||
[`Block`]: https://docs.rs/ratatui-widgets/latest/ratatui_widgets/block/struct.Block.html
|
||||
[`calendar::Monthly`]: https://docs.rs/ratatui-widgets/latest/ratatui_widgets/calendar/struct.Monthly.html
|
||||
[`Canvas`]: https://docs.rs/ratatui-widgets/latest/ratatui_widgets/canvas/struct.Canvas.html
|
||||
[`Chart`]: https://docs.rs/ratatui-widgets/latest/ratatui_widgets/chart/struct.Chart.html
|
||||
[`Clear`]: https://docs.rs/ratatui-widgets/latest/ratatui_widgets/clear/struct.Clear.html
|
||||
[`Gauge`]: https://docs.rs/ratatui-widgets/latest/ratatui_widgets/gauge/struct.Gauge.html
|
||||
[`LineGauge`]: https://docs.rs/ratatui-widgets/latest/ratatui_widgets/gauge/struct.LineGauge.html
|
||||
[`List`]: https://docs.rs/ratatui-widgets/latest/ratatui_widgets/list/struct.List.html
|
||||
[`RatatuiLogo`]: https://docs.rs/ratatui-widgets/latest/ratatui_widgets/logo/struct.RatatuiLogo.html
|
||||
[`Paragraph`]: https://docs.rs/ratatui-widgets/latest/ratatui_widgets/paragraph/struct.Paragraph.html
|
||||
[`Scrollbar`]: https://docs.rs/ratatui-widgets/latest/ratatui_widgets/scrollbar/struct.Scrollbar.html
|
||||
[`Sparkline`]: https://docs.rs/ratatui-widgets/latest/ratatui_widgets/sparkline/struct.Sparkline.html
|
||||
[`Table`]: https://docs.rs/ratatui-widgets/latest/ratatui_widgets/table/struct.Table.html
|
||||
[`Tabs`]: https://docs.rs/ratatui-widgets/latest/ratatui_widgets/tabs/struct.Tabs.html
|
||||
|
||||
All these widgets are re-exported directly under `ratatui::widgets` in the Ratatui crate.
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions are welcome! Please open an issue or submit a pull request on GitHub. For more
|
||||
details on contributing, please see the [CONTRIBUTING](CONTRIBUTING.md) document.
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the MIT License. See the [LICENSE](LICENSE) file for details.
|
||||
|
||||
<!-- cargo-rdme end -->
|
|
@ -1,18 +1,20 @@
|
|||
use crate::{
|
||||
//! The [`BarChart`] widget and its related types (e.g. [`Bar`], [`BarGroup`]).
|
||||
|
||||
use ratatui_core::{
|
||||
buffer::Buffer,
|
||||
layout::{Direction, Rect},
|
||||
style::{Style, Styled},
|
||||
symbols::{self},
|
||||
text::Line,
|
||||
widgets::{block::BlockExt, Block, Widget, WidgetRef},
|
||||
widgets::{Widget, WidgetRef},
|
||||
};
|
||||
|
||||
pub use self::{bar::Bar, bar_group::BarGroup};
|
||||
use crate::block::{Block, BlockExt};
|
||||
|
||||
mod bar;
|
||||
mod bar_group;
|
||||
|
||||
pub use bar::Bar;
|
||||
pub use bar_group::BarGroup;
|
||||
|
||||
/// A chart showing values as [bars](Bar).
|
||||
///
|
||||
/// Here is a possible `BarChart` output.
|
||||
|
@ -189,7 +191,7 @@ impl<'a> BarChart<'a> {
|
|||
/// It is also possible to set individually the style of each [`Bar`].
|
||||
/// In this case the default style will be patched by the individual style
|
||||
///
|
||||
/// [`Color`]: crate::style::Color
|
||||
/// [`Color`]: ratatui_core::style::Color
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn bar_style<S: Into<Style>>(mut self, style: S) -> Self {
|
||||
self.bar_style = style.into();
|
||||
|
@ -198,8 +200,8 @@ impl<'a> BarChart<'a> {
|
|||
|
||||
/// Set the width of the displayed bars.
|
||||
///
|
||||
/// For [`Horizontal`](crate::layout::Direction::Horizontal) bars this becomes the height of
|
||||
/// the bar.
|
||||
/// For [`Horizontal`](ratatui_core::layout::Direction::Horizontal) bars this becomes the height
|
||||
/// of the bar.
|
||||
///
|
||||
/// If not set, this defaults to `1`.
|
||||
/// The bar label also uses this value as its width.
|
||||
|
@ -234,9 +236,9 @@ impl<'a> BarChart<'a> {
|
|||
self
|
||||
}
|
||||
|
||||
/// The [`bar::Set`](crate::symbols::bar::Set) to use for displaying the bars.
|
||||
/// The [`bar::Set`](ratatui_core::symbols::bar::Set) to use for displaying the bars.
|
||||
///
|
||||
/// If not set, the default is [`bar::NINE_LEVELS`](crate::symbols::bar::NINE_LEVELS).
|
||||
/// If not set, the default is [`bar::NINE_LEVELS`](ratatui_core::symbols::bar::NINE_LEVELS).
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub const fn bar_set(mut self, bar_set: symbols::bar::Set) -> Self {
|
||||
self.bar_set = bar_set;
|
||||
|
@ -255,7 +257,7 @@ impl<'a> BarChart<'a> {
|
|||
///
|
||||
/// [`Bar::value_style`] to set the value style individually.
|
||||
///
|
||||
/// [`Color`]: crate::style::Color
|
||||
/// [`Color`]: ratatui_core::style::Color
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn value_style<S: Into<Style>>(mut self, style: S) -> Self {
|
||||
self.value_style = style.into();
|
||||
|
@ -274,7 +276,7 @@ impl<'a> BarChart<'a> {
|
|||
///
|
||||
/// [`Bar::label`] to set the label style individually.
|
||||
///
|
||||
/// [`Color`]: crate::style::Color
|
||||
/// [`Color`]: ratatui_core::style::Color
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn label_style<S: Into<Style>>(mut self, style: S) -> Self {
|
||||
self.label_style = style.into();
|
||||
|
@ -295,7 +297,7 @@ impl<'a> BarChart<'a> {
|
|||
///
|
||||
/// The style will be applied to everything that isn't styled (borders, bars, labels, ...).
|
||||
///
|
||||
/// [`Color`]: crate::style::Color
|
||||
/// [`Color`]: ratatui_core::style::Color
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn style<S: Into<Style>>(mut self, style: S) -> Self {
|
||||
self.style = style.into();
|
||||
|
@ -304,7 +306,7 @@ impl<'a> BarChart<'a> {
|
|||
|
||||
/// Set the direction of the bars.
|
||||
///
|
||||
/// [`Vertical`](crate::layout::Direction::Vertical) bars are the default.
|
||||
/// [`Vertical`](ratatui_core::layout::Direction::Vertical) bars are the default.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -634,15 +636,15 @@ impl<'a> Styled for BarChart<'a> {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use itertools::iproduct;
|
||||
|
||||
use super::*;
|
||||
use crate::{
|
||||
use ratatui_core::{
|
||||
layout::Alignment,
|
||||
style::{Color, Modifier, Stylize},
|
||||
text::Span,
|
||||
widgets::BorderType,
|
||||
};
|
||||
|
||||
use super::*;
|
||||
use crate::borders::BorderType;
|
||||
|
||||
#[test]
|
||||
fn default() {
|
||||
let mut buffer = Buffer::empty(Rect::new(0, 0, 10, 3));
|
|
@ -1,7 +1,7 @@
|
|||
use ratatui_core::{buffer::Buffer, layout::Rect, style::Style, text::Line, widgets::Widget};
|
||||
use unicode_width::UnicodeWidthStr;
|
||||
|
||||
use crate::{buffer::Buffer, layout::Rect, style::Style, text::Line, widgets::Widget};
|
||||
/// A bar to be shown by the [`BarChart`](crate::widgets::BarChart) widget.
|
||||
/// A bar to be shown by the [`BarChart`](crate::barchart::BarChart) widget.
|
||||
///
|
||||
/// Here is an explanation of a `Bar`'s components.
|
||||
/// ```plain
|
||||
|
@ -59,11 +59,11 @@ impl<'a> Bar<'a> {
|
|||
|
||||
/// Set the label of the bar.
|
||||
///
|
||||
/// For [`Vertical`](crate::layout::Direction::Vertical) bars,
|
||||
/// For [`Vertical`](ratatui_core::layout::Direction::Vertical) bars,
|
||||
/// display the label **under** the bar.
|
||||
/// For [`Horizontal`](crate::layout::Direction::Horizontal) bars,
|
||||
/// For [`Horizontal`](ratatui_core::layout::Direction::Horizontal) bars,
|
||||
/// display the label **in** the bar.
|
||||
/// See [`BarChart::direction`](crate::widgets::BarChart::direction) to set the direction.
|
||||
/// See [`BarChart::direction`](crate::barchart::BarChart::direction) to set the direction.
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn label(mut self, label: Line<'a>) -> Self {
|
||||
self.label = Some(label);
|
||||
|
@ -77,7 +77,7 @@ impl<'a> Bar<'a> {
|
|||
///
|
||||
/// This will apply to every non-styled element. It can be seen and used as a default value.
|
||||
///
|
||||
/// [`Color`]: crate::style::Color
|
||||
/// [`Color`]: ratatui_core::style::Color
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn style<S: Into<Style>>(mut self, style: S) -> Self {
|
||||
self.style = style.into();
|
||||
|
@ -93,7 +93,7 @@ impl<'a> Bar<'a> {
|
|||
///
|
||||
/// [`Bar::value`] to set the value.
|
||||
///
|
||||
/// [`Color`]: crate::style::Color
|
||||
/// [`Color`]: ratatui_core::style::Color
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn value_style<S: Into<Style>>(mut self, style: S) -> Self {
|
||||
self.value_style = style.into();
|
|
@ -1,11 +1,13 @@
|
|||
use crate::{
|
||||
use ratatui_core::{
|
||||
buffer::Buffer,
|
||||
layout::{Alignment, Rect},
|
||||
style::Style,
|
||||
text::Line,
|
||||
widgets::{barchart::Bar, Widget},
|
||||
widgets::Widget,
|
||||
};
|
||||
|
||||
use crate::barchart::Bar;
|
||||
|
||||
/// A group of bars to be shown by the Barchart.
|
||||
///
|
||||
/// # Examples
|
|
@ -6,24 +6,25 @@
|
|||
//! [title](Block::title) and [padding](Block::padding).
|
||||
|
||||
use itertools::Itertools;
|
||||
use strum::{Display, EnumString};
|
||||
|
||||
use crate::{
|
||||
use ratatui_core::{
|
||||
buffer::Buffer,
|
||||
layout::{Alignment, Rect},
|
||||
style::{Style, Styled},
|
||||
symbols::border,
|
||||
text::Line,
|
||||
widgets::{Borders, Widget, WidgetRef},
|
||||
widgets::{Widget, WidgetRef},
|
||||
};
|
||||
|
||||
pub use self::{
|
||||
padding::Padding,
|
||||
title::{Position, Title},
|
||||
};
|
||||
use crate::borders::{BorderType, Borders};
|
||||
|
||||
mod padding;
|
||||
pub mod title;
|
||||
|
||||
pub use padding::Padding;
|
||||
pub use title::{Position, Title};
|
||||
|
||||
/// Base widget to be used to display a box border around all [upper level ones](crate::widgets).
|
||||
/// Base widget to be used to display a box border around all other built-in widgets.
|
||||
///
|
||||
/// The borders can be configured with [`Block::borders`] and others. A block can have multiple
|
||||
/// [`Title`] using [`Block::title`]. It can also be [styled](Block::style) and
|
||||
|
@ -132,79 +133,6 @@ pub struct Block<'a> {
|
|||
padding: Padding,
|
||||
}
|
||||
|
||||
/// The type of border of a [`Block`].
|
||||
///
|
||||
/// See the [`borders`](Block::borders) method of `Block` to configure its borders.
|
||||
#[derive(Debug, Default, Display, EnumString, Clone, Copy, Eq, PartialEq, Hash)]
|
||||
pub enum BorderType {
|
||||
/// A plain, simple border.
|
||||
///
|
||||
/// This is the default
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```plain
|
||||
/// ┌───────┐
|
||||
/// │ │
|
||||
/// └───────┘
|
||||
/// ```
|
||||
#[default]
|
||||
Plain,
|
||||
/// A plain border with rounded corners.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```plain
|
||||
/// ╭───────╮
|
||||
/// │ │
|
||||
/// ╰───────╯
|
||||
/// ```
|
||||
Rounded,
|
||||
/// A doubled border.
|
||||
///
|
||||
/// Note this uses one character that draws two lines.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```plain
|
||||
/// ╔═══════╗
|
||||
/// ║ ║
|
||||
/// ╚═══════╝
|
||||
/// ```
|
||||
Double,
|
||||
/// A thick border.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```plain
|
||||
/// ┏━━━━━━━┓
|
||||
/// ┃ ┃
|
||||
/// ┗━━━━━━━┛
|
||||
/// ```
|
||||
Thick,
|
||||
/// A border with a single line on the inside of a half block.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```plain
|
||||
/// ▗▄▄▄▄▄▄▄▖
|
||||
/// ▐ ▌
|
||||
/// ▐ ▌
|
||||
/// ▝▀▀▀▀▀▀▀▘
|
||||
QuadrantInside,
|
||||
|
||||
/// A border with a single line on the outside of a half block.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```plain
|
||||
/// ▛▀▀▀▀▀▀▀▜
|
||||
/// ▌ ▐
|
||||
/// ▌ ▐
|
||||
/// ▙▄▄▄▄▄▄▄▟
|
||||
QuadrantOutside,
|
||||
}
|
||||
|
||||
impl<'a> Block<'a> {
|
||||
/// Creates a new block with no [`Borders`] or [`Padding`].
|
||||
pub const fn new() -> Self {
|
||||
|
@ -244,8 +172,8 @@ impl<'a> Block<'a> {
|
|||
/// space is calculated based on the full width of the block, rather than the leftover width.
|
||||
///
|
||||
/// You can provide any type that can be converted into [`Title`] including: strings, string
|
||||
/// slices (`&str`), borrowed strings (`Cow<str>`), [spans](crate::text::Span), or vectors of
|
||||
/// [spans](crate::text::Span) (`Vec<Span>`).
|
||||
/// slices (`&str`), borrowed strings (`Cow<str>`), [spans](ratatui_core::text::Span), or
|
||||
/// vectors of [spans](ratatui_core::text::Span) (`Vec<Span>`).
|
||||
///
|
||||
/// By default, the titles will avoid being rendered in the corners of the block but will align
|
||||
/// against the left or right edge of the block if there is no border on that edge. The
|
||||
|
@ -319,8 +247,8 @@ impl<'a> Block<'a> {
|
|||
/// Adds a title to the top of the block.
|
||||
///
|
||||
/// You can provide any type that can be converted into [`Line`] including: strings, string
|
||||
/// slices (`&str`), borrowed strings (`Cow<str>`), [spans](crate::text::Span), or vectors of
|
||||
/// [spans](crate::text::Span) (`Vec<Span>`).
|
||||
/// slices (`&str`), borrowed strings (`Cow<str>`), [spans](ratatui_core::text::Span), or
|
||||
/// vectors of [spans](ratatui_core::text::Span) (`Vec<Span>`).
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
|
@ -348,8 +276,8 @@ impl<'a> Block<'a> {
|
|||
/// Adds a title to the bottom of the block.
|
||||
///
|
||||
/// You can provide any type that can be converted into [`Line`] including: strings, string
|
||||
/// slices (`&str`), borrowed strings (`Cow<str>`), [spans](crate::text::Span), or vectors of
|
||||
/// [spans](crate::text::Span) (`Vec<Span>`).
|
||||
/// slices (`&str`), borrowed strings (`Cow<str>`), [spans](ratatui_core::text::Span), or
|
||||
/// vectors of [spans](ratatui_core::text::Span) (`Vec<Span>`).
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
|
@ -385,7 +313,7 @@ impl<'a> Block<'a> {
|
|||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
///
|
||||
/// [`Color`]: crate::style::Color
|
||||
/// [`Color`]: ratatui_core::style::Color
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn title_style<S: Into<Style>>(mut self, style: S) -> Self {
|
||||
self.titles_style = style.into();
|
||||
|
@ -461,7 +389,7 @@ impl<'a> Block<'a> {
|
|||
/// Block::bordered().border_style(Style::new().blue());
|
||||
/// ```
|
||||
///
|
||||
/// [`Color`]: crate::style::Color
|
||||
/// [`Color`]: ratatui_core::style::Color
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn border_style<S: Into<Style>>(mut self, style: S) -> Self {
|
||||
self.border_style = style.into();
|
||||
|
@ -504,8 +432,8 @@ impl<'a> Block<'a> {
|
|||
/// .style(Style::new().white().not_bold()); // will be white, and italic
|
||||
/// ```
|
||||
///
|
||||
/// [`Paragraph`]: crate::widgets::Paragraph
|
||||
/// [`Color`]: crate::style::Color
|
||||
/// [`Paragraph`]: crate::paragraph::Paragraph
|
||||
/// [`Color`]: ratatui_core::style::Color
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn style<S: Into<Style>>(mut self, style: S) -> Self {
|
||||
self.style = style.into();
|
||||
|
@ -556,7 +484,7 @@ impl<'a> Block<'a> {
|
|||
self
|
||||
}
|
||||
|
||||
/// Sets the symbols used to display the border as a [`crate::symbols::border::Set`].
|
||||
/// Sets the symbols used to display the border as a [`ratatui_core::symbols::border::Set`].
|
||||
///
|
||||
/// Setting this overwrites any [`border_type`](Block::border_type) that was set.
|
||||
///
|
||||
|
@ -673,25 +601,6 @@ impl<'a> Block<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
impl BorderType {
|
||||
/// Convert this `BorderType` into the corresponding [`Set`](border::Set) of border symbols.
|
||||
pub const fn border_symbols(border_type: Self) -> border::Set {
|
||||
match border_type {
|
||||
Self::Plain => border::PLAIN,
|
||||
Self::Rounded => border::ROUNDED,
|
||||
Self::Double => border::DOUBLE,
|
||||
Self::Thick => border::THICK,
|
||||
Self::QuadrantInside => border::QUADRANT_INSIDE,
|
||||
Self::QuadrantOutside => border::QUADRANT_OUTSIDE,
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert this `BorderType` into the corresponding [`Set`](border::Set) of border symbols.
|
||||
pub const fn to_border_set(self) -> border::Set {
|
||||
Self::border_symbols(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Widget for Block<'_> {
|
||||
fn render(self, area: Rect, buf: &mut Buffer) {
|
||||
self.render_ref(area, buf);
|
||||
|
@ -1000,11 +909,11 @@ impl<'a> Styled for Block<'a> {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use ratatui_core::style::{Color, Modifier, Stylize};
|
||||
use rstest::rstest;
|
||||
use strum::ParseError;
|
||||
|
||||
use super::*;
|
||||
use crate::style::{Color, Modifier, Stylize};
|
||||
|
||||
#[test]
|
||||
fn create_with_all_borders() {
|
|
@ -19,8 +19,8 @@
|
|||
/// Padding::symmetric(5, 6);
|
||||
/// ```
|
||||
///
|
||||
/// [`Block`]: crate::widgets::Block
|
||||
/// [`padding`]: crate::widgets::Block::padding
|
||||
/// [`Block`]: crate::block::Block
|
||||
/// [`padding`]: crate::block::Block::padding
|
||||
/// [CSS padding]: https://developer.mozilla.org/en-US/docs/Web/CSS/padding
|
||||
#[derive(Debug, Default, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
|
||||
pub struct Padding {
|
|
@ -1,11 +1,10 @@
|
|||
//! This module holds the [`Title`] element and its related configuration types.
|
||||
//! A title is a piece of [`Block`](crate::widgets::Block) configuration.
|
||||
//! A title is a piece of [`Block`](crate::block::Block) configuration.
|
||||
|
||||
use ratatui_core::{layout::Alignment, text::Line};
|
||||
use strum::{Display, EnumString};
|
||||
|
||||
use crate::{layout::Alignment, text::Line};
|
||||
|
||||
/// A [`Block`](crate::widgets::Block) title.
|
||||
/// A [`Block`](crate::block::Block) title.
|
||||
///
|
||||
/// It can be aligned (see [`Alignment`]) and positioned (see [`Position`]).
|
||||
///
|
||||
|
@ -17,8 +16,8 @@ use crate::{layout::Alignment, text::Line};
|
|||
/// <https://github.com/ratatui/ratatui/issues/738>.
|
||||
///
|
||||
/// Use [`Line`] instead, when the position is not defined as part of the title. When a specific
|
||||
/// position is needed, use [`Block::title_top`](crate::widgets::Block::title_top) or
|
||||
/// [`Block::title_bottom`](crate::widgets::Block::title_bottom) instead.
|
||||
/// position is needed, use [`Block::title_top`](crate::block::Block::title_top) or
|
||||
/// [`Block::title_bottom`](crate::block::Block::title_bottom) instead.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
|
@ -29,14 +28,14 @@ use crate::{layout::Alignment, text::Line};
|
|||
/// Title::from("Title");
|
||||
/// ```
|
||||
///
|
||||
/// Blue title on a white background (via [`Stylize`](crate::style::Stylize) trait).
|
||||
/// Blue title on a white background (via [`Stylize`](ratatui_core::style::Stylize) trait).
|
||||
/// ```
|
||||
/// use ratatui::{style::Stylize, widgets::block::Title};
|
||||
///
|
||||
/// Title::from("Title".blue().on_white());
|
||||
/// ```
|
||||
///
|
||||
/// Title with multiple styles (see [`Line`] and [`Stylize`](crate::style::Stylize)).
|
||||
/// Title with multiple styles (see [`Line`] and [`Stylize`](ratatui_core::style::Stylize)).
|
||||
/// ```
|
||||
/// use ratatui::{style::Stylize, text::Line, widgets::block::Title};
|
||||
///
|
||||
|
@ -64,19 +63,19 @@ pub struct Title<'a> {
|
|||
/// Title alignment
|
||||
///
|
||||
/// If [`None`], defaults to the alignment defined with
|
||||
/// [`Block::title_alignment`](crate::widgets::Block::title_alignment) in the associated
|
||||
/// [`Block`](crate::widgets::Block).
|
||||
/// [`Block::title_alignment`](crate::block::Block::title_alignment) in the associated
|
||||
/// [`Block`](crate::block::Block).
|
||||
pub alignment: Option<Alignment>,
|
||||
|
||||
/// Title position
|
||||
///
|
||||
/// If [`None`], defaults to the position defined with
|
||||
/// [`Block::title_position`](crate::widgets::Block::title_position) in the associated
|
||||
/// [`Block`](crate::widgets::Block).
|
||||
/// [`Block::title_position`](crate::block::Block::title_position) in the associated
|
||||
/// [`Block`](crate::block::Block).
|
||||
pub position: Option<Position>,
|
||||
}
|
||||
|
||||
/// Defines the [title](crate::widgets::block::Title) position.
|
||||
/// Defines the [title](crate::block::Title) position.
|
||||
///
|
||||
/// The title can be positioned on top or at the bottom of the block.
|
||||
/// Defaults to [`Position::Top`].
|
|
@ -1,6 +1,9 @@
|
|||
//! Border related types ([`Borders`], [`BorderType`]) and a macro to create borders ([`border`]).
|
||||
use std::fmt;
|
||||
|
||||
use bitflags::bitflags;
|
||||
use ratatui_core::symbols::border;
|
||||
use strum::{Display, EnumString};
|
||||
|
||||
bitflags! {
|
||||
/// Bitflags that can be composed to set the visible borders essentially on the block widget.
|
||||
|
@ -21,6 +24,98 @@ bitflags! {
|
|||
}
|
||||
}
|
||||
|
||||
/// The type of border of a [`Block`](crate::block::Block).
|
||||
///
|
||||
/// See the [`borders`](crate::block::Block::borders) method of `Block` to configure its borders.
|
||||
#[derive(Debug, Default, Display, EnumString, Clone, Copy, Eq, PartialEq, Hash)]
|
||||
pub enum BorderType {
|
||||
/// A plain, simple border.
|
||||
///
|
||||
/// This is the default
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```plain
|
||||
/// ┌───────┐
|
||||
/// │ │
|
||||
/// └───────┘
|
||||
/// ```
|
||||
#[default]
|
||||
Plain,
|
||||
/// A plain border with rounded corners.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```plain
|
||||
/// ╭───────╮
|
||||
/// │ │
|
||||
/// ╰───────╯
|
||||
/// ```
|
||||
Rounded,
|
||||
/// A doubled border.
|
||||
///
|
||||
/// Note this uses one character that draws two lines.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```plain
|
||||
/// ╔═══════╗
|
||||
/// ║ ║
|
||||
/// ╚═══════╝
|
||||
/// ```
|
||||
Double,
|
||||
/// A thick border.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```plain
|
||||
/// ┏━━━━━━━┓
|
||||
/// ┃ ┃
|
||||
/// ┗━━━━━━━┛
|
||||
/// ```
|
||||
Thick,
|
||||
/// A border with a single line on the inside of a half block.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```plain
|
||||
/// ▗▄▄▄▄▄▄▄▖
|
||||
/// ▐ ▌
|
||||
/// ▐ ▌
|
||||
/// ▝▀▀▀▀▀▀▀▘
|
||||
QuadrantInside,
|
||||
|
||||
/// A border with a single line on the outside of a half block.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```plain
|
||||
/// ▛▀▀▀▀▀▀▀▜
|
||||
/// ▌ ▐
|
||||
/// ▌ ▐
|
||||
/// ▙▄▄▄▄▄▄▄▟
|
||||
QuadrantOutside,
|
||||
}
|
||||
|
||||
impl BorderType {
|
||||
/// Convert this `BorderType` into the corresponding [`Set`](border::Set) of border symbols.
|
||||
pub const fn border_symbols(border_type: Self) -> border::Set {
|
||||
match border_type {
|
||||
Self::Plain => border::PLAIN,
|
||||
Self::Rounded => border::ROUNDED,
|
||||
Self::Double => border::DOUBLE,
|
||||
Self::Thick => border::THICK,
|
||||
Self::QuadrantInside => border::QUADRANT_INSIDE,
|
||||
Self::QuadrantOutside => border::QUADRANT_OUTSIDE,
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert this `BorderType` into the corresponding [`Set`](border::Set) of border symbols.
|
||||
pub const fn to_border_set(self) -> border::Set {
|
||||
Self::border_symbols(self)
|
||||
}
|
||||
}
|
||||
|
||||
/// Implement the `Debug` trait for the `Borders` bitflags. This is a manual implementation to
|
||||
/// display the flags in a more readable way. The default implementation would display the
|
||||
/// flags as 'Border(0x0)' for `Borders::NONE` for example.
|
||||
|
@ -55,7 +150,7 @@ impl fmt::Debug for Borders {
|
|||
/// and RIGHT.
|
||||
///
|
||||
/// When used with NONE you should consider omitting this completely. For ALL you should consider
|
||||
/// [`Block::bordered()`](crate::widgets::Block::bordered) instead.
|
||||
/// [`Block::bordered()`](crate::block::Block::bordered) instead.
|
||||
///
|
||||
/// ## Examples
|
||||
///
|
||||
|
@ -87,7 +182,6 @@ impl fmt::Debug for Borders {
|
|||
/// assert_eq!(border!(ALL), Borders::ALL);
|
||||
/// assert_eq!(border!(), Borders::NONE);
|
||||
/// ```
|
||||
#[cfg(feature = "macros")]
|
||||
#[macro_export]
|
||||
macro_rules! border {
|
||||
() => {
|
||||
|
@ -124,11 +218,6 @@ mod tests {
|
|||
"TOP | BOTTOM"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(all(test, feature = "macros"))]
|
||||
mod macro_tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn can_be_const() {
|
|
@ -10,15 +10,16 @@
|
|||
//! [`Monthly`] has several controls for what should be displayed
|
||||
use std::collections::HashMap;
|
||||
|
||||
use time::{Date, Duration, OffsetDateTime};
|
||||
|
||||
use crate::{
|
||||
use ratatui_core::{
|
||||
buffer::Buffer,
|
||||
layout::{Alignment, Constraint, Layout, Rect},
|
||||
style::Style,
|
||||
text::{Line, Span},
|
||||
widgets::{block::BlockExt, Block, Widget, WidgetRef},
|
||||
widgets::{Widget, WidgetRef},
|
||||
};
|
||||
use time::{Date, Duration, OffsetDateTime};
|
||||
|
||||
use crate::block::{Block, BlockExt};
|
||||
|
||||
/// Display a month calendar for the month containing `display_date`
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
|
||||
|
@ -53,7 +54,7 @@ impl<'a, DS: DateStyler> Monthly<'a, DS> {
|
|||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
///
|
||||
/// [`Color`]: crate::style::Color
|
||||
/// [`Color`]: ratatui_core::style::Color
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn show_surrounding<S: Into<Style>>(mut self, style: S) -> Self {
|
||||
self.show_surrounding = Some(style.into());
|
||||
|
@ -65,7 +66,7 @@ impl<'a, DS: DateStyler> Monthly<'a, DS> {
|
|||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
///
|
||||
/// [`Color`]: crate::style::Color
|
||||
/// [`Color`]: ratatui_core::style::Color
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn show_weekdays_header<S: Into<Style>>(mut self, style: S) -> Self {
|
||||
self.show_weekday = Some(style.into());
|
||||
|
@ -77,7 +78,7 @@ impl<'a, DS: DateStyler> Monthly<'a, DS> {
|
|||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
///
|
||||
/// [`Color`]: crate::style::Color
|
||||
/// [`Color`]: ratatui_core::style::Color
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn show_month_header<S: Into<Style>>(mut self, style: S) -> Self {
|
||||
self.show_month = Some(style.into());
|
||||
|
@ -89,7 +90,7 @@ impl<'a, DS: DateStyler> Monthly<'a, DS> {
|
|||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
///
|
||||
/// [`Color`]: crate::style::Color
|
||||
/// [`Color`]: ratatui_core::style::Color
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn default_style<S: Into<Style>>(mut self, style: S) -> Self {
|
||||
self.default_style = style.into();
|
||||
|
@ -216,7 +217,7 @@ impl CalendarEventStore {
|
|||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
///
|
||||
/// [`Color`]: crate::style::Color
|
||||
/// [`Color`]: ratatui_core::style::Color
|
||||
pub fn today<S: Into<Style>>(style: S) -> Self {
|
||||
let mut res = Self::default();
|
||||
res.add(
|
||||
|
@ -233,7 +234,7 @@ impl CalendarEventStore {
|
|||
/// `style` accepts any type that is convertible to [`Style`] (e.g. [`Style`], [`Color`], or
|
||||
/// your own type that implements [`Into<Style>`]).
|
||||
///
|
||||
/// [`Color`]: crate::style::Color
|
||||
/// [`Color`]: ratatui_core::style::Color
|
||||
pub fn add<S: Into<Style>>(&mut self, date: Date, style: S) {
|
||||
// to simplify style nonsense, last write wins
|
||||
let _ = self.0.insert(date, style.into());
|
||||
|
@ -265,10 +266,10 @@ impl Default for CalendarEventStore {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use ratatui_core::style::Color;
|
||||
use time::Month;
|
||||
|
||||
use super::*;
|
||||
use crate::style::Color;
|
||||
|
||||
#[test]
|
||||
fn event_store() {
|
|
@ -12,16 +12,18 @@
|
|||
//! - [`Rectangle`]: A basic rectangle
|
||||
//!
|
||||
//! You can also implement your own custom [`Shape`]s.
|
||||
mod circle;
|
||||
mod line;
|
||||
mod map;
|
||||
mod points;
|
||||
mod rectangle;
|
||||
mod world;
|
||||
|
||||
use std::{fmt, iter::zip};
|
||||
|
||||
use itertools::Itertools;
|
||||
use ratatui_core::{
|
||||
buffer::Buffer,
|
||||
layout::Rect,
|
||||
style::{Color, Style},
|
||||
symbols::{self, Marker},
|
||||
text::Line as TextLine,
|
||||
widgets::{Widget, WidgetRef},
|
||||
};
|
||||
|
||||
pub use self::{
|
||||
circle::Circle,
|
||||
|
@ -30,14 +32,14 @@ pub use self::{
|
|||
points::Points,
|
||||
rectangle::Rectangle,
|
||||
};
|
||||
use crate::{
|
||||
buffer::Buffer,
|
||||
layout::Rect,
|
||||
style::{Color, Style},
|
||||
symbols::{self, Marker},
|
||||
text::Line as TextLine,
|
||||
widgets::{block::BlockExt, Block, Widget, WidgetRef},
|
||||
};
|
||||
use crate::block::{Block, BlockExt};
|
||||
|
||||
mod circle;
|
||||
mod line;
|
||||
mod map;
|
||||
mod points;
|
||||
mod rectangle;
|
||||
mod world;
|
||||
|
||||
/// Something that can be drawn on a [`Canvas`].
|
||||
///
|
||||
|
@ -437,9 +439,7 @@ impl<'a, 'b> From<&'a mut Context<'b>> for Painter<'a, 'b> {
|
|||
/// Holds the state of the [`Canvas`] when painting to it.
|
||||
///
|
||||
/// This is used by the [`Canvas`] widget to draw shapes on the grid. It can be useful to think of
|
||||
/// this as similar to the [`Frame`] struct that is used to draw widgets on the terminal.
|
||||
///
|
||||
/// [`Frame`]: crate::Frame
|
||||
/// this as similar to the `Frame` struct that is used to draw widgets on the terminal.
|
||||
#[derive(Debug)]
|
||||
pub struct Context<'a> {
|
||||
x_bounds: [f64; 2],
|
||||
|
@ -528,7 +528,7 @@ impl<'a> Context<'a> {
|
|||
/// Note that the text is always printed on top of the canvas and is **not** affected by the
|
||||
/// layers.
|
||||
///
|
||||
/// [`Text`]: crate::text::Text
|
||||
/// [`Text`]: ratatui_core::text::Text
|
||||
pub fn print<T>(&mut self, x: f64, y: f64, line: T)
|
||||
where
|
||||
T: Into<TextLine<'a>>,
|
||||
|
@ -709,10 +709,10 @@ where
|
|||
/// cell. This allows for more flexibility than the `BrailleGrid` which only supports a single
|
||||
/// foreground color for each 2x4 dots cell.
|
||||
///
|
||||
/// [`Braille`]: crate::symbols::Marker::Braille
|
||||
/// [`HalfBlock`]: crate::symbols::Marker::HalfBlock
|
||||
/// [`Dot`]: crate::symbols::Marker::Dot
|
||||
/// [`Block`]: crate::symbols::Marker::Block
|
||||
/// [`Braille`]: ratatui_core::symbols::Marker::Braille
|
||||
/// [`HalfBlock`]: ratatui_core::symbols::Marker::HalfBlock
|
||||
/// [`Dot`]: ratatui_core::symbols::Marker::Dot
|
||||
/// [`Block`]: ratatui_core::symbols::Marker::Block
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -828,9 +828,9 @@ where
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use indoc::indoc;
|
||||
use ratatui_core::buffer::Cell;
|
||||
|
||||
use super::*;
|
||||
use crate::buffer::Cell;
|
||||
|
||||
// helper to test the canvas checks that drawing a vertical and horizontal line
|
||||
// results in the expected output
|
|
@ -1,7 +1,6 @@
|
|||
use crate::{
|
||||
style::Color,
|
||||
widgets::canvas::{Painter, Shape},
|
||||
};
|
||||
use ratatui_core::style::Color;
|
||||
|
||||
use crate::canvas::{Painter, Shape};
|
||||
|
||||
/// A circle with a given center and radius and with a given color
|
||||
#[derive(Debug, Default, Clone, PartialEq)]
|
||||
|
@ -31,17 +30,12 @@ impl Shape for Circle {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::{
|
||||
buffer::Buffer,
|
||||
layout::Rect,
|
||||
style::Color,
|
||||
symbols::Marker,
|
||||
widgets::{
|
||||
canvas::{Canvas, Circle},
|
||||
Widget,
|
||||
},
|
||||
use ratatui_core::{
|
||||
buffer::Buffer, layout::Rect, style::Color, symbols::Marker, widgets::Widget,
|
||||
};
|
||||
|
||||
use crate::canvas::{Canvas, Circle};
|
||||
|
||||
#[test]
|
||||
fn test_it_draws_a_circle() {
|
||||
let mut buffer = Buffer::empty(Rect::new(0, 0, 10, 5));
|
|
@ -1,7 +1,6 @@
|
|||
use crate::{
|
||||
style::Color,
|
||||
widgets::canvas::{Painter, Shape},
|
||||
};
|
||||
use ratatui_core::style::Color;
|
||||
|
||||
use crate::canvas::{Painter, Shape};
|
||||
|
||||
/// A line from `(x1, y1)` to `(x2, y2)` with the given color
|
||||
#[derive(Debug, Default, Clone, PartialEq)]
|
||||
|
@ -112,16 +111,17 @@ fn draw_line_high(painter: &mut Painter, x1: usize, y1: usize, x2: usize, y2: us
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use rstest::rstest;
|
||||
|
||||
use super::*;
|
||||
use crate::{
|
||||
use ratatui_core::{
|
||||
buffer::Buffer,
|
||||
layout::Rect,
|
||||
style::{Style, Stylize},
|
||||
symbols::Marker,
|
||||
widgets::{canvas::Canvas, Widget},
|
||||
widgets::Widget,
|
||||
};
|
||||
use rstest::rstest;
|
||||
|
||||
use super::*;
|
||||
use crate::canvas::Canvas;
|
||||
|
||||
#[rstest]
|
||||
#[case::off_grid(&Line::new(-1.0, -1.0, 10.0, 10.0, Color::Red), [" "; 10])]
|
||||
|
@ -207,7 +207,7 @@ mod tests {
|
|||
fn tests<'expected_line, ExpectedLines>(#[case] line: &Line, #[case] expected: ExpectedLines)
|
||||
where
|
||||
ExpectedLines: IntoIterator,
|
||||
ExpectedLines::Item: Into<crate::text::Line<'expected_line>>,
|
||||
ExpectedLines::Item: Into<ratatui_core::text::Line<'expected_line>>,
|
||||
{
|
||||
let mut buffer = Buffer::empty(Rect::new(0, 0, 10, 10));
|
||||
let canvas = Canvas::default()
|
|
@ -1,11 +1,9 @@
|
|||
use ratatui_core::style::Color;
|
||||
use strum::{Display, EnumString};
|
||||
|
||||
use crate::{
|
||||
style::Color,
|
||||
widgets::canvas::{
|
||||
world::{WORLD_HIGH_RESOLUTION, WORLD_LOW_RESOLUTION},
|
||||
Painter, Shape,
|
||||
},
|
||||
use crate::canvas::{
|
||||
world::{WORLD_HIGH_RESOLUTION, WORLD_LOW_RESOLUTION},
|
||||
Painter, Shape,
|
||||
};
|
||||
|
||||
/// Defines how many points are going to be used to draw a [`Map`].
|
||||
|
@ -22,7 +20,7 @@ pub enum MapResolution {
|
|||
///
|
||||
/// Contains about 5000 points, you likely want to use [`Marker::Braille`] with this.
|
||||
///
|
||||
/// [`Marker::Braille`]: (crate::symbols::Marker::Braille)
|
||||
/// [`Marker::Braille`]: (ratatui_core::symbols::Marker::Braille)
|
||||
High,
|
||||
}
|
||||
|
||||
|
@ -62,15 +60,11 @@ impl Shape for Map {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use ratatui_core::{buffer::Buffer, layout::Rect, symbols::Marker, widgets::Widget};
|
||||
use strum::ParseError;
|
||||
|
||||
use super::*;
|
||||
use crate::{
|
||||
buffer::Buffer,
|
||||
layout::Rect,
|
||||
symbols::Marker,
|
||||
widgets::{canvas::Canvas, Widget},
|
||||
};
|
||||
use crate::canvas::Canvas;
|
||||
|
||||
#[test]
|
||||
fn map_resolution_to_string() {
|
|
@ -1,7 +1,6 @@
|
|||
use crate::{
|
||||
style::Color,
|
||||
widgets::canvas::{Painter, Shape},
|
||||
};
|
||||
use ratatui_core::style::Color;
|
||||
|
||||
use crate::canvas::{Painter, Shape};
|
||||
|
||||
/// A group of points with a given color
|
||||
#[derive(Debug, Default, Clone, PartialEq)]
|
|
@ -1,9 +1,8 @@
|
|||
use crate::{
|
||||
style::Color,
|
||||
widgets::canvas::{Line, Painter, Shape},
|
||||
};
|
||||
use ratatui_core::style::Color;
|
||||
|
||||
/// A rectangle to draw on a [`Canvas`](crate::widgets::canvas::Canvas)
|
||||
use crate::canvas::{Line, Painter, Shape};
|
||||
|
||||
/// A rectangle to draw on a [`Canvas`](crate::canvas::Canvas)
|
||||
///
|
||||
/// Sizes used here are **not** in terminal cell. This is much more similar to the
|
||||
/// mathematic coordinate system.
|
||||
|
@ -65,15 +64,17 @@ impl Shape for Rectangle {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::{
|
||||
use ratatui_core::{
|
||||
buffer::Buffer,
|
||||
layout::{Margin, Rect},
|
||||
style::{Style, Stylize},
|
||||
symbols::Marker,
|
||||
widgets::{canvas::Canvas, Widget},
|
||||
widgets::Widget,
|
||||
};
|
||||
|
||||
use super::*;
|
||||
use crate::canvas::Canvas;
|
||||
|
||||
#[test]
|
||||
fn draw_block_lines() {
|
||||
let mut buffer = Buffer::empty(Rect::new(0, 0, 10, 10));
|
|
@ -1,18 +1,19 @@
|
|||
//! The [`Chart`] widget is used to plot one or more [`Dataset`] in a cartesian coordinate system.
|
||||
use std::{cmp::max, ops::Not};
|
||||
|
||||
use strum::{Display, EnumString};
|
||||
|
||||
use crate::{
|
||||
use ratatui_core::{
|
||||
buffer::Buffer,
|
||||
layout::{Alignment, Constraint, Flex, Layout, Position, Rect},
|
||||
style::{Color, Style, Styled},
|
||||
symbols::{self},
|
||||
text::Line,
|
||||
widgets::{
|
||||
block::BlockExt,
|
||||
canvas::{Canvas, Line as CanvasLine, Points},
|
||||
Block, Widget, WidgetRef,
|
||||
},
|
||||
widgets::{Widget, WidgetRef},
|
||||
};
|
||||
use strum::{Display, EnumString};
|
||||
|
||||
use crate::{
|
||||
block::{Block, BlockExt},
|
||||
canvas::{Canvas, Line as CanvasLine, Points},
|
||||
};
|
||||
|
||||
/// An X or Y axis for the [`Chart`] widget
|
||||
|
@ -126,8 +127,8 @@ impl<'a> Axis<'a> {
|
|||
///
|
||||
/// # Example
|
||||
///
|
||||
/// [`Axis`] also implements [`Stylize`](crate::style::Stylize) which mean you can style it
|
||||
/// like so
|
||||
/// [`Axis`] also implements [`Stylize`](ratatui_core::style::Stylize) which mean you can style
|
||||
/// it like so
|
||||
///
|
||||
/// ```rust
|
||||
/// use ratatui::{style::Stylize, widgets::Axis};
|
||||
|
@ -410,8 +411,8 @@ impl<'a> Dataset<'a> {
|
|||
///
|
||||
/// # Example
|
||||
///
|
||||
/// [`Dataset`] also implements [`Stylize`](crate::style::Stylize) which mean you can style it
|
||||
/// like so
|
||||
/// [`Dataset`] also implements [`Stylize`](ratatui_core::style::Stylize) which mean you can
|
||||
/// style it like so
|
||||
///
|
||||
/// ```rust
|
||||
/// use ratatui::{style::Stylize, widgets::Dataset};
|
||||
|
@ -1157,11 +1158,11 @@ impl<'a> Styled for Chart<'a> {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use ratatui_core::style::{Modifier, Stylize};
|
||||
use rstest::rstest;
|
||||
use strum::ParseError;
|
||||
|
||||
use super::*;
|
||||
use crate::style::{Modifier, Stylize};
|
||||
|
||||
struct LegendTestCase {
|
||||
chart_area: Rect,
|
|
@ -1,4 +1,5 @@
|
|||
use crate::{
|
||||
//! The [`Clear`] widget allows you to clear a certain area to allow overdrawing (e.g. for popups).
|
||||
use ratatui_core::{
|
||||
buffer::Buffer,
|
||||
layout::Rect,
|
||||
widgets::{Widget, WidgetRef},
|
||||
|
@ -7,7 +8,7 @@ use crate::{
|
|||
/// A widget to clear/reset a certain area to allow overdrawing (e.g. for popups).
|
||||
///
|
||||
/// This widget **cannot be used to clear the terminal on the first render** as `ratatui` assumes
|
||||
/// the render area is empty. Use [`crate::Terminal::clear`] instead.
|
||||
/// the render area is empty. Use `Terminal::clear` instead.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
@ -50,8 +51,10 @@ impl WidgetRef for Clear {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use ratatui_core::{buffer::Buffer, layout::Rect, widgets::Widget};
|
||||
|
||||
use super::*;
|
||||
use crate::{buffer::Buffer, layout::Rect, widgets::Widget};
|
||||
|
||||
#[test]
|
||||
fn render() {
|
||||
let mut buffer = Buffer::with_lines(["xxxxxxxxxxxxxxx"; 7]);
|
|
@ -1,12 +1,15 @@
|
|||
use crate::{
|
||||
//! The [`Gauge`] widget is used to display a horizontal progress bar.
|
||||
use ratatui_core::{
|
||||
buffer::Buffer,
|
||||
layout::Rect,
|
||||
style::{Color, Style, Styled},
|
||||
symbols::{self},
|
||||
text::{Line, Span},
|
||||
widgets::{block::BlockExt, Block, Widget, WidgetRef},
|
||||
widgets::{Widget, WidgetRef},
|
||||
};
|
||||
|
||||
use crate::block::{Block, BlockExt};
|
||||
|
||||
/// A widget to display a progress bar.
|
||||
///
|
||||
/// A `Gauge` renders a bar filled according to the value given to [`Gauge::percent`] or
|
||||
|
@ -446,11 +449,13 @@ impl<'a> Styled for LineGauge<'a> {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::{
|
||||
use ratatui_core::{
|
||||
style::{Color, Modifier, Style, Stylize},
|
||||
symbols,
|
||||
};
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
#[should_panic = "Percentage should be between 0 and 100 inclusively"]
|
||||
fn gauge_invalid_percentage() {
|
89
ratatui-widgets/src/lib.rs
Normal file
89
ratatui-widgets/src/lib.rs
Normal file
|
@ -0,0 +1,89 @@
|
|||
#![warn(missing_docs)]
|
||||
//! Ratatui-widgets contains all the widgets that were previously part of the Ratatui crate. It is
|
||||
//! meant to be used in conjunction with the [Ratatui] crate, which provides the core functionality
|
||||
//! for building terminal user interfaces.
|
||||
//!
|
||||
//! [Ratatui]: https://crates.io/crates/ratatui
|
||||
//!
|
||||
//! Most applications shouldn't need to depend directly on Ratatui-widgets, as all the Ratatui crate
|
||||
//! re-exports all the widgets from this crate. However, if you are building a widget library that
|
||||
//! internally uses Ratatui widgets, or if you prefer finer grained dependencies, you may want to
|
||||
//! depend on this crate rather than transitively through the Ratatui crate.
|
||||
//!
|
||||
//! Previously, a crate named `Ratatui-widgets` was published with some formative ideas about an
|
||||
//! eventual Ratatui framework. That crate is now move to [tui-framework-experiment], pending a new
|
||||
//! name.
|
||||
//!
|
||||
//! [tui-framework-experiment]: https://crates.io/crates/tui-framework-experiment
|
||||
//!
|
||||
//! # Installation
|
||||
//!
|
||||
//! Run the following command to add this crate to your project:
|
||||
//!
|
||||
//! ```sh
|
||||
//! cargo add ratatui-widgets
|
||||
//! ```
|
||||
//!
|
||||
//! # Available Widgets
|
||||
//!
|
||||
//! - [`BarChart`]: displays multiple datasets as bars with optional grouping.
|
||||
//! - [`Block`]: a basic widget that draws a block with optional borders, titles, and styles.
|
||||
//! - [`calendar::Monthly`]: displays a single month.
|
||||
//! - [`Canvas`]: draws arbitrary shapes using drawing characters.
|
||||
//! - [`Chart`]: displays multiple datasets as lines or scatter graphs.
|
||||
//! - [`Clear`]: clears the area it occupies. Useful to render over previously drawn widgets.
|
||||
//! - [`Gauge`]: displays progress percentage using block characters.
|
||||
//! - [`LineGauge`]: displays progress as a line.
|
||||
//! - [`List`]: displays a list of items and allows selection.
|
||||
//! - [`RatatuiLogo`]: displays the Ratatui logo.
|
||||
//! - [`Paragraph`]: displays a paragraph of optionally styled and wrapped text.
|
||||
//! - [`Scrollbar`]: displays a scrollbar.
|
||||
//! - [`Sparkline`]: displays a single dataset as a sparkline.
|
||||
//! - [`Table`]: displays multiple rows and columns in a grid and allows selection.
|
||||
//! - [`Tabs`]: displays a tab bar and allows selection.
|
||||
//!
|
||||
//! [`BarChart`]: crate::barchart::BarChart
|
||||
//! [`Block`]: crate::block::Block
|
||||
//! [`calendar::Monthly`]: crate::calendar::Monthly
|
||||
//! [`Canvas`]: crate::canvas::Canvas
|
||||
//! [`Chart`]: crate::chart::Chart
|
||||
//! [`Clear`]: crate::clear::Clear
|
||||
//! [`Gauge`]: crate::gauge::Gauge
|
||||
//! [`LineGauge`]: crate::gauge::LineGauge
|
||||
//! [`List`]: crate::list::List
|
||||
//! [`RatatuiLogo`]: crate::logo::RatatuiLogo
|
||||
//! [`Paragraph`]: crate::paragraph::Paragraph
|
||||
//! [`Scrollbar`]: crate::scrollbar::Scrollbar
|
||||
//! [`Sparkline`]: crate::sparkline::Sparkline
|
||||
//! [`Table`]: crate::table::Table
|
||||
//! [`Tabs`]: crate::tabs::Tabs
|
||||
//!
|
||||
//! All these widgets are re-exported directly under `ratatui::widgets` in the Ratatui crate.
|
||||
//!
|
||||
//! # Contributing
|
||||
//!
|
||||
//! Contributions are welcome! Please open an issue or submit a pull request on GitHub. For more
|
||||
//! details on contributing, please see the [CONTRIBUTING](CONTRIBUTING.md) document.
|
||||
//!
|
||||
//! # License
|
||||
//!
|
||||
//! This project is licensed under the MIT License. See the [LICENSE](../LICENSE) file for details.
|
||||
pub mod barchart;
|
||||
pub mod block;
|
||||
pub mod borders;
|
||||
pub mod canvas;
|
||||
pub mod chart;
|
||||
pub mod clear;
|
||||
pub mod gauge;
|
||||
pub mod list;
|
||||
pub mod logo;
|
||||
pub mod paragraph;
|
||||
pub mod scrollbar;
|
||||
pub mod sparkline;
|
||||
pub mod table;
|
||||
pub mod tabs;
|
||||
|
||||
mod reflow;
|
||||
|
||||
#[cfg(feature = "calendar")]
|
||||
pub mod calendar;
|
|
@ -1,9 +1,14 @@
|
|||
//! The [`List`] widget is used to display a list of items and allows selecting one or multiple
|
||||
//! items.
|
||||
use ratatui_core::style::{Style, Styled};
|
||||
use strum::{Display, EnumString};
|
||||
|
||||
use crate::{
|
||||
style::{Style, Styled},
|
||||
widgets::{Block, HighlightSpacing, ListItem},
|
||||
};
|
||||
pub use self::{item::ListItem, state::ListState};
|
||||
use crate::{block::Block, table::HighlightSpacing};
|
||||
|
||||
mod item;
|
||||
mod rendering;
|
||||
mod state;
|
||||
|
||||
/// A widget to display several items among which one can be selected (optional)
|
||||
///
|
||||
|
@ -13,13 +18,10 @@ use crate::{
|
|||
/// the item's height is automatically determined. A `List` can also be put in reverse order (i.e.
|
||||
/// *bottom to top*) whereas a [`Table`] cannot.
|
||||
///
|
||||
/// [`Table`]: crate::widgets::Table
|
||||
/// [`Table`]: crate::table::Table
|
||||
///
|
||||
/// List items can be aligned using [`Text::alignment`], for more details see [`ListItem`].
|
||||
///
|
||||
/// [`List`] implements [`Widget`] and so it can be drawn using
|
||||
/// [`Frame::render_widget`](crate::terminal::Frame::render_widget).
|
||||
///
|
||||
/// [`List`] is also a [`StatefulWidget`], which means you can use it with [`ListState`] to allow
|
||||
/// the user to [scroll] through items and [select] one of them.
|
||||
///
|
||||
|
@ -95,12 +97,12 @@ use crate::{
|
|||
/// (0..5).map(|i| format!("Item{i}")).collect::<List>();
|
||||
/// ```
|
||||
///
|
||||
/// [`ListState`]: crate::widgets::list::ListState
|
||||
/// [scroll]: crate::widgets::list::ListState::offset
|
||||
/// [select]: crate::widgets::list::ListState::select
|
||||
/// [`Text::alignment`]: crate::text::Text::alignment
|
||||
/// [`StatefulWidget`]: crate::widgets::StatefulWidget
|
||||
/// [`Widget`]: crate::widgets::Widget
|
||||
/// [`ListState`]: crate::list::ListState
|
||||
/// [scroll]: crate::list::ListState::offset
|
||||
/// [select]: crate::list::ListState::select
|
||||
/// [`Text::alignment`]: ratatui_core::text::Text::alignment
|
||||
/// [`StatefulWidget`]: ratatui_core::widgets::StatefulWidget
|
||||
/// [`Widget`]: ratatui_core::widgets::Widget
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Hash, Default)]
|
||||
pub struct List<'a> {
|
||||
/// An optional block to wrap the widget in
|
||||
|
@ -178,7 +180,7 @@ impl<'a> List<'a> {
|
|||
/// let filled_list = empty_list.items(["Item 1"]);
|
||||
/// ```
|
||||
///
|
||||
/// [`Text`]: crate::text::Text
|
||||
/// [`Text`]: ratatui_core::text::Text
|
||||
pub fn new<T>(items: T) -> Self
|
||||
where
|
||||
T: IntoIterator,
|
||||
|
@ -208,7 +210,7 @@ impl<'a> List<'a> {
|
|||
/// let list = List::default().items(["Item 1", "Item 2"]);
|
||||
/// ```
|
||||
///
|
||||
/// [`Text`]: crate::text::Text
|
||||
/// [`Text`]: ratatui_core::text::Text
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn items<T>(mut self, items: T) -> Self
|
||||
where
|
||||
|
@ -265,7 +267,7 @@ impl<'a> List<'a> {
|
|||
/// `List` also implements the [`Styled`] trait, which means you can use style shorthands from
|
||||
/// the [`Stylize`] trait to set the style of the widget more concisely.
|
||||
///
|
||||
/// [`Stylize`]: crate::style::Stylize
|
||||
/// [`Stylize`]: ratatui_core::style::Stylize
|
||||
///
|
||||
/// ```rust
|
||||
/// use ratatui::{style::Stylize, widgets::List};
|
||||
|
@ -274,7 +276,7 @@ impl<'a> List<'a> {
|
|||
/// let list = List::new(items).red().italic();
|
||||
/// ```
|
||||
///
|
||||
/// [`Color`]: crate::style::Color
|
||||
/// [`Color`]: ratatui_core::style::Color
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn style<S: Into<Style>>(mut self, style: S) -> Self {
|
||||
self.style = style.into();
|
||||
|
@ -324,7 +326,7 @@ impl<'a> List<'a> {
|
|||
/// let list = List::new(items).highlight_style(Style::new().red().italic());
|
||||
/// ```
|
||||
///
|
||||
/// [`Color`]: crate::style::Color
|
||||
/// [`Color`]: ratatui_core::style::Color
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn highlight_style<S: Into<Style>>(mut self, style: S) -> Self {
|
||||
self.highlight_style = style.into();
|
||||
|
@ -464,9 +466,9 @@ where
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use pretty_assertions::assert_eq;
|
||||
use ratatui_core::style::{Color, Modifier, Stylize};
|
||||
|
||||
use super::*;
|
||||
use crate::style::{Color, Modifier, Stylize};
|
||||
|
||||
#[test]
|
||||
fn collect_list_from_iterator() {
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{style::Style, text::Text};
|
||||
use ratatui_core::{style::Style, text::Text};
|
||||
|
||||
/// A single item in a [`List`]
|
||||
///
|
||||
|
@ -63,10 +63,10 @@ use crate::{style::Style, text::Text};
|
|||
/// ListItem::new(Text::from("foo").right_aligned());
|
||||
/// ```
|
||||
///
|
||||
/// [`List`]: crate::widgets::List
|
||||
/// [`Stylize`]: crate::style::Stylize
|
||||
/// [`Line`]: crate::text::Line
|
||||
/// [`Line::alignment`]: crate::text::Line::alignment
|
||||
/// [`List`]: crate::list::List
|
||||
/// [`Stylize`]: ratatui_core::style::Stylize
|
||||
/// [`Line`]: ratatui_core::text::Line
|
||||
/// [`Line::alignment`]: ratatui_core::text::Line::alignment
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
|
||||
pub struct ListItem<'a> {
|
||||
pub(crate) content: Text<'a>,
|
||||
|
@ -107,8 +107,8 @@ impl<'a> ListItem<'a> {
|
|||
///
|
||||
/// # See also
|
||||
///
|
||||
/// - [`List::new`](crate::widgets::List::new) to create a list of items that can be converted
|
||||
/// to [`ListItem`]
|
||||
/// - [`List::new`](super::List::new) to create a list of items that can be converted to
|
||||
/// [`ListItem`]
|
||||
pub fn new<T>(content: T) -> Self
|
||||
where
|
||||
T: Into<Text<'a>>,
|
||||
|
@ -140,7 +140,7 @@ impl<'a> ListItem<'a> {
|
|||
/// ```
|
||||
///
|
||||
/// `ListItem` also implements the [`Styled`] trait, which means you can use style shorthands
|
||||
/// from the [`Stylize`](crate::style::Stylize) trait to set the style of the widget more
|
||||
/// from the [`Stylize`](ratatui_core::style::Stylize) trait to set the style of the widget more
|
||||
/// concisely.
|
||||
///
|
||||
/// ```rust
|
||||
|
@ -149,9 +149,9 @@ impl<'a> ListItem<'a> {
|
|||
/// let item = ListItem::new("Item 1").red().italic();
|
||||
/// ```
|
||||
///
|
||||
/// [`Styled`]: crate::style::Styled
|
||||
/// [`ListState`]: crate::widgets::list::ListState
|
||||
/// [`Color`]: crate::style::Color
|
||||
/// [`Styled`]: ratatui_core::style::Styled
|
||||
/// [`ListState`]: crate::list::ListState
|
||||
/// [`Color`]: ratatui_core::style::Color
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn style<S: Into<Style>>(mut self, style: S) -> Self {
|
||||
self.style = style.into();
|
||||
|
@ -219,13 +219,13 @@ mod tests {
|
|||
use std::borrow::Cow;
|
||||
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
use super::*;
|
||||
use crate::{
|
||||
use ratatui_core::{
|
||||
style::{Color, Modifier, Stylize},
|
||||
text::{Line, Span},
|
||||
};
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn new_from_str() {
|
||||
let item = ListItem::new("Test item");
|
|
@ -1,12 +1,13 @@
|
|||
use ratatui_core::{
|
||||
buffer::Buffer,
|
||||
layout::Rect,
|
||||
widgets::{StatefulWidget, StatefulWidgetRef, Widget, WidgetRef},
|
||||
};
|
||||
use unicode_width::UnicodeWidthStr;
|
||||
|
||||
use crate::{
|
||||
buffer::Buffer,
|
||||
layout::Rect,
|
||||
widgets::{
|
||||
block::BlockExt, List, ListDirection, ListState, StatefulWidget, StatefulWidgetRef, Widget,
|
||||
WidgetRef,
|
||||
},
|
||||
block::BlockExt,
|
||||
list::{List, ListDirection, ListState},
|
||||
};
|
||||
|
||||
impl Widget for List<'_> {
|
||||
|
@ -273,17 +274,16 @@ impl List<'_> {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use pretty_assertions::assert_eq;
|
||||
use rstest::{fixture, rstest};
|
||||
|
||||
use super::*;
|
||||
use crate::{
|
||||
backend,
|
||||
use ratatui_core::{
|
||||
layout::{Alignment, Rect},
|
||||
style::{Color, Modifier, Style, Stylize},
|
||||
text::Line,
|
||||
widgets::{Block, HighlightSpacing, ListItem, StatefulWidget, Widget},
|
||||
Terminal,
|
||||
widgets::{StatefulWidget, Widget},
|
||||
};
|
||||
use rstest::{fixture, rstest};
|
||||
|
||||
use super::*;
|
||||
use crate::{block::Block, list::ListItem, table::HighlightSpacing};
|
||||
|
||||
#[fixture]
|
||||
fn single_line_buf() -> Buffer {
|
||||
|
@ -1148,8 +1148,7 @@ mod tests {
|
|||
Lines: IntoIterator,
|
||||
Lines::Item: Into<Line<'line>>,
|
||||
{
|
||||
let backend = backend::TestBackend::new(10, render_height);
|
||||
let mut terminal = Terminal::new(backend).unwrap();
|
||||
let mut buffer = Buffer::empty(Rect::new(0, 0, 10, render_height));
|
||||
let mut state = ListState::default();
|
||||
|
||||
*state.offset_mut() = offset;
|
||||
|
@ -1158,10 +1157,8 @@ mod tests {
|
|||
let list = List::new(["Item 0", "Item 1", "Item 2", "Item 3", "Item 4", "Item 5"])
|
||||
.scroll_padding(padding)
|
||||
.highlight_symbol(">> ");
|
||||
terminal
|
||||
.draw(|f| f.render_stateful_widget(list, f.area(), &mut state))
|
||||
.unwrap();
|
||||
terminal.backend().assert_buffer_lines(expected);
|
||||
StatefulWidget::render(list, buffer.area, &mut buffer, &mut state);
|
||||
assert_eq!(buffer, Buffer::with_lines(expected));
|
||||
}
|
||||
|
||||
/// If there isn't enough room for the selected item and the requested padding the list can jump
|
||||
|
@ -1169,8 +1166,7 @@ mod tests {
|
|||
/// isn't currently happening
|
||||
#[test]
|
||||
fn padding_flicker() {
|
||||
let backend = backend::TestBackend::new(10, 5);
|
||||
let mut terminal = Terminal::new(backend).unwrap();
|
||||
let mut buffer = Buffer::empty(Rect::new(0, 0, 10, 5));
|
||||
let mut state = ListState::default();
|
||||
|
||||
*state.offset_mut() = 2;
|
||||
|
@ -1181,15 +1177,11 @@ mod tests {
|
|||
];
|
||||
let list = List::new(items).scroll_padding(3).highlight_symbol(">> ");
|
||||
|
||||
terminal
|
||||
.draw(|f| f.render_stateful_widget(&list, f.area(), &mut state))
|
||||
.unwrap();
|
||||
StatefulWidget::render(&list, buffer.area, &mut buffer, &mut state);
|
||||
|
||||
let offset_after_render = state.offset();
|
||||
|
||||
terminal
|
||||
.draw(|f| f.render_stateful_widget(&list, f.area(), &mut state))
|
||||
.unwrap();
|
||||
StatefulWidget::render(&list, buffer.area, &mut buffer, &mut state);
|
||||
|
||||
// Offset after rendering twice should remain the same as after once
|
||||
assert_eq!(offset_after_render, state.offset());
|
||||
|
@ -1197,8 +1189,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn padding_inconsistent_item_sizes() {
|
||||
let backend = backend::TestBackend::new(10, 3);
|
||||
let mut terminal = Terminal::new(backend).unwrap();
|
||||
let mut buffer = Buffer::empty(Rect::new(0, 0, 10, 3));
|
||||
let mut state = ListState::default().with_offset(0).with_selected(Some(3));
|
||||
|
||||
let items = [
|
||||
|
@ -1211,9 +1202,7 @@ mod tests {
|
|||
];
|
||||
let list = List::new(items).scroll_padding(1).highlight_symbol(">> ");
|
||||
|
||||
terminal
|
||||
.draw(|f| f.render_stateful_widget(list, f.area(), &mut state))
|
||||
.unwrap();
|
||||
StatefulWidget::render(list, buffer.area, &mut buffer, &mut state);
|
||||
|
||||
#[rustfmt::skip]
|
||||
let expected = [
|
||||
|
@ -1221,15 +1210,14 @@ mod tests {
|
|||
" Item 2 ",
|
||||
">> Item 3 ",
|
||||
];
|
||||
terminal.backend().assert_buffer_lines(expected);
|
||||
assert_eq!(buffer, Buffer::with_lines(expected));
|
||||
}
|
||||
|
||||
// Tests to make sure when it's pushing back the first visible index value that it doesnt
|
||||
// include an item that's too large
|
||||
#[test]
|
||||
fn padding_offset_pushback_break() {
|
||||
let backend = backend::TestBackend::new(10, 4);
|
||||
let mut terminal = Terminal::new(backend).unwrap();
|
||||
let mut buffer = Buffer::empty(Rect::new(0, 0, 10, 4));
|
||||
let mut state = ListState::default();
|
||||
|
||||
*state.offset_mut() = 1;
|
||||
|
@ -1243,16 +1231,16 @@ mod tests {
|
|||
];
|
||||
let list = List::new(items).scroll_padding(2).highlight_symbol(">> ");
|
||||
|
||||
terminal
|
||||
.draw(|f| f.render_stateful_widget(list, f.area(), &mut state))
|
||||
.unwrap();
|
||||
|
||||
terminal.backend().assert_buffer_lines([
|
||||
" Item 1 ",
|
||||
">> Item 2 ",
|
||||
" Item 3 ",
|
||||
" ",
|
||||
]);
|
||||
StatefulWidget::render(list, buffer.area, &mut buffer, &mut state);
|
||||
#[rustfmt::skip]
|
||||
assert_eq!(
|
||||
buffer,
|
||||
Buffer::with_lines([
|
||||
" Item 1 ",
|
||||
">> Item 2 ",
|
||||
" Item 3 ",
|
||||
" "])
|
||||
);
|
||||
}
|
||||
|
||||
/// Regression test for a bug where highlight symbol being greater than width caused a panic due
|
|
@ -3,7 +3,7 @@
|
|||
/// This state can be used to scroll through items and select one. When the list is rendered as a
|
||||
/// stateful widget, the selected item will be highlighted and the list will be shifted to ensure
|
||||
/// that the selected item is visible. This will modify the [`ListState`] object passed to the
|
||||
/// [`Frame::render_stateful_widget`](crate::terminal::Frame::render_stateful_widget) method.
|
||||
/// `Frame::render_stateful_widget` method.
|
||||
///
|
||||
/// The state consists of two fields:
|
||||
/// - [`offset`]: the index of the first item to be displayed
|
||||
|
@ -41,7 +41,7 @@
|
|||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// [`List`]: crate::widgets::List
|
||||
/// [`List`]: super::List
|
||||
#[derive(Debug, Default, Clone, Eq, PartialEq, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
pub struct ListState {
|
||||
|
@ -276,7 +276,7 @@ impl ListState {
|
|||
mod tests {
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
use crate::widgets::ListState;
|
||||
use crate::list::ListState;
|
||||
|
||||
#[test]
|
||||
fn selected() {
|
|
@ -1,6 +1,6 @@
|
|||
//! The [`RatatuiLogo`] widget renders the Ratatui logo.
|
||||
use indoc::indoc;
|
||||
|
||||
use crate::{buffer::Buffer, layout::Rect, text::Text, widgets::Widget};
|
||||
use ratatui_core::{buffer::Buffer, layout::Rect, text::Text, widgets::Widget};
|
||||
|
||||
/// A widget that renders the Ratatui logo
|
||||
///
|
|
@ -1,15 +1,17 @@
|
|||
use unicode_width::UnicodeWidthStr;
|
||||
|
||||
use crate::{
|
||||
//! The [`Paragraph`] widget and related types allows displaying a block of text with optional
|
||||
//! wrapping, alignment, and block styling.
|
||||
use ratatui_core::{
|
||||
buffer::Buffer,
|
||||
layout::{Alignment, Position, Rect},
|
||||
style::{Style, Styled},
|
||||
text::{Line, StyledGrapheme, Text},
|
||||
widgets::{
|
||||
block::BlockExt,
|
||||
reflow::{LineComposer, LineTruncator, WordWrapper, WrappedLine},
|
||||
Block, Widget, WidgetRef,
|
||||
},
|
||||
widgets::{Widget, WidgetRef},
|
||||
};
|
||||
use unicode_width::UnicodeWidthStr;
|
||||
|
||||
use crate::{
|
||||
block::{Block, BlockExt},
|
||||
reflow::{LineComposer, LineTruncator, WordWrapper, WrappedLine},
|
||||
};
|
||||
|
||||
const fn get_line_offset(line_width: u16, text_area_width: u16, alignment: Alignment) -> u16 {
|
||||
|
@ -84,7 +86,7 @@ const fn get_line_offset(line_width: u16, text_area_width: u16, alignment: Align
|
|||
/// .wrap(Wrap { trim: true });
|
||||
/// ```
|
||||
///
|
||||
/// [`Span`]: crate::text::Span
|
||||
/// [`Span`]: ratatui_core::text::Span
|
||||
#[derive(Debug, Default, Clone, Eq, PartialEq, Hash)]
|
||||
pub struct Paragraph<'a> {
|
||||
/// A block to wrap the widget in
|
||||
|
@ -211,7 +213,7 @@ impl<'a> Paragraph<'a> {
|
|||
/// let paragraph = Paragraph::new("Hello, world!").style(Style::new().red().on_white());
|
||||
/// ```
|
||||
///
|
||||
/// [`Color`]: crate::style::Color
|
||||
/// [`Color`]: ratatui_core::style::Color
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn style<S: Into<Style>>(mut self, style: S) -> Self {
|
||||
self.style = style.into();
|
||||
|
@ -500,30 +502,27 @@ impl<'a> Styled for Paragraph<'a> {
|
|||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use crate::{
|
||||
backend::TestBackend,
|
||||
mod tests {
|
||||
use ratatui_core::{
|
||||
buffer::Buffer,
|
||||
layout::{Alignment, Rect},
|
||||
style::{Color, Modifier, Style, Stylize},
|
||||
text::{Line, Span, Text},
|
||||
widgets::{block::Position, Borders, Widget},
|
||||
Terminal,
|
||||
widgets::Widget,
|
||||
};
|
||||
|
||||
use super::*;
|
||||
use crate::{block::Position, borders::Borders};
|
||||
|
||||
/// Tests the [`Paragraph`] widget against the expected [`Buffer`] by rendering it onto an equal
|
||||
/// area and comparing the rendered and expected content.
|
||||
/// This can be used for easy testing of varying configured paragraphs with the same expected
|
||||
/// buffer or any other test case really.
|
||||
#[track_caller]
|
||||
fn test_case(paragraph: &Paragraph, expected: &Buffer) {
|
||||
let backend = TestBackend::new(expected.area.width, expected.area.height);
|
||||
let mut terminal = Terminal::new(backend).unwrap();
|
||||
terminal
|
||||
.draw(|f| f.render_widget(paragraph.clone(), f.area()))
|
||||
.unwrap();
|
||||
terminal.backend().assert_buffer(expected);
|
||||
let mut buffer = Buffer::empty(Rect::new(0, 0, expected.area.width, expected.area.height));
|
||||
paragraph.render(buffer.area, &mut buffer);
|
||||
assert_eq!(buffer, *expected);
|
||||
}
|
||||
|
||||
#[test]
|
|
@ -1,10 +1,10 @@
|
|||
//! Internal module for reflowing text to fit into a certain width.
|
||||
use std::{collections::VecDeque, mem};
|
||||
|
||||
use ratatui_core::{layout::Alignment, text::StyledGrapheme};
|
||||
use unicode_segmentation::UnicodeSegmentation;
|
||||
use unicode_width::UnicodeWidthStr;
|
||||
|
||||
use crate::{layout::Alignment, text::StyledGrapheme};
|
||||
|
||||
/// A state machine to pack styled symbols into lines.
|
||||
/// Cannot implement it as Iterator since it yields slices of the internal buffer (need streaming
|
||||
/// iterators for that).
|
||||
|
@ -12,6 +12,7 @@ pub trait LineComposer<'a> {
|
|||
fn next_line<'lend>(&'lend mut self) -> Option<WrappedLine<'lend, 'a>>;
|
||||
}
|
||||
|
||||
/// A line that has been wrapped to a certain width.
|
||||
pub struct WrappedLine<'lend, 'text> {
|
||||
/// One line reflowed to the correct width
|
||||
pub line: &'lend [StyledGrapheme<'text>],
|
||||
|
@ -51,6 +52,7 @@ where
|
|||
O: Iterator<Item = (I, Alignment)>,
|
||||
I: Iterator<Item = StyledGrapheme<'a>>,
|
||||
{
|
||||
/// Create a new `WordWrapper` with the given lines and maximum line width.
|
||||
pub const fn new(lines: O, max_line_width: u16, trim: bool) -> Self {
|
||||
Self {
|
||||
input_lines: lines,
|
||||
|
@ -250,6 +252,7 @@ where
|
|||
O: Iterator<Item = (I, Alignment)>,
|
||||
I: Iterator<Item = StyledGrapheme<'a>>,
|
||||
{
|
||||
/// Create a new `LineTruncator` with the given lines and maximum line width.
|
||||
pub const fn new(lines: O, max_line_width: u16) -> Self {
|
||||
Self {
|
||||
input_lines: lines,
|
||||
|
@ -259,6 +262,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
/// Set the horizontal offset to skip render.
|
||||
pub fn set_horizontal_offset(&mut self, horizontal_offset: u16) {
|
||||
self.horizontal_offset = horizontal_offset;
|
||||
}
|
||||
|
@ -343,13 +347,14 @@ fn trim_offset(src: &str, mut offset: usize) -> &str {
|
|||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use crate::{
|
||||
mod tests {
|
||||
use ratatui_core::{
|
||||
style::Style,
|
||||
text::{Line, Text},
|
||||
};
|
||||
|
||||
use super::*;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
enum Composer {
|
||||
WordWrapper { trim: bool },
|
|
@ -1,3 +1,4 @@
|
|||
//! The [`Scrollbar`] widget is used to display a scrollbar alongside other widgets.
|
||||
#![warn(clippy::pedantic)]
|
||||
#![allow(
|
||||
clippy::cast_possible_truncation,
|
||||
|
@ -8,16 +9,15 @@
|
|||
|
||||
use std::iter;
|
||||
|
||||
use strum::{Display, EnumString};
|
||||
use unicode_width::UnicodeWidthStr;
|
||||
|
||||
use crate::{
|
||||
use ratatui_core::{
|
||||
buffer::Buffer,
|
||||
layout::Rect,
|
||||
style::Style,
|
||||
symbols::scrollbar::{Set, DOUBLE_HORIZONTAL, DOUBLE_VERTICAL},
|
||||
widgets::StatefulWidget,
|
||||
};
|
||||
use strum::{Display, EnumString};
|
||||
use unicode_width::UnicodeWidthStr;
|
||||
|
||||
/// A widget to display a scrollbar
|
||||
///
|
||||
|
@ -266,7 +266,7 @@ impl<'a> Scrollbar<'a> {
|
|||
///
|
||||
/// This is a fluent setter method which must be chained or used as it consumes self
|
||||
///
|
||||
/// [`Color`]: crate::style::Color
|
||||
/// [`Color`]: ratatui_core::style::Color
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn thumb_style<S: Into<Style>>(mut self, thumb_style: S) -> Self {
|
||||
self.thumb_style = thumb_style.into();
|
||||
|
@ -293,7 +293,7 @@ impl<'a> Scrollbar<'a> {
|
|||
///
|
||||
/// This is a fluent setter method which must be chained or used as it consumes self
|
||||
///
|
||||
/// [`Color`]: crate::style::Color
|
||||
/// [`Color`]: ratatui_core::style::Color
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn track_style<S: Into<Style>>(mut self, track_style: S) -> Self {
|
||||
self.track_style = track_style.into();
|
||||
|
@ -320,7 +320,7 @@ impl<'a> Scrollbar<'a> {
|
|||
///
|
||||
/// This is a fluent setter method which must be chained or used as it consumes self
|
||||
///
|
||||
/// [`Color`]: crate::style::Color
|
||||
/// [`Color`]: ratatui_core::style::Color
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn begin_style<S: Into<Style>>(mut self, begin_style: S) -> Self {
|
||||
self.begin_style = begin_style.into();
|
||||
|
@ -347,7 +347,7 @@ impl<'a> Scrollbar<'a> {
|
|||
///
|
||||
/// This is a fluent setter method which must be chained or used as it consumes self
|
||||
///
|
||||
/// [`Color`]: crate::style::Color
|
||||
/// [`Color`]: ratatui_core::style::Color
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn end_style<S: Into<Style>>(mut self, end_style: S) -> Self {
|
||||
self.end_style = end_style.into();
|
||||
|
@ -402,7 +402,7 @@ impl<'a> Scrollbar<'a> {
|
|||
///
|
||||
/// This is a fluent setter method which must be chained or used as it consumes self
|
||||
///
|
||||
/// [`Color`]: crate::style::Color
|
||||
/// [`Color`]: ratatui_core::style::Color
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn style<S: Into<Style>>(mut self, style: S) -> Self {
|
||||
let style = style.into();
|
||||
|
@ -638,11 +638,11 @@ impl ScrollbarOrientation {
|
|||
mod tests {
|
||||
use std::str::FromStr;
|
||||
|
||||
use ratatui_core::{text::Text, widgets::Widget};
|
||||
use rstest::{fixture, rstest};
|
||||
use strum::ParseError;
|
||||
|
||||
use super::*;
|
||||
use crate::{text::Text, widgets::Widget};
|
||||
|
||||
#[test]
|
||||
fn scroll_direction_to_string() {
|
|
@ -1,14 +1,16 @@
|
|||
//! The [`Sparkline`] widget is used to display a sparkline over one or more lines.
|
||||
use std::cmp::min;
|
||||
|
||||
use strum::{Display, EnumString};
|
||||
|
||||
use crate::{
|
||||
use ratatui_core::{
|
||||
buffer::Buffer,
|
||||
layout::Rect,
|
||||
style::{Style, Styled},
|
||||
symbols::{self},
|
||||
widgets::{block::BlockExt, Block, Widget, WidgetRef},
|
||||
widgets::{Widget, WidgetRef},
|
||||
};
|
||||
use strum::{Display, EnumString};
|
||||
|
||||
use crate::block::{Block, BlockExt};
|
||||
|
||||
/// Widget to render a sparkline over one or more lines.
|
||||
///
|
||||
|
@ -22,8 +24,8 @@ use crate::{
|
|||
/// of `None` is interpreted an as the _absence_ of a value.
|
||||
///
|
||||
/// `Sparkline` can be styled either using [`Sparkline::style`] or preferably using the methods
|
||||
/// provided by the [`Stylize`](crate::style::Stylize) trait. The style may be set for the entire
|
||||
/// widget or for individual bars by setting individual [`SparklineBar::style`].
|
||||
/// provided by the [`Stylize`](ratatui_core::style::Stylize) trait. The style may be set for the
|
||||
/// entire widget or for individual bars by setting individual [`SparklineBar::style`].
|
||||
///
|
||||
/// The bars are rendered using a set of symbols. The default set is [`symbols::bar::NINE_LEVELS`].
|
||||
/// You can change the set using [`Sparkline::bar_set`].
|
||||
|
@ -109,7 +111,7 @@ impl<'a> Sparkline<'a> {
|
|||
///
|
||||
/// The foreground corresponds to the bars while the background is everything else.
|
||||
///
|
||||
/// [`Color`]: crate::style::Color
|
||||
/// [`Color`]: ratatui_core::style::Color
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn style<S: Into<Style>>(mut self, style: S) -> Self {
|
||||
self.style = style.into();
|
||||
|
@ -125,7 +127,7 @@ impl<'a> Sparkline<'a> {
|
|||
///
|
||||
/// The foreground corresponds to the bars while the background is everything else.
|
||||
///
|
||||
/// [`Color`]: crate::style::Color
|
||||
/// [`Color`]: ratatui_core::style::Color
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn absent_value_style<S: Into<Style>>(mut self, style: S) -> Self {
|
||||
self.absent_value_style = style.into();
|
||||
|
@ -269,7 +271,7 @@ impl SparklineBar {
|
|||
/// style. If set, the style of the bar will be the style of the sparkline combined with
|
||||
/// the style of the bar.
|
||||
///
|
||||
/// [`Color`]: crate::style::Color
|
||||
/// [`Color`]: ratatui_core::style::Color
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn style<S: Into<Option<Style>>>(mut self, style: S) -> Self {
|
||||
self.style = style.into();
|
||||
|
@ -434,13 +436,13 @@ impl Sparkline<'_> {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use strum::ParseError;
|
||||
|
||||
use super::*;
|
||||
use crate::{
|
||||
use ratatui_core::{
|
||||
buffer::Cell,
|
||||
style::{Color, Modifier, Stylize},
|
||||
};
|
||||
use strum::ParseError;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn render_direction_to_string() {
|
|
@ -1,19 +1,23 @@
|
|||
use itertools::Itertools;
|
||||
//! The [`Table`] widget is used to display multiple rows and columns in a grid and allows selecting
|
||||
//! one or multiple cells.
|
||||
|
||||
#[allow(unused_imports)] // `Cell` is used in the doc comment but not the code
|
||||
use crate::widgets::table::Cell;
|
||||
use crate::{
|
||||
use itertools::Itertools;
|
||||
use ratatui_core::{
|
||||
buffer::Buffer,
|
||||
layout::{Constraint, Flex, Layout, Rect},
|
||||
style::{Style, Styled},
|
||||
text::Text,
|
||||
widgets::{
|
||||
block::BlockExt,
|
||||
table::{HighlightSpacing, Row, TableState},
|
||||
Block, StatefulWidget, StatefulWidgetRef, Widget, WidgetRef,
|
||||
},
|
||||
widgets::{StatefulWidget, StatefulWidgetRef, Widget, WidgetRef},
|
||||
};
|
||||
|
||||
pub use self::{cell::Cell, highlight_spacing::HighlightSpacing, row::Row, state::TableState};
|
||||
use crate::block::{Block, BlockExt};
|
||||
|
||||
mod cell;
|
||||
mod highlight_spacing;
|
||||
mod row;
|
||||
mod state;
|
||||
|
||||
/// A widget to display data in formatted columns.
|
||||
///
|
||||
/// A `Table` is a collection of [`Row`]s, each composed of [`Cell`]s:
|
||||
|
@ -26,7 +30,7 @@ use crate::{
|
|||
/// Make sure to call the [`Table::widths`] method, otherwise the columns will all have a width of 0
|
||||
/// and thus not be visible.
|
||||
///
|
||||
/// [`Table`] implements [`Widget`] and so it can be drawn using [`Frame::render_widget`].
|
||||
/// [`Table`] implements [`Widget`] and so it can be drawn using `Frame::render_widget`.
|
||||
///
|
||||
/// [`Table`] is also a [`StatefulWidget`], which means you can use it with [`TableState`] to allow
|
||||
/// the user to scroll through the rows and select one of them. When rendering a [`Table`] with a
|
||||
|
@ -232,8 +236,7 @@ use crate::{
|
|||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// [`Frame::render_widget`]: crate::Frame::render_widget
|
||||
/// [`Stylize`]: crate::style::Stylize
|
||||
/// [`Stylize`]: ratatui_core::style::Stylize
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
|
||||
pub struct Table<'a> {
|
||||
/// Data to display in each row
|
||||
|
@ -543,8 +546,8 @@ impl<'a> Table<'a> {
|
|||
/// let table = Table::new(rows, widths).red().italic();
|
||||
/// ```
|
||||
///
|
||||
/// [`Color`]: crate::style::Color
|
||||
/// [`Stylize`]: crate::style::Stylize
|
||||
/// [`Color`]: ratatui_core::style::Color
|
||||
/// [`Stylize`]: ratatui_core::style::Stylize
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn style<S: Into<Style>>(mut self, style: S) -> Self {
|
||||
self.style = style.into();
|
||||
|
@ -575,7 +578,7 @@ impl<'a> Table<'a> {
|
|||
/// let table = Table::new(rows, widths).highlight_style(Style::new().red().italic());
|
||||
/// ```
|
||||
///
|
||||
/// [`Color`]: crate::style::Color
|
||||
/// [`Color`]: ratatui_core::style::Color
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
#[deprecated(note = "use `Table::row_highlight_style` instead")]
|
||||
pub fn highlight_style<S: Into<Style>>(self, highlight_style: S) -> Self {
|
||||
|
@ -600,7 +603,7 @@ impl<'a> Table<'a> {
|
|||
/// # let widths = [Constraint::Length(5), Constraint::Length(5)];
|
||||
/// let table = Table::new(rows, widths).row_highlight_style(Style::new().red().italic());
|
||||
/// ```
|
||||
/// [`Color`]: crate::style::Color
|
||||
/// [`Color`]: ratatui_core::style::Color
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn row_highlight_style<S: Into<Style>>(mut self, highlight_style: S) -> Self {
|
||||
self.row_highlight_style = highlight_style.into();
|
||||
|
@ -625,7 +628,7 @@ impl<'a> Table<'a> {
|
|||
/// # let widths = [Constraint::Length(5), Constraint::Length(5)];
|
||||
/// let table = Table::new(rows, widths).column_highlight_style(Style::new().red().italic());
|
||||
/// ```
|
||||
/// [`Color`]: crate::style::Color
|
||||
/// [`Color`]: ratatui_core::style::Color
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn column_highlight_style<S: Into<Style>>(mut self, highlight_style: S) -> Self {
|
||||
self.column_highlight_style = highlight_style.into();
|
||||
|
@ -650,7 +653,7 @@ impl<'a> Table<'a> {
|
|||
/// # let widths = [Constraint::Length(5), Constraint::Length(5)];
|
||||
/// let table = Table::new(rows, widths).cell_highlight_style(Style::new().red().italic());
|
||||
/// ```
|
||||
/// [`Color`]: crate::style::Color
|
||||
/// [`Color`]: ratatui_core::style::Color
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn cell_highlight_style<S: Into<Style>>(mut self, highlight_style: S) -> Self {
|
||||
self.cell_highlight_style = highlight_style.into();
|
||||
|
@ -1085,15 +1088,15 @@ where
|
|||
mod tests {
|
||||
use std::vec;
|
||||
|
||||
use rstest::{fixture, rstest};
|
||||
|
||||
use super::*;
|
||||
use crate::{
|
||||
use ratatui_core::{
|
||||
layout::Constraint::*,
|
||||
style::{Color, Modifier, Style, Stylize},
|
||||
text::Line,
|
||||
widgets::Cell,
|
||||
};
|
||||
use rstest::{fixture, rstest};
|
||||
|
||||
use super::*;
|
||||
use crate::table::Cell;
|
||||
|
||||
#[test]
|
||||
fn new() {
|
||||
|
@ -1278,14 +1281,15 @@ mod tests {
|
|||
|
||||
#[cfg(test)]
|
||||
mod state {
|
||||
|
||||
use super::*;
|
||||
use crate::{
|
||||
use ratatui_core::{
|
||||
buffer::Buffer,
|
||||
layout::{Constraint, Rect},
|
||||
widgets::{Row, StatefulWidget, Table, TableState},
|
||||
widgets::StatefulWidget,
|
||||
};
|
||||
|
||||
use super::*;
|
||||
use crate::table::{Row, Table, TableState};
|
||||
|
||||
#[fixture]
|
||||
fn table_buf() -> Buffer {
|
||||
Buffer::empty(Rect::new(0, 0, 10, 10))
|
||||
|
@ -1358,8 +1362,9 @@ mod tests {
|
|||
|
||||
#[cfg(test)]
|
||||
mod render {
|
||||
use ratatui_core::layout::Alignment;
|
||||
|
||||
use super::*;
|
||||
use crate::layout::Alignment;
|
||||
|
||||
#[test]
|
||||
fn render_empty_area() {
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{
|
||||
use ratatui_core::{
|
||||
buffer::Buffer,
|
||||
layout::Rect,
|
||||
style::{Style, Styled},
|
||||
|
@ -47,9 +47,9 @@ use crate::{
|
|||
/// Cell::new("Cell 1").red().italic();
|
||||
/// ```
|
||||
///
|
||||
/// [`Row`]: crate::widgets::Row
|
||||
/// [`Table`]: crate::widgets::Table
|
||||
/// [`Stylize`]: crate::style::Stylize
|
||||
/// [`Row`]: super::Row
|
||||
/// [`Table`]: super::Table
|
||||
/// [`Stylize`]: ratatui_core::style::Stylize
|
||||
#[derive(Debug, Default, Clone, Eq, PartialEq, Hash)]
|
||||
pub struct Cell<'a> {
|
||||
content: Text<'a>,
|
||||
|
@ -150,9 +150,9 @@ impl<'a> Cell<'a> {
|
|||
/// Cell::new("Cell 1").red().italic();
|
||||
/// ```
|
||||
///
|
||||
/// [`Row`]: crate::widgets::Row
|
||||
/// [`Color`]: crate::style::Color
|
||||
/// [`Stylize`]: crate::style::Stylize
|
||||
/// [`Row`]: super::Row
|
||||
/// [`Color`]: ratatui_core::style::Color
|
||||
/// [`Stylize`]: ratatui_core::style::Stylize
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn style<S: Into<Style>>(mut self, style: S) -> Self {
|
||||
self.style = style.into();
|
||||
|
@ -193,8 +193,9 @@ impl<'a> Styled for Cell<'a> {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use ratatui_core::style::{Color, Modifier, Stylize};
|
||||
|
||||
use super::*;
|
||||
use crate::style::{Color, Modifier, Stylize};
|
||||
|
||||
#[test]
|
||||
fn new() {
|
|
@ -1,7 +1,6 @@
|
|||
use crate::{
|
||||
style::{Style, Styled},
|
||||
widgets::table::Cell,
|
||||
};
|
||||
use ratatui_core::style::{Style, Styled};
|
||||
|
||||
use super::Cell;
|
||||
|
||||
/// A single row of data to be displayed in a [`Table`] widget.
|
||||
///
|
||||
|
@ -68,9 +67,9 @@ use crate::{
|
|||
/// Row::new(cells).red().italic();
|
||||
/// ```
|
||||
///
|
||||
/// [`Table`]: crate::widgets::Table
|
||||
/// [`Text`]: crate::text::Text
|
||||
/// [`Stylize`]: crate::style::Stylize
|
||||
/// [`Table`]: super::Table
|
||||
/// [`Text`]: ratatui_core::text::Text
|
||||
/// [`Stylize`]: ratatui_core::style::Stylize
|
||||
#[derive(Debug, Default, Clone, Eq, PartialEq, Hash)]
|
||||
pub struct Row<'a> {
|
||||
pub(crate) cells: Vec<Cell<'a>>,
|
||||
|
@ -232,9 +231,9 @@ impl<'a> Row<'a> {
|
|||
/// let row = Row::new(cells).red().italic();
|
||||
/// ```
|
||||
///
|
||||
/// [`Color`]: crate::style::Color
|
||||
/// [`Stylize`]: crate::style::Stylize
|
||||
/// [`Text`]: crate::text::Text
|
||||
/// [`Color`]: ratatui_core::style::Color
|
||||
/// [`Stylize`]: ratatui_core::style::Stylize
|
||||
/// [`Text`]: ratatui_core::text::Text
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn style<S: Into<Style>>(mut self, style: S) -> Self {
|
||||
self.style = style.into();
|
||||
|
@ -277,8 +276,9 @@ where
|
|||
mod tests {
|
||||
use std::vec;
|
||||
|
||||
use ratatui_core::style::{Color, Modifier, Stylize};
|
||||
|
||||
use super::*;
|
||||
use crate::style::{Color, Modifier, Stylize};
|
||||
|
||||
#[test]
|
||||
fn new() {
|
|
@ -3,7 +3,7 @@
|
|||
/// This state can be used to scroll through the rows and select one of them. When the table is
|
||||
/// rendered as a stateful widget, the selected row, column and cell will be highlighted and the
|
||||
/// table will be shifted to ensure that the selected row is visible. This will modify the
|
||||
/// [`TableState`] object passed to the [`Frame::render_stateful_widget`] method.
|
||||
/// [`TableState`] object passed to the `Frame::render_stateful_widget` method.
|
||||
///
|
||||
/// The state consists of two fields:
|
||||
/// - [`offset`]: the index of the first row to be displayed
|
||||
|
@ -50,9 +50,8 @@
|
|||
/// Note that if [`Table::widths`] is not called before rendering, the rendered columns will have
|
||||
/// equal width.
|
||||
///
|
||||
/// [`Table`]: crate::widgets::Table
|
||||
/// [`Table::widths`]: crate::widgets::Table::widths
|
||||
/// [`Frame::render_stateful_widget`]: crate::Frame::render_stateful_widget
|
||||
/// [`Table`]: super::Table
|
||||
/// [`Table::widths`]: crate::table::Table::widths
|
||||
#[derive(Debug, Default, Clone, Eq, PartialEq, Hash)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
|
||||
pub struct TableState {
|
|
@ -1,14 +1,16 @@
|
|||
//! The [`Tabs`] widget displays a horizontal set of tabs with a single tab selected.
|
||||
use itertools::Itertools;
|
||||
|
||||
use crate::{
|
||||
use ratatui_core::{
|
||||
buffer::Buffer,
|
||||
layout::Rect,
|
||||
style::{Modifier, Style, Styled},
|
||||
symbols::{self},
|
||||
text::{Line, Span},
|
||||
widgets::{block::BlockExt, Block, Widget, WidgetRef},
|
||||
widgets::{Widget, WidgetRef},
|
||||
};
|
||||
|
||||
use crate::block::{Block, BlockExt};
|
||||
|
||||
const DEFAULT_HIGHLIGHT_STYLE: Style = Style::new().add_modifier(Modifier::REVERSED);
|
||||
|
||||
/// A widget that displays a horizontal set of Tabs with a single tab selected.
|
||||
|
@ -228,7 +230,7 @@ impl<'a> Tabs<'a> {
|
|||
/// More precise style can be applied to the titles by styling the ones given to [`Tabs::new`].
|
||||
/// The selected tab can be styled differently using [`Tabs::highlight_style`].
|
||||
///
|
||||
/// [`Color`]: crate::style::Color
|
||||
/// [`Color`]: ratatui_core::style::Color
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
pub fn style<S: Into<Style>>(mut self, style: S) -> Self {
|
||||
self.style = style.into();
|
||||
|
@ -243,7 +245,7 @@ impl<'a> Tabs<'a> {
|
|||
/// Highlighted tab can be selected with [`Tabs::select`].
|
||||
#[must_use = "method moves the value of self and returns the modified value"]
|
||||
///
|
||||
/// [`Color`]: crate::style::Color
|
||||
/// [`Color`]: ratatui_core::style::Color
|
||||
pub fn highlight_style<S: Into<Style>>(mut self, style: S) -> Self {
|
||||
self.highlight_style = style.into();
|
||||
self
|
||||
|
@ -443,8 +445,9 @@ where
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use ratatui_core::style::{Color, Stylize};
|
||||
|
||||
use super::*;
|
||||
use crate::style::{Color, Stylize};
|
||||
|
||||
#[test]
|
||||
fn new() {
|
|
@ -15,7 +15,6 @@ edition.workspace = true
|
|||
rust-version.workspace = true
|
||||
|
||||
[dependencies]
|
||||
bitflags.workspace = true
|
||||
crossterm = { version = "0.28.1", optional = true }
|
||||
document-features = { version = "0.2.7", optional = true }
|
||||
indoc = "2"
|
||||
|
@ -23,11 +22,11 @@ instability.workspace = true
|
|||
itertools.workspace = true
|
||||
palette = { version = "0.7.6", optional = true }
|
||||
ratatui-core = { workspace = true, features = ["unstable-widget-ref"] }
|
||||
ratatui-widgets = { workspace = true, features = ["unstable-widget-ref"] }
|
||||
serde = { workspace = true, optional = true }
|
||||
strum.workspace = true
|
||||
termwiz = { version = "0.22.0", optional = true }
|
||||
time = { version = "0.3.11", optional = true, features = ["local-offset"] }
|
||||
unicode-segmentation.workspace = true
|
||||
# See <https://github.com/ratatui/ratatui/issues/1271> for information about why we pin unicode-width
|
||||
unicode-width.workspace = true
|
||||
|
||||
|
@ -120,10 +119,7 @@ termwiz = ["dep:termwiz"]
|
|||
#! The following optional features are available for all backends:
|
||||
## enables serialization and deserialization of style and color types using the [`serde`] crate.
|
||||
## This is useful if you want to save themes to a file.
|
||||
serde = ["dep:serde", "ratatui-core/serde"]
|
||||
|
||||
## enables the [`border!`] macro.
|
||||
macros = []
|
||||
serde = ["dep:serde", "ratatui-core/serde", "ratatui-widgets/serde"]
|
||||
|
||||
## enables conversions from colors in the [`palette`] crate to [`Color`](crate::style::Color).
|
||||
palette = ["ratatui-core/palette", "dep:palette"]
|
||||
|
@ -138,7 +134,7 @@ all-widgets = ["widget-calendar"]
|
|||
#! Widgets that add dependencies are gated behind feature flags to prevent unused transitive
|
||||
#! dependencies. The available features are:
|
||||
## enables the [`calendar`](widgets::calendar) widget module and adds a dependency on [`time`].
|
||||
widget-calendar = ["dep:time"]
|
||||
widget-calendar = ["ratatui-widgets/calendar"]
|
||||
|
||||
#! The following optional features are only available for some backends:
|
||||
|
||||
|
@ -160,7 +156,7 @@ unstable = [
|
|||
## [`Paragraph::line_width`](widgets::Paragraph::line_width) methods
|
||||
## which are experimental and may change in the future.
|
||||
## See [Issue 293](https://github.com/ratatui/ratatui/issues/293) for more details.
|
||||
unstable-rendered-line-info = []
|
||||
unstable-rendered-line-info = ["ratatui-widgets/unstable-rendered-line-info"]
|
||||
|
||||
## enables the [`WidgetRef`] and [`StatefulWidgetRef`] traits which are experimental and may change
|
||||
## in the future.
|
||||
|
|
|
@ -350,3 +350,4 @@ pub use ratatui_core::{style, symbols};
|
|||
mod terminal;
|
||||
pub use ratatui_core::text;
|
||||
pub mod widgets;
|
||||
pub use ratatui_widgets::border;
|
||||
|
|
|
@ -1,8 +1,14 @@
|
|||
#![warn(missing_docs)]
|
||||
//! `widgets` is a collection of types that implement [`Widget`] or [`StatefulWidget`] or both.
|
||||
//!
|
||||
//! Widgets are created for each frame as they are consumed after rendered.
|
||||
//! They are not meant to be stored but used as *commands* to draw common figures in the UI.
|
||||
//! The widgets provided with Ratatui are implemented in the [`ratatui_widgets`] crate, and are
|
||||
//! re-exported here. The [`Widget`] and [`StatefulWidget`] traits are implemented in the
|
||||
//! [`ratatui_core`] crate and are also re-exported in this module. This means that you can use
|
||||
//! these types directly from the `ratatui` crate without having to import the `ratatui_widgets`
|
||||
//! crate.
|
||||
//!
|
||||
//! Widgets are created for each frame as they are consumed after rendered. They are not meant to be
|
||||
//! stored but used as *commands* to draw common figures in the UI.
|
||||
//!
|
||||
//! The available widgets are:
|
||||
//! - [`Block`]: a basic widget that draws a block with optional borders, titles and styles.
|
||||
|
@ -21,32 +27,19 @@
|
|||
//! - [`Tabs`]: displays a tab bar and allows selection.
|
||||
//!
|
||||
//! [`Canvas`]: crate::widgets::canvas::Canvas
|
||||
mod barchart;
|
||||
pub mod block;
|
||||
mod borders;
|
||||
#[cfg(feature = "widget-calendar")]
|
||||
pub mod calendar;
|
||||
pub mod canvas;
|
||||
mod chart;
|
||||
mod clear;
|
||||
mod gauge;
|
||||
mod list;
|
||||
mod logo;
|
||||
mod paragraph;
|
||||
mod reflow;
|
||||
mod scrollbar;
|
||||
mod sparkline;
|
||||
mod table;
|
||||
mod tabs;
|
||||
|
||||
pub use ratatui_core::widgets::{StatefulWidget, Widget};
|
||||
#[instability::unstable(feature = "widget-ref")]
|
||||
pub use ratatui_core::widgets::{StatefulWidgetRef, WidgetRef};
|
||||
|
||||
pub use self::{
|
||||
// TODO remove this module once title etc. are gone
|
||||
pub use ratatui_widgets::block;
|
||||
#[cfg(feature = "widget-calendar")]
|
||||
pub use ratatui_widgets::calendar;
|
||||
pub use ratatui_widgets::{
|
||||
barchart::{Bar, BarChart, BarGroup},
|
||||
block::{Block, BorderType, Padding},
|
||||
borders::*,
|
||||
block::{Block, Padding},
|
||||
borders::{BorderType, Borders},
|
||||
canvas,
|
||||
chart::{Axis, Chart, Dataset, GraphType, LegendPosition},
|
||||
clear::Clear,
|
||||
gauge::{Gauge, LineGauge},
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
pub use self::{
|
||||
item::ListItem,
|
||||
list::{List, ListDirection},
|
||||
state::ListState,
|
||||
};
|
||||
|
||||
mod item;
|
||||
mod list;
|
||||
mod rendering;
|
||||
mod state;
|
|
@ -1,11 +0,0 @@
|
|||
mod cell;
|
||||
mod highlight_spacing;
|
||||
mod row;
|
||||
mod table;
|
||||
mod table_state;
|
||||
|
||||
pub use cell::*;
|
||||
pub use highlight_spacing::*;
|
||||
pub use row::*;
|
||||
pub use table::*;
|
||||
pub use table_state::*;
|
Loading…
Reference in a new issue