@@ -1,9 +1,10 @@
use crate::{
self as gpui, hsla, point, px, relative, rems, AbsoluteLength, AlignItems, CursorStyle,
DefiniteLength, Fill, FlexDirection, FlexWrap, Font, FontStyle, FontWeight, Hsla,
- JustifyContent, Length, Position, SharedString, StyleRefinement, Visibility, WhiteSpace,
+ JustifyContent, Length, SharedString, StyleRefinement, Visibility, WhiteSpace,
};
use crate::{BoxShadow, TextStyleRefinement};
+pub use gpui_macros::{margin_style_methods, padding_style_methods, position_style_methods};
use smallvec::{smallvec, SmallVec};
use taffy::style::{AlignContent, Display, Overflow};
@@ -14,20 +15,9 @@ pub trait Styled: Sized {
fn style(&mut self) -> &mut StyleRefinement;
gpui_macros::style_helpers!();
-
- /// Sets the position of the element to `relative`.
- /// [Docs](https://tailwindcss.com/docs/position)
- fn relative(mut self) -> Self {
- self.style().position = Some(Position::Relative);
- self
- }
-
- /// Sets the position of the element to `absolute`.
- /// [Docs](https://tailwindcss.com/docs/position)
- fn absolute(mut self) -> Self {
- self.style().position = Some(Position::Absolute);
- self
- }
+ gpui_macros::margin_style_methods!();
+ gpui_macros::padding_style_methods!();
+ gpui_macros::position_style_methods!();
/// Sets the display type of the element to `block`.
/// [Docs](https://tailwindcss.com/docs/display)
@@ -2,15 +2,38 @@ use proc_macro::TokenStream;
use proc_macro2::TokenStream as TokenStream2;
use quote::{format_ident, quote};
use syn::{
+ braced,
parse::{Parse, ParseStream, Result},
- parse_macro_input,
+ parse_macro_input, Token, Visibility,
};
-struct StyleableMacroInput;
+#[derive(Debug)]
+struct StyleableMacroInput {
+ method_visibility: Visibility,
+}
impl Parse for StyleableMacroInput {
- fn parse(_input: ParseStream) -> Result<Self> {
- Ok(StyleableMacroInput)
+ fn parse(input: ParseStream) -> Result<Self> {
+ if !input.peek(syn::token::Brace) {
+ return Ok(Self {
+ method_visibility: Visibility::Inherited,
+ });
+ }
+
+ let content;
+ braced!(content in input);
+
+ let mut method_visibility = None;
+
+ let ident: syn::Ident = content.parse()?;
+ if ident == "visibility" {
+ let _colon: Token![:] = content.parse()?;
+ method_visibility = Some(content.parse()?);
+ }
+
+ Ok(Self {
+ method_visibility: method_visibility.unwrap_or(Visibility::Inherited),
+ })
}
}
@@ -24,11 +47,110 @@ pub fn style_helpers(input: TokenStream) -> TokenStream {
output.into()
}
-fn generate_methods() -> Vec<TokenStream2> {
+pub fn margin_style_methods(input: TokenStream) -> TokenStream {
+ let input = parse_macro_input!(input as StyleableMacroInput);
+ let methods = generate_box_style_methods(
+ margin_box_style_prefixes(),
+ box_style_suffixes(),
+ input.method_visibility,
+ );
+ let output = quote! {
+ #(#methods)*
+ };
+
+ output.into()
+}
+
+pub fn padding_style_methods(input: TokenStream) -> TokenStream {
+ let input = parse_macro_input!(input as StyleableMacroInput);
+ let methods = generate_box_style_methods(
+ padding_box_style_prefixes(),
+ box_style_suffixes(),
+ input.method_visibility,
+ );
+ let output = quote! {
+ #(#methods)*
+ };
+
+ output.into()
+}
+
+pub fn position_style_methods(input: TokenStream) -> TokenStream {
+ let input = parse_macro_input!(input as StyleableMacroInput);
+ let visibility = input.method_visibility;
+ let methods = generate_box_style_methods(
+ position_box_style_prefixes(),
+ box_style_suffixes(),
+ visibility.clone(),
+ );
+ let output = quote! {
+ /// Sets the position of the element to `relative`.
+ /// [Docs](https://tailwindcss.com/docs/position)
+ #visibility fn relative(mut self) -> Self {
+ self.style().position = Some(gpui::Position::Relative);
+ self
+ }
+
+ /// Sets the position of the element to `absolute`.
+ /// [Docs](https://tailwindcss.com/docs/position)
+ #visibility fn absolute(mut self) -> Self {
+ self.style().position = Some(gpui::Position::Absolute);
+ self
+ }
+
+ #(#methods)*
+ };
+
+ output.into()
+}
+
+struct BoxStylePrefix {
+ prefix: &'static str,
+ auto_allowed: bool,
+ fields: Vec<TokenStream2>,
+ doc_string_prefix: &'static str,
+}
+
+struct BoxStyleSuffix {
+ suffix: &'static str,
+ length_tokens: TokenStream2,
+ doc_string_suffix: &'static str,
+}
+
+struct CornerStylePrefix {
+ prefix: &'static str,
+ fields: Vec<TokenStream2>,
+ doc_string_prefix: &'static str,
+}
+
+struct CornerStyleSuffix {
+ suffix: &'static str,
+ radius_tokens: TokenStream2,
+ doc_string_suffix: &'static str,
+}
+
+struct BorderStylePrefix {
+ prefix: &'static str,
+ fields: Vec<TokenStream2>,
+ doc_string_prefix: &'static str,
+}
+
+struct BorderStyleSuffix {
+ suffix: &'static str,
+ width_tokens: TokenStream2,
+ doc_string_suffix: &'static str,
+}
+
+fn generate_box_style_methods(
+ prefixes: Vec<BoxStylePrefix>,
+ suffixes: Vec<BoxStyleSuffix>,
+ visibility: Visibility,
+) -> Vec<TokenStream2> {
let mut methods = Vec::new();
- for box_style_prefix in box_prefixes() {
+ for box_style_prefix in prefixes {
methods.push(generate_custom_value_setter(
+ visibility.clone(),
box_style_prefix.prefix,
if box_style_prefix.auto_allowed {
quote! { Length }
@@ -39,9 +161,10 @@ fn generate_methods() -> Vec<TokenStream2> {
&box_style_prefix.doc_string_prefix,
));
- for box_style_suffix in box_suffixes() {
+ for box_style_suffix in &suffixes {
if box_style_suffix.suffix != "auto" || box_style_prefix.auto_allowed {
methods.push(generate_predefined_setter(
+ visibility.clone(),
box_style_prefix.prefix,
box_style_suffix.suffix,
&box_style_prefix.fields,
@@ -57,6 +180,7 @@ fn generate_methods() -> Vec<TokenStream2> {
if box_style_suffix.suffix != "auto" {
methods.push(generate_predefined_setter(
+ visibility.clone(),
box_style_prefix.prefix,
box_style_suffix.suffix,
&box_style_prefix.fields,
@@ -72,8 +196,17 @@ fn generate_methods() -> Vec<TokenStream2> {
}
}
+ methods
+}
+
+fn generate_methods() -> Vec<TokenStream2> {
+ let visibility = Visibility::Inherited;
+ let mut methods =
+ generate_box_style_methods(box_prefixes(), box_style_suffixes(), visibility.clone());
+
for corner_style_prefix in corner_prefixes() {
methods.push(generate_custom_value_setter(
+ visibility.clone(),
corner_style_prefix.prefix,
quote! { AbsoluteLength },
&corner_style_prefix.fields,
@@ -82,6 +215,7 @@ fn generate_methods() -> Vec<TokenStream2> {
for corner_style_suffix in corner_suffixes() {
methods.push(generate_predefined_setter(
+ visibility.clone(),
corner_style_prefix.prefix,
corner_style_suffix.suffix,
&corner_style_prefix.fields,
@@ -98,6 +232,7 @@ fn generate_methods() -> Vec<TokenStream2> {
for border_style_prefix in border_prefixes() {
methods.push(generate_custom_value_setter(
+ visibility.clone(),
border_style_prefix.prefix,
quote! { AbsoluteLength },
&border_style_prefix.fields,
@@ -106,6 +241,7 @@ fn generate_methods() -> Vec<TokenStream2> {
for border_style_suffix in border_suffixes() {
methods.push(generate_predefined_setter(
+ visibility.clone(),
border_style_prefix.prefix,
border_style_suffix.suffix,
&border_style_prefix.fields,
@@ -123,6 +259,7 @@ fn generate_methods() -> Vec<TokenStream2> {
}
fn generate_predefined_setter(
+ visibility: Visibility,
name: &'static str,
length: &'static str,
fields: &[TokenStream2],
@@ -153,7 +290,7 @@ fn generate_predefined_setter(
let method = quote! {
#[doc = #doc_string]
- fn #method_name(mut self) -> Self {
+ #visibility fn #method_name(mut self) -> Self {
let style = self.style();
#(#field_assignments)*
self
@@ -164,6 +301,7 @@ fn generate_predefined_setter(
}
fn generate_custom_value_setter(
+ visibility: Visibility,
prefix: &str,
length_type: TokenStream2,
fields: &[TokenStream2],
@@ -186,7 +324,7 @@ fn generate_custom_value_setter(
let method = quote! {
#[doc = #doc_string]
- fn #method_name(mut self, length: impl std::clone::Clone + Into<gpui::#length_type>) -> Self {
+ #visibility fn #method_name(mut self, length: impl std::clone::Clone + Into<gpui::#length_type>) -> Self {
let style = self.style();
#(#field_assignments)*
self
@@ -196,65 +334,8 @@ fn generate_custom_value_setter(
method
}
-struct BoxStylePrefix {
- prefix: &'static str,
- auto_allowed: bool,
- fields: Vec<TokenStream2>,
- doc_string_prefix: &'static str,
-}
-
-fn box_prefixes() -> Vec<BoxStylePrefix> {
+fn margin_box_style_prefixes() -> Vec<BoxStylePrefix> {
vec![
- BoxStylePrefix {
- prefix: "w",
- auto_allowed: true,
- fields: vec![quote! { size.width }],
- doc_string_prefix: "Sets the width of the element. [Docs](https://tailwindcss.com/docs/width)",
- },
- BoxStylePrefix {
- prefix: "h",
- auto_allowed: true,
- fields: vec![quote! { size.height }],
- doc_string_prefix: "Sets the height of the element. [Docs](https://tailwindcss.com/docs/height)",
- },
- BoxStylePrefix {
- prefix: "size",
- auto_allowed: true,
- fields: vec![quote! {size.width}, quote! {size.height}],
- doc_string_prefix: "Sets the width and height of the element.",
- },
- // TODO: These don't use the same size ramp as the others
- // see https://tailwindcss.com/docs/max-width
- BoxStylePrefix {
- prefix: "min_w",
- auto_allowed: true,
- fields: vec![quote! { min_size.width }],
- doc_string_prefix: "Sets the minimum width of the element. [Docs](https://tailwindcss.com/docs/min-width)",
- },
- // TODO: These don't use the same size ramp as the others
- // see https://tailwindcss.com/docs/max-width
- BoxStylePrefix {
- prefix: "min_h",
- auto_allowed: true,
- fields: vec![quote! { min_size.height }],
- doc_string_prefix: "Sets the minimum height of the element. [Docs](https://tailwindcss.com/docs/min-height)",
- },
- // TODO: These don't use the same size ramp as the others
- // see https://tailwindcss.com/docs/max-width
- BoxStylePrefix {
- prefix: "max_w",
- auto_allowed: true,
- fields: vec![quote! { max_size.width }],
- doc_string_prefix: "Sets the maximum width of the element. [Docs](https://tailwindcss.com/docs/max-width)",
- },
- // TODO: These don't use the same size ramp as the others
- // see https://tailwindcss.com/docs/max-width
- BoxStylePrefix {
- prefix: "max_h",
- auto_allowed: true,
- fields: vec![quote! { max_size.height }],
- doc_string_prefix: "Sets the maximum height of the element. [Docs](https://tailwindcss.com/docs/max-height)",
- },
BoxStylePrefix {
prefix: "m",
auto_allowed: true,
@@ -302,6 +383,11 @@ fn box_prefixes() -> Vec<BoxStylePrefix> {
fields: vec![quote! { margin.right }],
doc_string_prefix: "Sets the right margin of the element. [Docs](https://tailwindcss.com/docs/margin#add-margin-to-a-single-side)",
},
+ ]
+}
+
+fn padding_box_style_prefixes() -> Vec<BoxStylePrefix> {
+ vec![
BoxStylePrefix {
prefix: "p",
auto_allowed: false,
@@ -349,6 +435,11 @@ fn box_prefixes() -> Vec<BoxStylePrefix> {
fields: vec![quote! { padding.right }],
doc_string_prefix: "Sets the right padding of the element. [Docs](https://tailwindcss.com/docs/padding#add-padding-to-a-single-side)",
},
+ ]
+}
+
+fn position_box_style_prefixes() -> Vec<BoxStylePrefix> {
+ vec![
BoxStylePrefix {
prefix: "inset",
auto_allowed: true,
@@ -384,6 +475,61 @@ fn box_prefixes() -> Vec<BoxStylePrefix> {
fields: vec![quote! { inset.right }],
doc_string_prefix: "Sets the right value of a positioned element. [Docs](https://tailwindcss.com/docs/top-right-bottom-left)",
},
+ ]
+}
+
+fn box_prefixes() -> Vec<BoxStylePrefix> {
+ vec![
+ BoxStylePrefix {
+ prefix: "w",
+ auto_allowed: true,
+ fields: vec![quote! { size.width }],
+ doc_string_prefix: "Sets the width of the element. [Docs](https://tailwindcss.com/docs/width)",
+ },
+ BoxStylePrefix {
+ prefix: "h",
+ auto_allowed: true,
+ fields: vec![quote! { size.height }],
+ doc_string_prefix: "Sets the height of the element. [Docs](https://tailwindcss.com/docs/height)",
+ },
+ BoxStylePrefix {
+ prefix: "size",
+ auto_allowed: true,
+ fields: vec![quote! {size.width}, quote! {size.height}],
+ doc_string_prefix: "Sets the width and height of the element.",
+ },
+ // TODO: These don't use the same size ramp as the others
+ // see https://tailwindcss.com/docs/max-width
+ BoxStylePrefix {
+ prefix: "min_w",
+ auto_allowed: true,
+ fields: vec![quote! { min_size.width }],
+ doc_string_prefix: "Sets the minimum width of the element. [Docs](https://tailwindcss.com/docs/min-width)",
+ },
+ // TODO: These don't use the same size ramp as the others
+ // see https://tailwindcss.com/docs/max-width
+ BoxStylePrefix {
+ prefix: "min_h",
+ auto_allowed: true,
+ fields: vec![quote! { min_size.height }],
+ doc_string_prefix: "Sets the minimum height of the element. [Docs](https://tailwindcss.com/docs/min-height)",
+ },
+ // TODO: These don't use the same size ramp as the others
+ // see https://tailwindcss.com/docs/max-width
+ BoxStylePrefix {
+ prefix: "max_w",
+ auto_allowed: true,
+ fields: vec![quote! { max_size.width }],
+ doc_string_prefix: "Sets the maximum width of the element. [Docs](https://tailwindcss.com/docs/max-width)",
+ },
+ // TODO: These don't use the same size ramp as the others
+ // see https://tailwindcss.com/docs/max-width
+ BoxStylePrefix {
+ prefix: "max_h",
+ auto_allowed: true,
+ fields: vec![quote! { max_size.height }],
+ doc_string_prefix: "Sets the maximum height of the element. [Docs](https://tailwindcss.com/docs/max-height)",
+ },
BoxStylePrefix {
prefix: "gap",
auto_allowed: false,
@@ -405,13 +551,7 @@ fn box_prefixes() -> Vec<BoxStylePrefix> {
]
}
-struct BoxStyleSuffix {
- suffix: &'static str,
- length_tokens: TokenStream2,
- doc_string_suffix: &'static str,
-}
-
-fn box_suffixes() -> Vec<BoxStyleSuffix> {
+fn box_style_suffixes() -> Vec<BoxStyleSuffix> {
vec![
BoxStyleSuffix {
suffix: "0",
@@ -646,12 +786,6 @@ fn box_suffixes() -> Vec<BoxStyleSuffix> {
]
}
-struct CornerStylePrefix {
- prefix: &'static str,
- fields: Vec<TokenStream2>,
- doc_string_prefix: &'static str,
-}
-
fn corner_prefixes() -> Vec<CornerStylePrefix> {
vec![
CornerStylePrefix {
@@ -719,12 +853,6 @@ fn corner_prefixes() -> Vec<CornerStylePrefix> {
]
}
-struct CornerStyleSuffix {
- suffix: &'static str,
- radius_tokens: TokenStream2,
- doc_string_suffix: &'static str,
-}
-
fn corner_suffixes() -> Vec<CornerStyleSuffix> {
vec![
CornerStyleSuffix {
@@ -770,12 +898,6 @@ fn corner_suffixes() -> Vec<CornerStyleSuffix> {
]
}
-struct BorderStylePrefix {
- prefix: &'static str,
- fields: Vec<TokenStream2>,
- doc_string_prefix: &'static str,
-}
-
fn border_prefixes() -> Vec<BorderStylePrefix> {
vec![
BorderStylePrefix {
@@ -827,12 +949,6 @@ fn border_prefixes() -> Vec<BorderStylePrefix> {
]
}
-struct BorderStyleSuffix {
- suffix: &'static str,
- width_tokens: TokenStream2,
- doc_string_suffix: &'static str,
-}
-
fn border_suffixes() -> Vec<BorderStyleSuffix> {
vec![
BorderStyleSuffix {