diff --git a/ratatui-macros/README.md b/ratatui-macros/README.md index c675cb26..c3c6cd54 100644 --- a/ratatui-macros/README.md +++ b/ratatui-macros/README.md @@ -1,20 +1,26 @@ # Ratatui Macros -[![Crates.io badge]][ratatui_macros crate] [![License badge]](./LICENSE) -[![Docs.rs badge]][API Docs] [![CI Badge]][CI Status] +[![Crates.io badge]][ratatui_macros crate] +[![License badge]](./LICENSE) +[![Docs.rs badge]][API Docs] +[![CI Badge]][CI Status] [![Crate Downloads badge]][ratatui_macros crate] + + + `ratatui-macros` is a Rust crate that provides easy-to-use macros for simplifying boilerplate associated with creating UI using [Ratatui]. -This is an experimental playground for us to explore macros that would be useful to have in Ratatui -proper. +This is an experimental playground for us to explore macros that would be useful to have in +Ratatui proper. ## Features -- Constraint-based Layouts: Easily define layout constraints such as fixed, percentage, minimum, and - maximum sizes, as well as ratios. -- Directional Layouts: Specify layouts as either horizontal or vertical with simple macro commands. +- Constraint-based Layouts: Easily define layout constraints such as fixed, percentage, minimum, + and maximum sizes, as well as ratios. +- Directional Layouts: Specify layouts as either horizontal or vertical with simple macro + commands. - Span and Line macros: Make it easier to create spans and lines with styling. ## Getting Started @@ -38,14 +44,16 @@ use ratatui_macros::{ }; ``` +## Macros + ### Layout -If you are new to Ratatui, check out the [Layout concepts] article on the Ratatui website before proceeding. +If you are new to Ratatui, check out the [Layout concepts] article on the Ratatui website before +proceeding. Use the `constraints!` macro to define layout constraints: ```rust -# use ratatui_core::layout::Constraint; use ratatui_macros::constraints; assert_eq!( @@ -62,7 +70,6 @@ assert_eq!( ``` ```rust -# use ratatui_core::layout::Constraint; use ratatui_macros::constraints; assert_eq!( @@ -79,7 +86,6 @@ assert_eq!( Use the `constraint!` macro to define individual constraints: ```rust -# use ratatui_core::layout::Constraint; use ratatui_macros::constraint; assert_eq!( @@ -91,7 +97,6 @@ assert_eq!( Create vertical and horizontal layouts using the `vertical!` and `horizontal!` macros: ```rust -# use ratatui_core::layout::Rect; use ratatui_macros::{vertical, horizontal}; let area = Rect { x: 0, y: 0, width: 10, height: 10 }; @@ -107,14 +112,13 @@ assert_eq!(left.width, 3); assert_eq!(right.width, 3); ``` -## Spans +### Spans The `span!` macro create raw and styled `Span`s. They each take a format string and arguments. -`span!` accepts as the first parameter any value that can be converted to a `Style` followed by a -`;` followed by the format string and arguments. +`span!` accepts as the first parameter any value that can be converted to a `Style` followed by +a `;` followed by the format string and arguments. ```rust -# use ratatui_core::style::{Color, Modifier, Style, Stylize}; use ratatui_macros::span; let name = "world!"; @@ -124,10 +128,10 @@ let styled_greeting = span!(Color::Green; "hello {name}"); let styled_greeting = span!(Modifier::BOLD; "hello {name}"); ``` -## Line +### Line -The `line!` macro creates a `Line` that contains a sequence of spans. It is similar to the `vec!` -macro. +The `line!` macro creates a `Line` that contains a sequence of spans. It is similar to the +`vec!` macro. ```rust use ratatui_macros::line; @@ -137,10 +141,10 @@ let line = line!["hello", format!("{name}")]; let line = line!["bye"; 2]; ``` -## Text +### Text -The `text!` macro creates a `Text` that contains a sequence of lines. It is similar to the `vec!` -macro. +The `text!` macro creates a `Text` that contains a sequence of lines. It is similar to the +`vec!` macro. ```rust use ratatui_macros::{span, line, text}; @@ -153,13 +157,12 @@ let text = text!["bye"; 2]; It is even possible to use `span!` and `line!` in the `text!` macro: ```rust -# use ratatui_core::style::{Modifier, Stylize}; use ratatui_macros::{span, line, text}; let name = "Bye!!!"; let text = text![line!["hello", "world".bold()], span!(Modifier::BOLD; "{name}")]; ``` -## Row +### Row The `row!` macro creates a `Row` that contains a sequence of `Cell`. It is similar to the `vec!` macro. A `Row` represents a sequence of `Cell`s in a single row of a table. @@ -176,7 +179,6 @@ let rows = [ It is even possible to use `span!`, `line!` and `text!` in the `row!` macro: ```rust -# use ratatui_core::style::{Modifier, Stylize}; use ratatui_macros::{span, line, text, row}; let name = "Bye!!!"; let text = row![text![line!["hello", "world".bold()]], span!(Modifier::BOLD; "{name}")]; @@ -190,11 +192,14 @@ request, or a pull request, all forms of contributions are valued and appreciate [Crates.io badge]: https://img.shields.io/crates/v/ratatui-macros?logo=rust&style=flat-square [License badge]: https://img.shields.io/crates/l/ratatui-macros [CI Badge]: - https://img.shields.io/github/actions/workflow/status/ratatui-org/ratatui-macros/ci.yml?logo=github&style=flat-square + https://img.shields.io/github/actions/workflow/status/ratatui/ratatui/ci.yml?logo=github&style=flat-square [Docs.rs badge]: https://img.shields.io/docsrs/ratatui-macros?logo=rust&style=flat-square -[Crate Downloads badge]: https://img.shields.io/crates/d/ratatui-macros?logo=rust&style=flat-square +[Crate Downloads badge]: + https://img.shields.io/crates/d/ratatui-macros?logo=rust&style=flat-square [ratatui_macros crate]: https://crates.io/crates/ratatui-macros [API Docs]: https://docs.rs/ratatui-macros -[CI Status]: https://github.com/kdheepak/ratatui-macros/actions -[Ratatui]: https://github.com/ratatui-org/ratatui +[CI Status]: https://github.com/ratatui/ratatui/actions +[Ratatui]: https://github.com/ratatui/ratatui [Layout concepts]: https://ratatui.rs/concepts/layout + + diff --git a/ratatui-macros/src/layout.rs b/ratatui-macros/src/layout.rs index d543531d..2f0968c7 100644 --- a/ratatui-macros/src/layout.rs +++ b/ratatui-macros/src/layout.rs @@ -15,6 +15,8 @@ /// assert_eq!(constraint!(== 10 %), Constraint::Percentage(10)); /// assert_eq!(constraint!(*= 1), Constraint::Fill(1)); /// ``` +/// +/// [`constraints!`]: crate::constraints #[macro_export] macro_rules! constraint { (== $token:tt %) => { @@ -67,6 +69,10 @@ macro_rules! constraint { /// ] /// ) /// ``` +/// +/// [`constraint!`]: crate::constraint +/// [`vertical!`]: crate::vertical +/// [`horizontal!`]: crate::horizontal #[macro_export] macro_rules! constraints { // Note: this implementation forgoes speed for the sake of simplicity. Adding variations of the diff --git a/ratatui-macros/src/lib.rs b/ratatui-macros/src/lib.rs index fdf88ea2..7b951a43 100644 --- a/ratatui-macros/src/lib.rs +++ b/ratatui-macros/src/lib.rs @@ -1,5 +1,202 @@ -#![doc = include_str!(concat!(env!("CARGO_MANIFEST_DIR"), "/README.md"))] - +//! `ratatui-macros` is a Rust crate that provides easy-to-use macros for simplifying boilerplate +//! associated with creating UI using [Ratatui]. +//! +//! This is an experimental playground for us to explore macros that would be useful to have in +//! Ratatui proper. +//! +//! # Features +//! +//! - Constraint-based Layouts: Easily define layout constraints such as fixed, percentage, minimum, +//! and maximum sizes, as well as ratios. +//! - Directional Layouts: Specify layouts as either horizontal or vertical with simple macro +//! commands. +//! - Span and Line macros: Make it easier to create spans and lines with styling. +//! +//! # Getting Started +//! +//! To use `ratatui-macros` in your Rust project, add it as a dependency in your `Cargo.toml`: +//! +//! ```shell +//! cargo add ratatui-macros +//! ``` +//! +//! Then, import the macros in your Rust file: +//! +//! ```rust +//! use ratatui_macros::{ +//! constraint, +//! constraints, +//! horizontal, +//! vertical, +//! span, +//! line, +//! }; +//! ``` +//! +//! # Macros +//! +//! ## Layout +//! +//! If you are new to Ratatui, check out the [Layout concepts] article on the Ratatui website before +//! proceeding. +//! +//! Use the `constraints!` macro to define layout constraints: +//! +//! ```rust +//! # use ratatui_core::layout::Constraint; +//! use ratatui_macros::constraints; +//! +//! assert_eq!( +//! constraints![==50, ==30%, >=3, <=1, ==1/2, *=1], +//! [ +//! Constraint::Length(50), +//! Constraint::Percentage(30), +//! Constraint::Min(3), +//! Constraint::Max(1), +//! Constraint::Ratio(1, 2), +//! Constraint::Fill(1), +//! ] +//! ) +//! ``` +//! +//! ```rust +//! # use ratatui_core::layout::Constraint; +//! use ratatui_macros::constraints; +//! +//! assert_eq!( +//! constraints![==1/4; 4], +//! [ +//! Constraint::Ratio(1, 4), +//! Constraint::Ratio(1, 4), +//! Constraint::Ratio(1, 4), +//! Constraint::Ratio(1, 4), +//! ] +//! ) +//! ``` +//! +//! Use the `constraint!` macro to define individual constraints: +//! +//! ```rust +//! # use ratatui_core::layout::Constraint; +//! use ratatui_macros::constraint; +//! +//! assert_eq!( +//! constraint!(==50), +//! Constraint::Length(50), +//! ) +//! ``` +//! +//! Create vertical and horizontal layouts using the `vertical!` and `horizontal!` macros: +//! +//! ```rust +//! # use ratatui_core::layout::Rect; +//! use ratatui_macros::{vertical, horizontal}; +//! +//! let area = Rect { x: 0, y: 0, width: 10, height: 10 }; +//! +//! let [main, bottom] = vertical![==100%, >=3].areas(area); +//! +//! assert_eq!(bottom.y, 7); +//! assert_eq!(bottom.height, 3); +//! +//! let [left, main, right] = horizontal![>=3, ==100%, >=3].areas(area); +//! +//! assert_eq!(left.width, 3); +//! assert_eq!(right.width, 3); +//! ``` +//! +//! ## Spans +//! +//! The `span!` macro create raw and styled `Span`s. They each take a format string and arguments. +//! `span!` accepts as the first parameter any value that can be converted to a `Style` followed by +//! a `;` followed by the format string and arguments. +//! +//! ```rust +//! # use ratatui_core::style::{Color, Modifier, Style, Stylize}; +//! use ratatui_macros::span; +//! +//! let name = "world!"; +//! let raw_greeting = span!("hello {name}"); +//! let styled_greeting = span!(Style::new().green(); "hello {name}"); +//! let styled_greeting = span!(Color::Green; "hello {name}"); +//! let styled_greeting = span!(Modifier::BOLD; "hello {name}"); +//! ``` +//! +//! ## Line +//! +//! The `line!` macro creates a `Line` that contains a sequence of spans. It is similar to the +//! `vec!` macro. +//! +//! ```rust +//! use ratatui_macros::line; +//! +//! let name = "world!"; +//! let line = line!["hello", format!("{name}")]; +//! let line = line!["bye"; 2]; +//! ``` +//! +//! ## Text +//! +//! The `text!` macro creates a `Text` that contains a sequence of lines. It is similar to the +//! `vec!` macro. +//! +//! ```rust +//! use ratatui_macros::{span, line, text}; +//! +//! let name = "world!"; +//! let text = text!["hello", format!("{name}")]; +//! let text = text!["bye"; 2]; +//! ``` +//! +//! It is even possible to use `span!` and `line!` in the `text!` macro: +//! +//! ```rust +//! # use ratatui_core::style::{Modifier, Stylize}; +//! use ratatui_macros::{span, line, text}; +//! let name = "Bye!!!"; +//! let text = text![line!["hello", "world".bold()], span!(Modifier::BOLD; "{name}")]; +//! ``` +//! +//! ## Row +//! +//! The `row!` macro creates a `Row` that contains a sequence of `Cell`. It is similar to the `vec!` +//! macro. A `Row` represents a sequence of `Cell`s in a single row of a table. +//! +//! ```rust +//! use ratatui_macros::row; +//! +//! let rows = [ +//! row!["hello", "world"], +//! row!["goodbye", "world"], +//! ]; +//! ``` +//! +//! It is even possible to use `span!`, `line!` and `text!` in the `row!` macro: +//! +//! ```rust +//! # use ratatui_core::style::{Modifier, Stylize}; +//! use ratatui_macros::{span, line, text, row}; +//! let name = "Bye!!!"; +//! let text = row![text![line!["hello", "world".bold()]], span!(Modifier::BOLD; "{name}")]; +//! ``` +//! +//! # Contributing +//! +//! Contributions to `ratatui-macros` are welcome! Whether it's submitting a bug report, a feature +//! request, or a pull request, all forms of contributions are valued and appreciated. +//! +//! [Crates.io badge]: https://img.shields.io/crates/v/ratatui-macros?logo=rust&style=flat-square +//! [License badge]: https://img.shields.io/crates/l/ratatui-macros +//! [CI Badge]: +//! https://img.shields.io/github/actions/workflow/status/ratatui/ratatui/ci.yml?logo=github&style=flat-square +//! [Docs.rs badge]: https://img.shields.io/docsrs/ratatui-macros?logo=rust&style=flat-square +//! [Crate Downloads badge]: +//! https://img.shields.io/crates/d/ratatui-macros?logo=rust&style=flat-square +//! [ratatui_macros crate]: https://crates.io/crates/ratatui-macros +//! [API Docs]: https://docs.rs/ratatui-macros +//! [CI Status]: https://github.com/ratatui/ratatui/actions +//! [Ratatui]: https://github.com/ratatui/ratatui +//! [Layout concepts]: https://ratatui.rs/concepts/layout mod layout; mod line; mod row; diff --git a/ratatui-macros/src/line.rs b/ratatui-macros/src/line.rs index c326c4a9..e907948e 100644 --- a/ratatui-macros/src/line.rs +++ b/ratatui-macros/src/line.rs @@ -30,8 +30,9 @@ /// let line = line![span!("hello {}", "world"), span!(Modifier::BOLD; "goodbye {}", "world")]; /// ``` /// -/// [`Line`]: crate::text::Line -/// [`Span`]: crate::text::Span +/// [`span!`]: crate::span +/// [`Line`]: ratatui_core::text::Line +/// [`Span`]: ratatui_core::text::Span #[macro_export] macro_rules! line { () => { diff --git a/ratatui-macros/src/row.rs b/ratatui-macros/src/row.rs index feb80c50..18e4f57c 100644 --- a/ratatui-macros/src/row.rs +++ b/ratatui-macros/src/row.rs @@ -40,8 +40,12 @@ /// ]; /// ``` /// -/// [`Row`]: crate::widgets::Row -/// [`Cell`]: crate::widgets::Cell +/// [`text!`]: crate::text +/// [`line!`]: crate::line +/// [`span!`]: crate::span +/// [`row!`]: crate::row +/// [`Row`]: ratatui_widgets::table::Row +/// [`Cell`]: ratatui_widgets::table::Cell #[macro_export] macro_rules! row { () => { diff --git a/ratatui-macros/src/span.rs b/ratatui-macros/src/span.rs index 1d25c9fe..12660acd 100644 --- a/ratatui-macros/src/span.rs +++ b/ratatui-macros/src/span.rs @@ -88,10 +88,9 @@ /// let span = span!("hello {}", "world"); /// ``` /// -/// [`Color`]: crate::style::Color -/// [`Style`]: crate::style::Style -/// [`Span`]: crate::text::Span -/// [`Style`]: crate::style::Style +/// [`Color`]: ratatui_core::style::Color +/// [`Span`]: ratatui_core::text::Span +/// [`Style`]: ratatui_core::style::Style #[macro_export] macro_rules! span { ($string:literal) => { diff --git a/ratatui-macros/src/text.rs b/ratatui-macros/src/text.rs index b206ecbd..482b11fa 100644 --- a/ratatui-macros/src/text.rs +++ b/ratatui-macros/src/text.rs @@ -30,9 +30,11 @@ /// let text = text![line!["hello", "world"], span!(Modifier::BOLD; "goodbye {}", "world")]; /// ``` /// -/// [`Text`]: crate::text::Text -/// [`Line`]: crate::text::Line -/// [`Span`]: crate::text::Span +/// [`span!`]: crate::span +/// [`text!`]: crate::text +/// [`Text`]: ratatui_core::text::Text +/// [`Line`]: ratatui_core::text::Line +/// [`Span`]: ratatui_core::text::Span #[macro_export] macro_rules! text { () => {