From 579bce6b1e8dcb68b119228126bac7ef2d41582c Mon Sep 17 00:00:00 2001
From: Lauri
Date: Thu, 6 Feb 2025 13:53:41 +0200
Subject: [PATCH 01/10] added v2 of scrollTop
---
.../ScrollTop/ui/v2/ScrollTop.module.scss | 39 ++++++++++
.../ScrollTop/ui/v2/ScrollTop.stories.tsx | 50 ++++++++++++
.../ScrollTop/ui/v2/ScrollTop.test.tsx | 78 +++++++++++++++++++
.../features/ScrollTop/ui/v2/ScrollTop.tsx | 40 ++++++++++
4 files changed, 207 insertions(+)
create mode 100644 frontend-next-migration/src/features/ScrollTop/ui/v2/ScrollTop.module.scss
create mode 100644 frontend-next-migration/src/features/ScrollTop/ui/v2/ScrollTop.stories.tsx
create mode 100644 frontend-next-migration/src/features/ScrollTop/ui/v2/ScrollTop.test.tsx
create mode 100644 frontend-next-migration/src/features/ScrollTop/ui/v2/ScrollTop.tsx
diff --git a/frontend-next-migration/src/features/ScrollTop/ui/v2/ScrollTop.module.scss b/frontend-next-migration/src/features/ScrollTop/ui/v2/ScrollTop.module.scss
new file mode 100644
index 000000000..0c6032576
--- /dev/null
+++ b/frontend-next-migration/src/features/ScrollTop/ui/v2/ScrollTop.module.scss
@@ -0,0 +1,39 @@
+.ScrollTop {
+ --primary-color: #FFA100;
+ --white: #FAF9F6;
+ --black: #121212;
+ --border-desktop: 4px;
+
+ color: var(--black);
+ border: var(--border-desktop) solid var(--black);
+ border-radius: var(--border-radius-custom);
+ z-index: var(--navbar-z-index);
+ background-color: var(--primary-color);
+ cursor: pointer;
+ width: 70px;
+ height: 70px;
+ position: fixed;
+ bottom: 117px; // 32px + 70px + 15px + 70px
+ right: 32px;
+ opacity: 0;
+ visibility: hidden;
+ transition: opacity 0.2s ease-in-out, visibility 0.2s ease-in-out;
+ transform: rotate(90deg);
+ font-size: 70px !important;
+ padding: 4px auto;
+}
+.ScrollTop::before {
+ position: absolute;
+ top:0px;
+ left:0px;
+ content:'\226A';
+}
+
+.show {
+ opacity: 1;
+ visibility: visible;
+}
+
+
+
+// 70px x 70px, bottom 102, right 32px
\ No newline at end of file
diff --git a/frontend-next-migration/src/features/ScrollTop/ui/v2/ScrollTop.stories.tsx b/frontend-next-migration/src/features/ScrollTop/ui/v2/ScrollTop.stories.tsx
new file mode 100644
index 000000000..add9879f4
--- /dev/null
+++ b/frontend-next-migration/src/features/ScrollTop/ui/v2/ScrollTop.stories.tsx
@@ -0,0 +1,50 @@
+import { ComponentStory, ComponentMeta } from '@storybook/react';
+import React from 'react';
+import { ScrollTop } from './ScrollTop';
+
+export default {
+ title: 'features/ScrollTopV2',
+ component: ScrollTop,
+ args: {
+ className: '',
+ children: 'UP',
+ },
+} as ComponentMeta;
+
+const Template: ComponentStory = (args) => {
+ return (
+ <>
+
+ Scroll down to see the button
+
+
+
+ ☏
+
+ >
+ );
+};
+
+export const Default = Template.bind({});
diff --git a/frontend-next-migration/src/features/ScrollTop/ui/v2/ScrollTop.test.tsx b/frontend-next-migration/src/features/ScrollTop/ui/v2/ScrollTop.test.tsx
new file mode 100644
index 000000000..27137ecef
--- /dev/null
+++ b/frontend-next-migration/src/features/ScrollTop/ui/v2/ScrollTop.test.tsx
@@ -0,0 +1,78 @@
+import { render, screen, fireEvent } from '@testing-library/react';
+import * as hooks from '@/shared/lib/hooks';
+import * as i18n from '@/shared/i18n';
+import { ScrollTop } from './ScrollTop';
+
+// Mocking the hooks used in the ScrollTop component
+jest.mock('@/shared/lib/hooks', () => ({
+ useCurrentYPosition: jest.fn(), // Mock the useCurrentYPosition hook
+}));
+
+jest.mock('@/shared/i18n', () => ({
+ useClientTranslation: jest.fn(), // Mock the useClientTranslation hook
+}));
+
+describe('ScrollTop', () => {
+ const mockScrollTo = jest.fn(); // Mock function to simulate scrolling
+ let originalScrollTo: typeof window.scrollTo; // Store original window.scrollTo function
+
+ beforeAll(() => {
+ // Before all tests, replace window.scrollTo with the mock function
+ originalScrollTo = window.scrollTo;
+ window.scrollTo = mockScrollTo;
+ });
+
+ afterAll(() => {
+ // Restore original window.scrollTo function after all tests
+ window.scrollTo = originalScrollTo;
+ });
+
+ beforeEach(() => {
+ // Clear all mocks before each test to ensure clean state
+ jest.clearAllMocks();
+ // Mock translation function to return the key as the translation
+ (i18n.useClientTranslation as jest.Mock).mockReturnValue({ t: (key: string) => key });
+ });
+
+ it('renders correctly with default props', () => {
+ // Mock the hook to simulate being at the top of the page
+ (hooks.useCurrentYPosition as jest.Mock).mockReturnValue(0);
+
+ render(); // Render the ScrollTop component
+
+ // Check if the button is in the document and has the correct text and class
+ const button = screen.getByTestId('scroll-to-top-btn');
+ expect(button).toBeInTheDocument();
+ expect(button).toHaveClass('ScrollTop');
+ });
+
+ it('shows button when scrolled down', () => {
+ // Mock the hook to simulate scrolling down the page
+ (hooks.useCurrentYPosition as jest.Mock).mockReturnValue(window.innerHeight / 4);
+ render(); // Render the component
+
+ // Verify that the button is visible
+ expect(screen.getByTestId('scroll-to-top-btn')).toHaveClass('show');
+ });
+
+ it('hides button when scrolled up', () => {
+ // Mock the hook to simulate being at the top of the page
+ (hooks.useCurrentYPosition as jest.Mock).mockReturnValue(0);
+ render(); // Render the component
+
+ // Verify that the button is hidden
+ expect(screen.getByTestId('scroll-to-top-btn')).not.toHaveClass('show');
+ });
+
+ it('scrolls to top when button is clicked', () => {
+ // Mock the hook to simulate scrolling down the page
+ (hooks.useCurrentYPosition as jest.Mock).mockReturnValue(window.innerHeight / 4);
+ render(); // Render the component
+
+ const button = screen.getByTestId('scroll-to-top-btn'); // Get the button element
+ fireEvent.click(button); // Simulate a click on the button
+
+ // Check if the mock scrollTo function was called with correct parameters
+ expect(mockScrollTo).toHaveBeenCalledWith({ top: 0, behavior: 'smooth' });
+ });
+});
diff --git a/frontend-next-migration/src/features/ScrollTop/ui/v2/ScrollTop.tsx b/frontend-next-migration/src/features/ScrollTop/ui/v2/ScrollTop.tsx
new file mode 100644
index 000000000..4e5070f50
--- /dev/null
+++ b/frontend-next-migration/src/features/ScrollTop/ui/v2/ScrollTop.tsx
@@ -0,0 +1,40 @@
+'use client';
+import { memo, useCallback, useEffect, useState } from 'react';
+import { classNames } from '@/shared/lib/classNames/classNames';
+import { Button, ButtonSize, ButtonTheme } from '@/shared/ui/Button/Button';
+import { useCurrentYPosition } from '@/shared/lib/hooks';
+import cls from './ScrollTop.module.scss';
+
+interface ScrollTopProps {
+ className?: string;
+}
+
+export const ScrollTop = memo(({ className = '' }: ScrollTopProps) => {
+ const currentYPosition = useCurrentYPosition();
+
+ const handleButtonClick = useCallback(() => {
+ window.scrollTo({ top: 0, behavior: 'smooth' });
+ }, []);
+
+ const [showButton, setShowButton] = useState(false);
+
+ useEffect(() => {
+ if (currentYPosition > window.innerHeight / 6) {
+ setShowButton(true);
+ } else {
+ setShowButton(false);
+ }
+ }, [currentYPosition]);
+
+ return (
+
+ );
+});
+
+ScrollTop.displayName = 'ScrollTop';
From ee9db1a0b777a89f62d7a2d53d9dd0f0c51780f5 Mon Sep 17 00:00:00 2001
From: Lauri
Date: Thu, 6 Feb 2025 14:13:13 +0200
Subject: [PATCH 02/10] added comments
---
.../ScrollTop/ui/v2/ScrollTop.module.scss | 15 ++++++---------
1 file changed, 6 insertions(+), 9 deletions(-)
diff --git a/frontend-next-migration/src/features/ScrollTop/ui/v2/ScrollTop.module.scss b/frontend-next-migration/src/features/ScrollTop/ui/v2/ScrollTop.module.scss
index 0c6032576..f044daf8b 100644
--- a/frontend-next-migration/src/features/ScrollTop/ui/v2/ScrollTop.module.scss
+++ b/frontend-next-migration/src/features/ScrollTop/ui/v2/ScrollTop.module.scss
@@ -1,4 +1,5 @@
.ScrollTop {
+ // _styles/themes/main.scss
--primary-color: #FFA100;
--white: #FAF9F6;
--black: #121212;
@@ -7,33 +8,29 @@
color: var(--black);
border: var(--border-desktop) solid var(--black);
border-radius: var(--border-radius-custom);
- z-index: var(--navbar-z-index);
background-color: var(--primary-color);
+ z-index: var(--navbar-z-index);
cursor: pointer;
width: 70px;
height: 70px;
position: fixed;
- bottom: 117px; // 32px + 70px + 15px + 70px
+ bottom: 118px; // 32px + 70px + 16px + 70px
right: 32px;
opacity: 0;
visibility: hidden;
transition: opacity 0.2s ease-in-out, visibility 0.2s ease-in-out;
- transform: rotate(90deg);
+ transform: rotate(90deg); // For making '<<' (\226A) point up
font-size: 70px !important;
- padding: 4px auto;
}
+
.ScrollTop::before {
position: absolute;
top:0px;
left:0px;
- content:'\226A';
+ content:'\226A'; // Much less than -symbol ('<<')
}
.show {
opacity: 1;
visibility: visible;
}
-
-
-
-// 70px x 70px, bottom 102, right 32px
\ No newline at end of file
From c5b37838fe5621b1b46847261d9f781e0f884ca4 Mon Sep 17 00:00:00 2001
From: Lauri
Date: Thu, 6 Feb 2025 15:20:05 +0200
Subject: [PATCH 03/10] change to v2
---
frontend-next-migration/src/features/ScrollTop/index.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/frontend-next-migration/src/features/ScrollTop/index.ts b/frontend-next-migration/src/features/ScrollTop/index.ts
index 58c21d0ff..0f9e161c8 100644
--- a/frontend-next-migration/src/features/ScrollTop/index.ts
+++ b/frontend-next-migration/src/features/ScrollTop/index.ts
@@ -1 +1 @@
-export { ScrollTop } from './ui/ScrollTop';
+export { ScrollTop } from './ui/v2/ScrollTop';
From a48721f694350b0a1cf5a68f3aa0bb5214b79af6 Mon Sep 17 00:00:00 2001
From: Lauri
Date: Fri, 7 Feb 2025 10:00:20 +0200
Subject: [PATCH 04/10] updated css
---
.../src/features/ScrollTop/ui/v2/ScrollTop.module.scss | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/frontend-next-migration/src/features/ScrollTop/ui/v2/ScrollTop.module.scss b/frontend-next-migration/src/features/ScrollTop/ui/v2/ScrollTop.module.scss
index f044daf8b..20e716c73 100644
--- a/frontend-next-migration/src/features/ScrollTop/ui/v2/ScrollTop.module.scss
+++ b/frontend-next-migration/src/features/ScrollTop/ui/v2/ScrollTop.module.scss
@@ -13,6 +13,8 @@
cursor: pointer;
width: 70px;
height: 70px;
+ padding:0 !important;
+ display: grid;
position: fixed;
bottom: 118px; // 32px + 70px + 16px + 70px
right: 32px;
@@ -24,9 +26,6 @@
}
.ScrollTop::before {
- position: absolute;
- top:0px;
- left:0px;
content:'\226A'; // Much less than -symbol ('<<')
}
From aa710058bef2e90a73338c4d9f233d8011e87776 Mon Sep 17 00:00:00 2001
From: Lauri
Date: Fri, 7 Feb 2025 10:12:08 +0200
Subject: [PATCH 05/10] deprecated old ScrollTop
---
.../src/features/ScrollTop/ui/ScrollTop.tsx | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/frontend-next-migration/src/features/ScrollTop/ui/ScrollTop.tsx b/frontend-next-migration/src/features/ScrollTop/ui/ScrollTop.tsx
index 47cca52b4..cca086693 100644
--- a/frontend-next-migration/src/features/ScrollTop/ui/ScrollTop.tsx
+++ b/frontend-next-migration/src/features/ScrollTop/ui/ScrollTop.tsx
@@ -11,6 +11,10 @@ interface ScrollTopProps {
innerText?: string;
}
+/**
+ * @deprecated use v2 instead
+ * (features/ScrollTop/ui/v2/ScrollTop)
+ */
export const ScrollTop = memo(({ className = '', innerText }: ScrollTopProps) => {
const { t } = useClientTranslation('translation');
From 59db078903400fcc903e313ced71b0bf948af3f5 Mon Sep 17 00:00:00 2001
From: Lauri
Date: Fri, 7 Feb 2025 11:54:27 +0200
Subject: [PATCH 06/10] update
---
.../features/ScrollTop/ui/v2/ScrollTop.module.scss | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/frontend-next-migration/src/features/ScrollTop/ui/v2/ScrollTop.module.scss b/frontend-next-migration/src/features/ScrollTop/ui/v2/ScrollTop.module.scss
index 20e716c73..6f9d6fd7e 100644
--- a/frontend-next-migration/src/features/ScrollTop/ui/v2/ScrollTop.module.scss
+++ b/frontend-next-migration/src/features/ScrollTop/ui/v2/ScrollTop.module.scss
@@ -4,6 +4,8 @@
--white: #FAF9F6;
--black: #121212;
--border-desktop: 4px;
+ --border-mobile: 2px;
+ --h1-size-mobile: 32px;
color: var(--black);
border: var(--border-desktop) solid var(--black);
@@ -23,6 +25,15 @@
transition: opacity 0.2s ease-in-out, visibility 0.2s ease-in-out;
transform: rotate(90deg); // For making '<<' (\226A) point up
font-size: 70px !important;
+
+ @media (max-width:breakpoint(lg)) {
+ width:60px;
+ height:60px;
+ right: 16px;
+ border-width: var(--border-mobile);
+ border-radius: calc(var(--border-radius-custom) * 1.5);
+ font: var(--font-xxl) !important;
+ }
}
.ScrollTop::before {
From 883ee2bc74fbe64a5c30980306f8a0e1faedab8f Mon Sep 17 00:00:00 2001
From: Lauri
Date: Mon, 10 Feb 2025 16:30:14 +0200
Subject: [PATCH 07/10] changed button location on mobile
---
.../src/features/ScrollTop/ui/v2/ScrollTop.module.scss | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/frontend-next-migration/src/features/ScrollTop/ui/v2/ScrollTop.module.scss b/frontend-next-migration/src/features/ScrollTop/ui/v2/ScrollTop.module.scss
index 6f9d6fd7e..3a3c2e110 100644
--- a/frontend-next-migration/src/features/ScrollTop/ui/v2/ScrollTop.module.scss
+++ b/frontend-next-migration/src/features/ScrollTop/ui/v2/ScrollTop.module.scss
@@ -25,11 +25,11 @@
transition: opacity 0.2s ease-in-out, visibility 0.2s ease-in-out;
transform: rotate(90deg); // For making '<<' (\226A) point up
font-size: 70px !important;
-
@media (max-width:breakpoint(lg)) {
width:60px;
height:60px;
right: 16px;
+ bottom: 260px;
border-width: var(--border-mobile);
border-radius: calc(var(--border-radius-custom) * 1.5);
font: var(--font-xxl) !important;
From 66bc7f5d78434a4113ea0f7496c0a56c94cd0074 Mon Sep 17 00:00:00 2001
From: Lauri
Date: Mon, 10 Feb 2025 17:16:32 +0200
Subject: [PATCH 08/10] added to ScrollTop
---
frontend-next-migration/src/app/[lng]/(helper)/admin/page.tsx | 2 ++
1 file changed, 2 insertions(+)
diff --git a/frontend-next-migration/src/app/[lng]/(helper)/admin/page.tsx b/frontend-next-migration/src/app/[lng]/(helper)/admin/page.tsx
index a65b74c1e..64a3d0e54 100644
--- a/frontend-next-migration/src/app/[lng]/(helper)/admin/page.tsx
+++ b/frontend-next-migration/src/app/[lng]/(helper)/admin/page.tsx
@@ -1,5 +1,6 @@
// import { CustomEditor } from '@/shared/ui/CustomEditor';
'use client';
+import { ScrollTop } from '@/features/ScrollTop';
import {
NavMenuWithDropdowns,
NavMenuWithDropdownsProps,
@@ -243,6 +244,7 @@ const Page = () => {
This is the main content, adapting to both desktop and mobile devices. This is the
main content, adapting to both desktop and mobile devices
+
);
};
From 8398e468fe6c862e096ead6343467ae9c3f0b44b Mon Sep 17 00:00:00 2001
From: Lauri
Date: Mon, 10 Feb 2025 17:16:32 +0200
Subject: [PATCH 09/10] added the scrolltop component
---
frontend-next-migration/src/app/[lng]/(helper)/admin/page.tsx | 2 ++
1 file changed, 2 insertions(+)
diff --git a/frontend-next-migration/src/app/[lng]/(helper)/admin/page.tsx b/frontend-next-migration/src/app/[lng]/(helper)/admin/page.tsx
index a65b74c1e..64a3d0e54 100644
--- a/frontend-next-migration/src/app/[lng]/(helper)/admin/page.tsx
+++ b/frontend-next-migration/src/app/[lng]/(helper)/admin/page.tsx
@@ -1,5 +1,6 @@
// import { CustomEditor } from '@/shared/ui/CustomEditor';
'use client';
+import { ScrollTop } from '@/features/ScrollTop';
import {
NavMenuWithDropdowns,
NavMenuWithDropdownsProps,
@@ -243,6 +244,7 @@ const Page = () => {
This is the main content, adapting to both desktop and mobile devices. This is the
main content, adapting to both desktop and mobile devices
+
);
};
From 6464e66b045586c4cf64c59cfd8c1fd9e8c11a97 Mon Sep 17 00:00:00 2001
From: Lauri
Date: Wed, 12 Feb 2025 10:08:17 +0200
Subject: [PATCH 10/10] placed arrows more to the center
---
.../src/features/ScrollTop/ui/v2/ScrollTop.module.scss | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/frontend-next-migration/src/features/ScrollTop/ui/v2/ScrollTop.module.scss b/frontend-next-migration/src/features/ScrollTop/ui/v2/ScrollTop.module.scss
index 3a3c2e110..407eb554b 100644
--- a/frontend-next-migration/src/features/ScrollTop/ui/v2/ScrollTop.module.scss
+++ b/frontend-next-migration/src/features/ScrollTop/ui/v2/ScrollTop.module.scss
@@ -16,7 +16,6 @@
width: 70px;
height: 70px;
padding:0 !important;
- display: grid;
position: fixed;
bottom: 118px; // 32px + 70px + 16px + 70px
right: 32px;
@@ -32,12 +31,19 @@
bottom: 260px;
border-width: var(--border-mobile);
border-radius: calc(var(--border-radius-custom) * 1.5);
- font: var(--font-xxl) !important;
+ font-size: 40px !important;
}
}
.ScrollTop::before {
content:'\226A'; // Much less than -symbol ('<<')
+ position:absolute;
+ top:0;
+ left:0;
+ @media (max-width:breakpoint(lg)) {
+ top:-2px;
+ left:10px;
+ }
}
.show {