aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/components/Footer/Footer.module.scss73
-rw-r--r--src/components/Footer/Footer.tsx33
-rw-r--r--src/components/Header/Header.tsx2
-rw-r--r--src/styles/base/_animations.scss13
-rw-r--r--src/styles/globals.scss1
5 files changed, 121 insertions, 1 deletions
diff --git a/src/components/Footer/Footer.module.scss b/src/components/Footer/Footer.module.scss
index b5d098d..debddfb 100644
--- a/src/components/Footer/Footer.module.scss
+++ b/src/components/Footer/Footer.module.scss
@@ -1,3 +1,5 @@
+@use "@styles/abstracts/functions" as fun;
+
.wrapper {
display: flex;
flex-flow: row wrap;
@@ -6,3 +8,74 @@
gap: var(--spacing-xs);
padding: var(--spacing-md) 0 calc(var(--toolbar-size) + var(--spacing-md));
}
+
+.back-to-top {
+ --button-size: #{fun.convert-px(55)};
+
+ position: fixed;
+ bottom: calc(var(--toolbar-size) + var(--spacing-md));
+ right: var(--spacing-md);
+ transition: all 0.4s ease-in 0s;
+
+ &--hidden {
+ opacity: 0;
+ transform: translateY(calc(var(--button-size) + var(--spacing-md)));
+ }
+
+ &--visible {
+ opacity: 1;
+ transform: translateY(0);
+ }
+
+ a {
+ display: flex;
+ place-content: center;
+ padding: 0;
+ width: var(--button-size);
+ height: var(--button-size);
+
+ svg {
+ width: 100%;
+ padding: var(--spacing-2xs);
+ }
+
+ :global {
+ .arrow-head {
+ transform: translateY(12px) translateX(-5px) scale(1.5);
+ transition: all 0.6s ease-in-out 0s;
+ }
+
+ .arrow-bar {
+ opacity: 0;
+ transform: translateY(12px) translateX(5px) scale(0.5);
+ transition: transform 0.6s ease-in-out 0s, opacity 0.7s ease-in-out 0s;
+ }
+ }
+
+ &:hover,
+ &:focus {
+ :global {
+ .arrow-head {
+ transform: translateY(0) translateX(0) scale(1);
+ }
+
+ .arrow-bar {
+ opacity: 1;
+ transform: translateY(0) translateX(0) scale(1);
+ }
+ }
+
+ svg {
+ :global {
+ animation: pulse 1.2s ease-in-out 0.6s infinite;
+ }
+ }
+ }
+
+ &:active {
+ svg {
+ animation-play-state: paused;
+ }
+ }
+ }
+}
diff --git a/src/components/Footer/Footer.tsx b/src/components/Footer/Footer.tsx
index 12d86ce..15a4660 100644
--- a/src/components/Footer/Footer.tsx
+++ b/src/components/Footer/Footer.tsx
@@ -1,12 +1,45 @@
+import { ButtonLink } from '@components/Buttons';
import Copyright from '@components/Copyright/Copyright';
import FooterNav from '@components/FooterNav/FooterNav';
+import { ArrowIcon } from '@components/Icons';
+import { t } from '@lingui/macro';
+import { useEffect, useState } from 'react';
import styles from './Footer.module.scss';
const Footer = () => {
+ const [backToTopClasses, setBackToTopClasses] = useState(
+ `${styles['back-to-top']} ${styles['back-to-top--hidden']}`
+ );
+
+ const handleScroll = () => {
+ const currentScrollY = window.scrollY;
+
+ if (currentScrollY > 300) {
+ setBackToTopClasses(
+ `${styles['back-to-top']} ${styles['back-to-top--visible']}`
+ );
+ } else {
+ setBackToTopClasses(
+ `${styles['back-to-top']} ${styles['back-to-top--hidden']}`
+ );
+ }
+ };
+
+ useEffect(() => {
+ window.addEventListener('scroll', handleScroll);
+ return () => window.removeEventListener('scroll', handleScroll);
+ }, []);
+
return (
<footer className={styles.wrapper}>
<Copyright />
<FooterNav />
+ <div className={backToTopClasses}>
+ <ButtonLink target="#top" position="center">
+ <span className="screen-reader-text">{t`Back to top`}</span>
+ <ArrowIcon direction="top" />
+ </ButtonLink>
+ </div>
</footer>
);
};
diff --git a/src/components/Header/Header.tsx b/src/components/Header/Header.tsx
index 9f2c454..0b773e9 100644
--- a/src/components/Header/Header.tsx
+++ b/src/components/Header/Header.tsx
@@ -4,7 +4,7 @@ import styles from './Header.module.scss';
const Header = ({ isHome }: { isHome: boolean }) => {
return (
- <header className={styles.wrapper}>
+ <header id="top" className={styles.wrapper}>
<div className={styles.body}>
<Branding isHome={isHome} />
<Toolbar />
diff --git a/src/styles/base/_animations.scss b/src/styles/base/_animations.scss
new file mode 100644
index 0000000..903645f
--- /dev/null
+++ b/src/styles/base/_animations.scss
@@ -0,0 +1,13 @@
+@keyframes pulse {
+ from {
+ transform: scale(1);
+ }
+
+ 50% {
+ transform: scale(0.8);
+ }
+
+ to {
+ transform: scale(1);
+ }
+}
diff --git a/src/styles/globals.scss b/src/styles/globals.scss
index 86e3ea8..0a7a618 100644
--- a/src/styles/globals.scss
+++ b/src/styles/globals.scss
@@ -14,6 +14,7 @@
* Define some standard styles and CSS variables (colors, fonts...).
*/
@use "base/base";
+@use "base/animations";
@use "base/colors";
@use "base/fonts";
@use "base/helpers";