mixxorz / slippers

A UI component framework for Django. Built on top of Django Template Language.

Home Page:https://mitchel.me/slippers/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

pass arbitrary attributes to a component that knows how to 'spread' them into attributes?

RileyMathews opened this issue · comments

Hey there! Thanks so much for this library it has been a huge help in being able to clean up a lot of my templates.

I have what might be a pretty specific issue and there might be a way to solve it already I'm just not sure.

Say I have a relatively simple 'button' component that mostly just abstracts away the styling of the component.

{% var type=type|default:"button" %}
<button type={{ type }} class="p-4 bg-blue-400 rounded-md">{{ children }}</button>

This works great for being able to create a styled simple button that can optionally be turned into a 'submit' button for a form.

The use case where I am running into issues though is that I now need buttons with arbitrary data attributes specific to the javascript functionality I'm wiring up on some pages. This doesn't really play well with the current component system as the button component currently needs to be aware of all possible attributes passed to it. But I might have one page that needs an attribute data-refresh-trigger and another one that is data-delete-widget etc... it doesn't make sense that I would need to bloat the actual button component with logic to potentially add all of these arbitrary attributes.

Is it possible then to pass arbitrary attributes to a component and have them 'spread' into an element similar to python's **kwargs? If not I would be happy to discuss the appetite and possibility of including this and would be happy to explore and open a PR if that would be welcome.

My initial thought for how this feature would look from the consumer side is something like...

# component
<button type={{ type }} {{ attrs|spread }}>{{ children }}</button>

# template
{% #button type="submit" attrs="data-validate=true:data-refresh" %}Save and Refresh{% /button %}

# output
<button type="submit" data-validate="true" data-refresh>Save and Refresh</button>

I think after thinking about this more I have found some workarounds that are working for me. For the most part, I've been able to get the functionality I need by keeping 'style' information in the component while wrapping the slipper tags with 'spans' that have the data attributes. I'm not sure if this is 'accessible' or semantically the best way to write HTML but it is helping me keep my components generic and only worried about styles while letting the wrapping templates keep the knowledge of behavior which can differ from site to site.