rails_onboarding 0.8.8 → 0.8.10

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 408fd1e294065de10f66f097028bca6ea0ef929c2da585fb5fe20034a14e0202
4
- data.tar.gz: 2e015226988b1bda4bf5594d43c00341f4a9fb2c21c020b0607446be87dfe671
3
+ metadata.gz: c05ac141e36d0ce4babc403026980c036569d9ae47a6dfe7fd945b9023bdce8b
4
+ data.tar.gz: a4a1482feee59b542485b5368e9cadbbe99dc16d3bcb9da6da399b7ca22c02c6
5
5
  SHA512:
6
- metadata.gz: 6f924adbe61c18fc3b8070653655b04d74bd01a97562ed5eaa274d43276c07a331a11ef233ceab5484f545b20779485cbe55417921516bc9c2cd0557da694884
7
- data.tar.gz: 678c83c71d204f027f92d65555af8cff1b3aecd53992cda79e5d234f5deffaf3a465e4b786295bc5ca2319b97a74946750e3a98083a45b8f1ad5ea4a37f3d4c1
6
+ metadata.gz: abcfa7de7380a5a5591fbcad733a093c0eb11dfacf89e82fb20d25d7570c67e2f4d26040a7c871d1990d9de5283bfe45b42584241676a55173078f29b5ff8393
7
+ data.tar.gz: 95ed36308b6f64e56bb4b2cac753efec1f6359dde989b8ccd516f57f2a0e9106c4621e2e4ca0e59ec72b9eb0f6dfdc092da1dcd3a5e3b803dbc45a6f40821809
@@ -28,6 +28,12 @@ export default class extends Controller {
28
28
  scrollBehavior: { type: String, default: "smooth" }, // smooth, auto, none
29
29
  scrollOffset: { type: Number, default: 80 }, // px offset from top when scrolling
30
30
  persistProgress: { type: Boolean, default: true },
31
+ // Whether the highlighted element stays clickable. It is lifted above the
32
+ // overlay so that a tour can say "click here to continue", and that is the
33
+ // default. An informational tour wants the opposite: a link inside the
34
+ // spotlight is a trap, because following it navigates away and the tour is
35
+ // either lost or restarted from step one. Overridable per step.
36
+ allowInteraction: { type: Boolean, default: true },
31
37
  tourId: String
32
38
  }
33
39
 
@@ -80,6 +86,7 @@ export default class extends Controller {
80
86
  beforeHide: step.beforeHide,
81
87
  onComplete: step.onComplete,
82
88
  width: step.width || 400, // Popup width in px
89
+ allowInteraction: step.allowInteraction ?? this.allowInteractionValue,
83
90
  ...step
84
91
  }))
85
92
  }
@@ -190,6 +197,7 @@ export default class extends Controller {
190
197
  const targetElement = step.selector ? document.querySelector(step.selector) : null
191
198
 
192
199
  this.currentTargetElement = targetElement
200
+ this.applyScrim(step, targetElement)
193
201
 
194
202
  if (targetElement) {
195
203
  this.scrollToElement(targetElement, step)
@@ -258,13 +266,25 @@ export default class extends Controller {
258
266
  }
259
267
  }
260
268
 
269
+ /**
270
+ * Elements the controller injects into document.body. Turbo caches the whole body
271
+ * when you navigate away, so without this a Back lands you on a snapshot with a
272
+ * frozen overlay and popup baked in - which then sit underneath the live tour the
273
+ * launcher starts, as duplicated and inert DOM. The attribute is ignored by hosts
274
+ * that do not use Turbo.
275
+ */
276
+ excludeFromSnapshot(element) {
277
+ element.setAttribute('data-turbo-cache', 'false')
278
+ return element
279
+ }
280
+
261
281
  /**
262
282
  * Create modal overlay
263
283
  */
264
284
  createOverlay() {
265
285
  if (this.overlay) return
266
286
 
267
- this.overlay = document.createElement('div')
287
+ this.overlay = this.excludeFromSnapshot(document.createElement('div'))
268
288
  this.overlay.className = 'tour-overlay'
269
289
  this.overlay.style.cssText = `
270
290
  position: fixed;
@@ -272,7 +292,7 @@ export default class extends Controller {
272
292
  left: 0;
273
293
  width: 100%;
274
294
  height: 100%;
275
- background: rgba(0, 0, 0, ${this.overlayOpacityValue});
295
+ background: transparent;
276
296
  z-index: 9998;
277
297
  opacity: 0;
278
298
  transition: opacity 0.3s ease;
@@ -300,6 +320,7 @@ export default class extends Controller {
300
320
  const overlay = this.overlay
301
321
  if (!overlay) return
302
322
 
323
+ document.documentElement.style.removeProperty('--onboarding-tour-scrim')
303
324
  this.overlay = null
304
325
  overlay.style.opacity = '0'
305
326
 
@@ -320,7 +341,7 @@ export default class extends Controller {
320
341
 
321
342
  if (style === 'none') return
322
343
 
323
- this.spotlight = document.createElement('div')
344
+ this.spotlight = this.excludeFromSnapshot(document.createElement('div'))
324
345
  this.spotlight.className = `tour-spotlight tour-spotlight-${style}`
325
346
 
326
347
  const baseStyles = `
@@ -339,7 +360,6 @@ export default class extends Controller {
339
360
  left: ${rect.left - padding}px;
340
361
  width: ${rect.width + (padding * 2)}px;
341
362
  height: ${rect.height + (padding * 2)}px;
342
- box-shadow: 0 0 0 9999px rgba(0, 0, 0, ${this.overlayOpacityValue});
343
363
  border-radius: 8px;
344
364
  `
345
365
  break
@@ -380,8 +400,40 @@ export default class extends Controller {
380
400
  this.highlightedElement = element
381
401
  this.previousElementPosition = element.style.position
382
402
  this.previousElementZIndex = element.style.zIndex
403
+ this.previousElementPointerEvents = element.style.pointerEvents
383
404
  element.style.position = 'relative'
384
405
  element.style.zIndex = '10000'
406
+
407
+ // With interaction off, clicks fall through the highlighted element to the
408
+ // overlay beneath, which swallows them like the rest of the page. The element
409
+ // is still lifted above the overlay so it stays fully lit.
410
+ if (step.allowInteraction === false) {
411
+ element.style.pointerEvents = 'none'
412
+ }
413
+ }
414
+
415
+ /**
416
+ * Decide which layer paints the scrim for this step, and at what strength.
417
+ *
418
+ * A 'spotlight' highlight is already a full-viewport scrim - its box-shadow has a
419
+ * 9999px spread and covers everything but the cutout - so painting the overlay on
420
+ * top of it darkens every pixel twice. At the default 0.7 that composites to ~0.92,
421
+ * which buries the surrounding page and leaves someone unfamiliar with the layout
422
+ * with no idea what the highlight is being singled out *from*. Every other style
423
+ * (border, glow, none) draws no scrim of its own, and nor does a step with no target
424
+ * element, so those still need the overlay.
425
+ */
426
+ applyScrim(step, targetElement) {
427
+ document.documentElement.style.setProperty(
428
+ '--onboarding-tour-scrim', this.overlayOpacityValue
429
+ )
430
+
431
+ if (!this.overlay) return
432
+
433
+ const spotlit = Boolean(targetElement) && step.highlightStyle === 'spotlight'
434
+ this.overlay.style.background = spotlit
435
+ ? 'transparent'
436
+ : `rgba(0, 0, 0, ${this.overlayOpacityValue})`
385
437
  }
386
438
 
387
439
  /**
@@ -401,6 +453,7 @@ export default class extends Controller {
401
453
  if (this.highlightedElement) {
402
454
  this.highlightedElement.style.position = this.previousElementPosition || ''
403
455
  this.highlightedElement.style.zIndex = this.previousElementZIndex || ''
456
+ this.highlightedElement.style.pointerEvents = this.previousElementPointerEvents || ''
404
457
  this.highlightedElement = null
405
458
  }
406
459
  }
@@ -411,7 +464,7 @@ export default class extends Controller {
411
464
  createPopup(step, targetElement) {
412
465
  this.removePopup()
413
466
 
414
- this.popup = document.createElement('div')
467
+ this.popup = this.excludeFromSnapshot(document.createElement('div'))
415
468
  this.popup.className = 'tour-popup'
416
469
 
417
470
  // Build popup HTML
@@ -22,19 +22,15 @@
22
22
  border-radius: 8px;
23
23
  }
24
24
 
25
- /* Spotlight style - Creates cutout effect */
25
+ /* Spotlight style - Creates cutout effect.
26
+ The 9999px spread makes this box-shadow a full-viewport scrim in its own right, so
27
+ tour_controller stops painting .tour-overlay whenever a spotlight is drawn - the two
28
+ together composited to ~0.92 and buried the surrounding page.
29
+ The alpha comes from --onboarding-tour-scrim, which the controller sets on :root from
30
+ its overlayOpacity value. It is deliberately not animated: an animation on this
31
+ property overrides the inline style, which is what made overlayOpacity a dead knob. */
26
32
  .tour-spotlight-spotlight {
27
- box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.7);
28
- animation: onboarding-spotlightPulse 2s ease-in-out infinite;
29
- }
30
-
31
- @keyframes onboarding-spotlightPulse {
32
- 0%, 100% {
33
- box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.7);
34
- }
35
- 50% {
36
- box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.75);
37
- }
33
+ box-shadow: 0 0 0 9999px rgba(0, 0, 0, var(--onboarding-tour-scrim, 0.7));
38
34
  }
39
35
 
40
36
  /* Border highlight style */
@@ -327,6 +323,10 @@
327
323
  background: rgba(0, 0, 0, 0.85);
328
324
  }
329
325
 
326
+ .tour-spotlight-spotlight {
327
+ --onboarding-tour-scrim: 0.85;
328
+ }
329
+
330
330
  .tour-spotlight-border {
331
331
  border-width: 4px;
332
332
  }
@@ -351,10 +351,6 @@
351
351
  animation: none;
352
352
  }
353
353
 
354
- .tour-spotlight-spotlight {
355
- animation: none;
356
- }
357
-
358
354
  .tour-spotlight-border {
359
355
  animation: none;
360
356
  }
@@ -1,3 +1,3 @@
1
1
  module RailsOnboarding
2
- VERSION = "0.8.8"
2
+ VERSION = "0.8.10"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_onboarding
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.8
4
+ version: 0.8.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - David Lewis
@@ -282,7 +282,7 @@ licenses:
282
282
  metadata:
283
283
  allowed_push_host: https://rubygems.org
284
284
  homepage_uri: https://github.com/bunnahabhain/rails_onboarding
285
- source_code_uri: https://github.com/bunnahabhain/rails_onboarding/tree/v0.8.8
285
+ source_code_uri: https://github.com/bunnahabhain/rails_onboarding/tree/v0.8.10
286
286
  changelog_uri: https://github.com/bunnahabhain/rails_onboarding/blob/master/docs/CHANGELOG.md
287
287
  rdoc_options: []
288
288
  require_paths: