Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optional concatenation in attribute blocks #347

Open
TheNeikos opened this issue Jun 23, 2022 · 9 comments
Open

Optional concatenation in attribute blocks #347

TheNeikos opened this issue Jun 23, 2022 · 9 comments

Comments

@TheNeikos
Copy link
Contributor

I'm using tailwindcss, it uses a lot of classes that are annoying to write in rust/maud: mt-8, space-y-6 etc...

So, I usually resort to write div class="mt-8 space-y-6", and sometimes even

div class={
  "mt-8 etc..."
}

Now, currently maud supports having concatenating multiple strings like this:

div class={
  "mt-8 "
  "space-y-6"
}

(notice the extra space in the first, since no additional space is added here sadly)

Now, I would like to be able to have an optional class in this situation. I did not find a suitable feature in this situation, so I would suggest something akin to this:

let optional_error_classes: Option<String>;

// ...
div class={
  "mt-8 "
  [optional_error_classes]
}

With None simply being handled as "" and the content otherwise.

What do you think?

@lambda-fairy
Copy link
Owner

Hi @TheNeikos!

Sorry about the late response 😅

Do you know about the class shorthand syntax? We can get something similar with the following:

let has_space: bool;

// ...
div ."mt-8" ."space-y-6"[has_space]

https://maud.lambda.xyz/elements-attributes.html#classes-and-ids-foo-bar
https://maud.lambda.xyz/splices-toggles.html#toggles-foo

If you need to support Option<String> specifically, then we could add a .[some_option] syntax, similar to the existing attr=[some_option] syntax for optional attributes. But I want to check if this is needed first.

@bgrundmann
Copy link

I would love to have .[aoptionalclassname]

rationale:

when using bulma I sometimes want to apply one of the Color modifier classes (is-primary, is-danger) computed at runtime, sadly the neutral Color in bulma is indicated by the absence of any indicator…

@lambda-fairy
Copy link
Owner

@bgrundmann does .is-primary[state == State::Primary].is-danger[state == State::Danger] work for you?

@TheNeikos
Copy link
Contributor Author

Do you know about the class shorthand syntax? We can get something similar with the following:

let has_space: bool;

// ...
div ."mt-8" ."space-y-6"[has_space]

Yes that is true, but I find writing ."" very cumbersome for the 10+ classes tailwind sometimes requires.

@bgrundmann
Copy link

@bgrundmann does .is-primary[state == State::Primary].is-danger[state == State::Danger] work for you?

Sorry for the late reply my GitHub email notifications got lost in my inbox. Yeah that works. That said the '.[aoptionalclassname]' would I think in the end read better. But I can understand not wanting to make the language too complicated.

@lambda-fairy
Copy link
Owner

I would love to have .[aoptionalclassname]

Oh that sounds good to me. I don't think it makes the language more complicated, since it's "filling in a hole" (so to speak).

@mattfbacon
Copy link
Contributor

Can't you use @if let Some?

@hirschenberger
Copy link

hirschenberger commented Aug 16, 2023

How about:

#[derive(Clone, Default, Debug, PartialEq, strum_macros::Display)]
pub enum Color {
    #[default]
    #[strum(serialize = "")]
    Default,
    #[strum(serialize = "is-success")]
    Success,
    #[strum(serialize = "is-warning")]
    Warning,
    #[strum(serialize = "is-danger")]
    Danger,
    #[strum(serialize = "is-info")]
    Info,
}

#[derive(Clone, Default, Debug, PartialEq, strum_macros::Display)]
pub enum Size {
    #[strum(serialize = "is-small")]
    Small,
    #[default]
    #[strum(serialize = "")]
    Default,
    #[strum(serialize = "is-medium")]
    Medium,
    #[strum(serialize = "is-large")]
    Large,
}

And using it like:

let state = Color::Danger;
let size = Size::Large;

html! {
  .message (size) (state) {
    .message-body {
      "Hamburgefontsiv" 
    }
  }
}

You can even make it more compact by using strum's kebab-case conversion:

#[derive(Clone, Default, Debug, PartialEq, strum_macros::Display)]
#[strum(serialize_all = "kebab-case")]
pub enum Size {
    IsSmall,
    IsMedium,
    IsLarge,
}

@avdb13
Copy link

avdb13 commented May 13, 2024

Updates? Attempting to use Maud with Tailwind too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants