kamrify commited on
Commit
edd7dca
·
1 Parent(s): fd57e7f

Refactor stage padding and radius

Browse files
Files changed (7) hide show
  1. index.html +124 -152
  2. package.json +6 -6
  3. pnpm-lock.yaml +0 -0
  4. src/config.ts +4 -0
  5. src/highlight.ts +25 -3
  6. src/popover.ts +6 -5
  7. src/stage.ts +8 -11
index.html CHANGED
@@ -12,8 +12,8 @@
12
  }
13
 
14
  body {
15
- font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
16
- Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
17
  font-size: 14px;
18
  -webkit-font-smoothing: antialiased;
19
  -moz-osx-font-smoothing: grayscale;
@@ -121,7 +121,7 @@
121
  <button id="dim-highlight-btn">Super Dim Highlight</button>
122
  <button id="scrollable-area-btn">Scrollable Area</button>
123
  <button id="inner-scroll-area-btn">Inner Scroll Area</button>
124
- <button id="tour-btn">Start Tour</button>
125
  <button id="destroy-btn">Destroy</button>
126
  </div>
127
 
@@ -134,19 +134,15 @@
134
 
135
  <h2>Yet another Tour Library?</h2>
136
  <p>
137
- No, it is not. Tours are just one of the many use-cases. Driver.js can
138
- be used wherever you need some sort of overlay for the page; some common
139
- usecases could be: e.g. dimming the background when user is interacting
140
- with some component, using it as a focus shifter to bring user's
141
- attention to some component on page, or using it to simulate those "Turn
142
- off the Lights" widgets that you might have seen on video players
143
- online, etc.
144
  </p>
145
  <p class="second-para">
146
- Driver.js is written in Vanilla JS, has zero dependencies and is highly
147
- customizable. It has several options allowing you to manipulate how it
148
- behaves and also provides you the hooks to manipulate the elements as
149
- they are highlighted, about to be highlighted, or deselected.
150
  </p>
151
 
152
  <h2 id="installation-head">Installation</h2>
@@ -157,120 +153,100 @@ yarn add driver.js
157
  npm install driver.js</pre
158
  >
159
 
160
- <p>
161
- Or include it using CDN — put the version as [email protected] in the name
162
- </p>
163
 
164
  <pre>https://unpkg.com/driver.js/dist/driver.min.js</pre>
165
 
166
  <h2>Usage and Demo</h2>
167
 
168
  <p id="large-paragraph-text">
169
- Lorem ipsum dolor sit amet, consectetur adipisicing elit. Animi
170
- blanditiis consectetur ea eligendi id in inventore ipsa iure laudantium
171
- libero, minus molestias necessitatibus nesciunt non omnis, quasi
172
- recusandae tempore voluptates! Lorem ipsum dolor sit amet, consectetur
173
- adipisicing elit. Animi blanditiis consectetur ea eligendi id in
174
- inventore ipsa iure laudantium libero, minus molestias necessitatibus
175
- nesciunt non omnis, quasi recusandae tempore voluptates!
176
  </p>
177
  <p>
178
- Lorem ipsum dolor sit amet, consectetur adipisicing elit. Animi
179
- blanditiis consectetur ea eligendi id in inventore ipsa iure laudantium
180
- libero, minus molestias necessitatibus nesciunt non omnis, quasi
181
- recusandae tempore voluptates!
182
  </p>
183
  <p>
184
- Lorem ipsum dolor sit amet, consectetur adipisicing elit. Animi
185
- blanditiis consectetur ea eligendi id in inventore ipsa iure laudantium
186
- libero, minus molestias necessitatibus nesciunt non omnis, quasi
187
- recusandae tempore voluptates!
188
  </p>
189
  <div id="scrollable-area">
190
  <p>
191
- First -> Lorem ipsum dolor sit amet, consectetur adipisicing elit.
192
- Consequuntur dicta ipsum labore quod tempora ullam? Alias consequatur
193
- doloremque laborum maxime necessitatibus nostrum odio, officiis
194
- quibusdam veniam! Doloribus eos id quaerat.
195
  </p>
196
  <p>
197
- Second -> Lorem ipsum dolor sit amet, consectetur adipisicing elit.
198
- Consequuntur dicta ipsum labore quod tempora ullam? Alias consequatur
199
- doloremque laborum maxime necessitatibus nostrum odio, officiis
200
- quibusdam veniam! Doloribus eos id quaerat.
201
  </p>
202
  <p id="third-scroll-paragraph">
203
- Third -> Lorem ipsum dolor sit amet, consectetur adipisicing elit.
204
- Consequuntur dicta ipsum labore quod tempora ullam? Alias consequatur
205
- doloremque laborum maxime necessitatibus nostrum odio, officiis
206
- quibusdam veniam! Doloribus eos id quaerat.
207
  </p>
208
  <p>
209
- Fourth -> Lorem ipsum dolor sit amet, consectetur adipisicing elit.
210
- Consequuntur dicta ipsum labore quod tempora ullam? Alias consequatur
211
- doloremque laborum maxime necessitatibus nostrum odio, officiis
212
- quibusdam veniam! Doloribus eos id quaerat.
213
  </p>
214
  <p>
215
- Fifth -> Lorem ipsum dolor sit amet, consectetur adipisicing elit.
216
- Consequuntur dicta ipsum labore quod tempora ullam? Alias consequatur
217
- doloremque laborum maxime necessitatibus nostrum odio, officiis
218
- quibusdam veniam! Doloribus eos id quaerat.
219
  </p>
220
  <p>
221
- Sixth -> Lorem ipsum dolor sit amet, consectetur adipisicing elit.
222
- Consequuntur dicta ipsum labore quod tempora ullam? Alias consequatur
223
- doloremque laborum maxime necessitatibus nostrum odio, officiis
224
- quibusdam veniam! Doloribus eos id quaerat.
225
  </p>
226
  <p>
227
- Seventh -> Lorem ipsum dolor sit amet, consectetur adipisicing elit.
228
- Consequuntur dicta ipsum labore quod tempora ullam? Alias consequatur
229
- doloremque laborum maxime necessitatibus nostrum odio, officiis
230
- quibusdam veniam! Doloribus eos id quaerat.
231
  </p>
232
  <p>
233
- Eighth -> Lorem ipsum dolor sit amet, consectetur adipisicing elit.
234
- Consequuntur dicta ipsum labore quod tempora ullam? Alias consequatur
235
- doloremque laborum maxime necessitatibus nostrum odio, officiis
236
- quibusdam veniam! Doloribus eos id quaerat.
237
  </p>
238
  <p>
239
- Ninth -> Lorem ipsum dolor sit amet, consectetur adipisicing elit.
240
- Consequuntur dicta ipsum labore quod tempora ullam? Alias consequatur
241
- doloremque laborum maxime necessitatibus nostrum odio, officiis
242
- quibusdam veniam! Doloribus eos id quaerat.
243
  </p>
244
  </div>
245
  <p>
246
- Lorem ipsum dolor sit amet, consectetur adipisicing elit. Animi
247
- blanditiis consectetur ea eligendi id in inventore ipsa iure laudantium
248
- libero, minus molestias necessitatibus nesciunt non omnis, quasi
249
- recusandae tempore voluptates!
250
  </p>
251
  <p>
252
- Lorem ipsum dolor sit amet, consectetur adipisicing elit. Animi
253
- blanditiis consectetur ea eligendi id in inventore ipsa iure laudantium
254
- libero, minus molestias necessitatibus nesciunt non omnis, quasi
255
- recusandae tempore voluptates!
256
  </p>
257
  <p>
258
- Lorem ipsum dolor sit amet, consectetur adipisicing elit. Animi
259
- blanditiis consectetur ea eligendi id in inventore ipsa iure laudantium
260
- libero, minus molestias necessitatibus nesciunt non omnis, quasi
261
- recusandae tempore voluptates!
262
  </p>
263
  <p>
264
- Lorem ipsum dolor sit amet, consectetur adipisicing elit. Animi
265
- blanditiis consectetur ea eligendi id in inventore ipsa iure laudantium
266
- libero, minus molestias necessitatibus nesciunt non omnis, quasi
267
- recusandae tempore voluptates!
268
  </p>
269
  <p>
270
- Lorem ipsum dolor sit amet, consectetur adipisicing elit. Animi
271
- blanditiis consectetur ea eligendi id in inventore ipsa iure laudantium
272
- libero, minus molestias necessitatibus nesciunt non omnis, quasi
273
- recusandae tempore voluptates!
274
  </p>
275
  </div>
276
  <script type="module">
@@ -280,84 +256,80 @@ npm install driver.js</pre
280
  driver({ animate: true }).highlight({ element: "h1" });
281
  });
282
 
283
- document
284
- .getElementById("simple-highlight-btn")
285
- .addEventListener("click", () => {
286
- driver({ animate: false }).highlight({
287
- element: "#large-paragraph-text",
288
- popover: {
289
- title: "driver.js",
290
- description: "Highlight anything, anywhere on the page",
291
- align: "end",
292
- side: "top",
293
- },
294
- });
295
  });
 
296
 
297
- document
298
- .getElementById("dark-highlight-btn")
299
- .addEventListener("click", () => {
300
- driver({
301
- animate: true,
302
- opacity: 0.9,
303
- }).highlight({ element: "ul" });
304
- });
305
 
306
- document
307
- .getElementById("dim-highlight-btn")
308
- .addEventListener("click", () => {
309
- driver({
310
- animate: true,
311
- opacity: 0.2,
312
- }).highlight({ element: ".buttons" });
313
- });
314
 
315
- document
316
- .getElementById("transition-highlight-btn")
317
- .addEventListener("click", () => {
318
- const driverObj = driver({ animate: true });
319
 
320
- driverObj.highlight({ element: "h1" });
321
 
322
- window.setTimeout(() => {
323
- driverObj.highlight({ element: ".buttons button:first-child" });
324
- }, 2000);
325
 
326
- window.setTimeout(() => {
327
- driverObj.highlight({ element: ".buttons button:nth-child(5)" });
328
- }, 4000);
329
 
330
- window.setTimeout(() => {
331
- driverObj.highlight({ element: "h2" });
332
- }, 6000);
333
- });
334
 
335
- document
336
- .getElementById("scrollable-area-btn")
337
- .addEventListener("click", () => {
338
- const driverObj = driver({ animate: true });
339
- driverObj.highlight({ element: "#scrollable-area" });
 
 
 
 
 
 
 
340
  });
 
341
 
342
- document
343
- .getElementById("inner-scroll-area-btn")
344
- .addEventListener("click", () => {
345
- const driverObj = driver({ animate: true });
346
- driverObj.highlight({ element: "#third-scroll-paragraph" });
 
 
 
 
347
  });
348
 
349
- document
350
- .getElementById("disallow-close")
351
- .addEventListener("click", () => {
352
- const driverObj = driver({
353
- animate: true,
354
- allowClose: false,
355
- });
356
-
357
- driverObj.highlight({
358
- element: ".buttons",
359
- });
360
  });
 
361
 
362
  document.getElementById("destroy-btn").addEventListener("click", () => {
363
  driver().destroy();
 
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;
 
121
  <button id="dim-highlight-btn">Super Dim Highlight</button>
122
  <button id="scrollable-area-btn">Scrollable Area</button>
123
  <button id="inner-scroll-area-btn">Inner Scroll Area</button>
124
+ <button id="without-element-btn">No Element</button>
125
  <button id="destroy-btn">Destroy</button>
126
  </div>
127
 
 
134
 
135
  <h2>Yet another Tour Library?</h2>
136
  <p>
137
+ No, it is not. Tours are just one of the many use-cases. Driver.js can be used wherever you need some sort of
138
+ overlay for the page; some common usecases could be: e.g. dimming the background when user is interacting with
139
+ some component, using it as a focus shifter to bring user's attention to some component on page, or using it to
140
+ simulate those "Turn off the Lights" widgets that you might have seen on video players online, etc.
 
 
 
141
  </p>
142
  <p class="second-para">
143
+ Driver.js is written in Vanilla JS, has zero dependencies and is highly customizable. It has several options
144
+ allowing you to manipulate how it behaves and also provides you the hooks to manipulate the elements as they are
145
+ highlighted, about to be highlighted, or deselected.
 
146
  </p>
147
 
148
  <h2 id="installation-head">Installation</h2>
 
153
  npm install driver.js</pre
154
  >
155
 
156
+ <p>Or include it using CDN — put the version as [email protected] in the name</p>
 
 
157
 
158
  <pre>https://unpkg.com/driver.js/dist/driver.min.js</pre>
159
 
160
  <h2>Usage and Demo</h2>
161
 
162
  <p id="large-paragraph-text">
163
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit. Animi blanditiis consectetur ea eligendi id in
164
+ inventore ipsa iure laudantium libero, minus molestias necessitatibus nesciunt non omnis, quasi recusandae
165
+ tempore voluptates! Lorem ipsum dolor sit amet, consectetur adipisicing elit. Animi blanditiis consectetur ea
166
+ eligendi id in inventore ipsa iure laudantium libero, minus molestias necessitatibus nesciunt non omnis, quasi
167
+ recusandae tempore voluptates!
 
 
168
  </p>
169
  <p>
170
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit. Animi blanditiis consectetur ea eligendi id in
171
+ inventore ipsa iure laudantium libero, minus molestias necessitatibus nesciunt non omnis, quasi recusandae
172
+ tempore voluptates!
 
173
  </p>
174
  <p>
175
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit. Animi blanditiis consectetur ea eligendi id in
176
+ inventore ipsa iure laudantium libero, minus molestias necessitatibus nesciunt non omnis, quasi recusandae
177
+ tempore voluptates!
 
178
  </p>
179
  <div id="scrollable-area">
180
  <p>
181
+ First -> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequuntur dicta ipsum labore quod
182
+ tempora ullam? Alias consequatur doloremque laborum maxime necessitatibus nostrum odio, officiis quibusdam
183
+ veniam! Doloribus eos id quaerat.
 
184
  </p>
185
  <p>
186
+ Second -> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequuntur dicta ipsum labore quod
187
+ tempora ullam? Alias consequatur doloremque laborum maxime necessitatibus nostrum odio, officiis quibusdam
188
+ veniam! Doloribus eos id quaerat.
 
189
  </p>
190
  <p id="third-scroll-paragraph">
191
+ Third -> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequuntur dicta ipsum labore quod
192
+ tempora ullam? Alias consequatur doloremque laborum maxime necessitatibus nostrum odio, officiis quibusdam
193
+ veniam! Doloribus eos id quaerat.
 
194
  </p>
195
  <p>
196
+ Fourth -> Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequuntur dicta ipsum labore quod
197
+ tempora ullam? Alias consequatur doloremque laborum maxime necessitatibus nostrum odio, officiis quibusdam
198
+ veniam! Doloribus eos id quaerat.
 
199
  </p>
200
  <p>
201
+ Fifth -> 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
+ Sixth -> 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>
211
+ Seventh -> 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
+ Eighth -> 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
+ Ninth -> 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
  </div>
226
  <p>
227
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit. Animi blanditiis consectetur ea eligendi id in
228
+ inventore ipsa iure laudantium libero, minus molestias necessitatibus nesciunt non omnis, quasi recusandae
229
+ tempore voluptates!
 
230
  </p>
231
  <p>
232
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit. Animi blanditiis consectetur ea eligendi id in
233
+ inventore ipsa iure laudantium libero, minus molestias necessitatibus nesciunt non omnis, quasi recusandae
234
+ tempore voluptates!
 
235
  </p>
236
  <p>
237
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit. Animi blanditiis consectetur ea eligendi id in
238
+ inventore ipsa iure laudantium libero, minus molestias necessitatibus nesciunt non omnis, quasi recusandae
239
+ tempore voluptates!
 
240
  </p>
241
  <p>
242
+ Lorem ipsum dolor sit amet, consectetur adipisicing elit. Animi blanditiis consectetur ea eligendi id in
243
+ inventore ipsa iure laudantium libero, minus molestias necessitatibus nesciunt non omnis, quasi recusandae
244
+ tempore voluptates!
 
245
  </p>
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
  </div>
252
  <script type="module">
 
256
  driver({ animate: true }).highlight({ element: "h1" });
257
  });
258
 
259
+ document.getElementById("simple-highlight-btn").addEventListener("click", () => {
260
+ driver({ animate: false }).highlight({
261
+ element: "#large-paragraph-text",
262
+ popover: {
263
+ title: "driver.js",
264
+ description: "Highlight anything, anywhere on the page",
265
+ align: "end",
266
+ side: "top",
267
+ },
 
 
 
268
  });
269
+ });
270
 
271
+ document.getElementById("dark-highlight-btn").addEventListener("click", () => {
272
+ driver({
273
+ animate: true,
274
+ opacity: 0.9,
275
+ }).highlight({ element: "ul" });
276
+ });
 
 
277
 
278
+ document.getElementById("dim-highlight-btn").addEventListener("click", () => {
279
+ driver({
280
+ animate: true,
281
+ opacity: 0.2,
282
+ }).highlight({ element: ".buttons" });
283
+ });
 
 
284
 
285
+ document.getElementById("transition-highlight-btn").addEventListener("click", () => {
286
+ const driverObj = driver({ animate: true });
 
 
287
 
288
+ driverObj.highlight({ element: "h1" });
289
 
290
+ window.setTimeout(() => {
291
+ driverObj.highlight({ element: ".buttons button:first-child" });
292
+ }, 2000);
293
 
294
+ window.setTimeout(() => {
295
+ driverObj.highlight({ element: ".buttons button:nth-child(5)" });
296
+ }, 4000);
297
 
298
+ window.setTimeout(() => {
299
+ driverObj.highlight({ element: "h2" });
300
+ }, 6000);
301
+ });
302
 
303
+ document.getElementById("scrollable-area-btn").addEventListener("click", () => {
304
+ const driverObj = driver({ animate: true });
305
+ driverObj.highlight({ element: "#scrollable-area" });
306
+ });
307
+
308
+ document.getElementById("without-element-btn").addEventListener("click", () => {
309
+ const driverObj = driver({ animate: true });
310
+ driverObj.highlight({
311
+ popover: {
312
+ title: "driver.js",
313
+ description: "Highlight anything, anywhere on the page",
314
+ }
315
  });
316
+ });
317
 
318
+ document.getElementById("inner-scroll-area-btn").addEventListener("click", () => {
319
+ const driverObj = driver({ animate: true });
320
+ driverObj.highlight({ element: "#third-scroll-paragraph" });
321
+ });
322
+
323
+ document.getElementById("disallow-close").addEventListener("click", () => {
324
+ const driverObj = driver({
325
+ animate: true,
326
+ allowClose: false,
327
  });
328
 
329
+ driverObj.highlight({
330
+ element: ".buttons",
 
 
 
 
 
 
 
 
 
331
  });
332
+ });
333
 
334
  document.getElementById("destroy-btn").addEventListener("click", () => {
335
  driver().destroy();
package.json CHANGED
@@ -19,15 +19,15 @@
19
  },
20
  "devDependencies": {
21
  "@types/jsdom": "^21.1.1",
22
- "@types/node": "^20.1.0",
23
- "@vitest/coverage-c8": "^0.31.0",
24
  "dts-bundle-generator": "^8.0.1",
25
- "postcss": "^8.4.23",
26
  "postcss-scss": "^4.0.6",
27
  "prettier": "^2.8.8",
28
  "ts-node": "^10.9.1",
29
- "typescript": "^5.0.4",
30
- "vite": "^4.3.5",
31
- "vitest": "^0.31.0"
32
  }
33
  }
 
19
  },
20
  "devDependencies": {
21
  "@types/jsdom": "^21.1.1",
22
+ "@types/node": "^20.3.0",
23
+ "@vitest/coverage-c8": "^0.32.0",
24
  "dts-bundle-generator": "^8.0.1",
25
+ "postcss": "^8.4.24",
26
  "postcss-scss": "^4.0.6",
27
  "prettier": "^2.8.8",
28
  "ts-node": "^10.9.1",
29
+ "typescript": "^5.1.3",
30
+ "vite": "^4.3.9",
31
+ "vitest": "^0.32.0"
32
  }
33
  }
pnpm-lock.yaml CHANGED
The diff for this file is too large to render. See raw diff
 
src/config.ts CHANGED
@@ -3,6 +3,8 @@ export type Config = {
3
  smoothScroll?: boolean;
4
  allowClose?: boolean;
5
  opacity?: number;
 
 
6
  };
7
 
8
  let currentConfig: Config = {};
@@ -13,6 +15,8 @@ export function configure(config: Config = {}) {
13
  allowClose: true,
14
  opacity: 0.7,
15
  smoothScroll: false,
 
 
16
  ...config,
17
  };
18
  }
 
3
  smoothScroll?: boolean;
4
  allowClose?: boolean;
5
  opacity?: number;
6
+ stagePadding?: number;
7
+ stageRadius?: number;
8
  };
9
 
10
  let currentConfig: Config = {};
 
15
  allowClose: true,
16
  opacity: 0.7,
17
  smoothScroll: false,
18
+ stagePadding: 10,
19
+ stageRadius: 5,
20
  ...config,
21
  };
22
  }
src/highlight.ts CHANGED
@@ -8,13 +8,34 @@ let previousHighlight: Element | undefined;
8
  let activeHighlight: Element | undefined;
9
  let currentTransitionCallback: undefined | (() => void);
10
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  export function highlight(step: DriveStep) {
12
  const { element } = step;
13
- const elemObj =
14
- typeof element === "string" ? document.querySelector(element) : element;
15
 
16
  if (!elemObj) {
17
- return;
18
  }
19
 
20
  previousHighlight = activeHighlight;
@@ -86,6 +107,7 @@ export function destroyHighlight() {
86
  currentTransitionCallback = undefined;
87
  previousHighlight = undefined;
88
  activeHighlight = undefined;
 
89
 
90
  document.querySelectorAll(".driver-active-element").forEach(element => {
91
  element.classList.remove("driver-active-element");
 
8
  let activeHighlight: Element | undefined;
9
  let currentTransitionCallback: undefined | (() => void);
10
 
11
+ function mountDummyElement(): Element {
12
+ const existingDummy = document.getElementById("driver-dummy-element");
13
+ if (existingDummy) {
14
+ return existingDummy;
15
+ }
16
+
17
+ let element = document.createElement("div");
18
+
19
+ element.id = "driver-dummy-element";
20
+ element.style.width = "0";
21
+ element.style.height = "0";
22
+ element.style.pointerEvents = "none";
23
+ element.style.opacity = "0";
24
+ element.style.position = "fixed";
25
+ element.style.top = "50%";
26
+ element.style.left = "50%";
27
+
28
+ document.body.appendChild(element);
29
+
30
+ return element;
31
+ }
32
+
33
  export function highlight(step: DriveStep) {
34
  const { element } = step;
35
+ let elemObj = typeof element === "string" ? document.querySelector(element) : element;
 
36
 
37
  if (!elemObj) {
38
+ elemObj = mountDummyElement();
39
  }
40
 
41
  previousHighlight = activeHighlight;
 
107
  currentTransitionCallback = undefined;
108
  previousHighlight = undefined;
109
  activeHighlight = undefined;
110
+ document.getElementById("driver-dummy-element")?.remove();
111
 
112
  document.querySelectorAll(".driver-active-element").forEach(element => {
113
  element.classList.remove("driver-active-element");
src/popover.ts CHANGED
@@ -1,5 +1,5 @@
1
  import { bringInView } from "./utils";
2
- import { STAGE_PADDING } from "./stage";
3
 
4
  export type Side = "top" | "right" | "bottom" | "left";
5
  export type Alignment = "start" | "center" | "end";
@@ -62,7 +62,7 @@ type PopoverDimensions = {
62
  height: number;
63
  realWidth: number;
64
  realHeight: number;
65
- }
66
 
67
  function getPopoverDimensions(): PopoverDimensions | undefined {
68
  if (!popover?.wrapper) {
@@ -70,10 +70,11 @@ function getPopoverDimensions(): PopoverDimensions | undefined {
70
  }
71
 
72
  const boundingClientRect = popover.wrapper.getBoundingClientRect();
 
73
 
74
  return {
75
- width: boundingClientRect.width + STAGE_PADDING + POPOVER_OFFSET,
76
- height: boundingClientRect.height + STAGE_PADDING + POPOVER_OFFSET,
77
 
78
  realWidth: boundingClientRect.width,
79
  realHeight: boundingClientRect.height,
@@ -178,7 +179,7 @@ export function repositionPopover(element: Element) {
178
  // Configure the popover positioning
179
  const requiredAlignment: Alignment = "start";
180
  const requiredSide: Side = "left" as Side;
181
- const popoverPadding = STAGE_PADDING;
182
 
183
  const popoverDimensions = getPopoverDimensions()!;
184
  const popoverArrowDimensions = popover.arrow.getBoundingClientRect();
 
1
  import { bringInView } from "./utils";
2
+ import { getConfig } from "./config";
3
 
4
  export type Side = "top" | "right" | "bottom" | "left";
5
  export type Alignment = "start" | "center" | "end";
 
62
  height: number;
63
  realWidth: number;
64
  realHeight: number;
65
+ };
66
 
67
  function getPopoverDimensions(): PopoverDimensions | undefined {
68
  if (!popover?.wrapper) {
 
70
  }
71
 
72
  const boundingClientRect = popover.wrapper.getBoundingClientRect();
73
+ const stagePadding = getConfig("stagePadding") || 0;
74
 
75
  return {
76
+ width: boundingClientRect.width + stagePadding + POPOVER_OFFSET,
77
+ height: boundingClientRect.height + stagePadding + POPOVER_OFFSET,
78
 
79
  realWidth: boundingClientRect.width,
80
  realHeight: boundingClientRect.height,
 
179
  // Configure the popover positioning
180
  const requiredAlignment: Alignment = "start";
181
  const requiredSide: Side = "left" as Side;
182
+ const popoverPadding = getConfig('stagePadding') || 0;
183
 
184
  const popoverDimensions = getPopoverDimensions()!;
185
  const popoverArrowDimensions = popover.arrow.getBoundingClientRect();
src/stage.ts CHANGED
@@ -3,9 +3,6 @@ import { onDriverClick } from "./events";
3
  import { emit } from "./emitter";
4
  import { getConfig } from "./config";
5
 
6
- export const STAGE_PADDING = 10;
7
- export const STAGE_RADIUS = 5;
8
-
9
  export type StageDefinition = {
10
  x: number;
11
  y: number;
@@ -24,11 +21,8 @@ export function transitionStage(elapsed: number, duration: number, from: Element
24
  const toDefinition = to.getBoundingClientRect();
25
 
26
  const x = easeInOutQuad(elapsed, fromDefinition.x, toDefinition.x - fromDefinition.x, duration);
27
-
28
  const y = easeInOutQuad(elapsed, fromDefinition.y, toDefinition.y - fromDefinition.y, duration);
29
-
30
  const width = easeInOutQuad(elapsed, fromDefinition.width, toDefinition.width - fromDefinition.width, duration);
31
-
32
  const height = easeInOutQuad(elapsed, fromDefinition.height, toDefinition.height - fromDefinition.height, duration);
33
 
34
  activeStagePosition = {
@@ -146,17 +140,20 @@ function generateSvgCutoutPathString(stage: StageDefinition) {
146
  const windowX = window.innerWidth;
147
  const windowY = window.innerHeight;
148
 
149
- const stageWidth = stage.width + STAGE_PADDING * 2;
150
- const stageHeight = stage.height + STAGE_PADDING * 2;
 
 
 
151
 
152
  // prevent glitches when stage is too small for radius
153
- const limitedRadius = Math.min(STAGE_RADIUS, stageWidth / 2, stageHeight / 2);
154
 
155
  // no value below 0 allowed + round down
156
  const normalizedRadius = Math.floor(Math.max(limitedRadius, 0));
157
 
158
- const highlightBoxX = stage.x - STAGE_PADDING + normalizedRadius;
159
- const highlightBoxY = stage.y - STAGE_PADDING;
160
  const highlightBoxWidth = stageWidth - normalizedRadius * 2;
161
  const highlightBoxHeight = stageHeight - normalizedRadius * 2;
162
 
 
3
  import { emit } from "./emitter";
4
  import { getConfig } from "./config";
5
 
 
 
 
6
  export type StageDefinition = {
7
  x: number;
8
  y: number;
 
21
  const toDefinition = to.getBoundingClientRect();
22
 
23
  const x = easeInOutQuad(elapsed, fromDefinition.x, toDefinition.x - fromDefinition.x, duration);
 
24
  const y = easeInOutQuad(elapsed, fromDefinition.y, toDefinition.y - fromDefinition.y, duration);
 
25
  const width = easeInOutQuad(elapsed, fromDefinition.width, toDefinition.width - fromDefinition.width, duration);
 
26
  const height = easeInOutQuad(elapsed, fromDefinition.height, toDefinition.height - fromDefinition.height, duration);
27
 
28
  activeStagePosition = {
 
140
  const windowX = window.innerWidth;
141
  const windowY = window.innerHeight;
142
 
143
+ const stagePadding = getConfig('stagePadding') || 0;
144
+ const stageRadius = getConfig('stageRadius') || 0;
145
+
146
+ const stageWidth = stage.width + stagePadding * 2;
147
+ const stageHeight = stage.height + stagePadding * 2;
148
 
149
  // prevent glitches when stage is too small for radius
150
+ const limitedRadius = Math.min(stageRadius, stageWidth / 2, stageHeight / 2);
151
 
152
  // no value below 0 allowed + round down
153
  const normalizedRadius = Math.floor(Math.max(limitedRadius, 0));
154
 
155
+ const highlightBoxX = stage.x - stagePadding + normalizedRadius;
156
+ const highlightBoxY = stage.y - stagePadding;
157
  const highlightBoxWidth = stageWidth - normalizedRadius * 2;
158
  const highlightBoxHeight = stageHeight - normalizedRadius * 2;
159