feat!: implement stylize methods directly on Style (#1572)
This makes it possible to create constants using the shorthand methods. ```rust const MY_STYLE: Style = Style::new().blue().on_black(); ``` Rather than implementing Styled for Style and then adding extension methods that implement the Stylize shorthands, this implements the methods as const functions directly on Style. BREAKING CHANGE: `Style` no longer implements `Styled`. Any calls to methods implemented by the blanket implementation of Stylize are now defined directly on Style. Remove the Stylize import if it is no longer used by your code. The `reset()` method does not have a direct replacement, as it clashes with the existing `reset()` method. Use `Style::reset()` rather than `some_style.reset()` Fixes: #1158
This commit is contained in:
@@ -10,7 +10,7 @@ GitHub with a [breaking change] label.
|
||||
|
||||
This is a quick summary of the sections below:
|
||||
|
||||
- [Unreleased](#unreleased)
|
||||
- [v0.30.0 Unreleased](#v0300-unreleased)
|
||||
- The `From` impls for backend types are now replaced with more specific traits
|
||||
- `FrameExt` trait for `unstable-widget-ref` feature
|
||||
- `List::highlight_symbol` now accepts `Into<Line>` instead of `&str`
|
||||
@@ -83,7 +83,28 @@ This is a quick summary of the sections below:
|
||||
- MSRV is now 1.63.0
|
||||
- `List` no longer ignores empty strings
|
||||
|
||||
## Unreleased (0.30.0)
|
||||
## v0.30.0 Unreleased
|
||||
|
||||
### `Style` no longer implements `Styled` ([#1572])
|
||||
|
||||
[#1572]: https://github.com/ratatui/ratatui/pull/1572
|
||||
|
||||
Any calls to methods implemented by the blanket implementation of `Stylize` are now defined directly
|
||||
on `Style`. Remove the `Stylize` import if it is no longer used by your code.
|
||||
|
||||
```diff
|
||||
- use ratatui::style::Stylize;
|
||||
|
||||
let style = Style::new().red();
|
||||
```
|
||||
|
||||
The `reset()` method does not have a direct replacement, as it clashes with the existing `reset()`
|
||||
method. Use the `Style::reset()` method instead.
|
||||
|
||||
```diff
|
||||
- some_style.reset();
|
||||
+ Style::reset();
|
||||
```
|
||||
|
||||
### Disabling `default-features` suppresses the error message if `show_cursor()` fails when dropping `Terminal` ([#1794])
|
||||
|
||||
@@ -101,8 +122,6 @@ enabled feature flags.
|
||||
|
||||
### Disabling `default-features` will now disable layout cache, which can have a negative impact on performance ([#1795])
|
||||
|
||||
[#1795]: https://github.com/ratatui/ratatui/pull/1795
|
||||
|
||||
Layout cache is now opt-in in `ratatui-core` and enabled by default in `ratatui`. If app doesn't
|
||||
make use of `no_std`-compatibility, and disables `default-feature`, it is recommended to explicitly
|
||||
re-enable layout cache. Not doing so may impact performance.
|
||||
|
||||
@@ -202,7 +202,7 @@ fn title_block(title: String) -> Block<'static> {
|
||||
.borders(Borders::TOP)
|
||||
.title_alignment(Alignment::Center)
|
||||
.border_style(Style::new().dark_gray())
|
||||
.title_style(Style::new().reset())
|
||||
.title_style(Style::reset())
|
||||
.title(title)
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ use itertools::Itertools;
|
||||
use palette::Okhsv;
|
||||
use ratatui::buffer::Buffer;
|
||||
use ratatui::layout::{Constraint, Direction, Layout, Margin, Rect};
|
||||
use ratatui::style::{Color, Style, Stylize};
|
||||
use ratatui::style::{Color, Style};
|
||||
use ratatui::symbols;
|
||||
use ratatui::widgets::calendar::{CalendarEventStore, Monthly};
|
||||
use ratatui::widgets::{Bar, BarChart, BarGroup, Block, Clear, LineGauge, Padding, Widget};
|
||||
|
||||
@@ -81,6 +81,7 @@ mod color;
|
||||
pub mod palette;
|
||||
#[cfg(feature = "palette")]
|
||||
mod palette_conversion;
|
||||
#[macro_use]
|
||||
mod stylize;
|
||||
|
||||
bitflags! {
|
||||
@@ -259,18 +260,6 @@ impl fmt::Debug for Style {
|
||||
}
|
||||
}
|
||||
|
||||
impl Styled for Style {
|
||||
type Item = Self;
|
||||
|
||||
fn style(&self) -> Style {
|
||||
*self
|
||||
}
|
||||
|
||||
fn set_style<S: Into<Self>>(self, style: S) -> Self::Item {
|
||||
self.patch(style)
|
||||
}
|
||||
}
|
||||
|
||||
impl Style {
|
||||
/// Returns a `Style` with default properties.
|
||||
pub const fn new() -> Self {
|
||||
@@ -493,6 +482,33 @@ impl Style {
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
color!(pub const Color::Black, black(), on_black() -> Self);
|
||||
color!(pub const Color::Red, red(), on_red() -> Self);
|
||||
color!(pub const Color::Green, green(), on_green() -> Self);
|
||||
color!(pub const Color::Yellow, yellow(), on_yellow() -> Self);
|
||||
color!(pub const Color::Blue, blue(), on_blue() -> Self);
|
||||
color!(pub const Color::Magenta, magenta(), on_magenta() -> Self);
|
||||
color!(pub const Color::Cyan, cyan(), on_cyan() -> Self);
|
||||
color!(pub const Color::Gray, gray(), on_gray() -> Self);
|
||||
color!(pub const Color::DarkGray, dark_gray(), on_dark_gray() -> Self);
|
||||
color!(pub const Color::LightRed, light_red(), on_light_red() -> Self);
|
||||
color!(pub const Color::LightGreen, light_green(), on_light_green() -> Self);
|
||||
color!(pub const Color::LightYellow, light_yellow(), on_light_yellow() -> Self);
|
||||
color!(pub const Color::LightBlue, light_blue(), on_light_blue() -> Self);
|
||||
color!(pub const Color::LightMagenta, light_magenta(), on_light_magenta() -> Self);
|
||||
color!(pub const Color::LightCyan, light_cyan(), on_light_cyan() -> Self);
|
||||
color!(pub const Color::White, white(), on_white() -> Self);
|
||||
|
||||
modifier!(pub const Modifier::BOLD, bold(), not_bold() -> Self);
|
||||
modifier!(pub const Modifier::DIM, dim(), not_dim() -> Self);
|
||||
modifier!(pub const Modifier::ITALIC, italic(), not_italic() -> Self);
|
||||
modifier!(pub const Modifier::UNDERLINED, underlined(), not_underlined() -> Self);
|
||||
modifier!(pub const Modifier::SLOW_BLINK, slow_blink(), not_slow_blink() -> Self);
|
||||
modifier!(pub const Modifier::RAPID_BLINK, rapid_blink(), not_rapid_blink() -> Self);
|
||||
modifier!(pub const Modifier::REVERSED, reversed(), not_reversed() -> Self);
|
||||
modifier!(pub const Modifier::HIDDEN, hidden(), not_hidden() -> Self);
|
||||
modifier!(pub const Modifier::CROSSED_OUT, crossed_out(), not_crossed_out() -> Self);
|
||||
}
|
||||
|
||||
impl From<Color> for Style {
|
||||
@@ -734,14 +750,19 @@ mod tests {
|
||||
|
||||
const _RESET: Style = Style::reset();
|
||||
const _RED_FG: Style = Style::new().fg(RED);
|
||||
const _RED_FG_SHORT: Style = Style::new().red();
|
||||
const _BLACK_BG: Style = Style::new().bg(BLACK);
|
||||
const _BLACK_BG_SHORT: Style = Style::new().on_black();
|
||||
const _ADD_BOLD: Style = Style::new().add_modifier(BOLD);
|
||||
const _ADD_BOLD_SHORT: Style = Style::new().bold();
|
||||
const _REMOVE_ITALIC: Style = Style::new().remove_modifier(ITALIC);
|
||||
const _REMOVE_ITALIC_SHORT: Style = Style::new().not_italic();
|
||||
const ALL: Style = Style::new()
|
||||
.fg(RED)
|
||||
.bg(BLACK)
|
||||
.add_modifier(BOLD)
|
||||
.remove_modifier(ITALIC);
|
||||
const ALL_SHORT: Style = Style::new().red().on_black().bold().not_italic();
|
||||
assert_eq!(
|
||||
ALL,
|
||||
Style::new()
|
||||
@@ -750,6 +771,7 @@ mod tests {
|
||||
.add_modifier(Modifier::BOLD)
|
||||
.remove_modifier(Modifier::ITALIC)
|
||||
);
|
||||
assert_eq!(ALL, ALL_SHORT);
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
@@ -824,11 +846,6 @@ mod tests {
|
||||
assert_eq!(stylized, Style::new().remove_modifier(expected));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reset_can_be_stylized() {
|
||||
assert_eq!(Style::new().reset(), Style::reset());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn from_color() {
|
||||
assert_eq!(Style::from(Color::Red), Style::new().fg(Color::Red));
|
||||
|
||||
@@ -126,16 +126,16 @@ macro_rules! color {
|
||||
}
|
||||
};
|
||||
|
||||
( const $variant:ident, $fg:ident(), $bg:ident() -> $ty:ty ) => {
|
||||
(pub const $variant:expr, $color:ident(), $on_color:ident() -> $ty:ty ) => {
|
||||
#[doc = concat!("Sets the foreground color to [`", stringify!($color), "`](", stringify!($variant), ").")]
|
||||
#[must_use = concat!("`", stringify!($color), "` returns the modified style without modifying the original")]
|
||||
const fn $color(self) -> $ty {
|
||||
pub const fn $color(self) -> $ty {
|
||||
self.fg($variant)
|
||||
}
|
||||
|
||||
#[doc = concat!("Sets the background color to [`", stringify!($color), "`](", stringify!($variant), ").")]
|
||||
#[must_use = concat!("`", stringify!($on_color), "` returns the modified style without modifying the original")]
|
||||
const fn $on_color(self) -> $ty {
|
||||
pub const fn $on_color(self) -> $ty {
|
||||
self.bg($variant)
|
||||
}
|
||||
};
|
||||
@@ -176,16 +176,16 @@ macro_rules! modifier {
|
||||
}
|
||||
};
|
||||
|
||||
( const $variant:expr, $modifier:ident(), $not_modifier:ident() -> $ty:ty ) => {
|
||||
(pub const $variant:expr, $modifier:ident(), $not_modifier:ident() -> $ty:ty ) => {
|
||||
#[doc = concat!("Adds the [`", stringify!($modifier), "`](", stringify!($variant), ") modifier.")]
|
||||
#[must_use = concat!("`", stringify!($modifier), "` returns the modified style without modifying the original")]
|
||||
const fn $modifier>(self) -> $ty {
|
||||
pub const fn $modifier(self) -> $ty {
|
||||
self.add_modifier($variant)
|
||||
}
|
||||
|
||||
#[doc = concat!("Removes the [`", stringify!($modifier), "`](", stringify!($variant), ") modifier.")]
|
||||
#[must_use = concat!("`", stringify!($not_modifier), "` returns the modified style without modifying the original")]
|
||||
const fn $not_modifier(self) -> $ty {
|
||||
pub const fn $not_modifier(self) -> $ty {
|
||||
self.remove_modifier($variant)
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1106,12 +1106,12 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn styled_graphemes() {
|
||||
const RED: Style = Style::new().fg(Color::Red);
|
||||
const GREEN: Style = Style::new().fg(Color::Green);
|
||||
const BLUE: Style = Style::new().fg(Color::Blue);
|
||||
const RED_ON_WHITE: Style = Style::new().fg(Color::Red).bg(Color::White);
|
||||
const GREEN_ON_WHITE: Style = Style::new().fg(Color::Green).bg(Color::White);
|
||||
const BLUE_ON_WHITE: Style = Style::new().fg(Color::Blue).bg(Color::White);
|
||||
const RED: Style = Style::new().red();
|
||||
const GREEN: Style = Style::new().green();
|
||||
const BLUE: Style = Style::new().blue();
|
||||
const RED_ON_WHITE: Style = Style::new().red().on_white();
|
||||
const GREEN_ON_WHITE: Style = Style::new().green().on_white();
|
||||
const BLUE_ON_WHITE: Style = Style::new().blue().on_white();
|
||||
|
||||
let line = Line::from(vec![
|
||||
Span::styled("He", RED),
|
||||
@@ -1192,9 +1192,9 @@ mod tests {
|
||||
use super::*;
|
||||
use crate::buffer::Cell;
|
||||
|
||||
const BLUE: Style = Style::new().fg(Color::Blue);
|
||||
const GREEN: Style = Style::new().fg(Color::Green);
|
||||
const ITALIC: Style = Style::new().add_modifier(Modifier::ITALIC);
|
||||
const BLUE: Style = Style::new().blue();
|
||||
const GREEN: Style = Style::new().green();
|
||||
const ITALIC: Style = Style::new().italic();
|
||||
|
||||
#[fixture]
|
||||
fn hello_world() -> Line<'static> {
|
||||
|
||||
@@ -119,7 +119,7 @@ macro_rules! span {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use ratatui_core::{
|
||||
style::{Color, Modifier, Style, Stylize},
|
||||
style::{Color, Modifier, Style},
|
||||
text::Span,
|
||||
};
|
||||
|
||||
|
||||
@@ -541,8 +541,6 @@ impl fmt::Display for ResetRegion {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use ratatui_core::style::Stylize;
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -780,8 +780,6 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn from_cell_attribute_for_style() {
|
||||
use ratatui_core::style::Stylize;
|
||||
|
||||
#[cfg(feature = "underline-color")]
|
||||
const STYLE: Style = Style::new()
|
||||
.underline_color(Color::Reset)
|
||||
|
||||
@@ -143,7 +143,7 @@ fn draw_line_high(painter: &mut Painter, x1: usize, y1: usize, x2: usize, y2: us
|
||||
mod tests {
|
||||
use ratatui_core::buffer::Buffer;
|
||||
use ratatui_core::layout::Rect;
|
||||
use ratatui_core::style::{Style, Stylize};
|
||||
use ratatui_core::style::Style;
|
||||
use ratatui_core::symbols::Marker;
|
||||
use ratatui_core::widgets::Widget;
|
||||
use rstest::rstest;
|
||||
|
||||
@@ -79,7 +79,7 @@ impl Shape for Rectangle {
|
||||
mod tests {
|
||||
use ratatui_core::buffer::Buffer;
|
||||
use ratatui_core::layout::{Margin, Rect};
|
||||
use ratatui_core::style::{Style, Stylize};
|
||||
use ratatui_core::style::Style;
|
||||
use ratatui_core::symbols::Marker;
|
||||
use ratatui_core::widgets::Widget;
|
||||
|
||||
|
||||
@@ -4,14 +4,14 @@ use alloc::vec::Vec;
|
||||
use itertools::Itertools;
|
||||
use ratatui_core::buffer::Buffer;
|
||||
use ratatui_core::layout::Rect;
|
||||
use ratatui_core::style::{Modifier, Style, Styled};
|
||||
use ratatui_core::style::{Style, Styled};
|
||||
use ratatui_core::symbols;
|
||||
use ratatui_core::text::{Line, Span};
|
||||
use ratatui_core::widgets::Widget;
|
||||
|
||||
use crate::block::{Block, BlockExt};
|
||||
|
||||
const DEFAULT_HIGHLIGHT_STYLE: Style = Style::new().add_modifier(Modifier::REVERSED);
|
||||
const DEFAULT_HIGHLIGHT_STYLE: Style = Style::new().reversed();
|
||||
|
||||
/// A widget that displays a horizontal set of Tabs with a single tab selected.
|
||||
///
|
||||
@@ -125,6 +125,7 @@ impl<'a> Tabs<'a> {
|
||||
/// let tabs = Tabs::new(vec!["Tab 1".red(), "Tab 2".blue()]);
|
||||
/// ```
|
||||
/// [`String`]: alloc::string::String
|
||||
/// [`Modifier::REVERSED`]: ratatui_core::style::Modifier
|
||||
pub fn new<Iter>(titles: Iter) -> Self
|
||||
where
|
||||
Iter: IntoIterator,
|
||||
@@ -672,11 +673,7 @@ mod tests {
|
||||
.bold()
|
||||
.not_italic()
|
||||
.style,
|
||||
Style::default()
|
||||
.fg(Color::Black)
|
||||
.bg(Color::White)
|
||||
.add_modifier(Modifier::BOLD)
|
||||
.remove_modifier(Modifier::ITALIC)
|
||||
Style::default().black().on_white().bold().not_italic()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use ratatui::backend::TestBackend;
|
||||
use ratatui::buffer::Buffer;
|
||||
use ratatui::layout::{Constraint, Direction, Layout, Rect};
|
||||
use ratatui::style::{Color, Modifier, Style, Stylize};
|
||||
use ratatui::style::{Color, Modifier, Style};
|
||||
use ratatui::text::Span;
|
||||
use ratatui::widgets::{Block, Gauge, LineGauge};
|
||||
use ratatui::{symbols, Terminal};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use ratatui::backend::TestBackend;
|
||||
use ratatui::buffer::Buffer;
|
||||
use ratatui::layout::Rect;
|
||||
use ratatui::style::{Style, Stylize};
|
||||
use ratatui::style::Style;
|
||||
use ratatui::widgets::Tabs;
|
||||
use ratatui::{symbols, Terminal};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user