maud icon indicating copy to clipboard operation
maud copied to clipboard

Optional concatenation in attribute blocks

Open TheNeikos opened this issue 2 years ago • 9 comments

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?

TheNeikos avatar Jun 23 '22 10:06 TheNeikos

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.

lambda-fairy avatar Sep 18 '22 12:09 lambda-fairy

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…

bgrundmann avatar Nov 23 '22 16:11 bgrundmann

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

lambda-fairy avatar Dec 15 '22 10:12 lambda-fairy

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.

TheNeikos avatar Dec 15 '22 14:12 TheNeikos

@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.

bgrundmann avatar Mar 01 '23 16:03 bgrundmann

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).

lambda-fairy avatar May 28 '23 11:05 lambda-fairy

Can't you use @if let Some?

mattfbacon avatar Jun 06 '23 22:06 mattfbacon

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,
}

hirschenberger avatar Aug 16 '23 07:08 hirschenberger