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

Add attributes to partials #440

Open
Xenira opened this issue Aug 24, 2024 · 2 comments
Open

Add attributes to partials #440

Xenira opened this issue Aug 24, 2024 · 2 comments

Comments

@Xenira
Copy link

Xenira commented Aug 24, 2024

I know there have already been some issues regarding dynamic attributes, but I want to make this one for my specific case.
I am using maud together with htmx and want to create reusable components.

Given this simple example component I want to add different hx-* attributes to the button depending on where I use it.

fn my_fancy_btn(icon_name: &str, title: &str) -> Markup {
    html! {
        button.some.button.classes title=(title) {
            (icon(icon_name))
        }
    }
}

Possible solutions would be an Attribute function parameter similar to the Markup type (In this case a list of attributes would also need to be possible)

fn my_fancy_btn(icon_name: &str, title: &str, some_attr: Attribute) -> Markup {
    html! {
        button.some.button.classes title=(title) (attribute) {
            (icon(icon_name))
        }
    }
}

And/Or an option to add attributes to the root element of the Markup type:

html! {
  (my_fancy_btn("icon", "title")) hx-get="some-url"
  (my_fancy_btn("icon", "delete")) hx-delete="some-url"
}

Syntax for this one may need some tweeking

@puetzp
Copy link
Contributor

puetzp commented Sep 28, 2024

Have you considered using a match expression to achieve this? Currently there are two ways to use a match to create a reusable component like this. Let's say Attribute is an enum:

Option 1 (mauds own internal @match)

fn my_fancy_btn(icon_name: &str, title: &str, some_attr: Attribute) -> Markup {
    html! {
        @match some_attr {
            Attribute::HxGet(url) => {
                button.some.button.classes title=(title) hx-get=(url) {
                    (icon(icon_name))
                }
            },
            Attribute::HxDelete(url) => {
                button.some.button.classes title=(title) hx-delete=(url) {
                    (icon(icon_name))
                }
            },
            _ => todo!()
        }
    }
}

Option 2 (rusts pattern matching)

fn my_fancy_btn(icon_name: &str, title: &str, some_attr: Attribute) -> Markup {
    match some_attr {
        Attribute::HxGet(url) => html! {
            button.some.button.classes title=(title) hx-get=(url) {
                (icon(icon_name))
            }
        },
        Attribute::HxDelete(url) => html !{
            button.some.button.classes title=(title) hx-delete=(url) {
                (icon(icon_name))
            }
        },
        _ => todo!()
    }
}

Of course both possibilities are more verbose than the solution you are interested in. I just wanted to offer a workaround for your specific issue in case you were not aware how to resolve it.

@Xenira
Copy link
Author

Xenira commented Sep 28, 2024

Thanks for the reply. In cases where it just one attribute I did exactly this, but with more attributes it is not rly maintainable.

I also used

hx-get=[get_uri] hx-put=[put_uri] hx-switch=[switch] hx-target=[target] [...]

With a series of optionals in other cases where nested matches would have been way too much.

Still think that the ability to pass attributes directly would be great and would be willing to try implementing that.

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

No branches or pull requests

2 participants