`MergeProvider`
- Dominant language
- TypeScript
- Stars
- 15.9k
- Forks
- 1.6k
- Avg merge
- 3d 5h
- Merged PRs (30d)
- 58
Description
### Provide a general summary of the feature here
It is desirable to be able to merge slot props onto an existing slot. In order to do so, you must extract the context and merge your props into the existing slot and then provide the updated context.
### 🤔 Expected Behavior?
`MergeProvider` would consume the context of any context that it is provided and attempt to merge the new values in on top using the `mergeProps` util
### 😯 Current Behavior
Only `Provider` exists and it doesn't support merging, only overriding
### 💁 Possible Solution
I've created a rough first draft. Keep in mind that I'm using my own `mergeProps` that is built on top of the RAC `mergeProps` but replaces the behavior for merging of `className` and `style` to support render props.
```tsx
import { type Context, type ReactNode } from 'react';
import { mergeProps } from '../../utils';
import { type MergeProviderProps } from './types';
function merge(context: Context, next: T, children: ReactNode) {
return function Consumer(prev: T) {
let merged = next;
if (
prev != null &&
next != null &&
typeof prev === 'object' &&
typeof next === 'object'
) {
const prevSlots =
'slots' in prev && (prev.slots as Record);
const nextSlots =
'slots' in next && (next.slots as Record);
if (prevSlots && nextSlots) {
merged = {
...prev,
...next,
slots: {
...prevSlots,
...nextSlots,
...Object.entries(nextSlots).reduce>(
(acc, [key, value]) => {
if (Object.hasOwn(prevSlots, key)) {
acc[key] = mergeProps(prevSlots[key], value);
}
return acc;
},
{}
),
},
} as T;
} else if (!prevSlots && !nextSlots) {
merged = mergeProps(prev as object, next as object) as T;
}
}
return {children};
};
}
export function MergeProvider({
values,
children,
}: MergeProviderProps) {
for (let [context, next] of values) {
children = (
{merge(context as Context, next, children)}
);
}
return <>{children};
}
```
### 🔦 Context
I'm implementing a custom component built on top of an RAC that currently implements the "remove" slot for a button. I want to maintain all of the RAC props for that slot, but I also want to add my own. If I were to just implement the `Provider`, then the context is overridden and I would lose (or have to completely reimplement) the RAC props. Instead, I'd like to implement `MergeProvider` that will automatically merge props for slots that exist in both versions of the context
### 💻 Examples
_No response_
### 🧢 Your Company/Team
_No response_
### 🕷 Tracking Issue
_No response_
Contributor guide
Research direction
Start by locating the existing Provider, MergeProviderProps, and mergeProps utility referenced by the proposal, then read how React context values and slot props are currently handled. Done means a MergeProvider can merge supplied context values, including overlapping slot props, without losing existing provider values; the issue does not name a test file or specific implementation entry point.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- react, typescript
- Domain
- frontend
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100