diff options
-rw-r--r-- | src/components/Global/ButtonBackToTop.vue | 64 | ||||
-rw-r--r-- | src/layouts/AppLayout.vue | 5 | ||||
-rw-r--r-- | src/locales/en-US.json | 1 |
3 files changed, 70 insertions, 0 deletions
diff --git a/src/components/Global/ButtonBackToTop.vue b/src/components/Global/ButtonBackToTop.vue new file mode 100644 index 00000000..9608c4a2 --- /dev/null +++ b/src/components/Global/ButtonBackToTop.vue @@ -0,0 +1,64 @@ +<template> + <b-button + id="scrollToTopBtn" + class="btn-top btn-icon-only" + :class="{ showBtn: showButton }" + variant="secondary" + :title="$t('global.ariaLabel.scrollToTop')" + :aria-label="$t('global.ariaLabel.scrollToTop')" + @click="scrollToTop" + > + <icon-up-to-top /> + </b-button> +</template> + +<script> +import UpToTop24 from '@carbon/icons-vue/es/up-to-top/24'; + +import { debounce } from 'lodash'; + +export default { + name: 'BackToTop', + components: { IconUpToTop: UpToTop24 }, + data() { + return { + showButton: false, + }; + }, + created() { + window.addEventListener('scroll', debounce(this.handleScroll, 200)); + }, + methods: { + handleScroll() { + document.documentElement.scrollTop > 500 + ? (this.showButton = true) + : (this.showButton = false); + }, + scrollToTop() { + document.documentElement.scrollTo({ + top: 0, + behavior: 'smooth', + }); + }, + }, +}; +</script> + +<style lang="scss" scoped> +.btn-top { + position: fixed; + bottom: 24px; + right: 24px; + z-index: $zindex-fixed; + box-shadow: $box-shadow; + opacity: 0; + transition: $transition-base; + @media (min-width: 1600px) { + left: 1485px; + right: auto; + } +} +.showBtn { + opacity: 1; +} +</style> diff --git a/src/layouts/AppLayout.vue b/src/layouts/AppLayout.vue index a4f73daf..228b25cd 100644 --- a/src/layouts/AppLayout.vue +++ b/src/layouts/AppLayout.vue @@ -4,6 +4,8 @@ <app-navigation class="app-navigation" /> <page-container class="app-content"> <router-view ref="routerView" :key="routerKey" /> + <!-- Scroll to top button --> + <button-back-to-top /> </page-container> </div> </template> @@ -12,12 +14,15 @@ import AppHeader from '@/components/AppHeader'; import AppNavigation from '@/components/AppNavigation'; import PageContainer from '@/components/Global/PageContainer'; +import ButtonBackToTop from '@/components/Global/ButtonBackToTop'; + export default { name: 'App', components: { AppHeader, AppNavigation, PageContainer, + ButtonBackToTop, }, data() { return { diff --git a/src/locales/en-US.json b/src/locales/en-US.json index 3e2a09ce..fb0d45a4 100644 --- a/src/locales/en-US.json +++ b/src/locales/en-US.json @@ -21,6 +21,7 @@ "ariaLabel": { "clearSearch": "Clear search input", "hidePassword": "Hide password", + "scrollToTop": "Scroll to top", "showPassword": "Show password as plain text. Note: this will visually expose your password on the screen.", "tooltip": "Tooltip", "progressBar": "Page loading progress bar" |