rails_onboarding 0.8.11 → 0.8.12
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:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 532f89d681d2a2bf5cdf575a99b26742497707b65c1109525f51307d09bc50c6
|
|
4
|
+
data.tar.gz: 6f5e6c0c374b350ac09ac25c36846ad93eee2c2e10d31a531629f65cb19062f7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 68277199c94e5109304653b498934f8971779b6fe58696133b992b365753527545b06982f013e75faa2fd34e4cb7f71f4730937c2c599da30efdbd0a218d7f7e
|
|
7
|
+
data.tar.gz: f2b95e0a399d1981f5f01783231179ea62d7398e8145f0aed809e0621f158c8949e1152c8305f9c5f05daf328350eddf4a293885f954dfa99400c5bf8dac491f
|
|
@@ -216,8 +216,7 @@ export default class extends Controller {
|
|
|
216
216
|
this.executeCallback(step.beforeShow, step)
|
|
217
217
|
}
|
|
218
218
|
|
|
219
|
-
|
|
220
|
-
const targetElement = step.selector ? document.querySelector(step.selector) : null
|
|
219
|
+
const targetElement = this.resolveTarget(step)
|
|
221
220
|
|
|
222
221
|
this.currentTargetElement = targetElement
|
|
223
222
|
this.applyScrim(step, targetElement)
|
|
@@ -244,6 +243,37 @@ export default class extends Controller {
|
|
|
244
243
|
this.dispatch('step-shown', { detail: { step, index } })
|
|
245
244
|
}
|
|
246
245
|
|
|
246
|
+
/**
|
|
247
|
+
* Find the element a step should point at.
|
|
248
|
+
*
|
|
249
|
+
* `selector` may be a list, which is how a step survives a responsive layout:
|
|
250
|
+
* the same idea is often two elements, one of them display:none at the current
|
|
251
|
+
* breakpoint - a row of tabs on a wide screen and a select on a narrow one. The
|
|
252
|
+
* first candidate that is actually rendered wins.
|
|
253
|
+
*
|
|
254
|
+
* An element with no layout box is treated as absent rather than used anyway.
|
|
255
|
+
* getBoundingClientRect() on a display:none element is all zeroes, so the
|
|
256
|
+
* spotlight became a small square in the top-left corner and the popup was
|
|
257
|
+
* placed against the origin - pointing confidently at nothing, on top of
|
|
258
|
+
* whatever happened to be there.
|
|
259
|
+
*/
|
|
260
|
+
resolveTarget(step) {
|
|
261
|
+
const selectors = Array.isArray(step.selector) ? step.selector : [step.selector]
|
|
262
|
+
|
|
263
|
+
for (const selector of selectors) {
|
|
264
|
+
if (!selector) continue
|
|
265
|
+
|
|
266
|
+
const element = document.querySelector(selector)
|
|
267
|
+
if (element && this.hasLayoutBox(element)) return element
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
return null
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
hasLayoutBox(element) {
|
|
274
|
+
return element.getClientRects().length > 0
|
|
275
|
+
}
|
|
276
|
+
|
|
247
277
|
/**
|
|
248
278
|
* Hide current step
|
|
249
279
|
*/
|
|
@@ -592,26 +622,26 @@ export default class extends Controller {
|
|
|
592
622
|
|
|
593
623
|
const popupRect = this.popup.getBoundingClientRect()
|
|
594
624
|
const margin = 20
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
if (targetElement) {
|
|
598
|
-
const targetRect = targetElement.getBoundingClientRect()
|
|
599
|
-
const position = this.calculateBestPosition(step, targetRect, popupRect, margin)
|
|
625
|
+
const targetRect = targetElement ? targetElement.getBoundingClientRect() : null
|
|
600
626
|
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
}
|
|
627
|
+
const coords = targetRect
|
|
628
|
+
? this.calculateBestPosition(step, targetRect, popupRect, margin)
|
|
629
|
+
: {
|
|
630
|
+
top: (window.innerHeight - popupRect.height) / 2,
|
|
631
|
+
left: (window.innerWidth - popupRect.width) / 2
|
|
632
|
+
}
|
|
608
633
|
|
|
609
|
-
//
|
|
610
|
-
|
|
611
|
-
|
|
634
|
+
// The clamp keeps the popup reachable, which matters more than anything else -
|
|
635
|
+
// its own buttons are the only way forward. calculateBestPosition is what keeps
|
|
636
|
+
// it off the highlight; this is the last word on staying on screen.
|
|
637
|
+
this.popup.style.top =
|
|
638
|
+
`${this.clamp(coords.top, margin, window.innerHeight - popupRect.height - margin)}px`
|
|
639
|
+
this.popup.style.left =
|
|
640
|
+
`${this.clamp(coords.left, margin, window.innerWidth - popupRect.width - margin)}px`
|
|
641
|
+
}
|
|
612
642
|
|
|
613
|
-
|
|
614
|
-
|
|
643
|
+
clamp(value, min, max) {
|
|
644
|
+
return Math.max(min, Math.min(value, max))
|
|
615
645
|
}
|
|
616
646
|
|
|
617
647
|
/**
|
|
@@ -641,22 +671,40 @@ export default class extends Controller {
|
|
|
641
671
|
}
|
|
642
672
|
}
|
|
643
673
|
|
|
644
|
-
//
|
|
645
|
-
|
|
646
|
-
|
|
674
|
+
// 'center' is a host saying "do not point at anything", so it is taken at its
|
|
675
|
+
// word. Every other position is a *preference*: it used to be handed back
|
|
676
|
+
// without being checked, and positionPopup then clamped it into the viewport -
|
|
677
|
+
// which on a phone slides the popup straight over the element it is describing.
|
|
678
|
+
// A tour that hides what it is explaining is worse than one placed on the wrong
|
|
679
|
+
// side, so the asked-for side is tried first and the others are tried after it.
|
|
680
|
+
if (step.position === 'center') return positions.center
|
|
647
681
|
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
}
|
|
653
|
-
}
|
|
682
|
+
const fallbacks = ['bottom', 'top', 'right', 'left']
|
|
683
|
+
const order = positions[step.position] && step.position !== 'auto'
|
|
684
|
+
? [step.position, ...fallbacks.filter((pos) => pos !== step.position)]
|
|
685
|
+
: fallbacks
|
|
654
686
|
|
|
655
|
-
|
|
656
|
-
return positions
|
|
687
|
+
for (const pos of order) {
|
|
688
|
+
if (this.isPositionValid(positions[pos], popupRect, margin)) return positions[pos]
|
|
657
689
|
}
|
|
658
690
|
|
|
659
|
-
return
|
|
691
|
+
return this.positionBesideTarget(targetRect, popupRect, margin)
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
/**
|
|
695
|
+
* Nothing fits cleanly on any side, which on a small viewport is the ordinary
|
|
696
|
+
* case rather than the exceptional one. Put the popup in whichever band - above
|
|
697
|
+
* the target or below it - has more room. Centring instead, which is what this
|
|
698
|
+
* used to do, lands on the target more often than not.
|
|
699
|
+
*/
|
|
700
|
+
positionBesideTarget(targetRect, popupRect, margin) {
|
|
701
|
+
const roomAbove = targetRect.top - margin
|
|
702
|
+
const roomBelow = window.innerHeight - targetRect.bottom - margin
|
|
703
|
+
const left = targetRect.left + (targetRect.width - popupRect.width) / 2
|
|
704
|
+
|
|
705
|
+
return roomBelow >= roomAbove
|
|
706
|
+
? { top: targetRect.bottom + margin, left }
|
|
707
|
+
: { top: targetRect.top - popupRect.height - margin, left }
|
|
660
708
|
}
|
|
661
709
|
|
|
662
710
|
/**
|
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.
|
|
4
|
+
version: 0.8.12
|
|
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.
|
|
285
|
+
source_code_uri: https://github.com/bunnahabhain/rails_onboarding/tree/v0.8.12
|
|
286
286
|
changelog_uri: https://github.com/bunnahabhain/rails_onboarding/blob/master/docs/CHANGELOG.md
|
|
287
287
|
rdoc_options: []
|
|
288
288
|
require_paths:
|