Skip to content

Commit

Permalink
feat(highlight): add the possibility to highlight elements during the…
Browse files Browse the repository at this point in the history
… tour
  • Loading branch information
Yan committed Oct 26, 2018
1 parent c704b5e commit 317ff35
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 9 deletions.
60 changes: 52 additions & 8 deletions src/components/VStep.vue
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
import Popper from 'popper.js'
import jump from 'jump.js'
import sum from 'hash-sum'
import { DEFAULT_STEP_OPTIONS } from '../shared/constants'
import { DEFAULT_STEP_OPTIONS, HIGHLIGHT } from '../shared/constants'
export default {
name: 'v-step',
Expand All @@ -55,29 +55,32 @@ export default {
},
labels: {
type: Object
},
highlight: {
type: Boolean
}
},
data () {
return {
hash: sum(this.step.target)
hash: sum(this.step.target),
targetElement: document.querySelector(this.step.target)
}
},
computed: {
params () {
return {
highlight: this.highlight,
...DEFAULT_STEP_OPTIONS,
...this.step.params
}
}
},
methods: {
createStep () {
let targetElement = document.querySelector(this.step.target)
// TODO: debug mode
// console.log('[Vue Tour] The target element ' + this.step.target + ' of .v-step[id="' + this.hash + '"] is:', targetElement)
if (targetElement) {
if (this.targetElement) {
if (this.params.enableScrolling) {
if (this.step.duration || this.step.offset) {
let jumpOptions = {
Expand All @@ -87,27 +90,68 @@ export default {
a11y: false
}
jump(targetElement, jumpOptions)
jump(this.targetElement, jumpOptions)
} else {
// Use the native scroll by default if no scroll options has been defined
targetElement.scrollIntoView({ behavior: 'smooth' })
this.targetElement.scrollIntoView({ behavior: 'smooth' })
}
}
this.createHighlight()
/* eslint-disable no-new */
new Popper(
targetElement,
this.targetElement,
this.$refs['v-step-' + this.hash],
this.params
)
} else {
console.error('[Vue Tour] The target element ' + this.step.target + ' of .v-step[id="' + this.hash + '"] does not exist!')
this.$emit('targetNotFound', this.step)
}
},
checkHightlight () {
return ((this.highlight && this.params.highlight) || this.params.highlight)
},
createHighlight () {
if (this.checkHightlight()) {
document.body.classList.add(HIGHLIGHT.ACTIVE_TOUR)
const transitionValue = window.getComputedStyle(this.targetElement).getPropertyValue('transition')
// Make sure our background doesn't flick on transitions.
if (transitionValue !== 'all 0s ease 0s') {
this.targetElement.style.transition = `${transitionValue}${HIGHLIGHT.TRANSITION}`
}
this.targetElement.classList.add(HIGHLIGHT.ACTIVE_STEP)
// The element must have a position, if it doesn't have, add relative position class.
if (!HIGHLIGHT.POSITIONS.includes(this.targetElement.style.position)) {
this.targetElement.classList.add(HIGHLIGHT.POSITION_CLASS)
}
} else {
document.body.classList.remove(HIGHLIGHT.ACTIVE_TOUR)
}
},
removeHighlight () {
if (this.checkHightlight()) {
const target = this.targetElement
const currTransition = this.targetElement.style.transition
this.targetElement.classList.remove(HIGHLIGHT.ACTIVE_STEP)
this.targetElement.classList.remove(HIGHLIGHT.POSITION_CLASS)
// Remove our transition when step is finished.
if (currTransition.includes(HIGHLIGHT.TRANSITION)) {
setTimeout(() => {
target.style.transition = currTransition.replace(HIGHLIGHT.TRANSITION, '')
}, 0)
}
}
}
},
mounted () {
this.createStep()
},
destroyed () {
this.removeHighlight()
}
}
</script>
Expand Down
35 changes: 34 additions & 1 deletion src/components/VTour.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
:is-first="isFirst"
:is-last="isLast"
:labels="customOptions.labels"
:highlight="customOptions.highlight"
>
<!--Default slot {{ currentStep }}-->
<v-step
Expand All @@ -22,6 +23,7 @@
:is-first="isFirst"
:is-last="isLast"
:labels="customOptions.labels"
:highlight="customOptions.highlight"
>
<!--<div v-if="index === 2" slot="actions">
<a @click="nextStep">Next step</a>
Expand All @@ -32,7 +34,7 @@
</template>

<script>
import { DEFAULT_CALLBACKS, DEFAULT_OPTIONS, KEYS } from '../shared/constants'
import { DEFAULT_CALLBACKS, DEFAULT_OPTIONS, KEYS, HIGHLIGHT } from '../shared/constants'
export default {
name: 'v-tour',
Expand Down Expand Up @@ -122,6 +124,7 @@ export default {
},
stop () {
this.customCallbacks.onStop()
document.body.classList.remove(HIGHLIGHT.ACTIVE_TOUR)
this.currentStep = -1
},
Expand All @@ -143,3 +146,33 @@ export default {
}
}
</script>

<style lang="scss">
body.v-tour-active {
pointer-events: none;
}
.v-tour {
pointer-events: auto;
}
.v-tour-highlight {
pointer-events: auto;
z-index: 9999;
}
.v-tour-highlight:after {
content: "";
position: absolute;
z-index: -1;
box-shadow: 0 0 50px 25px rgba(0, 0, 0, 0.5);
width: calc(100% + 10px);
height: calc(100% + 10px);
left: -5px;
top: -5px;
}
.v-tour-position {
position: relative;
}
</style>
9 changes: 9 additions & 0 deletions src/shared/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export const DEFAULT_CALLBACKS = {
export const DEFAULT_OPTIONS = {
useKeyboardNavigation: true,
startTimeout: 0,
highlight: false,
labels: {
buttonSkip: 'Skip tour',
buttonPrevious: 'Previous',
Expand All @@ -16,6 +17,14 @@ export const DEFAULT_OPTIONS = {
}
}

export const HIGHLIGHT = {
ACTIVE_STEP: 'v-tour-highlight',
ACTIVE_TOUR: 'v-tour-active',
POSITION_CLASS: 'v-tour-position',
TRANSITION: ', box-shadow 0s ease-in-out 0s',
POSITIONS: ['absolute', 'relative', 'fixed', 'sticky']
}

export const DEFAULT_STEP_OPTIONS = {
placement: 'bottom',
enableScrolling: true,
Expand Down

0 comments on commit 317ff35

Please sign in to comment.