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

plugins.mddocs/

0

# Plugins

1

2

Built-in plugin system with four official plugins for advanced behaviors and effects, plus a framework for creating custom plugins.

3

4

## Capabilities

5

6

### Plugin System

7

8

Extensible plugin architecture allowing custom behaviors and lifecycle hook modifications.

9

10

```typescript { .api }

11

interface Plugin<TProps = Props> {

12

/** Optional plugin name for identification */

13

name?: string;

14

/** Default value when plugin property is not specified */

15

defaultValue?: any;

16

/** Plugin function that returns lifecycle hooks */

17

fn(instance: Instance<TProps>): Partial<LifecycleHooks<TProps>>;

18

}

19

20

// Usage in props

21

interface Props {

22

/** Array of plugins to apply to the instance */

23

plugins: Plugin[];

24

}

25

```

26

27

**Usage Examples:**

28

29

```typescript

30

import tippy, { animateFill, followCursor } from "tippy.js";

31

32

// Using built-in plugins

33

tippy('.animated', {

34

content: 'Animated tooltip',

35

plugins: [animateFill, followCursor],

36

animateFill: true,

37

followCursor: true

38

});

39

40

// Custom plugin example

41

const customPlugin = {

42

name: 'customBehavior',

43

defaultValue: false,

44

fn(instance) {

45

return {

46

onShow() {

47

console.log('Custom plugin: tooltip showing');

48

},

49

onHide() {

50

console.log('Custom plugin: tooltip hiding');

51

}

52

};

53

}

54

};

55

56

tippy('#custom', {

57

content: 'Custom plugin tooltip',

58

plugins: [customPlugin]

59

});

60

```

61

62

### Animate Fill Plugin

63

64

Creates a backdrop fill animation effect that fills the tooltip background before showing content.

65

66

```typescript { .api }

67

interface AnimateFill extends Plugin {

68

name: 'animateFill';

69

defaultValue: false;

70

}

71

72

const animateFill: AnimateFill;

73

74

// Props extension

75

interface Props {

76

/** Enable animate fill effect */

77

animateFill: boolean;

78

}

79

```

80

81

**Usage Examples:**

82

83

```typescript

84

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

85

86

// Basic animate fill

87

tippy('.fill-animation', {

88

content: 'Filling tooltip',

89

plugins: [animateFill],

90

animateFill: true,

91

animation: 'shift-away' // Required for proper effect

92

});

93

94

// Animate fill with custom styling

95

tippy('.custom-fill', {

96

content: 'Custom fill effect',

97

plugins: [animateFill],

98

animateFill: true,

99

theme: 'custom-fill', // Style the backdrop in CSS

100

duration: 500

101

});

102

103

// Note: animateFill requires the default render function

104

// It automatically sets arrow: false and animation: 'shift-away'

105

```

106

107

### Follow Cursor Plugin

108

109

Makes the tooltip follow the mouse cursor with various tracking modes.

110

111

```typescript { .api }

112

interface FollowCursor extends Plugin {

113

name: 'followCursor';

114

defaultValue: false;

115

}

116

117

const followCursor: FollowCursor;

118

119

// Props extension

120

interface Props {

121

/** Follow cursor behavior */

122

followCursor: boolean | 'horizontal' | 'vertical' | 'initial';

123

}

124

```

125

126

**Usage Examples:**

127

128

```typescript

129

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

130

131

// Full cursor following

132

tippy('.follow-cursor', {

133

content: 'Follows cursor',

134

plugins: [followCursor],

135

followCursor: true

136

});

137

138

// Horizontal only

139

tippy('.follow-horizontal', {

140

content: 'Follows horizontally',

141

plugins: [followCursor],

142

followCursor: 'horizontal'

143

});

144

145

// Vertical only

146

tippy('.follow-vertical', {

147

content: 'Follows vertically',

148

plugins: [followCursor],

149

followCursor: 'vertical'

150

});

151

152

// Initial position then fixed

153

tippy('.follow-initial', {

154

content: 'Initial position only',

155

plugins: [followCursor],

156

followCursor: 'initial' // Follows until shown, then stays

157

});

158

159

// Follow cursor with boundaries

160

tippy('.bounded-follow', {

161

content: 'Bounded following',

162

plugins: [followCursor],

163

followCursor: true,

164

boundary: 'viewport' // Respect viewport boundaries

165

});

166

```

167

168

### Inline Positioning Plugin

169

170

Improves positioning for inline elements like text selections and inline spans.

171

172

```typescript { .api }

173

interface InlinePositioning extends Plugin {

174

name: 'inlinePositioning';

175

defaultValue: false;

176

}

177

178

const inlinePositioning: InlinePositioning;

179

180

// Props extension

181

interface Props {

182

/** Enable inline positioning improvements */

183

inlinePositioning: boolean;

184

}

185

```

186

187

**Usage Examples:**

188

189

```typescript

190

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

191

192

// Better positioning for inline elements

193

tippy('span.inline-tooltip', {

194

content: 'Inline element tooltip',

195

plugins: [inlinePositioning],

196

inlinePositioning: true,

197

placement: 'top'

198

});

199

200

// Text selection tooltips

201

tippy('.text-content', {

202

content: 'Text selection tooltip',

203

plugins: [inlinePositioning],

204

inlinePositioning: true,

205

trigger: 'manual', // Control manually

206

getReferenceClientRect() {

207

const selection = window.getSelection();

208

return selection.getRangeAt(0).getBoundingClientRect();

209

}

210

});

211

212

// Inline code elements

213

tippy('code', {

214

content: 'Code documentation',

215

plugins: [inlinePositioning],

216

inlinePositioning: true,

217

placement: 'bottom',

218

delay: 500

219

});

220

```

221

222

### Sticky Plugin

223

224

Keeps the tooltip positioned relative to its reference element during scrolling or element movement.

225

226

```typescript { .api }

227

interface Sticky extends Plugin {

228

name: 'sticky';

229

defaultValue: false;

230

}

231

232

const sticky: Sticky;

233

234

// Props extension

235

interface Props {

236

/** Sticky behavior */

237

sticky: boolean | 'reference' | 'popper';

238

}

239

```

240

241

**Usage Examples:**

242

243

```typescript

244

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

245

246

// Stick to both reference and popper

247

tippy('.sticky-tooltip', {

248

content: 'Sticky tooltip',

249

plugins: [sticky],

250

sticky: true // Monitor both reference and popper positions

251

});

252

253

// Stick only to reference element

254

tippy('.sticky-reference', {

255

content: 'Sticks to reference',

256

plugins: [sticky],

257

sticky: 'reference' // Only monitor reference element

258

});

259

260

// Stick only to popper element

261

tippy('.sticky-popper', {

262

content: 'Sticks to popper',

263

plugins: [sticky],

264

sticky: 'popper' // Only monitor popper element

265

});

266

267

// Sticky with scrollable containers

268

tippy('.scrollable-content .tooltip-trigger', {

269

content: 'Scrollable sticky tooltip',

270

plugins: [sticky],

271

sticky: true,

272

boundary: 'scrollParent' // Respect scroll boundaries

273

});

274

```

275

276

### Combining Plugins

277

278

Using multiple plugins together for complex behaviors.

279

280

**Usage Examples:**

281

282

```typescript

283

import tippy, { followCursor, sticky, inlinePositioning } from "tippy.js";

284

285

// Follow cursor with sticky behavior

286

tippy('.advanced-tooltip', {

287

content: 'Advanced behavior',

288

plugins: [followCursor, sticky],

289

followCursor: 'initial', // Initial follow, then stick

290

sticky: true,

291

duration: 200

292

});

293

294

// Inline positioning with animate fill

295

tippy('span.highlighted', {

296

content: 'Highlighted text tooltip',

297

plugins: [inlinePositioning, animateFill],

298

inlinePositioning: true,

299

animateFill: true,

300

theme: 'highlight'

301

});

302

303

// All plugins combined

304

tippy('.kitchen-sink', {

305

content: 'All features tooltip',

306

plugins: [followCursor, sticky, inlinePositioning, animateFill],

307

followCursor: 'horizontal',

308

sticky: 'reference',

309

inlinePositioning: true,

310

animateFill: true,

311

interactive: true

312

});

313

```

314

315

### Custom Plugin Development

316

317

Framework for creating custom plugins with lifecycle hooks.

318

319

**Usage Examples:**

320

321

```typescript

322

import tippy from "tippy.js";

323

324

// Simple logging plugin

325

const loggingPlugin = {

326

name: 'logging',

327

defaultValue: false,

328

fn(instance) {

329

return {

330

onCreate() {

331

console.log(`Tooltip created for:`, instance.reference);

332

},

333

onShow() {

334

console.log(`Tooltip showing:`, instance.props.content);

335

},

336

onHide() {

337

console.log(`Tooltip hiding:`, instance.reference);

338

}

339

};

340

}

341

};

342

343

// Analytics plugin

344

const analyticsPlugin = {

345

name: 'analytics',

346

defaultValue: false,

347

fn(instance) {

348

return {

349

onShow() {

350

if (instance.props.analytics) {

351

analytics.track('tooltip_shown', {

352

content: instance.props.content,

353

element: instance.reference.tagName

354

});

355

}

356

}

357

};

358

}

359

};

360

361

// Auto-hide plugin

362

const autoHidePlugin = {

363

name: 'autoHide',

364

defaultValue: 0,

365

fn(instance) {

366

let timeoutId;

367

368

return {

369

onShow() {

370

if (instance.props.autoHide > 0) {

371

timeoutId = setTimeout(() => {

372

instance.hide();

373

}, instance.props.autoHide);

374

}

375

},

376

onHide() {

377

if (timeoutId) {

378

clearTimeout(timeoutId);

379

}

380

}

381

};

382

}

383

};

384

385

// Usage of custom plugins

386

tippy('.custom-behavior', {

387

content: 'Custom plugin tooltip',

388

plugins: [loggingPlugin, analyticsPlugin, autoHidePlugin],

389

analytics: true,

390

autoHide: 3000 // Auto-hide after 3 seconds

391

});

392

393

// Plugin with state management

394

const counterPlugin = {

395

name: 'counter',

396

defaultValue: false,

397

fn(instance) {

398

let showCount = 0;

399

400

return {

401

onShow() {

402

if (instance.props.counter) {

403

showCount++;

404

instance.setContent(`Shown ${showCount} times`);

405

}

406

}

407

};

408

}

409

};

410

```