fix(global): add scroll-to-top
This commit is contained in:
26
.idea/workspace.xml
generated
26
.idea/workspace.xml
generated
@@ -5,27 +5,13 @@
|
|||||||
</component>
|
</component>
|
||||||
<component name="ChangeListManager">
|
<component name="ChangeListManager">
|
||||||
<list default="true" id="2a96f817-9dc2-4f3c-893a-c4974c750774" name="Changes" comment="">
|
<list default="true" id="2a96f817-9dc2-4f3c-893a-c4974c750774" name="Changes" comment="">
|
||||||
<change afterPath="$PROJECT_DIR$/src/shared/ui/burger/index.ts" afterDir="false" />
|
<change afterPath="$PROJECT_DIR$/src/widgets/scroll-to-top/index.ts" afterDir="false" />
|
||||||
<change afterPath="$PROJECT_DIR$/src/shared/ui/burger/styles.module.scss" afterDir="false" />
|
<change afterPath="$PROJECT_DIR$/src/widgets/scroll-to-top/styles.module.scss" afterDir="false" />
|
||||||
<change afterPath="$PROJECT_DIR$/src/shared/ui/burger/ui.tsx" afterDir="false" />
|
<change afterPath="$PROJECT_DIR$/src/widgets/scroll-to-top/ui.tsx" afterDir="false" />
|
||||||
<change afterPath="$PROJECT_DIR$/src/widgets/mobile-callback/index.ts" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/src/widgets/mobile-callback/styles.module.scss" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/src/widgets/mobile-callback/ui.tsx" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/src/widgets/sidebar/index.ts" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/src/widgets/sidebar/menu-item.tsx" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/src/widgets/sidebar/menu-list.tsx" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/src/widgets/sidebar/styles.module.scss" afterDir="false" />
|
|
||||||
<change afterPath="$PROJECT_DIR$/src/widgets/sidebar/ui.tsx" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/app/layout.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/app/layout.tsx" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/app/layout.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/app/layout.tsx" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/entities/base-menu/styles.module.scss" beforeDir="false" afterPath="$PROJECT_DIR$/src/entities/base-menu/styles.module.scss" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/entities/base-menu/ui.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/entities/base-menu/ui.tsx" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/shared/const/menu.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/shared/const/menu.ts" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/shared/types/menu.ts" beforeDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/shared/ui/icon/base.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/shared/ui/icon/base.tsx" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/shared/ui/icon/base.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/shared/ui/icon/base.tsx" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/shared/ui/icon/ui.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/shared/ui/icon/ui.tsx" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/shared/ui/icon/ui.tsx" beforeDir="false" afterPath="$PROJECT_DIR$/src/shared/ui/icon/ui.tsx" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/src/shared/ui/index.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/shared/ui/index.ts" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/widgets/footer/styles.module.scss" beforeDir="false" afterPath="$PROJECT_DIR$/src/widgets/footer/styles.module.scss" afterDir="false" />
|
|
||||||
<change beforePath="$PROJECT_DIR$/src/widgets/index.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/widgets/index.ts" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/src/widgets/index.ts" beforeDir="false" afterPath="$PROJECT_DIR$/src/widgets/index.ts" afterDir="false" />
|
||||||
</list>
|
</list>
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
@@ -34,16 +20,16 @@
|
|||||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||||
</component>
|
</component>
|
||||||
<component name="DarkyenusTimeTracker">
|
<component name="DarkyenusTimeTracker">
|
||||||
<option name="totalTimeSeconds" value="192744" />
|
<option name="totalTimeSeconds" value="194048" />
|
||||||
<option name="gitIntegration" value="true" />
|
<option name="gitIntegration" value="true" />
|
||||||
<option name="naggedAbout" value="1" />
|
<option name="naggedAbout" value="1" />
|
||||||
</component>
|
</component>
|
||||||
<component name="FileTemplateManagerImpl">
|
<component name="FileTemplateManagerImpl">
|
||||||
<option name="RECENT_TEMPLATES">
|
<option name="RECENT_TEMPLATES">
|
||||||
<list>
|
<list>
|
||||||
<option value="SCSS File" />
|
|
||||||
<option value="TypeScript File" />
|
<option value="TypeScript File" />
|
||||||
<option value="TypeScript JSX File" />
|
<option value="TypeScript JSX File" />
|
||||||
|
<option value="SCSS File" />
|
||||||
</list>
|
</list>
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
@@ -128,7 +114,7 @@
|
|||||||
<workItem from="1764590282382" duration="1201000" />
|
<workItem from="1764590282382" duration="1201000" />
|
||||||
<workItem from="1764591867512" duration="4332000" />
|
<workItem from="1764591867512" duration="4332000" />
|
||||||
<workItem from="1764657017067" duration="21490000" />
|
<workItem from="1764657017067" duration="21490000" />
|
||||||
<workItem from="1764741053553" duration="16724000" />
|
<workItem from="1764741053553" duration="18011000" />
|
||||||
</task>
|
</task>
|
||||||
<servers />
|
<servers />
|
||||||
</component>
|
</component>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { ReactNode } from 'react';
|
|||||||
import { Montserrat, Roboto } from 'next/font/google';
|
import { Montserrat, Roboto } from 'next/font/google';
|
||||||
import '@core/styles/globals.scss';
|
import '@core/styles/globals.scss';
|
||||||
import '@core/styles/reset.scss';
|
import '@core/styles/reset.scss';
|
||||||
import { Footer, Header, MobileCallback } from '@/widgets';
|
import { Footer, Header, MobileCallback, ScrollToTop } from '@/widgets';
|
||||||
import { ModalProvider } from '@core/providers/modal-provider';
|
import { ModalProvider } from '@core/providers/modal-provider';
|
||||||
|
|
||||||
const roboto = Roboto({
|
const roboto = Roboto({
|
||||||
@@ -35,6 +35,7 @@ export default function RootLayout({
|
|||||||
<main>{children}</main>
|
<main>{children}</main>
|
||||||
<Footer />
|
<Footer />
|
||||||
<MobileCallback />
|
<MobileCallback />
|
||||||
|
<ScrollToTop />
|
||||||
</ModalProvider>
|
</ModalProvider>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -342,6 +342,22 @@ const MobilePhone = (props: SVGProps<SVGSVGElement>) => (
|
|||||||
</svg>
|
</svg>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//fluent:chevron-up-12-filled
|
||||||
|
const Chevron = (props: SVGProps<SVGSVGElement>) => (
|
||||||
|
<svg
|
||||||
|
xmlns='http://www.w3.org/2000/svg'
|
||||||
|
width={96}
|
||||||
|
height={96}
|
||||||
|
viewBox='0 0 12 12'
|
||||||
|
{...props}
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fill='currentColor'
|
||||||
|
d='M2.22 7.53a.75.75 0 0 0 1.06 0L6 4.81l2.72 2.72a.75.75 0 0 0 1.06-1.06L6.53 3.22a.75.75 0 0 0-1.06 0L2.22 6.47a.75.75 0 0 0 0 1.06'
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
|
||||||
export {
|
export {
|
||||||
Map,
|
Map,
|
||||||
Envelope,
|
Envelope,
|
||||||
@@ -362,4 +378,5 @@ export {
|
|||||||
MapOutline,
|
MapOutline,
|
||||||
MobileContact,
|
MobileContact,
|
||||||
MobilePhone,
|
MobilePhone,
|
||||||
|
Chevron,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import {
|
|||||||
MapOutline,
|
MapOutline,
|
||||||
MobileContact,
|
MobileContact,
|
||||||
MobilePhone,
|
MobilePhone,
|
||||||
|
Chevron,
|
||||||
} from './base';
|
} from './base';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -73,6 +74,7 @@ const Icons = Object.assign(
|
|||||||
MapOutline,
|
MapOutline,
|
||||||
MobileContact,
|
MobileContact,
|
||||||
MobilePhone,
|
MobilePhone,
|
||||||
|
Chevron,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
GridBook,
|
GridBook,
|
||||||
|
|||||||
@@ -3,3 +3,4 @@ export * from './footer';
|
|||||||
export * from './breadcrumbs';
|
export * from './breadcrumbs';
|
||||||
export * from './mobile-callback';
|
export * from './mobile-callback';
|
||||||
export * from './sidebar';
|
export * from './sidebar';
|
||||||
|
export * from './scroll-to-top';
|
||||||
|
|||||||
1
src/widgets/scroll-to-top/index.ts
Normal file
1
src/widgets/scroll-to-top/index.ts
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export * from './ui';
|
||||||
35
src/widgets/scroll-to-top/styles.module.scss
Normal file
35
src/widgets/scroll-to-top/styles.module.scss
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
.Scroll {
|
||||||
|
position: fixed;
|
||||||
|
right: rem(20px);
|
||||||
|
bottom: rem(50px);
|
||||||
|
|
||||||
|
width: rem(64px);
|
||||||
|
height: rem(64px);
|
||||||
|
|
||||||
|
border-radius: 15%;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
background: $color-green;
|
||||||
|
color: $color-white;
|
||||||
|
font-size: rem(22px);
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
opacity: 0;
|
||||||
|
transform: translateY(20px);
|
||||||
|
pointer-events: none;
|
||||||
|
transition: opacity 0.3s ease, transform 0.3s ease;
|
||||||
|
|
||||||
|
&.Visible {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translateY(0);
|
||||||
|
pointer-events: all;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: $color-green-hover;
|
||||||
|
}
|
||||||
|
}
|
||||||
38
src/widgets/scroll-to-top/ui.tsx
Normal file
38
src/widgets/scroll-to-top/ui.tsx
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import s from './styles.module.scss';
|
||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
import clsx from 'clsx';
|
||||||
|
import { Icons } from '@/shared/ui';
|
||||||
|
|
||||||
|
function ScrollToTop() {
|
||||||
|
const [visible, setVisible] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const onScroll = () => {
|
||||||
|
setVisible(window.scrollY > 300);
|
||||||
|
};
|
||||||
|
|
||||||
|
window.addEventListener('scroll', onScroll);
|
||||||
|
return () => window.removeEventListener('scroll', onScroll);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const scrollToTop = () => {
|
||||||
|
window.scrollTo({
|
||||||
|
top: 0,
|
||||||
|
behavior: 'smooth',
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
className={clsx(s.Scroll, visible && s.Visible)}
|
||||||
|
onClick={scrollToTop}
|
||||||
|
aria-label='Переместить наверх'
|
||||||
|
>
|
||||||
|
<Icons.Chevron />
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export { ScrollToTop };
|
||||||
Reference in New Issue
Block a user