React component for merging props and composing elements with customizable rendering behavior through slot pattern implementation
npx @tessl/cli install tessl/npm-radix-ui--react-slot@1.2.0React Slot provides a powerful slot pattern implementation for React, enabling prop merging and element composition with customizable rendering behavior. It allows developers to create flexible, reusable components where child elements can override or extend parent component behavior while maintaining proper ref forwarding and event handler composition.
npm install @radix-ui/react-slotimport { Slot, Slottable } from "@radix-ui/react-slot";For CommonJS:
const { Slot, Slottable } = require("@radix-ui/react-slot");Additional imports:
import {
Slot,
Slottable,
Root,
createSlot,
createSlottable,
type SlotProps
} from "@radix-ui/react-slot";import React from "react";
import { Slot, Slottable } from "@radix-ui/react-slot";
// Basic slot usage - merges props between parent and child
function MyButton({ asChild, ...props }) {
const Comp = asChild ? Slot : "button";
return <Comp {...props} />;
}
// Usage: renders an anchor with button's props
<MyButton asChild onClick={handleClick} className="btn">
<a href="/link">Link Button</a>
</MyButton>
// Complex composition with Slottable
function IconButton({ children, icon, asChild, ...props }) {
const Comp = asChild ? Slot : "button";
return (
<Comp {...props}>
{icon}
<Slottable>{children}</Slottable>
</Comp>
);
}
// Usage: child content replaces Slottable, preserving icon
<IconButton asChild icon={<HomeIcon />} onClick={handleClick}>
<a href="/home">Home</a>
</IconButton>React Slot implements the slot pattern through several key components:
Main component implementing the slot pattern for prop merging and element composition.
interface SlotProps extends React.HTMLAttributes<HTMLElement> {
children?: React.ReactNode;
}
declare const Slot: React.ForwardRefExoticComponent<
SlotProps & React.RefAttributes<HTMLElement>
>;The Slot component:
Usage Example:
// Component using slot pattern
function Button({ asChild, children, ...props }) {
const Comp = asChild ? Slot : "button";
return <Comp {...props}>{children}</Comp>;
}
// Usage - child element receives merged props
<Button asChild onClick={handleClick} className="btn-primary">
<a href="/link" className="link">Custom Link</a>
</Button>
// Renders: <a href="/link" onClick={handleClick} className="btn-primary link">Custom Link</a>Component for marking content as slottable within slot composition patterns.
interface SlottableProps {
children: React.ReactNode;
}
declare const Slottable: React.FC<SlottableProps>;The Slottable component:
Usage Example:
function IconButton({ children, icon, asChild, ...props }) {
const Comp = asChild ? Slot : "button";
return (
<Comp {...props}>
{icon}
<Slottable>{children}</Slottable>
</Comp>
);
}
// When used with asChild, only Slottable content is replaced
<IconButton asChild icon={<StarIcon />}>
<a href="/favorite">Favorite</a>
</IconButton>
// Result: <a href="/favorite"><StarIcon />Favorite</a>Alias for the Slot component, provided for semantic naming convenience.
declare const Root: React.ForwardRefExoticComponent<
SlotProps & React.RefAttributes<HTMLElement>
>;Root is identical to Slot and can be used interchangeably for improved component naming in specific contexts.
Utilities for creating custom slot components with proper display names.
/**
* Creates a custom Slot component with specified display name
* @param ownerName - Name used for component displayName
* @returns ForwardRef Slot component
*/
function createSlot(ownerName: string): React.ForwardRefExoticComponent<
SlotProps & React.RefAttributes<HTMLElement>
>;
/**
* Creates a custom Slottable component with specified display name
* @param ownerName - Name used for component displayName
* @returns Slottable component with internal identifier for slot recognition
*/
function createSlottable(ownerName: string): React.FC<SlottableProps>;These factory functions allow creating custom slot components with meaningful display names for debugging and development tools.
Usage Example:
// Create custom slot components
const MySlot = createSlot("MyComponent");
const MySlottable = createSlottable("MyComponent");
// MySlot.displayName === "MyComponent.Slot"
// MySlottable.displayName === "MyComponent.Slottable"React Slot implements intelligent prop merging with specific rules:
// Both onClick handlers will be called
<Slot onClick={() => console.log("slot")}>
<button onClick={() => console.log("child")}>Click</button>
</Slot>
// Output when clicked: "child", then "slot"{ ...slotStyles, ...childStyles }<Slot style={{ color: "red", fontSize: "16px" }}>
<div style={{ fontSize: "18px", fontWeight: "bold" }}>Text</div>
</Slot>
// Result: { color: "red", fontSize: "18px", fontWeight: "bold" }<Slot className="btn btn-primary">
<button className="custom-btn">Click</button>
</Slot>
// Result: className="btn btn-primary custom-btn"React Slot handles edge cases gracefully:
interface SlotProps extends React.HTMLAttributes<HTMLElement> {
children?: React.ReactNode;
}
interface SlottableProps {
children: React.ReactNode;
}