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 name="ChangeListManager">
|
||||
<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/shared/ui/burger/styles.module.scss" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/shared/ui/burger/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 afterPath="$PROJECT_DIR$/src/widgets/scroll-to-top/index.ts" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/widgets/scroll-to-top/styles.module.scss" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/src/widgets/scroll-to-top/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$/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/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" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
@@ -34,16 +20,16 @@
|
||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||
</component>
|
||||
<component name="DarkyenusTimeTracker">
|
||||
<option name="totalTimeSeconds" value="192744" />
|
||||
<option name="totalTimeSeconds" value="194048" />
|
||||
<option name="gitIntegration" value="true" />
|
||||
<option name="naggedAbout" value="1" />
|
||||
</component>
|
||||
<component name="FileTemplateManagerImpl">
|
||||
<option name="RECENT_TEMPLATES">
|
||||
<list>
|
||||
<option value="SCSS File" />
|
||||
<option value="TypeScript File" />
|
||||
<option value="TypeScript JSX File" />
|
||||
<option value="SCSS File" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
@@ -128,7 +114,7 @@
|
||||
<workItem from="1764590282382" duration="1201000" />
|
||||
<workItem from="1764591867512" duration="4332000" />
|
||||
<workItem from="1764657017067" duration="21490000" />
|
||||
<workItem from="1764741053553" duration="16724000" />
|
||||
<workItem from="1764741053553" duration="18011000" />
|
||||
</task>
|
||||
<servers />
|
||||
</component>
|
||||
|
||||
@@ -3,7 +3,7 @@ import { ReactNode } from 'react';
|
||||
import { Montserrat, Roboto } from 'next/font/google';
|
||||
import '@core/styles/globals.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';
|
||||
|
||||
const roboto = Roboto({
|
||||
@@ -35,6 +35,7 @@ export default function RootLayout({
|
||||
<main>{children}</main>
|
||||
<Footer />
|
||||
<MobileCallback />
|
||||
<ScrollToTop />
|
||||
</ModalProvider>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -342,6 +342,22 @@ const MobilePhone = (props: SVGProps<SVGSVGElement>) => (
|
||||
</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 {
|
||||
Map,
|
||||
Envelope,
|
||||
@@ -362,4 +378,5 @@ export {
|
||||
MapOutline,
|
||||
MobileContact,
|
||||
MobilePhone,
|
||||
Chevron,
|
||||
};
|
||||
|
||||
@@ -22,6 +22,7 @@ import {
|
||||
MapOutline,
|
||||
MobileContact,
|
||||
MobilePhone,
|
||||
Chevron,
|
||||
} from './base';
|
||||
|
||||
import {
|
||||
@@ -73,6 +74,7 @@ const Icons = Object.assign(
|
||||
MapOutline,
|
||||
MobileContact,
|
||||
MobilePhone,
|
||||
Chevron,
|
||||
},
|
||||
{
|
||||
GridBook,
|
||||
|
||||
@@ -3,3 +3,4 @@ export * from './footer';
|
||||
export * from './breadcrumbs';
|
||||
export * from './mobile-callback';
|
||||
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