-
Notifications
You must be signed in to change notification settings - Fork 59
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
Feature Proposal: otherProps #205
Comments
The idea looks nice, even though I have few questions and implementation concerns. Let me start with basic question then we can go deeper. When you do this: <button {...otherProps(this)} class={`btn btn-size-${size}`}>
{children}
</button> Who is registering the other props as |
The basic implementation we have used so far can be seen here. It only takes one argument (which is the component itself, So in the case of Button.PROPS = {
size: Config.oneOf(['small', 'medium', 'large'])
}; I can render it like this: /* notice `title` and `onHover` are not listed as props above */
<Button size="small" title="myButton" onClick={myFunc} /> and calling {
title: "myButton",
onClick: [Function]
} From there we can just use the The reason we don't just apply something like Hopefully that helps to explain it a bit better. |
It does, thanks. That means you don't need the other props to be mapped as props, therefore you don't have any ability of a prop, like re-render when changed. You just want to pass them to an internal element. |
Feature Proposal:
otherProps
Hey everyone, so I had a feature proposal after seeing that we had a pattern that we both liked and saw ourselves repeating in probably all of our
metal-jsx
projects going forward. For now, I am calling itotherProps
and it works something like this:The Problem
Let's say have a basic component like
Button
and it is defined like this:It's pretty simple, but it allows use to create a component that behaves like a normal
button
, while exposing extra configuration that is specific to our app. However, we have a problem here when we want to start adding normal DOM attributes that we would expect to work with abutton
(or adiv
,input
, etc.):The API of your component will essentially keep growing endlessly as our use cases change and we require the ability to add basically any of the possible attributes in the HTML standard.
The Solution
What we have instead done is use a helper function to simplify this. You can
see it copied here to
metal-devtools
. So the previous example becomes this:Essentially,
otherProps
will take the component, and from it extract any passed props that was not defined in it'sPROPS
configuration, and pass them to theJSXElement
that it is being applied to. More specifically, it is making use of babel'sJSXSpreadAttribute
.While this is useful with very basic components like this
Button
, (or things like anIcon
component or aCard
component), it can also be very useful for larger components.Imagine you have some kind of
AutoComplete
component that accepts many different types of configuration through it's props. Later you write a higher-order component likeSelectWithAutoComplete
, that wraps your originalAutoComplete
component. Here you can also useotherProps
, so that any prop not defined bySelectWithAutoComplete
will be passed down toAutoComplete
. Even nicer still, if later someone adds more to theAutoComplete
API,SelectWithAutoComplete
will automatically work with those new features while not requiring any changes to its code.Implementations
My first thought was that this could just be a separate module, completely outside of
metal-jsx
. However because it was such a strong pattern for us, I thought it might be good to propose it here first.The simplest way would be to just expose it as a helper function like in the
above examples.
If we wanted to make it even nicer, we could check for some kind of special
attribute that tells
metal
to perform this behavior:element
or the child component containing theelement
will always receive the other props. Not my favorite idea, sinceyou might want to instead pass props down to some nested element in our
component. However, it would be simple.
Soy
So far this is mostly focused on
metal-jsx
, but it would be nice if we could also somehow implement this behavior formetal-soy
as well. Maybe it is already possible to achieve similar behavior somehow throughdata-all
but I am not sure. I know it is something we have missed when working withSoy
.Thanks!
@bryceosterhaus @ethib137
The text was updated successfully, but these errors were encountered: