or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

configuration-options.mdevent-handling.mdhint-system.mdindex.mdtour-management.md
tile.json

event-handling.mddocs/

0

# Event Handling

1

2

Rich callback system for handling tour and hint lifecycle events, enabling custom behavior and integration with analytics or other systems.

3

4

## Capabilities

5

6

### Tour Event Callbacks

7

8

Comprehensive event system for Tour instances with lifecycle hooks and interaction events.

9

10

```typescript { .api }

11

/**

12

* Callback fired before changing to a new step

13

* Return false to prevent the step change

14

*/

15

type introBeforeChangeCallback = (

16

this: Tour,

17

targetElement: HTMLElement,

18

currentStep: number,

19

direction: "backward" | "forward"

20

) => Promise<boolean> | boolean;

21

22

/**

23

* Callback fired when changing to a new step

24

*/

25

type introChangeCallback = (

26

this: Tour,

27

targetElement: HTMLElement

28

) => void | Promise<void>;

29

30

/**

31

* Callback fired after changing to a new step

32

*/

33

type introAfterChangeCallback = (

34

this: Tour,

35

targetElement: HTMLElement

36

) => void | Promise<void>;

37

38

/**

39

* Callback fired when tour is completed

40

*/

41

type introCompleteCallback = (

42

this: Tour,

43

currentStep: number,

44

reason: "skip" | "end" | "done"

45

) => void | Promise<void>;

46

47

/**

48

* Callback fired when tour is started

49

*/

50

type introStartCallback = (

51

this: Tour,

52

targetElement: HTMLElement

53

) => void | Promise<void>;

54

55

/**

56

* Callback fired when tour is exited

57

*/

58

type introExitCallback = (

59

this: Tour

60

) => void | Promise<void>;

61

62

/**

63

* Callback fired when tour is skipped

64

*/

65

type introSkipCallback = (

66

this: Tour,

67

currentStep: number

68

) => void | Promise<void>;

69

70

/**

71

* Callback fired before tour exit

72

* Return false to prevent the exit

73

*/

74

type introBeforeExitCallback = (

75

this: Tour,

76

targetElement: HTMLElement

77

) => boolean | Promise<boolean>;

78

```

79

80

### Tour Callback Registration

81

82

Methods for registering event callbacks on Tour instances.

83

84

```typescript { .api }

85

/**

86

* Set callback for before step change event

87

* @param callback - Function to call before changing steps

88

*/

89

onBeforeChange(callback: introBeforeChangeCallback): Tour;

90

91

/**

92

* Set callback for step change event

93

* @param callback - Function to call when changing steps

94

*/

95

onChange(callback: introChangeCallback): Tour;

96

97

/**

98

* Set callback for after step change event

99

* @param callback - Function to call after changing steps

100

*/

101

onAfterChange(callback: introAfterChangeCallback): Tour;

102

103

/**

104

* Set callback for tour completion event

105

* @param callback - Function to call when tour completes

106

*/

107

onComplete(callback: introCompleteCallback): Tour;

108

109

/**

110

* Set callback for tour start event

111

* @param callback - Function to call when tour starts

112

*/

113

onStart(callback: introStartCallback): Tour;

114

115

/**

116

* Set callback for tour exit event

117

* @param callback - Function to call when tour exits

118

*/

119

onExit(callback: introExitCallback): Tour;

120

121

/**

122

* Set callback for tour skip event

123

* @param callback - Function to call when tour is skipped

124

*/

125

onSkip(callback: introSkipCallback): Tour;

126

127

/**

128

* Set callback for before tour exit event

129

* @param callback - Function to call before tour exits

130

*/

131

onBeforeExit(callback: introBeforeExitCallback): Tour;

132

133

/**

134

* Get a specific callback function

135

* @param callbackName - Name of the callback to retrieve

136

*/

137

callback<K extends keyof TourCallbacks>(callbackName: K): TourCallbacks[K] | undefined;

138

139

interface TourCallbacks {

140

onBeforeChange?: introBeforeChangeCallback;

141

onChange?: introChangeCallback;

142

onAfterChange?: introAfterChangeCallback;

143

onComplete?: introCompleteCallback;

144

onStart?: introStartCallback;

145

onExit?: introExitCallback;

146

onSkip?: introSkipCallback;

147

onBeforeExit?: introBeforeExitCallback;

148

}

149

```

150

151

### Tour Event Usage Examples

152

153

**Basic Event Handling:**

154

155

```javascript

156

import introJs from "intro.js";

157

158

const tour = introJs.tour()

159

.addSteps([

160

{ title: "Welcome", intro: "Welcome to our app!", element: "#welcome" },

161

{ title: "Features", intro: "Check out these features", element: "#features" },

162

{ title: "Settings", intro: "Configure your preferences", element: "#settings" }

163

]);

164

165

// Track tour start

166

tour.onStart(function(targetElement) {

167

console.log("Tour started on:", targetElement);

168

169

// Analytics tracking

170

gtag('event', 'tour_started', {

171

'event_category': 'onboarding',

172

'event_label': 'product_tour'

173

});

174

});

175

176

// Track step changes

177

tour.onChange(function(targetElement) {

178

const currentStep = this.getCurrentStep();

179

console.log(`Moved to step ${currentStep + 1}`);

180

181

// Track step engagement

182

gtag('event', 'tour_step_viewed', {

183

'event_category': 'onboarding',

184

'step_number': currentStep + 1

185

});

186

});

187

188

// Handle tour completion

189

tour.onComplete(function(currentStep, reason) {

190

console.log(`Tour completed. Reason: ${reason}`);

191

192

// Track completion

193

gtag('event', 'tour_completed', {

194

'event_category': 'onboarding',

195

'completion_reason': reason,

196

'steps_completed': currentStep + 1

197

});

198

199

// Show success message

200

if (reason === "done") {

201

showSuccessMessage("Great! You've completed the tour.");

202

}

203

});

204

205

await tour.start();

206

```

207

208

**Advanced Event Handling with Conditional Logic:**

209

210

```javascript

211

import introJs from "intro.js";

212

213

const tour = introJs.tour();

214

215

// Conditional step progression

216

tour.onBeforeChange(function(targetElement, currentStep, direction) {

217

console.log(`About to ${direction} from step ${currentStep}`);

218

219

// Validate user action before proceeding

220

if (currentStep === 1 && direction === "forward") {

221

const isFormValid = validateRequiredForm();

222

if (!isFormValid) {

223

alert("Please complete the required form before continuing.");

224

return false; // Prevent step change

225

}

226

}

227

228

// Allow step change

229

return true;

230

});

231

232

// Custom step-specific behavior

233

tour.onAfterChange(function(targetElement) {

234

const currentStep = this.getCurrentStep();

235

const stepData = this.getStep(currentStep);

236

237

// Execute step-specific actions

238

switch (currentStep) {

239

case 0:

240

// First step: highlight important UI elements

241

highlightElement("#main-navigation");

242

break;

243

case 1:

244

// Second step: load dynamic content

245

loadUserDashboardData();

246

break;

247

case 2:

248

// Third step: enable interactive features

249

enableDemoMode();

250

break;

251

}

252

});

253

254

// Prevent exit unless confirmed

255

tour.onBeforeExit(function(targetElement) {

256

if (this.getCurrentStep() !== undefined && this.getCurrentStep() < this.getSteps().length - 1) {

257

return confirm("Are you sure you want to exit the tour?");

258

}

259

return true;

260

});

261

```

262

263

### Hint Event Callbacks

264

265

Event system for Hint instances with lifecycle and interaction events.

266

267

```typescript { .api }

268

/**

269

* Callback fired when hints are added to the page

270

*/

271

type hintsAddedCallback = (

272

this: Hint

273

) => void | Promise<void>;

274

275

/**

276

* Callback fired when a hint is clicked

277

*/

278

type hintClickCallback = (

279

this: Hint,

280

item: HintItem

281

) => void | Promise<void>;

282

283

/**

284

* Callback fired when a hint is closed

285

*/

286

type hintCloseCallback = (

287

this: Hint,

288

item: HintItem

289

) => void | Promise<void>;

290

```

291

292

### Hint Callback Registration

293

294

Methods for registering event callbacks on Hint instances.

295

296

```typescript { .api }

297

/**

298

* Set callback for when hints are added to the page

299

* @param callback - Function to call when hints are rendered

300

*/

301

onHintsAdded(callback: hintsAddedCallback): Hint;

302

303

/**

304

* Set callback for hint click events

305

* @param callback - Function to call when hint is clicked

306

*/

307

onHintClick(callback: hintClickCallback): Hint;

308

309

/**

310

* Set callback for hint close events

311

* @param callback - Function to call when hint is closed

312

*/

313

onHintClose(callback: hintCloseCallback): Hint;

314

315

/**

316

* Get a specific callback function

317

* @param callbackName - Name of the callback to retrieve

318

*/

319

callback<K extends keyof HintCallbacks>(callbackName: K): HintCallbacks[K] | undefined;

320

321

interface HintCallbacks {

322

onHintsAdded?: hintsAddedCallback;

323

onHintClick?: hintClickCallback;

324

onHintClose?: hintCloseCallback;

325

}

326

```

327

328

### Hint Event Usage Examples

329

330

**Basic Hint Event Handling:**

331

332

```javascript

333

import introJs from "intro.js";

334

335

const hint = introJs.hint()

336

.addHint({

337

element: "#help-button",

338

hint: "Click for help and support",

339

hintPosition: "top-middle"

340

})

341

.addHint({

342

element: "#settings-gear",

343

hint: "Access your account settings",

344

hintPosition: "bottom-left"

345

});

346

347

// Track when hints are rendered

348

hint.onHintsAdded(function() {

349

console.log("All hints have been added to the page");

350

351

// Analytics tracking

352

gtag('event', 'hints_displayed', {

353

'event_category': 'help_system',

354

'hint_count': this.getHints().length

355

});

356

});

357

358

// Track hint interactions

359

hint.onHintClick(function(item) {

360

console.log("Hint clicked:", item);

361

362

// Track which hints are most useful

363

gtag('event', 'hint_clicked', {

364

'event_category': 'help_system',

365

'hint_element': item.element?.id || 'unknown',

366

'hint_content': item.hint

367

});

368

369

// Show detailed help if needed

370

if (item.hint?.includes("settings")) {

371

showSettingsHelp();

372

}

373

});

374

375

// Track hint dismissals

376

hint.onHintClose(function(item) {

377

console.log("Hint closed:", item);

378

379

gtag('event', 'hint_closed', {

380

'event_category': 'help_system',

381

'hint_element': item.element?.id || 'unknown'

382

});

383

});

384

385

await hint.render();

386

```

387

388

**Advanced Hint Event Handling:**

389

390

```javascript

391

import introJs from "intro.js";

392

393

const hint = introJs.hint();

394

395

// Dynamic hint content based on user context

396

hint.onHintClick(async function(item) {

397

const element = item.element;

398

if (!element) return;

399

400

// Get contextual information

401

const userRole = getUserRole();

402

const featureAccess = await checkFeatureAccess(element.id);

403

404

// Customize hint behavior based on context

405

if (!featureAccess) {

406

showUpgradePrompt();

407

return;

408

}

409

410

// Show role-specific guidance

411

const roleSpecificHint = getHintForRole(item.hint, userRole);

412

if (roleSpecificHint !== item.hint) {

413

// Update hint content dynamically

414

item.hint = roleSpecificHint;

415

this.refresh(); // Refresh to show updated content

416

}

417

418

// Track contextual usage

419

gtag('event', 'contextual_hint_used', {

420

'user_role': userRole,

421

'feature_id': element.id,

422

'has_access': featureAccess

423

});

424

});

425

426

// Auto-close hints after user interaction

427

hint.onHintClick(function(item) {

428

// Close hint after 3 seconds

429

setTimeout(() => {

430

this.hideHintDialog();

431

}, 3000);

432

});

433

```

434

435

### Event Integration Patterns

436

437

**Analytics Integration:**

438

439

```javascript

440

import introJs from "intro.js";

441

442

// Comprehensive analytics tracking

443

function setupTourAnalytics(tour) {

444

const startTime = Date.now();

445

let stepTimes = [];

446

447

tour.onStart(function() {

448

gtag('event', 'tour_started', {

449

'event_category': 'onboarding',

450

'timestamp': startTime

451

});

452

});

453

454

tour.onChange(function() {

455

stepTimes.push(Date.now());

456

});

457

458

tour.onComplete(function(currentStep, reason) {

459

const totalTime = Date.now() - startTime;

460

const avgStepTime = stepTimes.length > 0 ?

461

stepTimes.reduce((a, b, i) => a + (i > 0 ? b - stepTimes[i-1] : 0), 0) / stepTimes.length : 0;

462

463

gtag('event', 'tour_completed', {

464

'event_category': 'onboarding',

465

'completion_reason': reason,

466

'total_time_ms': totalTime,

467

'avg_step_time_ms': avgStepTime,

468

'steps_completed': currentStep + 1

469

});

470

});

471

472

return tour;

473

}

474

475

// Usage

476

const tour = setupTourAnalytics(introJs.tour());

477

```

478

479

**State Management Integration:**

480

481

```javascript

482

import introJs from "intro.js";

483

484

// Redux/state management integration

485

function connectTourToStore(tour, store) {

486

tour.onStart(function() {

487

store.dispatch({ type: 'TOUR_STARTED' });

488

});

489

490

tour.onChange(function() {

491

const currentStep = this.getCurrentStep();

492

store.dispatch({

493

type: 'TOUR_STEP_CHANGED',

494

payload: { step: currentStep }

495

});

496

});

497

498

tour.onComplete(function(currentStep, reason) {

499

store.dispatch({

500

type: 'TOUR_COMPLETED',

501

payload: { step: currentStep, reason }

502

});

503

});

504

505

return tour;

506

}

507

```

508

509

### Deprecated Callback Methods

510

511

Legacy callback methods maintained for backward compatibility:

512

513

```typescript { .api }

514

/**

515

* @deprecated Use onBeforeChange instead

516

*/

517

onbeforechange(callback: introBeforeChangeCallback): Tour;

518

519

/**

520

* @deprecated Use onChange instead

521

*/

522

onchange(callback: introChangeCallback): Tour;

523

524

/**

525

* @deprecated Use onAfterChange instead

526

*/

527

onafterchange(callback: introAfterChangeCallback): Tour;

528

529

/**

530

* @deprecated Use onComplete instead

531

*/

532

oncomplete(callback: introCompleteCallback): Tour;

533

534

/**

535

* @deprecated Use onStart instead

536

*/

537

onstart(callback: introStartCallback): Tour;

538

539

/**

540

* @deprecated Use onExit instead

541

*/

542

onexit(callback: introExitCallback): Tour;

543

544

/**

545

* @deprecated Use onSkip instead

546

*/

547

onskip(callback: introSkipCallback): Tour;

548

549

/**

550

* @deprecated Use onBeforeExit instead

551

*/

552

onbeforeexit(callback: introBeforeExitCallback): Tour;

553

554

/**

555

* @deprecated Use onHintsAdded instead

556

*/

557

onhintsadded(callback: hintsAddedCallback): Hint;

558

559

/**

560

* @deprecated Use onHintClick instead

561

*/

562

onhintclick(callback: hintClickCallback): Hint;

563

564

/**

565

* @deprecated Use onHintClose instead

566

*/

567

onhintclose(callback: hintCloseCallback): Hint;

568

```