0
# React Slot
1
2
React 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.
3
4
## Package Information
5
6
- **Package Name**: @radix-ui/react-slot
7
- **Package Type**: npm
8
- **Language**: TypeScript
9
- **Installation**: `npm install @radix-ui/react-slot`
10
11
## Core Imports
12
13
```typescript
14
import { Slot, Slottable } from "@radix-ui/react-slot";
15
```
16
17
For CommonJS:
18
19
```javascript
20
const { Slot, Slottable } = require("@radix-ui/react-slot");
21
```
22
23
Additional imports:
24
25
```typescript
26
import {
27
Slot,
28
Slottable,
29
Root,
30
createSlot,
31
createSlottable,
32
type SlotProps
33
} from "@radix-ui/react-slot";
34
```
35
36
## Basic Usage
37
38
```typescript
39
import React from "react";
40
import { Slot, Slottable } from "@radix-ui/react-slot";
41
42
// Basic slot usage - merges props between parent and child
43
function MyButton({ asChild, ...props }) {
44
const Comp = asChild ? Slot : "button";
45
return <Comp {...props} />;
46
}
47
48
// Usage: renders an anchor with button's props
49
<MyButton asChild onClick={handleClick} className="btn">
50
<a href="/link">Link Button</a>
51
</MyButton>
52
53
// Complex composition with Slottable
54
function IconButton({ children, icon, asChild, ...props }) {
55
const Comp = asChild ? Slot : "button";
56
return (
57
<Comp {...props}>
58
{icon}
59
<Slottable>{children}</Slottable>
60
</Comp>
61
);
62
}
63
64
// Usage: child content replaces Slottable, preserving icon
65
<IconButton asChild icon={<HomeIcon />} onClick={handleClick}>
66
<a href="/home">Home</a>
67
</IconButton>
68
```
69
70
## Architecture
71
72
React Slot implements the slot pattern through several key components:
73
74
- **Slot Component**: Core component that merges props and renders child elements with intelligent prop composition
75
- **Slottable Component**: Marks content as replaceable within slot patterns, enabling complex composition scenarios
76
- **Prop Merging**: Intelligent merging of event handlers, styles, className, and refs between slot and child components
77
- **Ref Composition**: Cross-React-version compatible ref forwarding and composition using @radix-ui/react-compose-refs
78
- **Factory Functions**: Utilities for creating custom slot components with proper display names
79
80
## Capabilities
81
82
### Slot Component
83
84
Main component implementing the slot pattern for prop merging and element composition.
85
86
```typescript { .api }
87
interface SlotProps extends React.HTMLAttributes<HTMLElement> {
88
children?: React.ReactNode;
89
}
90
91
declare const Slot: React.ForwardRefExoticComponent<
92
SlotProps & React.RefAttributes<HTMLElement>
93
>;
94
```
95
96
The Slot component:
97
- Merges props between itself and its child element
98
- Composes event handlers (child first, then slot)
99
- Merges styles and concatenates className attributes
100
- Forwards and composes refs across React versions
101
- Handles Slottable children with special composition logic
102
103
**Usage Example:**
104
105
```typescript
106
// Component using slot pattern
107
function Button({ asChild, children, ...props }) {
108
const Comp = asChild ? Slot : "button";
109
return <Comp {...props}>{children}</Comp>;
110
}
111
112
// Usage - child element receives merged props
113
<Button asChild onClick={handleClick} className="btn-primary">
114
<a href="/link" className="link">Custom Link</a>
115
</Button>
116
// Renders: <a href="/link" onClick={handleClick} className="btn-primary link">Custom Link</a>
117
```
118
119
### Slottable Component
120
121
Component for marking content as slottable within slot composition patterns.
122
123
```typescript { .api }
124
interface SlottableProps {
125
children: React.ReactNode;
126
}
127
128
declare const Slottable: React.FC<SlottableProps>;
129
```
130
131
The Slottable component:
132
- Marks content as replaceable in slot patterns
133
- Renders children as a transparent wrapper (React Fragment)
134
- Contains internal identifier for slot recognition
135
- Enables complex composition where some content is replaced and some is preserved
136
137
**Usage Example:**
138
139
```typescript
140
function IconButton({ children, icon, asChild, ...props }) {
141
const Comp = asChild ? Slot : "button";
142
return (
143
<Comp {...props}>
144
{icon}
145
<Slottable>{children}</Slottable>
146
</Comp>
147
);
148
}
149
150
// When used with asChild, only Slottable content is replaced
151
<IconButton asChild icon={<StarIcon />}>
152
<a href="/favorite">Favorite</a>
153
</IconButton>
154
// Result: <a href="/favorite"><StarIcon />Favorite</a>
155
```
156
157
### Root Component
158
159
Alias for the Slot component, provided for semantic naming convenience.
160
161
```typescript { .api }
162
declare const Root: React.ForwardRefExoticComponent<
163
SlotProps & React.RefAttributes<HTMLElement>
164
>;
165
```
166
167
Root is identical to Slot and can be used interchangeably for improved component naming in specific contexts.
168
169
### Factory Functions
170
171
Utilities for creating custom slot components with proper display names.
172
173
```typescript { .api }
174
/**
175
* Creates a custom Slot component with specified display name
176
* @param ownerName - Name used for component displayName
177
* @returns ForwardRef Slot component
178
*/
179
function createSlot(ownerName: string): React.ForwardRefExoticComponent<
180
SlotProps & React.RefAttributes<HTMLElement>
181
>;
182
183
/**
184
* Creates a custom Slottable component with specified display name
185
* @param ownerName - Name used for component displayName
186
* @returns Slottable component with internal identifier for slot recognition
187
*/
188
function createSlottable(ownerName: string): React.FC<SlottableProps>;
189
```
190
191
These factory functions allow creating custom slot components with meaningful display names for debugging and development tools.
192
193
**Usage Example:**
194
195
```typescript
196
// Create custom slot components
197
const MySlot = createSlot("MyComponent");
198
const MySlottable = createSlottable("MyComponent");
199
200
// MySlot.displayName === "MyComponent.Slot"
201
// MySlottable.displayName === "MyComponent.Slottable"
202
```
203
204
## Prop Merging Behavior
205
206
React Slot implements intelligent prop merging with specific rules:
207
208
### Event Handlers
209
- Both slot and child handlers are called
210
- Child handler executes first, then slot handler
211
- Child handler's return value is preserved
212
- If only one handler exists, it's used directly
213
214
```typescript
215
// Both onClick handlers will be called
216
<Slot onClick={() => console.log("slot")}>
217
<button onClick={() => console.log("child")}>Click</button>
218
</Slot>
219
// Output when clicked: "child", then "slot"
220
```
221
222
### Style Props
223
- Object styles are merged with child styles taking precedence
224
- `{ ...slotStyles, ...childStyles }`
225
226
```typescript
227
<Slot style={{ color: "red", fontSize: "16px" }}>
228
<div style={{ fontSize: "18px", fontWeight: "bold" }}>Text</div>
229
</Slot>
230
// Result: { color: "red", fontSize: "18px", fontWeight: "bold" }
231
```
232
233
### ClassName
234
- Class names are concatenated with space separation
235
- Both slot and child classes are preserved
236
237
```typescript
238
<Slot className="btn btn-primary">
239
<button className="custom-btn">Click</button>
240
</Slot>
241
// Result: className="btn btn-primary custom-btn"
242
```
243
244
### Other Props
245
- Child props override slot props for all other attributes
246
- Refs are composed using @radix-ui/react-compose-refs
247
- React Fragment children are handled without ref warnings in React 19+
248
249
## Error Handling
250
251
React Slot handles edge cases gracefully:
252
253
- Invalid React elements are ignored and return null
254
- Multiple children in Slottable content throws appropriate React warnings
255
- Multiple direct children without valid React elements return null
256
- React Fragment children are handled without ref warnings in React 19+
257
- Cross-React-version ref handling prevents warnings in development mode
258
259
## Types
260
261
```typescript { .api }
262
interface SlotProps extends React.HTMLAttributes<HTMLElement> {
263
children?: React.ReactNode;
264
}
265
266
interface SlottableProps {
267
children: React.ReactNode;
268
}
269
```