diff --git a/crates/gpui/playground/src/adapter.rs b/crates/gpui/playground/src/adapter.rs index 13548644b5..452bce6f72 100644 --- a/crates/gpui/playground/src/adapter.rs +++ b/crates/gpui/playground/src/adapter.rs @@ -54,7 +54,7 @@ impl gpui::Element for Adapter { view: &V, cx: &gpui::ViewContext, ) -> Option { - todo!() + todo!("implement before merging to main") } fn debug( @@ -65,6 +65,6 @@ impl gpui::Element for Adapter { view: &V, cx: &gpui::ViewContext, ) -> gpui::serde_json::Value { - todo!() + todo!("implement before merging to main") } } diff --git a/crates/gpui/playground/src/div.rs b/crates/gpui/playground/src/div.rs index 449583f29e..946d77e1f1 100644 --- a/crates/gpui/playground/src/div.rs +++ b/crates/gpui/playground/src/div.rs @@ -7,7 +7,7 @@ use anyhow::Result; use derive_more::{Deref, DerefMut}; use gpui::EngineLayout; use gpui::{geometry::rect::RectF, platform::MouseMovedEvent, EventContext}; -use playground_macros::styleable_trait; +use playground_macros::styleable_helpers; use refineable::Refineable; use smallvec::SmallVec; use util::ResultExt; @@ -63,8 +63,25 @@ pub trait Element { } } -use crate as playground; -styleable_trait!(); +use crate as playground; // Macro invocation below references this crate as playground. +pub trait Styleable { + type Style: refineable::Refineable; + + fn declared_style(&mut self) -> &mut playground::style::StyleRefinement; + + fn style(&mut self) -> playground::style::Style { + let mut style = playground::style::Style::default(); + style.refine(self.declared_style()); + style + } + + // Tailwind-style helpers methods that take and return mut self + // + // Example: + // // Sets the padding to 0.5rem, just like class="p-2" in Tailwind. + // fn p_2(mut self) -> Self where Self: Sized; + styleable_helpers!(); +} pub struct Div { style: StyleRefinement, @@ -106,7 +123,7 @@ impl Element for Div { where Self: Sized, { - todo!() + let style = self.style(); } } diff --git a/crates/gpui/playground_macros/src/playground_macros.rs b/crates/gpui/playground_macros/src/playground_macros.rs index 6e387b03cd..ce5cb6ba59 100644 --- a/crates/gpui/playground_macros/src/playground_macros.rs +++ b/crates/gpui/playground_macros/src/playground_macros.rs @@ -2,12 +2,12 @@ use proc_macro::TokenStream; mod derive_element; mod derive_into_element; -mod styleable_trait; +mod styleable_helpers; mod tailwind_lengths; #[proc_macro] -pub fn styleable_trait(args: TokenStream) -> TokenStream { - styleable_trait::styleable_trait(args) +pub fn styleable_helpers(args: TokenStream) -> TokenStream { + styleable_helpers::styleable_helpers(args) } #[proc_macro_derive(Element, attributes(element_crate))] diff --git a/crates/gpui/playground_macros/src/styleable_trait.rs b/crates/gpui/playground_macros/src/styleable_helpers.rs similarity index 87% rename from crates/gpui/playground_macros/src/styleable_trait.rs rename to crates/gpui/playground_macros/src/styleable_helpers.rs index e4325f6269..6c312e9752 100644 --- a/crates/gpui/playground_macros/src/styleable_trait.rs +++ b/crates/gpui/playground_macros/src/styleable_helpers.rs @@ -1,6 +1,62 @@ use proc_macro::TokenStream; use proc_macro2::TokenStream as TokenStream2; use quote::{format_ident, quote}; +use syn::{ + parse::{Parse, ParseStream, Result}, + parse_macro_input, +}; + +struct StyleableMacroInput; + +impl Parse for StyleableMacroInput { + fn parse(_input: ParseStream) -> Result { + Ok(StyleableMacroInput) + } +} + +pub fn styleable_helpers(input: TokenStream) -> TokenStream { + let _ = parse_macro_input!(input as StyleableMacroInput); + let methods = generate_methods(); + let output = quote! { + #(#methods)* + }; + output.into() +} + +fn generate_methods() -> Vec { + let mut methods = Vec::new(); + + for (prefix, auto_allowed, fields) in tailwind_prefixes() { + for (suffix, length_tokens) in tailwind_lengths() { + if !auto_allowed && suffix == "auto" { + // Conditional to skip "auto" + continue; + } + + let method_name = format_ident!("{}_{}", prefix, suffix); + let field_assignments = fields + .iter() + .map(|field_tokens| { + quote! { + style.#field_tokens = Some(gpui::geometry::#length_tokens.into()); + } + }) + .collect::>(); + + let method = quote! { + fn #method_name(mut self) -> Self where Self: std::marker::Sized { + let mut style = self.declared_style(); + #(#field_assignments)* + self + } + }; + + methods.push(method); + } + } + + methods +} fn tailwind_lengths() -> Vec<(&'static str, TokenStream2)> { vec![ @@ -73,55 +129,3 @@ fn tailwind_prefixes() -> Vec<(&'static str, bool, Vec)> { ("right", true, vec![quote! { inset.right }]), ] } - -pub fn styleable_trait(_item: TokenStream) -> TokenStream { - let mut methods = Vec::new(); - - for (prefix, auto_allowed, fields) in tailwind_prefixes() { - for (suffix, length_tokens) in tailwind_lengths() { - if !auto_allowed && suffix == "auto" { - // Conditional to skip "auto" - continue; - } - - let method_name = format_ident!("{}_{}", prefix, suffix); - - let field_assignments = fields - .iter() - .map(|field_tokens| { - quote! { - style.#field_tokens = Some(gpui::geometry::#length_tokens.into()); - } - }) - .collect::>(); - - let method = quote! { - fn #method_name(mut self) -> Self where Self: Sized { - let mut style = self.declared_style(); - #(#field_assignments)* - self - } - }; - - methods.push(method); - } - } - - let output = quote! { - pub trait Styleable { - type Style: refineable::Refineable; - - fn declared_style(&mut self) -> &mut playground::style::StyleRefinement; - - fn style(&mut self) -> playground::style::Style { - let mut style = playground::style::Style::default(); - style.refine(self.declared_style()); - style - } - - #(#methods)* - } - }; - - output.into() -}