primitives
primitives copied to clipboard
Allow more props in radix-slot (TypeScript)
Feature request
Overview
radix-slot
's props extend React.HTMLAttributes<HTMLElement>
. That is fine most of the time, but for more specialized scenarios, one may want to pass down more props. For example, if building a wrapper for form elements, you may need to forward the "name" prop, which isn't part of HTMLAttributes.
Aside for the types, radix-slot fully works with this scenario. Just need to make TypeScript happy.
Examples in other libraries
Not public, but right now I used the nuclear approach, and reexported my own slot, using the following snippet. It's not great because now it allows any and all attributes, but it unblocked me. I wonder if it could be improved by allowing passing generic types directly, or a factory function that returns a custom component with the exact props one may want.
import { Slot as ReactSlot } from "@radix-ui/react-slot";
export interface SlotProps extends React.AllHTMLAttributes<HTMLElement> {
children?: React.ReactNode;
}
const Slot = ReactSlot as React.ForwardRefExoticComponent<
SlotProps & React.RefAttributes<HTMLElement>
>;
export { Slot };
I could see something like this:
const CustomSlot = createSlot<React.InputHTMLAttributes>();
<Custom slot ....></CustomSlot>
Who does this impact? Who is this for?
Specialized slot use cases. I hit it when trying to modify Shadcn/ui's Form component to work better with Remix. Shadcn normally uses react-hook-form, which is client side and doesn't always need name props. Or you can set the name prop on the child component yourself.
But I wanted the wrapper component to get the name prop and pass it down to the child automatically. The types are currently preventing that.
Additional context
The reexport example above works fine and is an okay workaround, but something upstream would be great.
I used this variant
I think that making Slot a generic would be nice
type SlotPropsGeneric<Attr extends React.HTMLAttributes<HTMLElement> = React.HTMLAttributes<HTMLElement>> = Attr & {
children?: React.ReactNode;
};
type ElementAttributes<El extends HTMLElement> = El extends HTMLInputElement
? React.InputHTMLAttributes<El>
: React.HTMLAttributes<El>;
type SlotGeneric<T extends HTMLElement> = React.ForwardRefExoticComponent<
SlotPropsGeneric<ElementAttributes<T>> & React.RefAttributes<T>
>;
const InputSlot = Slot as SlotGeneric<HTMLInputElement>;
I came here to open an issue but found this one. Any updates regarding the generic props for Slot?
This is how we will use it:
function GenericSlot<P = React.HTMLAttributes<HTMLElement>>(props: SlotProps & P) {
return <Slot {...props} />;
}
return (
<GenericSlot<React.ComponentProps<"svg">>
width={"100"}
height={undefined}
className="w-[50px] md:w-[100px]"
>
{children}
</GenericSlot>
);