@diabolic/pointy 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,69 +1,42 @@
1
- # Pointy 👆
1
+ # Pointy
2
2
 
3
3
  A lightweight, dependency-free JavaScript library for creating animated tooltips with a pointing cursor. Perfect for product tours, onboarding flows, and feature highlights.
4
4
 
5
5
  [![npm version](https://img.shields.io/npm/v/@diabolic/pointy.svg)](https://www.npmjs.com/package/@diabolic/pointy)
6
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
7
 
8
- > 🎎 [Live Demo](https://bugrakaan.github.io/pointy/)
8
+ > [Live Demo](https://bugrakaan.github.io/pointy/)
9
9
 
10
- ## âœĻ Features
10
+ ## Features
11
11
 
12
12
  - ðŸŽŊ **Animated Pointer** - Smooth cursor animation with customizable SVG
13
13
  - 📝 **Multi-step Tours** - Create guided product tours with multiple steps
14
14
  - 💎 **Multi-message Steps** - Each step can have multiple messages that auto-cycle
15
15
  - 🎎 **Autoplay Mode** - Automatically advance through steps
16
16
  - ðŸŽĻ **Customizable Styling** - CSS variables, custom class names, and SVG support
17
- - 📍 **Target Tracking** - Follows target elements in real-time (configurable FPS)
17
+ - 📍 **Target Tracking** - Follows target elements in real-time
18
18
  - ⚛ïļ **React Compatible** - Supports JSX/React elements as content
19
19
  - 🔗 **Event System** - Comprehensive events with group listeners
20
20
  - 🌊 **Smooth Animations** - 11 built-in easing presets
21
- - ðŸ“ą **Responsive** - Adapts to window resize and scroll
22
21
  - ðŸŠķ **Lightweight** - Zero dependencies, ~15KB
23
22
 
24
- ## ðŸ“Ķ Installation
23
+ ## Installation
25
24
 
26
25
  ```bash
27
- # npm
28
26
  npm install @diabolic/pointy
29
-
30
- # yarn
31
- yarn add @diabolic/pointy
32
-
33
-
34
- # pnpm
35
- pnpm add @diabolic/pointy
36
27
  ```
37
28
 
38
29
  ### CDN
39
30
 
40
31
  ```html
41
- <!-- UMD (Global variable) -->
42
32
  <script src="https://unpkg.com/@diabolic/pointy/dist/pointy.min.js"></script>
43
-
44
- <!-- Or from jsDelivr -->
45
- <script src="https://cdn.jsdelivr.net/npm/@diabolic/pointy/dist/pointy.min.js"></script>
46
33
  ```
47
34
 
48
- ### Direct Script Include
49
-
50
- ```html
51
- <script src="pointy.js"></script>
52
- ```
53
-
54
- ### Usage
35
+ ## Quick Start
55
36
 
56
37
  ```javascript
57
- // ES6 import
58
38
  import Pointy from '@diabolic/pointy';
59
39
 
60
- // CommonJS
61
- const Pointy = require('@diabolic/pointy');
62
- ```
63
-
64
- ## 🚀 Quick Start
65
-
66
- ```javascript
67
40
  const pointy = new Pointy({
68
41
  steps: [
69
42
  { target: '#welcome-btn', content: 'Click here to get started!' },
@@ -72,99 +45,67 @@ const pointy = new Pointy({
72
45
  ]
73
46
  });
74
47
 
75
-
76
48
  pointy.show();
77
49
  ```
78
50
 
79
- ## 📖 Configuration Options
51
+ ## Configuration
80
52
 
81
53
  ### Basic Options
82
54
 
83
55
  | Option | Type | Default | Description |
84
56
  |--------|------|---------|-------------|
85
57
  | `steps` | `Array` | `[]` | Array of step objects |
86
- | `target` | `string\|HTMLElement` | `null` | Initial target element (for single-step use) |
87
- | `content` | `string\|string[]` | `''` | Initial content (for single-step use) |
58
+ | `target` | `string\|HTMLElement` | `null` | Initial target (single-step use) |
59
+ | `content` | `string\|string[]` | `''` | Initial content (single-step use) |
88
60
 
89
61
  ### Step Object
90
62
 
91
63
  ```javascript
92
64
  {
93
65
  target: '#element', // CSS selector or HTMLElement
94
- content: 'Message', // String, HTML, array of strings, or React element
95
- direction: 'up', // Optional: 'up', 'down', or null (auto)
96
- duration: 3000 // Optional: step-specific autoplay duration (ms)
66
+ content: 'Message', // String, HTML, array, or React element
67
+ direction: 'up', // 'up', 'down', or null (auto)
68
+ duration: 3000 // Step-specific autoplay duration (ms)
97
69
  }
98
70
  ```
99
71
 
100
- ### Animation Options
72
+ ### Animation
101
73
 
102
74
  | Option | Type | Default | Description |
103
75
  |--------|------|---------|-------------|
104
76
  | `animationDuration` | `number` | `1000` | Move animation duration (ms) |
105
77
  | `introFadeDuration` | `number` | `1000` | Initial fade-in duration (ms) |
106
- | `bubbleFadeDuration` | `number` | `500` | Bubble fade-in duration (ms) |
107
- | `messageTransitionDuration` | `number` | `500` | Message change animation (ms) |
108
- | `easing` | `string` | `'default'` | Easing preset name or custom cubic-bezier |
109
- | `floatingAnimation` | `boolean` | `true` | Enable floating/bobbing animation |
78
+ | `bubbleFadeDuration` | `number` | `500` | Bubble fade duration (ms) |
79
+ | `easing` | `string` | `'default'` | Easing preset or cubic-bezier |
80
+ | `floatingAnimation` | `boolean` | `true` | Enable floating animation |
110
81
 
111
- ### Position Options
82
+ ### Position
112
83
 
113
84
  | Option | Type | Default | Description |
114
85
  |--------|------|---------|-------------|
115
86
  | `offsetX` | `number` | `20` | Horizontal offset from target |
116
87
  | `offsetY` | `number` | `16` | Vertical offset from target |
117
- | `initialPosition` | `string\|HTMLElement` | `'center'` | Starting position preset or element |
118
- | `initialPositionOffset` | `number` | `32` | Offset from edges for position presets |
119
- | `resetPositionOnHide` | `boolean` | `false` | Reset position when hiding |
120
-
121
- **Initial Position Presets:**
122
- - `'center'` - Center of viewport
123
- - `'top-left'`, `'top-center'`, `'top-right'`
124
- - `'middle-left'`, `'middle-right'`
125
- - `'bottom-left'`, `'bottom-center'`, `'bottom-right'`
126
- - `'first-step'` - Start directly at first step's target (no intro animation)
127
- - CSS selector (e.g., `'#my-element'`)
128
- - HTMLElement reference
129
-
130
- ### Tracking Options
131
-
132
- | Option | Type | Default | Description |
133
- |--------|------|---------|-------------|
88
+ | `initialPosition` | `string` | `'center'` | Starting position preset |
134
89
  | `tracking` | `boolean` | `true` | Enable real-time target tracking |
135
- | `trackingFps` | `number` | `60` | Tracking frame rate (0 = unlimited) |
136
90
 
137
- ### Message Cycling Options
91
+ **Initial Position Presets:** `'center'`, `'top-left'`, `'top-center'`, `'top-right'`, `'middle-left'`, `'middle-right'`, `'bottom-left'`, `'bottom-center'`, `'bottom-right'`, `'first-step'`
138
92
 
139
- | Option | Type | Default | Description |
140
- |--------|------|---------|-------------|
141
- | `messageInterval` | `number\|null` | `null` | Auto-cycle messages interval (ms) |
142
-
143
- ### Autoplay Options
93
+ ### Autoplay
144
94
 
145
95
  | Option | Type | Default | Description |
146
96
  |--------|------|---------|-------------|
147
- | `autoplay` | `number\|null` | `null` | Auto-advance interval (ms), null = manual |
148
- | `autoplayEnabled` | `boolean` | `false` | Whether autoplay is initially enabled |
149
- | `autoplayWaitForMessages` | `boolean` | `true` | Wait for all messages before advancing |
97
+ | `autoplay` | `number\|null` | `null` | Auto-advance interval (ms) |
98
+ | `autoplayEnabled` | `boolean` | `false` | Start autoplay on show |
99
+ | `autoplayWaitForMessages` | `boolean` | `true` | Wait for all messages |
100
+ | `messageInterval` | `number\|null` | `null` | Message auto-cycle interval (ms) |
150
101
 
151
- ### Completion Options
102
+ ### Completion
152
103
 
153
104
  | Option | Type | Default | Description |
154
105
  |--------|------|---------|-------------|
155
- | `resetOnComplete` | `boolean` | `true` | Reset to initial position on complete |
156
- | `hideOnComplete` | `boolean` | `true` | Auto-hide after tour completes |
157
- | `hideOnCompleteDelay` | `number\|null` | `null` | Delay before hide (null = animationDuration) |
158
-
159
- ### Styling Options
160
-
161
- | Option | Type | Default | Description |
162
- |--------|------|---------|-------------|
163
- | `classPrefix` | `string` | `'pointy'` | CSS class prefix |
164
- | `classSuffixes` | `object` | `{}` | Custom class suffixes |
165
- | `classNames` | `object` | `{}` | Full override of class names |
166
- | `cssVarPrefix` | `string` | `classPrefix` | CSS variable prefix |
167
- | `pointerSvg` | `string` | Built-in SVG | Custom SVG for pointer |
106
+ | `resetOnComplete` | `boolean` | `true` | Reset to initial position |
107
+ | `hideOnComplete` | `boolean` | `true` | Auto-hide after completion |
108
+ | `hideOnCompleteDelay` | `number\|null` | `null` | Delay before hide (ms) |
168
109
 
169
110
  ### Callbacks
170
111
 
@@ -173,7 +114,7 @@ pointy.show();
173
114
  | `onStepChange` | `function(index, step)` | Called when step changes |
174
115
  | `onComplete` | `function()` | Called when tour completes |
175
116
 
176
- ## ðŸŽŊ Methods
117
+ ## Methods
177
118
 
178
119
  ### Lifecycle
179
120
 
@@ -181,7 +122,7 @@ pointy.show();
181
122
  pointy.show(); // Show the pointer
182
123
  pointy.hide(); // Hide the pointer
183
124
  pointy.destroy(); // Remove and cleanup
184
- pointy.restart(); // Restart from initial position with intro animation
125
+ pointy.restart(); // Restart from initial position
185
126
  ```
186
127
 
187
128
  ### Navigation
@@ -189,411 +130,199 @@ pointy.restart(); // Restart from initial position with intro animation
189
130
  ```javascript
190
131
  pointy.next(); // Go to next step
191
132
  pointy.prev(); // Go to previous step
192
- pointy.goToStep(index); // Go to specific step by index
133
+ pointy.goToStep(index); // Go to specific step
193
134
  pointy.reset(); // Reset to initial position
194
- pointy.reset(false); // Reset position without changing step
195
135
  ```
196
136
 
197
- ### Custom Target
198
-
199
- ```javascript
200
- // Point to any element without changing the current step
201
- pointy.pointTo('#element');
202
- pointy.pointTo('#element', 'Custom message');
203
- pointy.pointTo('#element', 'Message', 'down'); // Force direction
204
- ```
205
-
206
- ### Content Management
137
+ ### Content
207
138
 
208
139
  ```javascript
209
140
  pointy.setContent('New message');
210
- pointy.setContent(['Message 1', 'Message 2', 'Message 3']);
211
- pointy.setContent('<strong>HTML</strong> content');
212
-
213
- pointy.nextMessage(); // Show next message
214
- pointy.prevMessage(); // Show previous message
215
- pointy.goToMessage(index); // Go to specific message
141
+ pointy.setContent(['Message 1', 'Message 2']);
216
142
 
217
- pointy.getCurrentMessage(); // Get current message index
218
- pointy.getTotalMessages(); // Get total messages count
143
+ pointy.nextMessage();
144
+ pointy.prevMessage();
145
+ pointy.goToMessage(index);
219
146
  ```
220
147
 
221
- ### Message Cycling
148
+ ### Point to Custom Target
222
149
 
223
150
  ```javascript
224
- pointy.startMessageCycle(); // Start auto-cycling
225
- pointy.startMessageCycle(3000); // Start with custom interval
226
- pointy.stopMessageCycle(); // Stop cycling
227
- pointy.pauseMessageCycle(); // Pause cycling
228
- pointy.resumeMessageCycle(); // Resume cycling
229
-
230
- pointy.isMessageCycleActive(); // Check if cycling
231
- pointy.isMessageCyclePaused(); // Check if paused
151
+ pointy.pointTo('#element');
152
+ pointy.pointTo('#element', 'Custom message');
153
+ pointy.pointTo('#element', 'Message', 'down');
232
154
  ```
233
155
 
234
156
  ### Autoplay Control
235
157
 
236
158
  ```javascript
237
- pointy.startAutoplay(); // Start autoplay
238
- pointy.stopAutoplay(); // Stop autoplay
239
- pointy.pauseAutoplay(); // Pause autoplay
240
- pointy.resumeAutoplay(); // Resume autoplay
241
-
242
- pointy.isAutoplayActive(); // Check if autoplay is active
243
- pointy.isAutoplayPaused(); // Check if autoplay is paused
159
+ pointy.startAutoplay();
160
+ pointy.stopAutoplay();
161
+ pointy.pauseAutoplay();
162
+ pointy.resumeAutoplay();
244
163
  ```
245
164
 
246
- ### State
247
-
248
- ```javascript
249
- pointy.getCurrentStep(); // Get current step index
250
- pointy.getTotalSteps(); // Get total steps count
251
- pointy.isVisible; // Check visibility (property)
252
- ```
253
-
254
- ### Setters
255
-
256
- All setters emit corresponding `*Change` events:
257
-
258
- ```javascript
259
- // Animation
260
- pointy.setEasing('bounce');
261
- pointy.setAnimationDuration(800);
262
- pointy.setIntroFadeDuration(500);
263
- pointy.setBubbleFadeDuration(300);
264
- pointy.setMessageTransitionDuration(400);
265
-
266
- // Position
267
- pointy.setOffset(30, 20);
268
- pointy.setInitialPosition('top-left');
269
- pointy.setInitialPositionOffset(50);
270
-
271
- // Tracking
272
- pointy.setTracking(false);
273
- pointy.setTrackingFps(30);
274
-
275
- // Messages
276
- pointy.setMessageInterval(2000);
277
-
278
- // Autoplay
279
- pointy.setAutoplayInterval(3000);
280
- pointy.setAutoplayWaitForMessages(false);
281
-
282
- // Completion
283
- pointy.setResetOnComplete(false);
284
- pointy.setHideOnComplete(true);
285
- pointy.setHideOnCompleteDelay(500);
286
-
287
- // Styling
288
- pointy.setFloatingAnimation(false);
289
- pointy.setPointerSvg('<svg>...</svg>');
290
- ```
291
-
292
- ### Animation
165
+ ### Message Cycling
293
166
 
294
167
  ```javascript
295
- pointy.animateToInitialPosition(); // Animate to current initial position
168
+ pointy.startMessageCycle();
169
+ pointy.stopMessageCycle();
170
+ pointy.pauseMessageCycle();
171
+ pointy.resumeMessageCycle();
296
172
  ```
297
173
 
298
- ## ðŸŽĻ Easing Presets
174
+ ## Easing Presets
299
175
 
300
176
  ```javascript
301
- // Built-in presets
302
- pointy.setEasing('default'); // Smooth deceleration (default)
177
+ pointy.setEasing('default'); // Smooth deceleration
303
178
  pointy.setEasing('bounce'); // Bouncy overshoot
304
179
  pointy.setEasing('elastic'); // Elastic spring
305
180
  pointy.setEasing('smooth'); // Symmetric ease
306
181
  pointy.setEasing('snap'); // Quick snap
307
-
308
- // Material Design
309
- pointy.setEasing('standard'); // Material standard
310
- pointy.setEasing('decelerate'); // Material decelerate
311
- pointy.setEasing('accelerate'); // Material accelerate
312
-
313
- // Classic curves
314
182
  pointy.setEasing('expo-out'); // Exponential out
315
- pointy.setEasing('circ-out'); // Circular out
316
183
  pointy.setEasing('back-out'); // Back out
317
184
 
318
- // CSS built-ins work too
185
+ // CSS built-ins
319
186
  pointy.setEasing('ease');
320
- pointy.setEasing('ease-in-out');
321
187
  pointy.setEasing('linear');
322
188
 
323
- // Custom cubic-bezier
189
+ // Custom
324
190
  pointy.setEasing('cubic-bezier(0.68, -0.55, 0.27, 1.55)');
325
191
  ```
326
192
 
327
- Get all available presets:
328
- ```javascript
329
- Pointy.getEasingPresets();
330
- // ['default', 'standard', 'decelerate', 'accelerate', 'bounce', 'elastic', ...]
331
- ```
332
-
333
- ## ðŸ“Ą Events
334
-
335
- ### Event System
193
+ ## Events
336
194
 
337
195
  ```javascript
338
- // Subscribe to events
339
- pointy.on('show', (data) => {
340
- console.log('Pointy shown!', data.target);
341
- });
196
+ pointy.on('show', (data) => console.log('Shown!'));
197
+ pointy.on('stepChange', (data) => console.log(data.toIndex));
198
+ pointy.on('complete', (data) => console.log('Done!'));
342
199
 
343
200
  // Unsubscribe
344
- const handler = (data) => console.log(data);
345
- pointy.on('stepChange', handler);
346
201
  pointy.off('stepChange', handler);
347
-
348
- // Remove all listeners for an event
349
- pointy.off('stepChange');
350
-
351
- // Chaining
352
- pointy.on('show', fn1).on('hide', fn2).on('complete', fn3);
353
202
  ```
354
203
 
355
204
  ### Event Groups
356
205
 
357
- Listen to multiple related events with a single handler:
206
+ Listen to multiple related events at once:
358
207
 
359
208
  ```javascript
360
- // Listen to all lifecycle events
361
209
  pointy.on('lifecycle', (data) => {
362
- console.log(data.type); // 'beforeShow', 'show', 'hide', etc.
210
+ // Fires for: show, hide, destroy, restart, reset
211
+ console.log(data.type);
363
212
  });
364
213
 
365
- // Listen to all navigation events
366
214
  pointy.on('navigation', (data) => {
367
- console.log(data.type); // 'stepChange', 'next', 'prev', 'complete'
215
+ // Fires for: stepChange, next, prev, complete
368
216
  });
369
217
 
370
- // Listen to ALL events
371
218
  pointy.on('all', (data) => {
372
- console.log(data.type, data);
219
+ // Fires for ALL events
373
220
  });
374
-
375
- // or
376
- pointy.on('*', (data) => { ... });
377
221
  ```
378
222
 
379
- **Available Groups:**
380
- | Group | Events |
381
- |-------|--------|
382
- | `lifecycle` | beforeShow, show, beforeHide, hide, destroy, beforeRestart, restart, beforeReset, reset |
383
- | `navigation` | beforeStepChange, stepChange, next, prev, complete |
384
- | `animation` | animationStart, animationEnd, move, moveComplete, introAnimationStart, introAnimationEnd |
385
- | `content` | contentSet, messagesSet, messageChange |
386
- | `messageCycle` | messageCycleStart, messageCycleStop, messageCyclePause, messageCycleResume, messageCycleComplete |
387
- | `pointing` | beforePointTo, pointTo, pointToComplete |
388
- | `tracking` | track, targetChange, trackingChange, trackingFpsChange |
389
- | `autoplay` | autoplayStart, autoplayStop, autoplayPause, autoplayResume, autoplayNext, autoplayComplete, autoHide |
390
- | `config` | All `*Change` events |
391
-
392
- ### Static Helpers
393
-
394
- ```javascript
395
- Pointy.getEventGroup('show'); // 'lifecycle'
396
- Pointy.getEventsInGroup('lifecycle'); // ['beforeShow', 'show', ...]
397
- Pointy.EVENT_GROUPS; // All groups object
398
- ```
399
-
400
- ### All Events Reference
401
-
402
- #### Lifecycle Events
403
- | Event | Data | Description |
404
- |-------|------|-------------|
405
- | `beforeShow` | `{ target }` | Before pointer becomes visible |
406
- | `show` | `{ target, isIntro, isFirstStep? }` | After pointer becomes visible |
407
- | `beforeHide` | `{ target }` | Before pointer hides |
408
- | `hide` | `{ target }` | After pointer hides |
409
- | `destroy` | `{}` | Instance destroyed |
410
- | `beforeRestart` | `{}` | Before restart |
411
- | `restart` | `{}` | After restart completed |
412
- | `beforeReset` | `{ currentStep }` | Before reset to initial position |
413
- | `reset` | `{ stepIndex }` | After reset completed |
414
-
415
- #### Navigation Events
416
- | Event | Data | Description |
417
- |-------|------|-------------|
418
- | `beforeStepChange` | `{ fromIndex, toIndex, step, fromTarget }` | Before step transition |
419
- | `stepChange` | `{ fromIndex, toIndex, step, target }` | After step changed |
420
- | `next` | `{ fromIndex, toIndex }` | Moving to next step |
421
- | `prev` | `{ fromIndex, toIndex }` | Moving to previous step |
422
- | `complete` | `{ totalSteps, source }` | Tour completed (source: 'manual' or 'autoplay') |
423
-
424
- #### Animation Events
425
- | Event | Data | Description |
426
- |-------|------|-------------|
427
- | `animationStart` | `{ fromTarget, toTarget, type, stepIndex? }` | Movement started |
428
- | `animationEnd` | `{ fromTarget, toTarget, type, stepIndex? }` | Movement completed |
429
- | `move` | `{ index, step }` | Position update started |
430
- | `moveComplete` | `{ index, step, target }` | Position update finished |
431
- | `introAnimationStart` | `{ duration, initialPosition }` | Intro fade started |
432
- | `introAnimationEnd` | `{ initialPosition }` | Intro fade completed |
433
-
434
- #### Content Events
435
- | Event | Data | Description |
436
- |-------|------|-------------|
437
- | `contentSet` | `{ messages, total, animated, cyclePaused }` | Content updated via setContent() |
438
- | `messagesSet` | `{ messages, total, cyclePaused }` | Messages array set for step |
439
- | `messageChange` | `{ fromIndex, toIndex, message, total, isAuto? }` | Message changed |
440
-
441
- #### Message Cycle Events
442
- | Event | Data | Description |
443
- |-------|------|-------------|
444
- | `messageCycleStart` | `{ interval, totalMessages }` | Auto-cycling started |
445
- | `messageCycleStop` | `{ currentIndex }` | Auto-cycling stopped |
446
- | `messageCyclePause` | `{ currentIndex }` | Cycling paused |
447
- | `messageCycleResume` | `{ currentIndex }` | Cycling resumed |
448
- | `messageCycleComplete` | `{ stepIndex, totalMessages }` | All messages shown |
449
-
450
- #### Pointing Events
451
- | Event | Data | Description |
452
- |-------|------|-------------|
453
- | `beforePointTo` | `{ target, content, direction, fromTarget }` | Before pointTo() |
454
- | `pointTo` | `{ target, content, direction }` | pointTo() called |
455
- | `pointToComplete` | `{ target, content }` | pointTo() animation done |
456
-
457
- #### Tracking Events
458
- | Event | Data | Description |
459
- |-------|------|-------------|
460
- | `track` | `{ target, timestamp }` | Position tracked (fires at trackingFps rate) |
461
- | `targetChange` | `{ from, to }` | Target element changed |
462
- | `trackingChange` | `{ from, to }` | Tracking enabled/disabled |
463
- | `trackingFpsChange` | `{ from, to }` | Tracking FPS changed |
464
-
465
- #### Autoplay Events
466
- | Event | Data | Description |
467
- |-------|------|-------------|
468
- | `autoplayStart` | `{}` | Autoplay started |
469
- | `autoplayStop` | `{}` | Autoplay stopped |
470
- | `autoplayPause` | `{}` | Autoplay paused |
471
- | `autoplayResume` | `{}` | Autoplay resumed |
472
- | `autoplayNext` | `{ fromIndex, duration?, afterMessages? }` | Auto-advancing |
473
- | `autoplayComplete` | `{ totalSteps }` | Autoplay finished |
474
- | `autoHide` | `{ delay, source }` | Auto-hide triggered |
475
-
476
- #### Configuration Events
477
- All setters emit `*Change` events with `{ from, to }` data:
478
- - `easingChange`, `animationDurationChange`, `introFadeDurationChange`
479
- - `bubbleFadeDurationChange`, `messageIntervalChange`, `messageTransitionDurationChange`
480
- - `offsetChange`, `resetOnCompleteChange`, `hideOnCompleteChange`
481
- - `hideOnCompleteDelayChange`, `floatingAnimationChange`
482
- - `initialPositionChange`, `initialPositionOffsetChange`
483
- - `autoplayChange`, `autoplayWaitForMessagesChange`, `pointerSvgChange`
484
-
485
- ## ðŸŽĻ CSS Customization
223
+ **Available Groups:** `lifecycle`, `navigation`, `animation`, `content`, `messageCycle`, `pointing`, `tracking`, `autoplay`, `config`
224
+
225
+ ### All Events
226
+
227
+ #### Lifecycle
228
+ | Event | Data |
229
+ |-------|------|
230
+ | `beforeShow` | `{ target }` |
231
+ | `show` | `{ target, isIntro, isFirstStep? }` |
232
+ | `beforeHide` | `{ target }` |
233
+ | `hide` | `{ target }` |
234
+ | `destroy` | `{}` |
235
+ | `beforeRestart` | `{}` |
236
+ | `restart` | `{}` |
237
+ | `beforeReset` | `{ currentStep }` |
238
+ | `reset` | `{ stepIndex }` |
239
+
240
+ #### Navigation
241
+ | Event | Data |
242
+ |-------|------|
243
+ | `beforeStepChange` | `{ fromIndex, toIndex, step, fromTarget }` |
244
+ | `stepChange` | `{ fromIndex, toIndex, step, target }` |
245
+ | `next` | `{ fromIndex, toIndex }` |
246
+ | `prev` | `{ fromIndex, toIndex }` |
247
+ | `complete` | `{ totalSteps, source }` |
248
+
249
+ #### Animation
250
+ | Event | Data |
251
+ |-------|------|
252
+ | `animationStart` | `{ fromTarget, toTarget, type, stepIndex? }` |
253
+ | `animationEnd` | `{ fromTarget, toTarget, type, stepIndex? }` |
254
+ | `move` | `{ index, step }` |
255
+ | `moveComplete` | `{ index, step, target }` |
256
+ | `introAnimationStart` | `{ duration, initialPosition }` |
257
+ | `introAnimationEnd` | `{ initialPosition }` |
258
+
259
+ #### Content
260
+ | Event | Data |
261
+ |-------|------|
262
+ | `contentSet` | `{ messages, total, animated, cyclePaused }` |
263
+ | `messagesSet` | `{ messages, total, cyclePaused }` |
264
+ | `messageChange` | `{ fromIndex, toIndex, message, total, isAuto? }` |
265
+
266
+ #### Message Cycle
267
+ | Event | Data |
268
+ |-------|------|
269
+ | `messageCycleStart` | `{ interval, totalMessages }` |
270
+ | `messageCycleStop` | `{ currentIndex }` |
271
+ | `messageCyclePause` | `{ currentIndex }` |
272
+ | `messageCycleResume` | `{ currentIndex }` |
273
+ | `messageCycleComplete` | `{ stepIndex, totalMessages }` |
274
+
275
+ #### Pointing
276
+ | Event | Data |
277
+ |-------|------|
278
+ | `beforePointTo` | `{ target, content, direction, fromTarget }` |
279
+ | `pointTo` | `{ target, content, direction }` |
280
+ | `pointToComplete` | `{ target, content }` |
281
+
282
+ #### Tracking
283
+ | Event | Data |
284
+ |-------|------|
285
+ | `track` | `{ target, timestamp }` |
286
+ | `targetChange` | `{ from, to }` |
287
+ | `trackingChange` | `{ from, to }` |
288
+ | `trackingFpsChange` | `{ from, to }` |
289
+
290
+ #### Autoplay
291
+ | Event | Data |
292
+ |-------|------|
293
+ | `autoplayStart` | `{}` |
294
+ | `autoplayStop` | `{}` |
295
+ | `autoplayPause` | `{}` |
296
+ | `autoplayResume` | `{}` |
297
+ | `autoplayNext` | `{ fromIndex, duration?, afterMessages? }` |
298
+ | `autoplayComplete` | `{ totalSteps }` |
299
+ | `autoHide` | `{ delay, source }` |
300
+
301
+ #### Config
302
+ All setter methods emit `*Change` events with `{ from, to }` data.
303
+
304
+ ## CSS Customization
486
305
 
487
306
  ### CSS Variables
488
307
 
489
308
  ```css
490
309
  .pointy-container {
491
- --pointy-duration: 1000ms; /* Animation duration */
492
- --pointy-easing: cubic-bezier(0, 0.55, 0.45, 1); /* Easing */
493
- --pointy-bubble-fade: 500ms; /* Bubble fade duration */
310
+ --pointy-duration: 1000ms;
311
+ --pointy-easing: cubic-bezier(0, 0.55, 0.45, 1);
312
+ --pointy-bubble-fade: 500ms;
494
313
  }
495
314
  ```
496
315
 
497
- ### Custom Class Prefix
498
-
499
- ```javascript
500
- const pointy = new Pointy({
501
- classPrefix: 'my-tooltip', // Uses: my-tooltip-container, my-tooltip-pointer, etc.
502
- cssVarPrefix: 'tooltip', // Uses: --tooltip-duration, etc.
503
- steps: [...]
504
- });
505
- ```
506
-
507
- ### Generated Classes
508
-
509
- | Class | Description |
510
- |-------|-------------|
511
- | `{prefix}-container` | Main container element |
512
- | `{prefix}-pointer` | Pointer/cursor element |
513
- | `{prefix}-bubble` | Tooltip bubble |
514
- | `{prefix}-bubble-text` | Text inside bubble |
515
- | `{prefix}-hidden` | Applied when hidden |
516
- | `{prefix}-visible` | Applied when visible |
517
- | `{prefix}-moving` | Applied during animation |
518
-
519
316
  ### Custom Pointer SVG
520
317
 
521
318
  ```javascript
522
319
  const pointy = new Pointy({
523
- pointerSvg: `
524
- <svg width="40" height="40" viewBox="0 0 40 40">
525
- <circle cx="20" cy="20" r="15" fill="#ff6b6b"/>
526
- </svg>
527
- `,
528
- steps: [...]
529
- });
530
-
531
- // Or change at runtime
532
- pointy.setPointerSvg('<svg>...</svg>');
533
- ```
534
-
535
- **React/JSX Support:**
536
-
537
- ```jsx
538
- // Use React elements as pointer SVG
539
- const CustomPointer = () => (
540
- <svg width="40" height="40" viewBox="0 0 40 40">
541
- <circle cx="20" cy="20" r="15" fill="#ff6b6b"/>
542
- </svg>
543
- );
544
-
545
- const pointy = new Pointy({
546
- pointerSvg: <CustomPointer />,
320
+ pointerSvg: `<svg width="40" height="40">...</svg>`,
547
321
  steps: [...]
548
322
  });
549
323
  ```
550
324
 
551
- ## ⚛ïļ React Integration
552
-
553
- Pointy supports React elements as content and pointer SVG:
554
-
555
- ```jsx
556
- const pointy = new Pointy({
557
- steps: [
558
- {
559
- target: '#element',
560
- content: <div><strong>Welcome!</strong> Click to continue</div>
561
- },
562
- {
563
- target: '#features',
564
- content: [
565
- <span key="1">First message with <em>JSX</em></span>,
566
- <span key="2">Second message</span>
567
- ]
568
- }
569
- ]
570
- });
571
- ```
572
-
573
- ## 🔧 Static Methods
574
-
575
- ```javascript
576
- // Render content (supports string/HTML and React elements)
577
- Pointy.renderContent(element, content);
578
-
579
- // Get DOM element from selector or element
580
- Pointy.getTargetElement('#selector');
581
- Pointy.getTargetElement(domElement);
582
-
583
- // Generate class names with custom prefix
584
- Pointy.generateClassNames('custom-prefix', { bubble: 'tooltip' });
585
-
586
- // Get available presets
587
- Pointy.getEasingPresets(); // ['default', 'bounce', ...]
588
- Pointy.getInitialPositions(); // ['center', 'top-left', ...]
589
-
590
- // Event group helpers
591
- Pointy.getEventGroup('show'); // 'lifecycle'
592
- Pointy.getEventsInGroup('navigation'); // ['stepChange', 'next', ...]
593
- Pointy.EVENT_GROUPS; // All groups object
594
- ```
595
-
596
- ## ðŸ’Ą Examples
325
+ ## Examples
597
326
 
598
327
  ### Basic Tour
599
328
 
@@ -602,11 +331,8 @@ const tour = new Pointy({
602
331
  steps: [
603
332
  { target: '#logo', content: 'Welcome to our app!' },
604
333
  { target: '#dashboard', content: 'This is your dashboard' },
605
- { target: '#settings', content: 'Customize your settings here' }
606
- ],
607
- onComplete: () => {
608
- console.log('Tour completed!');
609
- }
334
+ { target: '#settings', content: 'Customize settings here' }
335
+ ]
610
336
  });
611
337
 
612
338
  tour.show();
@@ -615,81 +341,39 @@ tour.show();
615
341
  ### Autoplay Tour
616
342
 
617
343
  ```javascript
618
- const autoTour = new Pointy({
344
+ const tour = new Pointy({
619
345
  steps: [
620
346
  { target: '#step1', content: 'Step 1' },
621
- { target: '#step2', content: 'Step 2', duration: 5000 }, // Longer pause
347
+ { target: '#step2', content: 'Step 2', duration: 5000 },
622
348
  { target: '#step3', content: 'Step 3' }
623
349
  ],
624
- autoplay: 3000, // 3 seconds per step
625
- autoplayEnabled: true, // Start automatically
626
- hideOnComplete: true, // Hide when done
627
- hideOnCompleteDelay: 500 // Wait 500ms before hiding
628
- });
629
-
630
- autoTour.show();
631
- ```
632
-
633
- ### Multi-Message Steps with Auto-Cycle
634
-
635
- ```javascript
636
- const multiMsg = new Pointy({
637
- steps: [
638
- {
639
- target: '#feature',
640
- content: [
641
- 'Did you know...',
642
- 'You can click this button',
643
- 'To access advanced features!'
644
- ]
645
- }
646
- ],
647
- messageInterval: 2500, // Change message every 2.5s
648
- autoplay: null, // Manual navigation
649
- autoplayWaitForMessages: true
650
- });
651
-
652
- multiMsg.show();
653
- ```
654
-
655
- ### Feature Highlight
656
-
657
- ```javascript
658
- const highlight = new Pointy({
659
- target: '#new-feature',
660
- content: 'New! Check out this feature',
661
- initialPosition: 'bottom-right',
662
- floatingAnimation: true
350
+ autoplay: 3000,
351
+ autoplayEnabled: true,
352
+ hideOnComplete: true
663
353
  });
664
354
 
665
- highlight.show();
666
-
667
- // Point to different elements
668
- highlight.pointTo('#another-element', 'Or explore this!');
355
+ tour.show();
669
356
  ```
670
357
 
671
- ### Event-Driven Tour
358
+ ### Multi-Message Steps
672
359
 
673
360
  ```javascript
674
- const eventTour = new Pointy({
675
- steps: [...],
676
- messageInterval: 2000
361
+ const tour = new Pointy({
362
+ steps: [{
363
+ target: '#feature',
364
+ content: [
365
+ 'Did you know...',
366
+ 'You can click this button',
367
+ 'To access advanced features!'
368
+ ]
369
+ }],
370
+ messageInterval: 2500
677
371
  });
678
372
 
679
- eventTour
680
- .on('show', () => console.log('Tour started'))
681
- .on('stepChange', ({ toIndex }) => analytics.track('tour_step', toIndex))
682
- .on('complete', ({ source }) => {
683
- analytics.track('tour_complete', { source });
684
- })
685
- .on('autoHide', () => {
686
- showFollowUpModal();
687
- });
688
-
689
- eventTour.show();
373
+ tour.show();
690
374
  ```
691
375
 
692
- ### Pause/Resume on Hover
376
+ ### Pause on Hover
693
377
 
694
378
  ```javascript
695
379
  const tour = new Pointy({
@@ -698,112 +382,37 @@ const tour = new Pointy({
698
382
  autoplayEnabled: true
699
383
  });
700
384
 
701
- tour.bubble.addEventListener('mouseenter', () => {
702
- tour.pauseAutoplay();
703
- tour.pauseMessageCycle();
704
- });
705
-
706
- tour.bubble.addEventListener('mouseleave', () => {
707
- tour.resumeAutoplay();
708
- tour.resumeMessageCycle();
709
- });
385
+ tour.container.addEventListener('mouseenter', () => tour.pauseAutoplay());
386
+ tour.container.addEventListener('mouseleave', () => tour.resumeAutoplay());
710
387
 
711
388
  tour.show();
712
389
  ```
713
390
 
714
- ### Custom Styling
391
+ ## TypeScript
715
392
 
716
- ```javascript
717
- const styledPointy = new Pointy({
718
- classPrefix: 'custom',
719
- steps: [
720
- { target: '#el', content: 'Styled tooltip!' }
721
- ],
722
- pointerSvg: `
723
- <svg width="24" height="24" viewBox="0 0 24 24">
724
- <path d="M12 2L2 12l10 10V2z" fill="#6366f1"/>
725
- </svg>
726
- `
727
- });
728
-
729
- // Add custom CSS
730
- const style = document.createElement('style');
731
- style.textContent = `
732
- .custom-bubble {
733
- background: linear-gradient(135deg, #6366f1, #8b5cf6);
734
- border-radius: 20px;
735
- padding: 12px 20px;
736
- }
737
- `;
738
- document.head.appendChild(style);
739
-
740
- styledPointy.show();
741
- ```
742
-
743
- ## 🌐 Browser Support
744
-
745
- - Chrome 60+
746
- - Firefox 55+
747
- - Safari 12+
748
- - Edge 79+
749
-
750
- ## 📘 TypeScript Support
751
-
752
- Pointy includes full TypeScript definitions out of the box. No additional `@types` package needed.
393
+ Full TypeScript support included:
753
394
 
754
395
  ```typescript
755
- import Pointy, { PointyOptions, PointyStep, PointyEventData } from '@diabolic/pointy';
396
+ import Pointy, { PointyOptions, PointyStep } from '@diabolic/pointy';
756
397
 
757
398
  const options: PointyOptions = {
758
- steps: [
759
- { target: '#btn', content: 'Click here!' }
760
- ],
761
- autoplay: 3000
399
+ steps: [{ target: '#btn', content: 'Click!' }]
762
400
  };
763
401
 
764
402
  const pointy = new Pointy(options);
765
403
 
766
- // Full type safety for events
767
404
  pointy.on('stepChange', (data) => {
768
- console.log(data.fromIndex, data.toIndex); // Types inferred
769
- });
770
-
771
- // Type-safe event groups
772
- pointy.on('lifecycle', (data) => {
773
- console.log(data.type); // 'beforeShow' | 'show' | 'hide' | ...
405
+ console.log(data.fromIndex, data.toIndex);
774
406
  });
775
407
  ```
776
408
 
777
- ### Exported Types
409
+ ## Browser Support
778
410
 
779
- ```typescript
780
- import {
781
- Pointy,
782
- PointyOptions,
783
- PointyStep,
784
- PointyClassNames,
785
- PointyInitialPosition,
786
- PointyEasing,
787
- PointyEvent,
788
- PointyEventGroup,
789
- PointyEventData,
790
- PointyEventCallback,
791
- // Event-specific data types
792
- PointyLifecycleEventData,
793
- PointyNavigationEventData,
794
- PointyAnimationEventData,
795
- PointyContentEventData,
796
- PointyMessageCycleEventData,
797
- PointyPointingEventData,
798
- PointyTrackingEventData,
799
- PointyAutoplayEventData,
800
- PointyConfigChangeEventData,
801
- } from '@diabolic/pointy';
802
- ```
411
+ Chrome 60+, Firefox 55+, Safari 12+, Edge 79+
803
412
 
804
- ## 📄 License
413
+ ## License
805
414
 
806
- MIT License - feel free to use in personal and commercial projects.
415
+ MIT License
807
416
 
808
417
  ---
809
418