formaat-design / reshaped

Community repository for storing examples, reporting issues and tracking roadmap
https://reshaped.so
97 stars 3 forks source link

New <Button> "as" attribute to avoid <button> nesting in HTML #222

Closed vladoyoung closed 4 months ago

vladoyoung commented 4 months ago

Is your feature request related to a problem? Please describe. image I'm building a file finder/system component within an app, and I want to have <Button> components within a <MenuItem> component. The problem here is that is semantically incorrect, and I get a console error thrown: Warning: validateDOMNesting(...): <button> cannot appear as a descendant of <button>.

This happens because both Reshaped <MenuItem> and <Button> have onClick events, and the Reshaped logic turns them into HTML <button> elements.

Describe the solution you'd like A new as="<string>" attribute to the Reshaped <Button> component, which would force the HTML render of the element to the component of my choosing. In this case I'll be using it as a <div>. I've wondered if this should actually be an option on the <MenuItem> component, but it being on <Button> will be more versatile on the long run.

Describe alternatives you've considered We've considered workarounds by switching <MenuItem> with <View>, but there will be more work involved, and many baked-in features of <MenuItem> will be omitted. Also tried with <Actionable>, but then we can't get the <Button> styling in there. We've also tried other design approaches, but when it comes to UX it becomes a bit unintuitive, because every other file finder/system provider (Google Drive for example) works this way.

Additional context Although this is a bit incorrect if we're trying to be semantically correct, it's a gain in terms of UX. We'll be introducing click events within click events and will need to stop propagation of the other click events (not needed by Reshaped if implemented), but the user experience will be generally better.

Open to any suggestions too!

blvdmitry commented 4 months ago

Hey, I'll prioritize this for the next release planned for the coming Monday. Actionable already supports an as property so it should be quite easy to add support for that.

I'm assuming that if you change the internal button to a div with tabIndex, clicking it will still trigger the the parent button click handler. Do you plan to add stopPropagation to handle that or have you had other ideas about it?

vladoyoung commented 4 months ago

I'm assuming that if you change the internal button to a div with tabIndex, clicking it will still trigger the the parent button click handler. Do you plan to add stopPropagation to handle that or have you had other ideas about it?

Yes, at the moment I'm using event.stopPropagation() to cancel out conflicting click events.

blvdmitry commented 4 months ago

Just merged, releasing it on Monday (which actually usually happens over the weekend)

blvdmitry commented 4 months ago

https://github.com/formaat-design/reshaped/assets/887379/44d59978-2c1b-4c3d-8e05-0b81c11936d1

vladoyoung commented 4 months ago

Awesome! Thanks for sorting so quickly!