Properly merge incoming props (#1265)

* rename inconsistent `passThroughProps` and `passthroughProps` to more
concise `incomingProps`

This is going to make a bit more sense in the next commits of this
branch, hold on!

* split props into `propsWeControl` and `propsTheyControl`

This will allow us to merge the props with a bit more control. Instead
of overriding every prop from the user' props with our props, we can now
merge event listeners.

* update `render` API to accept `propsWeControl` and `propsTheyControl`

* improve the merge logic

This will essentially do the exact same thing we were doing before:
```js
let props = { ...propsTheyControl, ...propsWeControl }
```

But instead of overriding everything, we will merge the event listener
related props like `onClick`, `onKeyDown`, ...

* fix typo in tests

* simplify naming

- Rename `propsWeControl` to `ourProps`
- Rename `propsTheyControl` to `theirProps`

* update changelog
This commit is contained in:
Robin Malfait
2022-03-22 17:32:11 +01:00
committed by GitHub
parent 4f8c615245
commit 3e19aa5c97
37 changed files with 398 additions and 283 deletions
@@ -49,6 +49,9 @@ function Group<TTag extends ElementType = typeof DEFAULT_GROUP_TAG>(props: Props
[switchElement, setSwitchElement, labelledby, describedby]
)
let ourProps = {}
let theirProps = props
return (
<DescriptionProvider name="Switch.Description">
<LabelProvider
@@ -62,7 +65,12 @@ function Group<TTag extends ElementType = typeof DEFAULT_GROUP_TAG>(props: Props
}}
>
<GroupContext.Provider value={context}>
{render({ props, defaultTag: DEFAULT_GROUP_TAG, name: 'Switch.Group' })}
{render({
ourProps,
theirProps,
defaultTag: DEFAULT_GROUP_TAG,
name: 'Switch.Group',
})}
</GroupContext.Provider>
</LabelProvider>
</DescriptionProvider>
@@ -101,7 +109,7 @@ let SwitchRoot = forwardRefWithAs(function Switch<
},
ref: Ref<HTMLElement>
) {
let { checked, onChange, name, value, ...passThroughProps } = props
let { checked, onChange, name, value, ...theirProps } = props
let id = `headlessui-switch-${useId()}`
let groupContext = useContext(GroupContext)
let internalSwitchRef = useRef<HTMLButtonElement | null>(null)
@@ -136,7 +144,7 @@ let SwitchRoot = forwardRefWithAs(function Switch<
)
let slot = useMemo<SwitchRenderPropArg>(() => ({ checked }), [checked])
let propsWeControl = {
let ourProps = {
id,
ref: switchRef,
role: 'switch',
@@ -151,7 +159,8 @@ let SwitchRoot = forwardRefWithAs(function Switch<
}
let renderConfiguration = {
props: { ...passThroughProps, ...propsWeControl },
ourProps,
theirProps,
slot,
defaultTag: DEFAULT_SWITCH_TAG,
name: 'Switch',