0
# Singleton Mode
1
2
Singleton mode is a performance optimization technique that allows multiple tooltips to share a single instance, reducing memory usage and improving performance. This is particularly useful when you have many tooltips on a page that don't need to be shown simultaneously.
3
4
## Capabilities
5
6
### useSingleton Hook
7
8
Creates a singleton configuration that can be shared across multiple Tippy components.
9
10
```typescript { .api }
11
/**
12
* Hook for creating singleton tooltip configuration
13
* @param props - Optional singleton configuration
14
* @returns Tuple of [source, target] singleton objects
15
*/
16
function useSingleton(
17
props?: UseSingletonProps
18
): [SingletonObject, SingletonObject];
19
20
interface UseSingletonProps {
21
/** Disable singleton functionality */
22
disabled?: boolean;
23
/** Array of prop names that individual tooltips can override */
24
overrides?: Array<keyof Props>;
25
}
26
27
interface SingletonObject {
28
/** Internal singleton data */
29
data?: any;
30
/** Lifecycle hook function for singleton behavior */
31
hook(args: SingletonHookArgs): void;
32
}
33
34
interface SingletonHookArgs {
35
/** Tippy instance */
36
instance: Instance;
37
/** Tooltip content */
38
content: React.ReactNode;
39
/** Tippy props */
40
props: Props;
41
}
42
```
43
44
**Usage Examples:**
45
46
```typescript
47
import React from 'react';
48
import Tippy, { useSingleton } from '@tippyjs/react';
49
50
// Basic singleton usage
51
function BasicSingleton() {
52
const [source, target] = useSingleton();
53
54
return (
55
<>
56
{/* Source tooltip - the actual tooltip instance */}
57
<Tippy singleton={source} delay={500} />
58
59
{/* Target tooltips - these become "virtual" */}
60
<Tippy content="First tooltip" singleton={target}>
61
<button>Button 1</button>
62
</Tippy>
63
64
<Tippy content="Second tooltip" singleton={target}>
65
<button>Button 2</button>
66
</Tippy>
67
68
<Tippy content="Third tooltip" singleton={target}>
69
<button>Button 3</button>
70
</Tippy>
71
</>
72
);
73
}
74
```
75
76
### Singleton Configuration
77
78
Configure singleton behavior with props and overrides.
79
80
```typescript { .api }
81
interface UseSingletonProps {
82
/** Disable singleton functionality */
83
disabled?: boolean;
84
/** Props that individual tooltips can override */
85
overrides?: Array<keyof Props>;
86
}
87
```
88
89
**Usage Examples:**
90
91
```typescript
92
import React from 'react';
93
import Tippy, { useSingleton } from '@tippyjs/react';
94
95
// Singleton with configuration
96
function ConfiguredSingleton() {
97
const [source, target] = useSingleton({
98
disabled: false,
99
overrides: ['placement', 'theme'], // Allow individual tooltips to override these
100
});
101
102
return (
103
<>
104
<Tippy
105
singleton={source}
106
delay={300}
107
theme="dark"
108
placement="top"
109
/>
110
111
<Tippy content="Top tooltip" singleton={target}>
112
<button>Default (top, dark)</button>
113
</Tippy>
114
115
<Tippy
116
content="Bottom tooltip"
117
singleton={target}
118
placement="bottom" // Override allowed
119
>
120
<button>Bottom placement</button>
121
</Tippy>
122
123
<Tippy
124
content="Light tooltip"
125
singleton={target}
126
theme="light" // Override allowed
127
>
128
<button>Light theme</button>
129
</Tippy>
130
</>
131
);
132
}
133
```
134
135
### Headless Singleton
136
137
Use singleton mode with headless rendering for custom tooltip appearance.
138
139
```typescript { .api }
140
// Headless singleton render function receives content as second parameter
141
interface HeadlessRenderFunction {
142
(
143
attrs: RenderAttrs,
144
content?: React.ReactNode,
145
instance?: Instance
146
): React.ReactNode;
147
}
148
```
149
150
**Usage Examples:**
151
152
```typescript
153
import React from 'react';
154
import Tippy, { useSingleton } from '@tippyjs/react/headless';
155
156
function HeadlessSingleton() {
157
const [source, target] = useSingleton();
158
159
return (
160
<>
161
<Tippy
162
singleton={source}
163
render={(attrs, content) => (
164
<div className="custom-tooltip" tabIndex={-1} {...attrs}>
165
{content}
166
</div>
167
)}
168
delay={500}
169
/>
170
171
<Tippy content="Hello" singleton={target}>
172
<button>Button 1</button>
173
</Tippy>
174
175
<Tippy content="World" singleton={target}>
176
<button>Button 2</button>
177
</Tippy>
178
</>
179
);
180
}
181
```
182
183
### Disabled Singleton
184
185
Temporarily disable singleton behavior while keeping components mounted.
186
187
**Usage Examples:**
188
189
```typescript
190
import React, { useState } from 'react';
191
import Tippy, { useSingleton } from '@tippyjs/react';
192
193
function DisableableSingleton() {
194
const [singletonDisabled, setSingletonDisabled] = useState(false);
195
const [source, target] = useSingleton({
196
disabled: singletonDisabled,
197
});
198
199
return (
200
<div>
201
<button onClick={() => setSingletonDisabled(!singletonDisabled)}>
202
{singletonDisabled ? 'Enable' : 'Disable'} Singleton
203
</button>
204
205
<Tippy singleton={source} delay={300} />
206
207
<Tippy content="Tooltip 1" singleton={target}>
208
<button>Button 1</button>
209
</Tippy>
210
211
<Tippy content="Tooltip 2" singleton={target}>
212
<button>Button 2</button>
213
</Tippy>
214
</div>
215
);
216
}
217
```
218
219
### Complex Singleton Example
220
221
Advanced singleton usage with dynamic content and state management.
222
223
**Usage Examples:**
224
225
```typescript
226
import React, { useState } from 'react';
227
import Tippy, { useSingleton } from '@tippyjs/react';
228
229
interface User {
230
id: number;
231
name: string;
232
email: string;
233
role: string;
234
}
235
236
function UserList() {
237
const [source, target] = useSingleton({
238
overrides: ['content'], // Allow each tooltip to have different content
239
});
240
241
const users: User[] = [
242
{ id: 1, name: 'Alice', email: 'alice@example.com', role: 'Admin' },
243
{ id: 2, name: 'Bob', email: 'bob@example.com', role: 'User' },
244
{ id: 3, name: 'Charlie', email: 'charlie@example.com', role: 'Moderator' },
245
];
246
247
const renderUserTooltip = (user: User) => (
248
<div>
249
<strong>{user.name}</strong>
250
<br />
251
{user.email}
252
<br />
253
Role: {user.role}
254
</div>
255
);
256
257
return (
258
<>
259
<Tippy
260
singleton={source}
261
placement="top"
262
delay={[800, 200]}
263
interactive={true}
264
/>
265
266
<div className="user-list">
267
{users.map(user => (
268
<Tippy
269
key={user.id}
270
content={renderUserTooltip(user)}
271
singleton={target}
272
>
273
<div className="user-card">
274
{user.name}
275
</div>
276
</Tippy>
277
))}
278
</div>
279
</>
280
);
281
}
282
```
283
284
## Performance Benefits
285
286
Singleton mode provides several performance advantages:
287
288
1. **Memory Efficiency**: Only one tooltip DOM element exists instead of multiple
289
2. **Reduced Overhead**: Shared event listeners and positioning calculations
290
3. **Smooth Transitions**: Tooltips can smoothly transition between different targets
291
4. **Better UX**: Prevents multiple tooltips from appearing simultaneously
292
293
## Key Considerations
294
295
- The source tooltip defines the shared configuration (styling, positioning, delays, etc.)
296
- Target tooltips can only override props specified in the `overrides` array
297
- Only one tooltip can be visible at a time in singleton mode
298
- The `content` prop on individual target tooltips is automatically included in overrides
299
- Singleton mode works with both default and headless rendering
300
- Use singleton when you have many tooltips that don't need to be shown simultaneously