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

event-delegation.mddocs/

0

# Event Delegation

1

2

Advanced event delegation system for handling tooltips on dynamically created elements and managing large sets of tooltip triggers efficiently.

3

4

## Capabilities

5

6

### Delegate Function

7

8

Creates delegate instances that automatically handle tooltip creation for child elements matching a CSS selector, perfect for dynamic content and large element sets.

9

10

```typescript { .api }

11

/**

12

* Creates a delegate instance that controls tooltip creation for child elements

13

* @param targets - Parent elements to monitor for delegation

14

* @param props - Tooltip properties including required target selector

15

* @returns Delegate instance(s) with enhanced destroy method

16

*/

17

function delegate(

18

targets: Element | Element[] | NodeList | string,

19

props: Partial<Props> & { target: string }

20

): DelegateInstance | DelegateInstance[];

21

22

interface DelegateInstance<TProps = Props> extends Instance<TProps> {

23

/** Destroy delegate and optionally destroy target instances */

24

destroy(shouldDestroyTargetInstances?: boolean): void;

25

}

26

```

27

28

**Usage Examples:**

29

30

```typescript

31

import { delegate } from "tippy.js";

32

33

// Basic delegation for dynamically added elements

34

const delegateInstance = delegate('#container', {

35

target: '.tooltip-target', // CSS selector for child elements

36

content: 'Delegated tooltip',

37

placement: 'top'

38

});

39

40

// Add elements dynamically - tooltips are created automatically

41

const container = document.querySelector('#container');

42

container.innerHTML += '<button class="tooltip-target">New Button</button>';

43

44

// Delegation with dynamic content

45

delegate('.list-container', {

46

target: '.list-item',

47

content(reference) {

48

return reference.getAttribute('data-tooltip') || 'Default content';

49

},

50

allowHTML: true

51

});

52

53

// Multiple containers with shared configuration

54

delegate(['.sidebar', '.main-content'], {

55

target: '[data-tippy]',

56

content(reference) {

57

return reference.dataset.tippy;

58

},

59

placement: 'auto'

60

});

61

```

62

63

### Dynamic Element Handling

64

65

Automatic tooltip creation and cleanup for elements that are added or removed from the DOM after delegation is set up.

66

67

```typescript { .api }

68

// Delegation automatically handles:

69

// - Elements added after delegation setup

70

// - Different trigger types per element (via data attributes)

71

// - Custom content per element

72

// - Cleanup when elements are removed

73

```

74

75

**Usage Examples:**

76

77

```typescript

78

import { delegate } from "tippy.js";

79

80

// Set up delegation for a dynamic list

81

const listDelegate = delegate('#dynamic-list', {

82

target: '.list-item',

83

content(reference) {

84

return `Item: ${reference.textContent}`;

85

},

86

trigger: 'mouseenter focus'

87

});

88

89

// Elements added later automatically get tooltips

90

function addListItem(text) {

91

const item = document.createElement('div');

92

item.className = 'list-item';

93

item.textContent = text;

94

document.querySelector('#dynamic-list').appendChild(item);

95

// Tooltip is automatically available on this new element

96

}

97

98

// Different triggers per element using data attributes

99

delegate('#mixed-triggers', {

100

target: '.interactive-element',

101

content: 'Flexible tooltip',

102

// Individual elements can override trigger via data-tippy-trigger

103

});

104

105

// HTML in list:

106

// <div class="interactive-element" data-tippy-trigger="click">Click me</div>

107

// <div class="interactive-element" data-tippy-trigger="mouseenter">Hover me</div>

108

```

109

110

### Delegate Instance Management

111

112

Enhanced instance management with child tooltip control and bulk operations.

113

114

```typescript { .api }

115

interface DelegateInstance<TProps = Props> extends Instance<TProps> {

116

/** Standard instance methods inherited */

117

show(): void;

118

hide(): void;

119

enable(): void;

120

disable(): void;

121

destroy(shouldDestroyChildInstances?: boolean): void;

122

}

123

```

124

125

**Usage Examples:**

126

127

```typescript

128

import { delegate } from "tippy.js";

129

130

const delegateInstance = delegate('#parent', {

131

target: '.child',

132

content: 'Child tooltip'

133

});

134

135

// Control all child tooltips via delegate

136

delegateInstance.enable(); // Enable all child tooltips

137

delegateInstance.disable(); // Disable all child tooltips

138

139

// Destroy with options

140

delegateInstance.destroy(true); // Destroy delegate and all child instances

141

delegateInstance.destroy(false); // Destroy delegate but keep child instances

142

143

// The delegate instance itself can be shown/hidden

144

delegateInstance.show(); // This won't work as expected - delegates don't have their own tooltip

145

```

146

147

### Performance Optimization

148

149

Delegation provides significant performance benefits for large numbers of elements by using event bubbling instead of individual event listeners.

150

151

```typescript { .api }

152

// Performance comparison:

153

// Individual tooltips: N event listeners for N elements

154

// Delegated tooltips: 4 event listeners total (touch, mouse, focus, click)

155

```

156

157

**Usage Examples:**

158

159

```typescript

160

import { delegate } from "tippy.js";

161

162

// Efficient for large tables

163

delegate('#data-table', {

164

target: 'td[data-tooltip]',

165

content(reference) {

166

return reference.dataset.tooltip;

167

},

168

delay: [500, 100] // Reduce accidental triggers

169

});

170

171

// Efficient for dynamic grids

172

delegate('.image-grid', {

173

target: '.image-item',

174

content(reference) {

175

const img = reference.querySelector('img');

176

return `

177

<div>

178

<strong>${img.alt}</strong><br>

179

${img.dataset.description || 'No description'}

180

</div>

181

`;

182

},

183

allowHTML: true,

184

placement: 'bottom'

185

});

186

187

// Memory efficient infinite scroll

188

const infiniteDelegate = delegate('#infinite-scroll', {

189

target: '.scroll-item',

190

content: 'Tooltip for scroll item'

191

});

192

193

// No need to manage tooltips when items are removed/added

194

// Delegation handles it automatically

195

```

196

197

### Advanced Delegation Patterns

198

199

Complex delegation scenarios with conditional logic and nested delegation.

200

201

**Usage Examples:**

202

203

```typescript

204

import { delegate } from "tippy.js";

205

206

// Conditional delegation based on element state

207

delegate('#conditional-container', {

208

target: '.conditional-target',

209

content(reference) {

210

if (reference.classList.contains('disabled')) {

211

return 'This feature is disabled';

212

}

213

return reference.getAttribute('data-help') || 'No help available';

214

},

215

onTrigger(instance, event) {

216

// Additional logic on trigger

217

if (event.target.classList.contains('no-tooltip')) {

218

return; // Skip tooltip creation

219

}

220

}

221

});

222

223

// Nested delegation for complex layouts

224

delegate('#outer-container', {

225

target: '.section',

226

content: 'Section tooltip'

227

});

228

229

delegate('#outer-container', {

230

target: '.section .item',

231

content: 'Item tooltip',

232

placement: 'right'

233

});

234

235

// Context-aware delegation

236

delegate('.context-sensitive', {

237

target: '[data-context-help]',

238

content(reference) {

239

const context = reference.closest('[data-context]')?.dataset.context;

240

const helpKey = reference.dataset.contextHelp;

241

return getContextualHelp(context, helpKey);

242

},

243

interactive: true,

244

allowHTML: true

245

});

246

```