or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-tooltip.mdevent-delegation.mdglobal-utilities.mdindex.mdplugins.mdsingleton-tooltips.md

singleton-tooltips.mddocs/

0

# Singleton Tooltips

1

2

Singleton system for creating shared tooltips that can be displayed across multiple reference elements with smooth transitions and centralized management.

3

4

## Capabilities

5

6

### Create Singleton

7

8

Creates a single tooltip instance that can be shared across multiple reference elements, providing smooth transitions and consistent presentation.

9

10

```typescript { .api }

11

/**

12

* Creates a singleton tooltip that can be shared across multiple instances

13

* @param tippyInstances - Array of existing tippy instances to control

14

* @param optionalProps - Optional properties for the singleton

15

* @returns Enhanced singleton instance with additional methods

16

*/

17

function createSingleton<TProps = Props>(

18

tippyInstances: Instance[],

19

optionalProps?: Partial<CreateSingletonProps<TProps>>

20

): CreateSingletonInstance<CreateSingletonProps<TProps>>;

21

22

type CreateSingletonProps<TProps = Props> = TProps & {

23

/** Properties that can be overridden by individual instances */

24

overrides: Array<keyof TProps>;

25

};

26

27

interface CreateSingletonInstance<TProps = CreateSingletonProps> extends Instance<TProps> {

28

/** Update the controlled instances */

29

setInstances(instances: Instance[]): void;

30

/** Show tooltip for specific target */

31

show(target?: ReferenceElement | Instance | number): void;

32

/** Show tooltip for next instance in sequence */

33

showNext(): void;

34

/** Show tooltip for previous instance in sequence */

35

showPrevious(): void;

36

}

37

```

38

39

**Usage Examples:**

40

41

```typescript

42

import tippy, { createSingleton } from "tippy.js";

43

44

// Create individual instances (initially disabled)

45

const instances = [

46

tippy('#button1', { content: 'Button 1 content' }),

47

tippy('#button2', { content: 'Button 2 content' }),

48

tippy('#button3', { content: 'Button 3 content' })

49

];

50

51

// Create singleton to control them

52

const singleton = createSingleton(instances, {

53

delay: 500,

54

placement: 'top',

55

moveTransition: 'transform 0.2s ease-out',

56

overrides: ['content', 'placement'] // Allow individual overrides

57

});

58

59

// Singleton automatically shows appropriate content when hovering over any button

60

```

61

62

### Navigation Methods

63

64

Built-in navigation methods for programmatically controlling which tooltip is displayed.

65

66

```typescript { .api }

67

interface CreateSingletonInstance<TProps = CreateSingletonProps> {

68

/** Show tooltip for specific target by element, instance, or index */

69

show(target?: ReferenceElement | Instance | number): void;

70

/** Show tooltip for next instance in sequence */

71

showNext(): void;

72

/** Show tooltip for previous instance in sequence */

73

showPrevious(): void;

74

}

75

```

76

77

**Usage Examples:**

78

79

```typescript

80

import tippy, { createSingleton } from "tippy.js";

81

82

const instances = [

83

tippy('#step1', { content: 'Step 1: Introduction' }),

84

tippy('#step2', { content: 'Step 2: Configuration' }),

85

tippy('#step3', { content: 'Step 3: Completion' })

86

];

87

88

const singleton = createSingleton(instances, {

89

placement: 'bottom',

90

theme: 'tutorial'

91

});

92

93

// Programmatic navigation

94

function startTutorial() {

95

singleton.show(0); // Show first tooltip

96

}

97

98

function nextStep() {

99

singleton.showNext(); // Move to next tooltip

100

}

101

102

function previousStep() {

103

singleton.showPrevious(); // Move to previous tooltip

104

}

105

106

// Keyboard navigation

107

document.addEventListener('keydown', (e) => {

108

if (e.key === 'ArrowRight') nextStep();

109

if (e.key === 'ArrowLeft') previousStep();

110

if (e.key === 'Escape') singleton.hide();

111

});

112

```

113

114

### Instance Management

115

116

Dynamic management of controlled instances with the ability to add, remove, or replace instances.

117

118

```typescript { .api }

119

interface CreateSingletonInstance<TProps = CreateSingletonProps> {

120

/** Replace all controlled instances with new set */

121

setInstances(instances: Instance[]): void;

122

}

123

```

124

125

**Usage Examples:**

126

127

```typescript

128

import tippy, { createSingleton } from "tippy.js";

129

130

// Initial setup

131

let instances = [

132

tippy('#item1', { content: 'Item 1' }),

133

tippy('#item2', { content: 'Item 2' })

134

];

135

136

const singleton = createSingleton(instances);

137

138

// Add new instances dynamically

139

function addTooltipTarget(element, content) {

140

const newInstance = tippy(element, { content });

141

instances.push(newInstance);

142

singleton.setInstances(instances); // Update singleton

143

}

144

145

// Remove instances

146

function removeTooltipTarget(element) {

147

instances = instances.filter(instance => instance.reference !== element);

148

singleton.setInstances(instances); // Update singleton

149

}

150

151

// Replace all instances

152

function updateAllTargets(newElements) {

153

instances = newElements.map(el => tippy(el, {

154

content: el.getAttribute('data-tooltip')

155

}));

156

singleton.setInstances(instances);

157

}

158

```

159

160

### Property Overrides

161

162

Flexible override system allowing individual instances to customize specific properties while sharing common singleton behavior.

163

164

```typescript { .api }

165

type CreateSingletonProps<TProps = Props> = TProps & {

166

/** Array of property names that can be overridden by individual instances */

167

overrides: Array<keyof TProps>;

168

};

169

```

170

171

**Usage Examples:**

172

173

```typescript

174

import tippy, { createSingleton } from "tippy.js";

175

176

// Create instances with different placements and content

177

const instances = [

178

tippy('#top-button', {

179

content: 'Top button',

180

placement: 'bottom' // Will override singleton

181

}),

182

tippy('#side-button', {

183

content: 'Side button',

184

placement: 'left' // Will override singleton

185

}),

186

tippy('#main-button', {

187

content: 'Main button'

188

// Will use singleton placement

189

})

190

];

191

192

const singleton = createSingleton(instances, {

193

delay: 300,

194

duration: 200,

195

placement: 'top', // Default placement

196

theme: 'custom',

197

overrides: ['content', 'placement'], // Allow these to be overridden

198

// delay, duration, theme cannot be overridden

199

});

200

201

// Individual instances can override content and placement

202

// but share delay, duration, and theme from singleton

203

```

204

205

### Smooth Transitions

206

207

Built-in transition system for smooth movement between tooltip positions when switching targets.

208

209

```typescript { .api }

210

// Singleton props for transition control

211

interface CreateSingletonProps {

212

/** CSS transition for smooth movement between positions */

213

moveTransition: string;

214

}

215

```

216

217

**Usage Examples:**

218

219

```typescript

220

import tippy, { createSingleton } from "tippy.js";

221

222

const instances = [

223

tippy('.nav-item', { content: 'Navigation item' })

224

];

225

226

// Custom transition effects

227

const smoothSingleton = createSingleton(instances, {

228

moveTransition: 'transform 0.3s cubic-bezier(0.4, 0, 0.2, 1)',

229

placement: 'bottom',

230

offset: [0, 8]

231

});

232

233

// Different transition for different contexts

234

const quickSingleton = createSingleton(instances, {

235

moveTransition: 'transform 0.1s ease-out', // Quick transitions

236

delay: 100

237

});

238

239

// No transition (instant movement)

240

const instantSingleton = createSingleton(instances, {

241

moveTransition: '', // Disable transitions

242

});

243

```

244

245

### Advanced Singleton Patterns

246

247

Complex singleton usage patterns for specialized use cases.

248

249

**Usage Examples:**

250

251

```typescript

252

import tippy, { createSingleton } from "tippy.js";

253

254

// Contextual help system

255

function createHelpSystem(containers) {

256

const allInstances = [];

257

258

containers.forEach(container => {

259

const helpElements = container.querySelectorAll('[data-help]');

260

const instances = Array.from(helpElements).map(el =>

261

tippy(el, {

262

content: el.dataset.help,

263

placement: el.dataset.placement || 'top'

264

})

265

);

266

allInstances.push(...instances);

267

});

268

269

return createSingleton(allInstances, {

270

theme: 'help-system',

271

delay: [600, 100],

272

moveTransition: 'transform 0.2s ease-out',

273

overrides: ['content', 'placement'],

274

interactive: true,

275

allowHTML: true

276

});

277

}

278

279

// Image gallery with captions

280

function createGalleryTooltips(gallery) {

281

const images = gallery.querySelectorAll('img[data-caption]');

282

const instances = Array.from(images).map(img =>

283

tippy(img, {

284

content: `

285

<div class="image-caption">

286

<h4>${img.alt}</h4>

287

<p>${img.dataset.caption}</p>

288

</div>

289

`,

290

allowHTML: true,

291

placement: 'bottom'

292

})

293

);

294

295

return createSingleton(instances, {

296

theme: 'gallery',

297

moveTransition: 'all 0.3s ease',

298

maxWidth: 300,

299

overrides: ['content']

300

});

301

}

302

303

// Keyboard-navigable tooltip tour

304

function createTooltipTour(steps) {

305

const instances = steps.map((step, index) =>

306

tippy(step.element, {

307

content: `

308

<div class="tour-step">

309

<div class="step-number">Step ${index + 1} of ${steps.length}</div>

310

<h3>${step.title}</h3>

311

<p>${step.description}</p>

312

</div>

313

`,

314

allowHTML: true,

315

placement: step.placement || 'top'

316

})

317

);

318

319

const tour = createSingleton(instances, {

320

theme: 'tour',

321

interactive: true,

322

hideOnClick: false,

323

trigger: 'manual',

324

overrides: ['content', 'placement']

325

});

326

327

// Add navigation controls

328

let currentStep = 0;

329

330

return {

331

start() {

332

currentStep = 0;

333

tour.show(0);

334

},

335

next() {

336

if (currentStep < instances.length - 1) {

337

currentStep++;

338

tour.show(currentStep);

339

}

340

},

341

previous() {

342

if (currentStep > 0) {

343

currentStep--;

344

tour.show(currentStep);

345

}

346

},

347

end() {

348

tour.hide();

349

}

350

};

351

}

352

```