kamrify commited on
Commit
70d8f15
·
1 Parent(s): 40c6a95

Refactor highlighting

Browse files
Files changed (3) hide show
  1. index.html +365 -359
  2. src/config.ts +5 -0
  3. src/highlight.ts +24 -26
index.html CHANGED
@@ -1,57 +1,57 @@
1
  <!DOCTYPE html>
2
  <html lang="en">
3
- <head>
4
- <meta charset="UTF-8" />
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
- <title>Vite App</title>
7
 
8
- <style>
9
  * {
10
- margin: 0;
11
- padding: 0;
12
  }
13
 
14
  body {
15
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans",
16
  "Helvetica Neue", sans-serif;
17
- font-size: 14px;
18
- -webkit-font-smoothing: antialiased;
19
- -moz-osx-font-smoothing: grayscale;
20
  }
21
 
22
  .gif-popover {
23
- display: flex;
24
- flex-direction: column;
25
- text-align: center;
26
  }
27
 
28
  .gif-popover img {
29
- width: 100%;
30
- height: auto;
31
- margin-bottom: 10px;
32
  }
33
 
34
  .gif-popover p {
35
- font-weight: 500;
36
- margin-bottom: 0;
37
  }
38
 
39
  p {
40
- line-height: 1.5;
41
- margin-bottom: 15px;
42
  }
43
 
44
  .page-header {
45
- text-align: center;
46
- margin-bottom: 10px;
47
  }
48
 
49
  .container {
50
- display: flex;
51
- flex-direction: column;
52
- max-width: 500px;
53
- margin: 0 auto;
54
- text-align: left;
55
  }
56
 
57
  h1,
@@ -60,365 +60,371 @@
60
  h4,
61
  h5,
62
  h6 {
63
- margin: 30px 0 10px;
64
  }
65
 
66
  h1 {
67
- font-size: 48px;
68
- font-weight: 600;
69
- text-align: center;
70
  }
71
 
72
  h1 sup {
73
- font-size: 18px;
74
- font-weight: 400;
75
  }
76
 
77
  ul {
78
- list-style: none;
79
- padding: 0;
80
- margin: 20px 10px 0;
81
- line-height: 1.5;
82
  }
83
 
84
  ul li:before {
85
- content: "•";
86
- margin-right: 10px;
87
  }
88
 
89
  .buttons {
90
- display: flex;
91
- margin-top: 20px;
92
- gap: 10px;
93
- max-width: 500px;
94
- flex-wrap: wrap;
95
  }
96
 
97
  button {
98
- all: unset;
99
- border: 1px solid #ccc;
100
- padding: 5px 15px;
101
- border-radius: 5px;
102
- display: block;
103
- cursor: pointer;
104
  }
105
 
106
  pre {
107
- margin-bottom: 20px;
108
- border: 1px solid #ccc;
109
- background: whitesmoke;
110
- border-radius: 5px;
111
- padding: 10px;
112
- line-height: 1.75;
113
  }
114
 
115
  #scrollable-area {
116
- height: 300px;
117
- overflow: auto;
118
- border: 1px solid #ccc;
119
- padding: 10px;
120
- border-radius: 5px;
121
- margin: 50px 0;
122
  }
123
- </style>
124
- </head>
125
- <body>
126
- <div class="container">
127
- <div class="page-header">
128
- <h1>driver.js <sup>next</sup></h1>
129
- <p>Rewritten and enhanced version of driver.js</p>
130
- </div>
131
-
132
- <div class="buttons">
133
- <button id="highlight-btn">Animated Highlight</button>
134
- <button id="simple-highlight-btn">Simple Highlight</button>
135
- <button id="transition-highlight-btn">Transition Highlight</button>
136
- <button id="disallow-close">Disallow Close</button>
137
- <button id="dark-highlight-btn">Super Dark Highlight</button>
138
- <button id="dim-highlight-btn">Super Dim Highlight</button>
139
- <button id="scrollable-area-btn">Scrollable Area</button>
140
- <button id="inner-scroll-area-btn">Inner Scroll Area</button>
141
- <button id="without-element-btn">No Element</button>
142
- <button id="is-active-btn">Is Active?</button>
143
- <button id="activate-check-btn">Activate and Check</button>
144
- <button id="modify-refresh">Modify Active + Refresh</button>
145
- <button id="destroy-btn">Destroy</button>
146
- </div>
147
-
148
- <ul>
149
- <li>Written in TypeScript</li>
150
- <li>Lightweight — only 5kb gzipped</li>
151
- <li>No dependencies</li>
152
- <li>MIT Licensed</li>
153
- </ul>
154
-
155
- <h2>Yet another Tour Library?</h2>
156
- <p>
157
- No, it is not. Tours are just one of the many use-cases. Driver.js can be used wherever you need some sort of
158
- overlay for the page; some common usecases could be: e.g. dimming the background when user is interacting with
159
- some component, using it as a focus shifter to bring user's attention to some component on page, or using it to
160
- simulate those "Turn off the Lights" widgets that you might have seen on video players online, etc.
161
- </p>
162
- <p class="second-para">
163
- Driver.js is written in Vanilla JS, has zero dependencies and is highly customizable. It has several options
164
- allowing you to manipulate how it behaves and also provides you the hooks to manipulate the elements as they are
165
- highlighted, about to be highlighted, or deselected.
166
- </p>
167
-
168
- <h2 id="installation-head">Installation</h2>
169
- <p>You can install it using yarn or npm, whatever you prefer.</p>
170
-
171
- <pre>
172
  yarn add driver.js
173
  npm install driver.js</pre
174
- >
175
-
176
- <p>Or include it using CDN — put the version as [email protected] in the name</p>
177
-
178
- <pre>https://unpkg.com/driver.js/dist/driver.min.js</pre>
179
-
180
- <h2>Usage and Demo</h2>
181
-
182
- <p id="large-paragraph-text">
183
- Lorem ipsum dolor sit amet, consectetur adipisicing elit. Animi blanditiis consectetur ea eligendi id in
184
- inventore ipsa iure laudantium libero, minus molestias necessitatibus nesciunt non omnis, quasi recusandae
185
- tempore voluptates! Lorem ipsum dolor sit amet, consectetur adipisicing elit. Animi blanditiis consectetur ea
186
- eligendi id in inventore ipsa iure laudantium libero, minus molestias necessitatibus nesciunt non omnis, quasi
187
- recusandae tempore voluptates!
188
- </p>
189
- <p>
190
- Lorem ipsum dolor sit amet, consectetur adipisicing elit. Animi blanditiis consectetur ea eligendi id in
191
- inventore ipsa iure laudantium libero, minus molestias necessitatibus nesciunt non omnis, quasi recusandae
192
- tempore voluptates!
193
- </p>
194
- <p>
195
- Lorem ipsum dolor sit amet, consectetur adipisicing elit. Animi blanditiis consectetur ea eligendi id in
196
- inventore ipsa iure laudantium libero, minus molestias necessitatibus nesciunt non omnis, quasi recusandae
197
- tempore voluptates!
198
- </p>
199
- <div id="scrollable-area">
200
- <p>
201
- First -> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequuntur dicta ipsum labore quod
202
- tempora ullam? Alias consequatur doloremque laborum maxime necessitatibus nostrum odio, officiis quibusdam
203
- veniam! Doloribus eos id quaerat.
204
- </p>
205
- <p>
206
- Second -> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequuntur dicta ipsum labore quod
207
- tempora ullam? Alias consequatur doloremque laborum maxime necessitatibus nostrum odio, officiis quibusdam
208
- veniam! Doloribus eos id quaerat.
209
- </p>
210
- <p id="third-scroll-paragraph">
211
- Third -> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequuntur dicta ipsum labore quod
212
- tempora ullam? Alias consequatur doloremque laborum maxime necessitatibus nostrum odio, officiis quibusdam
213
- veniam! Doloribus eos id quaerat.
214
- </p>
215
- <p>
216
- Fourth -> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequuntur dicta ipsum labore quod
217
- tempora ullam? Alias consequatur doloremque laborum maxime necessitatibus nostrum odio, officiis quibusdam
218
- veniam! Doloribus eos id quaerat.
219
- </p>
220
- <p>
221
- Fifth -> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequuntur dicta ipsum labore quod
222
- tempora ullam? Alias consequatur doloremque laborum maxime necessitatibus nostrum odio, officiis quibusdam
223
- veniam! Doloribus eos id quaerat.
224
- </p>
225
- <p>
226
- Sixth -> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequuntur dicta ipsum labore quod
227
- tempora ullam? Alias consequatur doloremque laborum maxime necessitatibus nostrum odio, officiis quibusdam
228
- veniam! Doloribus eos id quaerat.
229
- </p>
230
- <p>
231
- Seventh -> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequuntur dicta ipsum labore quod
232
- tempora ullam? Alias consequatur doloremque laborum maxime necessitatibus nostrum odio, officiis quibusdam
233
- veniam! Doloribus eos id quaerat.
234
- </p>
235
- <p>
236
- Eighth -> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequuntur dicta ipsum labore quod
237
- tempora ullam? Alias consequatur doloremque laborum maxime necessitatibus nostrum odio, officiis quibusdam
238
- veniam! Doloribus eos id quaerat.
239
- </p>
240
- <p>
241
- Ninth -> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequuntur dicta ipsum labore quod
242
- tempora ullam? Alias consequatur doloremque laborum maxime necessitatibus nostrum odio, officiis quibusdam
243
- veniam! Doloribus eos id quaerat.
244
- </p>
245
- </div>
246
- <p>
247
- Lorem ipsum dolor sit amet, consectetur adipisicing elit. Animi blanditiis consectetur ea eligendi id in
248
- inventore ipsa iure laudantium libero, minus molestias necessitatibus nesciunt non omnis, quasi recusandae
249
- tempore voluptates!
250
- </p>
251
- <p>
252
- Lorem ipsum dolor sit amet, consectetur adipisicing elit. Animi blanditiis consectetur ea eligendi id in
253
- inventore ipsa iure laudantium libero, minus molestias necessitatibus nesciunt non omnis, quasi recusandae
254
- tempore voluptates!
255
- </p>
256
- <p>
257
- Lorem ipsum dolor sit amet, consectetur adipisicing elit. Animi blanditiis consectetur ea eligendi id in
258
- inventore ipsa iure laudantium libero, minus molestias necessitatibus nesciunt non omnis, quasi recusandae
259
- tempore voluptates!
260
- </p>
261
- <p>
262
- Lorem ipsum dolor sit amet, consectetur adipisicing elit. Animi blanditiis consectetur ea eligendi id in
263
- inventore ipsa iure laudantium libero, minus molestias necessitatibus nesciunt non omnis, quasi recusandae
264
- tempore voluptates!
265
- </p>
266
- <p>
267
- Lorem ipsum dolor sit amet, consectetur adipisicing elit. Animi blanditiis consectetur ea eligendi id in
268
- inventore ipsa iure laudantium libero, minus molestias necessitatibus nesciunt non omnis, quasi recusandae
269
- tempore voluptates!
270
- </p>
271
- </div>
272
- <script type="module">
273
- import { driver } from "./src/driver.ts";
274
-
275
- document.getElementById("is-active-btn").addEventListener("click", () => {
276
- alert(driver().isActive());
277
- });
278
-
279
- document.getElementById("activate-check-btn").addEventListener("click", () => {
280
- const driverObj = driver({
281
- showButtons: false,
282
- });
283
-
284
- driverObj.highlight({
285
- element: "#activate-check-btn",
286
- popover: {
287
- title: "Check if driver is active",
288
- description: "This will alert the status after 2 seconds",
289
- side: 'bottom',
290
- align: 'start',
291
- },
292
- });
293
-
294
- setTimeout(() => {
295
- alert(`Status: ${driverObj.isActive()}. Destroying driver...`);
296
- driverObj.destroy();
297
- setTimeout(() => {
298
- alert(`Status: ${driverObj.isActive()}`);
299
- }, 0);
300
- }, 2000);
301
- });
302
-
303
- document.getElementById("highlight-btn").addEventListener("click", () => {
304
- driver({
305
- animate: true,
306
- popoverOffset: 10,
307
- }).highlight({
308
- element: "h2",
309
- popover: {
310
- title: "MIT License",
311
- description: "A lightweight, no-dependency JavaScript engine to drive user's focus.",
312
- side: "bottom",
313
- align: "start",
314
- showButtons: true,
315
- },
316
- });
317
- });
318
-
319
- document.getElementById("simple-highlight-btn").addEventListener("click", () => {
320
- driver({ animate: false }).highlight({
321
- element: "#large-paragraph-text",
322
- popover: {
323
- title: "driver.js",
324
- description:
325
- "Highlight anything, anywhere on the page. Yes, literally anything including SVG portions, scrollable items etc.",
326
- align: "start",
327
- side: "top",
328
- },
329
- });
330
- });
331
-
332
- document.getElementById("dark-highlight-btn").addEventListener("click", () => {
333
- driver({
334
- animate: true,
335
- opacity: 0.9,
336
- }).highlight({ element: "ul" });
337
- });
338
-
339
- document.getElementById("dim-highlight-btn").addEventListener("click", () => {
340
- driver({
341
- animate: true,
342
- opacity: 0.2,
343
- }).highlight({ element: ".buttons" });
344
- });
345
-
346
- document.getElementById("transition-highlight-btn").addEventListener("click", () => {
347
- const driverObj = driver({ animate: true });
348
-
349
- driverObj.highlight({
350
- popover: {
351
- title: "driver.js",
352
- description: "Highlight anything, anywhere on the page",
353
- },
354
- });
355
-
356
- window.setTimeout(() => {
357
- driverObj.highlight({
358
- element: ".buttons button:first-child",
359
- popover: {
360
- title: "driver.js",
361
- description: "Highlight anything, anywhere on the page",
362
- },
363
  });
364
- }, 2000);
365
-
366
- window.setTimeout(() => {
367
- driverObj.highlight({
368
- popover: {
369
- title: "driver.js",
370
- description: "Highlight anything, anywhere on the page",
371
- },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
372
  });
373
- }, 4000);
374
-
375
- window.setTimeout(() => {
376
- driverObj.highlight({
377
- element: "h2",
378
- popover: {
379
- description: "driver.js",
380
- },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
381
  });
382
- }, 6000);
383
- });
384
-
385
- document.getElementById("scrollable-area-btn").addEventListener("click", () => {
386
- const driverObj = driver({ animate: true });
387
- driverObj.highlight({ element: "#scrollable-area" });
388
- });
389
-
390
- document.getElementById("without-element-btn").addEventListener("click", () => {
391
- const driverObj = driver({
392
- animate: true,
393
- });
394
- driverObj.highlight({
395
- popover: {
396
- showButtons: false,
397
- description:
398
- "<div class='gif-popover'><img style='max-width: 100%' src='https://i.imgur.com/EAQhHu5.gif' /><p>Go and build something cool!</p></div>",
399
- },
400
- });
401
- });
402
-
403
- document.getElementById("inner-scroll-area-btn").addEventListener("click", () => {
404
- const driverObj = driver({ animate: true });
405
- driverObj.highlight({ element: "#third-scroll-paragraph" });
406
- });
407
-
408
- document.getElementById("disallow-close").addEventListener("click", () => {
409
- const driverObj = driver({
410
- animate: true,
411
- allowClose: false,
412
- });
413
-
414
- driverObj.highlight({
415
- element: ".buttons",
416
- });
417
- });
418
-
419
- document.getElementById("destroy-btn").addEventListener("click", () => {
420
- driver().destroy();
421
- });
422
- </script>
423
- </body>
424
  </html>
 
1
  <!DOCTYPE html>
2
  <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Vite App</title>
7
 
8
+ <style>
9
  * {
10
+ margin: 0;
11
+ padding: 0;
12
  }
13
 
14
  body {
15
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans",
16
  "Helvetica Neue", sans-serif;
17
+ font-size: 14px;
18
+ -webkit-font-smoothing: antialiased;
19
+ -moz-osx-font-smoothing: grayscale;
20
  }
21
 
22
  .gif-popover {
23
+ display: flex;
24
+ flex-direction: column;
25
+ text-align: center;
26
  }
27
 
28
  .gif-popover img {
29
+ width: 100%;
30
+ height: auto;
31
+ margin-bottom: 10px;
32
  }
33
 
34
  .gif-popover p {
35
+ font-weight: 500;
36
+ margin-bottom: 0;
37
  }
38
 
39
  p {
40
+ line-height: 1.5;
41
+ margin-bottom: 15px;
42
  }
43
 
44
  .page-header {
45
+ text-align: center;
46
+ margin-bottom: 10px;
47
  }
48
 
49
  .container {
50
+ display: flex;
51
+ flex-direction: column;
52
+ max-width: 500px;
53
+ margin: 0 auto;
54
+ text-align: left;
55
  }
56
 
57
  h1,
 
60
  h4,
61
  h5,
62
  h6 {
63
+ margin: 30px 0 10px;
64
  }
65
 
66
  h1 {
67
+ font-size: 48px;
68
+ font-weight: 600;
69
+ text-align: center;
70
  }
71
 
72
  h1 sup {
73
+ font-size: 18px;
74
+ font-weight: 400;
75
  }
76
 
77
  ul {
78
+ list-style: none;
79
+ padding: 0;
80
+ margin: 20px 10px 0;
81
+ line-height: 1.5;
82
  }
83
 
84
  ul li:before {
85
+ content: "•";
86
+ margin-right: 10px;
87
  }
88
 
89
  .buttons {
90
+ display: flex;
91
+ margin-top: 20px;
92
+ gap: 10px;
93
+ max-width: 500px;
94
+ flex-wrap: wrap;
95
  }
96
 
97
  button {
98
+ all: unset;
99
+ border: 1px solid #ccc;
100
+ padding: 5px 15px;
101
+ border-radius: 5px;
102
+ display: block;
103
+ cursor: pointer;
104
  }
105
 
106
  pre {
107
+ margin-bottom: 20px;
108
+ border: 1px solid #ccc;
109
+ background: whitesmoke;
110
+ border-radius: 5px;
111
+ padding: 10px;
112
+ line-height: 1.75;
113
  }
114
 
115
  #scrollable-area {
116
+ height: 300px;
117
+ overflow: auto;
118
+ border: 1px solid #ccc;
119
+ padding: 10px;
120
+ border-radius: 5px;
121
+ margin: 50px 0;
122
  }
123
+ </style>
124
+ </head>
125
+ <body>
126
+ <div class="container">
127
+ <div class="page-header">
128
+ <h1>driver.js <sup>next</sup></h1>
129
+ <p>Rewritten and enhanced version of driver.js</p>
130
+ </div>
131
+
132
+ <div class="buttons">
133
+ <button id="highlight-btn">Animated Highlight</button>
134
+ <button id="simple-highlight-btn">Simple Highlight</button>
135
+ <button id="transition-highlight-btn">Transition Highlight</button>
136
+ <button id="disallow-close">Disallow Close</button>
137
+ <button id="dark-highlight-btn">Super Dark Highlight</button>
138
+ <button id="dim-highlight-btn">Super Dim Highlight</button>
139
+ <button id="scrollable-area-btn">Scrollable Area</button>
140
+ <button id="inner-scroll-area-btn">Inner Scroll Area</button>
141
+ <button id="without-element-btn">No Element</button>
142
+ <button id="is-active-btn">Is Active?</button>
143
+ <button id="activate-check-btn">Activate and Check</button>
144
+ <button id="modify-refresh">Modify Active + Refresh</button>
145
+ <button id="destroy-btn">Destroy</button>
146
+ </div>
147
+
148
+ <ul>
149
+ <li>Written in TypeScript</li>
150
+ <li>Lightweight — only 5kb gzipped</li>
151
+ <li>No dependencies</li>
152
+ <li>MIT Licensed</li>
153
+ </ul>
154
+
155
+ <h2>Yet another Tour Library?</h2>
156
+ <p>
157
+ No, it is not. Tours are just one of the many use-cases. Driver.js can be used wherever you need some sort of
158
+ overlay for the page; some common usecases could be: e.g. dimming the background when user is interacting with
159
+ some component, using it as a focus shifter to bring user's attention to some component on page, or using it to
160
+ simulate those "Turn off the Lights" widgets that you might have seen on video players online, etc.
161
+ </p>
162
+ <p class="second-para">
163
+ Driver.js is written in Vanilla JS, has zero dependencies and is highly customizable. It has several options
164
+ allowing you to manipulate how it behaves and also provides you the hooks to manipulate the elements as they are
165
+ highlighted, about to be highlighted, or deselected.
166
+ </p>
167
+
168
+ <h2 id="installation-head">Installation</h2>
169
+ <p>You can install it using yarn or npm, whatever you prefer.</p>
170
+
171
+ <pre>
172
  yarn add driver.js
173
  npm install driver.js</pre
174
+ >
175
+
176
+ <p>Or include it using CDN — put the version as [email protected] in the name</p>
177
+
178
+ <pre>https://unpkg.com/driver.js/dist/driver.min.js</pre>
179
+
180
+ <h2>Usage and Demo</h2>
181
+
182
+ <p id="large-paragraph-text">
183
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit. Animi blanditiis consectetur ea eligendi id in
184
+ inventore ipsa iure laudantium libero, minus molestias necessitatibus nesciunt non omnis, quasi recusandae
185
+ tempore voluptates! Lorem ipsum dolor sit amet, consectetur adipisicing elit. Animi blanditiis consectetur ea
186
+ eligendi id in inventore ipsa iure laudantium libero, minus molestias necessitatibus nesciunt non omnis, quasi
187
+ recusandae tempore voluptates!
188
+ </p>
189
+ <p>
190
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit. Animi blanditiis consectetur ea eligendi id in
191
+ inventore ipsa iure laudantium libero, minus molestias necessitatibus nesciunt non omnis, quasi recusandae
192
+ tempore voluptates!
193
+ </p>
194
+ <p>
195
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit. Animi blanditiis consectetur ea eligendi id in
196
+ inventore ipsa iure laudantium libero, minus molestias necessitatibus nesciunt non omnis, quasi recusandae
197
+ tempore voluptates!
198
+ </p>
199
+ <div id="scrollable-area">
200
+ <p>
201
+ First -> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequuntur dicta ipsum labore quod
202
+ tempora ullam? Alias consequatur doloremque laborum maxime necessitatibus nostrum odio, officiis quibusdam
203
+ veniam! Doloribus eos id quaerat.
204
+ </p>
205
+ <p>
206
+ Second -> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequuntur dicta ipsum labore quod
207
+ tempora ullam? Alias consequatur doloremque laborum maxime necessitatibus nostrum odio, officiis quibusdam
208
+ veniam! Doloribus eos id quaerat.
209
+ </p>
210
+ <p id="third-scroll-paragraph">
211
+ Third -> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequuntur dicta ipsum labore quod
212
+ tempora ullam? Alias consequatur doloremque laborum maxime necessitatibus nostrum odio, officiis quibusdam
213
+ veniam! Doloribus eos id quaerat.
214
+ </p>
215
+ <p>
216
+ Fourth -> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequuntur dicta ipsum labore quod
217
+ tempora ullam? Alias consequatur doloremque laborum maxime necessitatibus nostrum odio, officiis quibusdam
218
+ veniam! Doloribus eos id quaerat.
219
+ </p>
220
+ <p>
221
+ Fifth -> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequuntur dicta ipsum labore quod
222
+ tempora ullam? Alias consequatur doloremque laborum maxime necessitatibus nostrum odio, officiis quibusdam
223
+ veniam! Doloribus eos id quaerat.
224
+ </p>
225
+ <p>
226
+ Sixth -> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequuntur dicta ipsum labore quod
227
+ tempora ullam? Alias consequatur doloremque laborum maxime necessitatibus nostrum odio, officiis quibusdam
228
+ veniam! Doloribus eos id quaerat.
229
+ </p>
230
+ <p>
231
+ Seventh -> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequuntur dicta ipsum labore quod
232
+ tempora ullam? Alias consequatur doloremque laborum maxime necessitatibus nostrum odio, officiis quibusdam
233
+ veniam! Doloribus eos id quaerat.
234
+ </p>
235
+ <p>
236
+ Eighth -> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequuntur dicta ipsum labore quod
237
+ tempora ullam? Alias consequatur doloremque laborum maxime necessitatibus nostrum odio, officiis quibusdam
238
+ veniam! Doloribus eos id quaerat.
239
+ </p>
240
+ <p>
241
+ Ninth -> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequuntur dicta ipsum labore quod
242
+ tempora ullam? Alias consequatur doloremque laborum maxime necessitatibus nostrum odio, officiis quibusdam
243
+ veniam! Doloribus eos id quaerat.
244
+ </p>
245
+ </div>
246
+ <p>
247
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit. Animi blanditiis consectetur ea eligendi id in
248
+ inventore ipsa iure laudantium libero, minus molestias necessitatibus nesciunt non omnis, quasi recusandae
249
+ tempore voluptates!
250
+ </p>
251
+ <p>
252
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit. Animi blanditiis consectetur ea eligendi id in
253
+ inventore ipsa iure laudantium libero, minus molestias necessitatibus nesciunt non omnis, quasi recusandae
254
+ tempore voluptates!
255
+ </p>
256
+ <p>
257
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit. Animi blanditiis consectetur ea eligendi id in
258
+ inventore ipsa iure laudantium libero, minus molestias necessitatibus nesciunt non omnis, quasi recusandae
259
+ tempore voluptates!
260
+ </p>
261
+ <p>
262
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit. Animi blanditiis consectetur ea eligendi id in
263
+ inventore ipsa iure laudantium libero, minus molestias necessitatibus nesciunt non omnis, quasi recusandae
264
+ tempore voluptates!
265
+ </p>
266
+ <p>
267
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit. Animi blanditiis consectetur ea eligendi id in
268
+ inventore ipsa iure laudantium libero, minus molestias necessitatibus nesciunt non omnis, quasi recusandae
269
+ tempore voluptates!
270
+ </p>
271
+ </div>
272
+ <script type="module">
273
+ import { driver } from "./src/driver.ts";
274
+
275
+ document.getElementById("is-active-btn").addEventListener("click", () => {
276
+ alert(driver().isActive());
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
277
  });
278
+
279
+ document.getElementById("activate-check-btn").addEventListener("click", () => {
280
+ const driverObj = driver({
281
+ showButtons: false,
282
+ });
283
+
284
+ driverObj.highlight({
285
+ element: "#activate-check-btn",
286
+ popover: {
287
+ title: "Check if driver is active",
288
+ description: "This will alert the status after 2 seconds",
289
+ side: "bottom",
290
+ align: "start",
291
+ },
292
+ });
293
+
294
+ setTimeout(() => {
295
+ alert(`Status: ${driverObj.isActive()}. Destroying driver...`);
296
+ driverObj.destroy();
297
+ setTimeout(() => {
298
+ alert(`Status: ${driverObj.isActive()}`);
299
+ }, 0);
300
+ }, 2000);
301
+ });
302
+
303
+ document.getElementById("highlight-btn").addEventListener("click", () => {
304
+ driver({
305
+ animate: true,
306
+ popoverOffset: 10,
307
+ stagePadding: 10,
308
+ onHighlightStarted: (element, step) => {
309
+ console.log("Started highlighting element", element, step);
310
+ },
311
+ onHighlighted: (element, step) => {
312
+ console.log("Highlighted element", element, step);
313
+ },
314
+ }).highlight({
315
+ element: "h2",
316
+ popover: {
317
+ title: "MIT License",
318
+ description: "A lightweight, no-dependency JavaScript engine to drive user's focus.",
319
+ side: "bottom",
320
+ align: "start",
321
+ },
322
+ });
323
+ });
324
+
325
+ document.getElementById("simple-highlight-btn").addEventListener("click", () => {
326
+ driver({ animate: false }).highlight({
327
+ element: "#large-paragraph-text",
328
+ popover: {
329
+ title: "driver.js",
330
+ description:
331
+ "Highlight anything, anywhere on the page. Yes, literally anything including SVG portions, scrollable items etc.",
332
+ align: "start",
333
+ side: "top",
334
+ },
335
+ });
336
+ });
337
+
338
+ document.getElementById("dark-highlight-btn").addEventListener("click", () => {
339
+ driver({
340
+ animate: true,
341
+ opacity: 0.9,
342
+ }).highlight({ element: "ul" });
343
+ });
344
+
345
+ document.getElementById("dim-highlight-btn").addEventListener("click", () => {
346
+ driver({
347
+ animate: true,
348
+ opacity: 0.2,
349
+ }).highlight({ element: ".buttons" });
350
+ });
351
+
352
+ document.getElementById("transition-highlight-btn").addEventListener("click", () => {
353
+ const driverObj = driver({ animate: true });
354
+
355
+ driverObj.highlight({
356
+ popover: {
357
+ title: "driver.js",
358
+ description: "Highlight anything, anywhere on the page",
359
+ },
360
+ });
361
+
362
+ window.setTimeout(() => {
363
+ driverObj.highlight({
364
+ element: ".buttons button:first-child",
365
+ popover: {
366
+ title: "driver.js",
367
+ description: "Highlight anything, anywhere on the page",
368
+ },
369
+ });
370
+ }, 2000);
371
+
372
+ window.setTimeout(() => {
373
+ driverObj.highlight({
374
+ popover: {
375
+ title: "driver.js",
376
+ description: "Highlight anything, anywhere on the page",
377
+ },
378
+ });
379
+ }, 4000);
380
+
381
+ window.setTimeout(() => {
382
+ driverObj.highlight({
383
+ element: "h2",
384
+ popover: {
385
+ description: "driver.js",
386
+ },
387
+ });
388
+ }, 6000);
389
  });
390
+
391
+ document.getElementById("scrollable-area-btn").addEventListener("click", () => {
392
+ const driverObj = driver({ animate: true });
393
+ driverObj.highlight({ element: "#scrollable-area" });
394
+ });
395
+
396
+ document.getElementById("without-element-btn").addEventListener("click", () => {
397
+ const driverObj = driver({
398
+ animate: true,
399
+ });
400
+ driverObj.highlight({
401
+ popover: {
402
+ showButtons: false,
403
+ description:
404
+ "<div class='gif-popover'><img style='max-width: 100%' src='https://i.imgur.com/EAQhHu5.gif' /><p>Go and build something cool!</p></div>",
405
+ },
406
+ });
407
+ });
408
+
409
+ document.getElementById("inner-scroll-area-btn").addEventListener("click", () => {
410
+ const driverObj = driver({ animate: true });
411
+ driverObj.highlight({ element: "#third-scroll-paragraph" });
412
+ });
413
+
414
+ document.getElementById("disallow-close").addEventListener("click", () => {
415
+ const driverObj = driver({
416
+ animate: true,
417
+ allowClose: false,
418
+ });
419
+
420
+ driverObj.highlight({
421
+ element: ".buttons",
422
+ });
423
+ });
424
+
425
+ document.getElementById("destroy-btn").addEventListener("click", () => {
426
+ driver().destroy();
427
  });
428
+ </script>
429
+ </body>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
430
  </html>
src/config.ts CHANGED
@@ -1,3 +1,5 @@
 
 
1
  export type Config = {
2
  animate?: boolean;
3
  smoothScroll?: boolean;
@@ -7,6 +9,9 @@ export type Config = {
7
  stageRadius?: number;
8
  popoverOffset?: number;
9
  showButtons?: boolean;
 
 
 
10
  };
11
 
12
  let currentConfig: Config = {};
 
1
+ import { DriveStep } from "./driver";
2
+
3
  export type Config = {
4
  animate?: boolean;
5
  smoothScroll?: boolean;
 
9
  stageRadius?: number;
10
  popoverOffset?: number;
11
  showButtons?: boolean;
12
+
13
+ onHighlightStarted?: (element: Element, step: DriveStep) => void;
14
+ onHighlighted?: (element: Element, step: DriveStep) => void;
15
  };
16
 
17
  let currentConfig: Config = {};
src/highlight.ts CHANGED
@@ -39,20 +39,7 @@ export function highlight(step: DriveStep) {
39
  elemObj = mountDummyElement();
40
  }
41
 
42
- // Keep track of the previous step so that we can
43
- // animate the transition between the two steps.
44
- setState("previousStep", getState("activeStep"));
45
- setState("activeStep", step);
46
-
47
- const transferHighlightFrom = getState("activeElement") || elemObj;
48
- const transferHighlightTo = elemObj;
49
-
50
- transferHighlight(transferHighlightFrom, transferHighlightTo, step);
51
-
52
- // Keep track of the previous element so that we can
53
- // animate the transition between the two elements.
54
- setState("previousElement", transferHighlightFrom);
55
- setState("activeElement", transferHighlightTo);
56
  }
57
 
58
  export function refreshActiveHighlight() {
@@ -68,18 +55,19 @@ export function refreshActiveHighlight() {
68
  repositionPopover(activeHighlight, activeStep);
69
  }
70
 
71
- function transferHighlight(from: Element, to: Element, toStep: DriveStep) {
72
  const duration = 400;
73
  const start = Date.now();
74
 
75
- const previousStep = getState("previousStep");
 
76
 
77
  // If it's the first time we're highlighting an element, we show
78
  // the popover immediately. Otherwise, we wait for the animation
79
  // to finish before showing the popover.
80
- const isFirstHighlight = !from || from === to;
81
- const hasNoPreviousPopover = previousStep && !previousStep.popover;
82
- const isNextOrPrevDummyElement = to.id === "driver-dummy-element" || from.id === "driver-dummy-element";
83
 
84
  const hasDelayedPopover = !isFirstHighlight && (hasNoPreviousPopover || isNextOrPrevDummyElement);
85
  let isPopoverRendered = false;
@@ -101,14 +89,14 @@ function transferHighlight(from: Element, to: Element, toStep: DriveStep) {
101
  const isHalfwayThrough = timeRemaining <= duration / 2;
102
 
103
  if (toStep.popover && isHalfwayThrough && !isPopoverRendered && hasDelayedPopover) {
104
- renderPopover(to, toStep);
105
  isPopoverRendered = true;
106
  }
107
 
108
  if (getConfig("animate") && elapsed < duration) {
109
- transitionStage(elapsed, duration, from, to);
110
  } else {
111
- trackActiveElement(to);
112
 
113
  setState("transitionCallback", undefined);
114
  }
@@ -119,13 +107,23 @@ function transferHighlight(from: Element, to: Element, toStep: DriveStep) {
119
  setState("transitionCallback", animate);
120
  window.requestAnimationFrame(animate);
121
 
122
- bringInView(to);
123
  if (!hasDelayedPopover && toStep.popover) {
124
- renderPopover(to, toStep);
125
  }
126
 
127
- from.classList.remove("driver-active-element");
128
- to.classList.add("driver-active-element");
 
 
 
 
 
 
 
 
 
 
129
  }
130
 
131
  export function destroyHighlight() {
 
39
  elemObj = mountDummyElement();
40
  }
41
 
42
+ transferHighlight(elemObj, step);
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  }
44
 
45
  export function refreshActiveHighlight() {
 
55
  repositionPopover(activeHighlight, activeStep);
56
  }
57
 
58
+ function transferHighlight(toElement: Element, toStep: DriveStep) {
59
  const duration = 400;
60
  const start = Date.now();
61
 
62
+ const fromStep = getState("activeStep");
63
+ const fromElement = getState("activeElement") || toElement;
64
 
65
  // If it's the first time we're highlighting an element, we show
66
  // the popover immediately. Otherwise, we wait for the animation
67
  // to finish before showing the popover.
68
+ const isFirstHighlight = !fromElement || fromElement === toElement;
69
+ const hasNoPreviousPopover = fromStep && !fromStep.popover;
70
+ const isNextOrPrevDummyElement = toElement.id === "driver-dummy-element" || fromElement.id === "driver-dummy-element";
71
 
72
  const hasDelayedPopover = !isFirstHighlight && (hasNoPreviousPopover || isNextOrPrevDummyElement);
73
  let isPopoverRendered = false;
 
89
  const isHalfwayThrough = timeRemaining <= duration / 2;
90
 
91
  if (toStep.popover && isHalfwayThrough && !isPopoverRendered && hasDelayedPopover) {
92
+ renderPopover(toElement, toStep);
93
  isPopoverRendered = true;
94
  }
95
 
96
  if (getConfig("animate") && elapsed < duration) {
97
+ transitionStage(elapsed, duration, fromElement, toElement);
98
  } else {
99
+ trackActiveElement(toElement);
100
 
101
  setState("transitionCallback", undefined);
102
  }
 
107
  setState("transitionCallback", animate);
108
  window.requestAnimationFrame(animate);
109
 
110
+ bringInView(toElement);
111
  if (!hasDelayedPopover && toStep.popover) {
112
+ renderPopover(toElement, toStep);
113
  }
114
 
115
+ fromElement.classList.remove("driver-active-element");
116
+ toElement.classList.add("driver-active-element");
117
+
118
+ // Keep track of the previous step so that we can
119
+ // animate the transition between the two steps.
120
+ setState("previousStep", fromStep);
121
+ setState("activeStep", toStep);
122
+
123
+ // Keep track of the previous element so that we can
124
+ // animate the transition between the two elements.
125
+ setState("previousElement", fromElement);
126
+ setState("activeElement", toElement);
127
  }
128
 
129
  export function destroyHighlight() {