react-spectrum
react-spectrum copied to clipboard
useSlottedContext should not throw when slot is not found
Provide a general summary of the issue here
Referring to this code:
if (!ctx.slots[slotKey]) {
let availableSlots = new Intl.ListFormat().format(Object.keys(ctx.slots).map(p => `"${p}"`));
let errorMessage = slot ? `Invalid slot "${slot}".` : 'A slot prop is required.';
throw new Error(`${errorMessage} Valid slot names are ${availableSlots}.`);
}
https://github.com/adobe/react-spectrum/blob/main/packages/react-aria-components/src/utils.tsx#L171-L176
This violates Open/Close principle, so that it hinders the ability to compose and add new slots in extended components.
Using Button as example, I want to add a clear slot and use the button to clear the text in a input field:
<InputField>
<ClearButton>
</InputField>
export function ClearButton() {
return <StyledButton slot="clear">X</StyledButton>
}
export const StyledButtonContext = createContext<ContextValue<...>>(null)
export const StyledButton = forwardRef(props, ref) {
;[props, ref] = useContextProps(props, ref, ButtonContext]
;[props, ref] = useContextProps(props, ref, StyledButtonContext]
return <Button ref={ref} {...props} style={{...}}/>
}
export function InputField({ children }) {
return (
<StyledButtonContext value={{ slots: { clear: { onPress: ... } } }}>
{children}
</StyledButtonContext>
)
}
Since the props { slot: 'clear' } is eventually passed to useSlottedContext, it throws.
Workaround this requires manually picking out slot: 'clear' in the StyledButton, breaking encapsulation and OCP.
Something like:
export const StyledButton = forwardRef(props, ref) {
const { slot, ...rest } = props
let baseButtonProps = slot === 'clear' ? rest : props
;[props, ref] = useContextProps(baseButtonProps, ref, ButtonContext]
;[props, ref] = useContextProps({ slot, ...props}, ref, StyledButtonContext]
baseButtonProps = slot === 'clear' ? rest : props
return <Button ref={ref} {...baseButtonProps} style={{...}}/>
}
You can see this is not scalable as more slots are used in the system.
๐ค Expected Behavior?
return undefined
๐ฏ Current Behavior
throw error
๐ Possible Solution
No response
๐ฆ Context
See above
๐ฅ๏ธ Steps to Reproduce
Hopefully the example above should be clear enough.
Version
1.13.0
What browsers are you seeing the problem on?
Chrome
If other, please specify.
No response
What operating system are you using?
macos
๐งข Your Company/Team
Palo Alto Networks
๐ท Tracking Issue
No response