Skip to content

Commit

Permalink
feat: add scroll to toolbar and useRouteChange
Browse files Browse the repository at this point in the history
  • Loading branch information
TomatoVan committed Apr 27, 2024
1 parent aaddfb4 commit ee7f820
Show file tree
Hide file tree
Showing 11 changed files with 116 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/app/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@ import { useTheme } from '@/shared/lib/hook/useTheme/useTheme';
import { useAppDispatch } from '@/shared/lib/hook/useAppDispatch/useAppDispatch';
import { MainLayout } from '@/shared/layouts/MainLayout';
import { AppLoaderLayout } from '@/shared/layouts/AppLoaderLayout';
import { useAppToolbar } from './lib/useAppToolbar';

function App() {
const { theme } = useTheme();
const dispatch = useAppDispatch();
const inited = useSelector(getUserInited);
const toolbar = useAppToolbar();

useEffect(() => {
dispatch(initAuthData());
Expand All @@ -35,6 +37,7 @@ function App() {
header={<Navbar />}
content={<AppRouter />}
sidebar={<Sidebar />}
toolbar={toolbar}
/>
</Suspense>
</div>
Expand Down
15 changes: 15 additions & 0 deletions src/app/lib/useAppToolbar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { ReactElement } from 'react';
import { AppRoutes } from '@/shared/const/router';
import { ScrollToolbar } from '@/widgets/ScrollToolbar';
import { useRouteChange } from '@/shared/lib/router/useRouteChange';

export function useAppToolbar() {
const appRoute = useRouteChange();

const toolbarByAppRoute: OptionalRecord<AppRoutes, ReactElement> = {
[AppRoutes.ARTICLES]: <ScrollToolbar />,
[AppRoutes.ARTICLE_DETAILS]: <ScrollToolbar />,
};

return toolbarByAppRoute[appRoute];
}
1 change: 1 addition & 0 deletions src/features/scrollToTopButton/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { ScrollToTopButton } from './ui/ScrollToTopButton/ScrollToTopButton';
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { memo } from 'react';
import { classNames } from '@/shared/lib/classNames/classNames';
import { Icon } from '@/shared/ui/redesigned/Icon';
import CircleIcon from '@/shared/assets/icons/circle-up.svg';

interface ScrollToTopButtonProps {
className?: string;
}

export const ScrollToTopButton = memo((props: ScrollToTopButtonProps) => {
const { className } = props;

const onCLick = () => {
window.scrollTo({ top: 0, behavior: 'smooth' });
};

return (
<Icon
Svg={CircleIcon}
clickable
onClick={onCLick}
width={32}
height={32}
className={classNames('', {}, [className])}
/>
);
});
10 changes: 10 additions & 0 deletions src/shared/assets/icons/circle-up.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions src/shared/const/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,16 @@ export const getRouteArticleEdit = (id: string) => `/articles/${id}/edit`;
export const getRouteAdminPanel = () => '/admin';
export const getRouteForbidden = () => '/forbidden';
export const getRouteNotFound = () => '*';

export const AppRouteByPathPattern: Record<string, AppRoutes> = {
[getRouteMain()]: AppRoutes.MAIN,
[getRouteSettings()]: AppRoutes.SETTINGS,
[getRouteAbout()]: AppRoutes.ABOUT,
[getRouteProfile(':id')]: AppRoutes.PROFILE,
[getRouteArticles()]: AppRoutes.ARTICLES,
[getRouteArticleDetails(':id')]: AppRoutes.ARTICLE_DETAILS,
[getRouteArticleCreate()]: AppRoutes.ARTICLE_CREATE,
[getRouteArticleEdit(':id')]: AppRoutes.ARTICLE_EDIT,
[getRouteAdminPanel()]: AppRoutes.ADMIN_PANEL,
[getRouteForbidden()]: AppRoutes.FORBIDDEN,
};
1 change: 1 addition & 0 deletions src/shared/layouts/MainLayout/MainLayout.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,5 @@

.toolbar {
height: 100%;
width: 100%;
}
18 changes: 18 additions & 0 deletions src/shared/lib/router/useRouteChange.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { matchPath, useLocation } from 'react-router-dom';
import { useEffect, useState } from 'react';
import { AppRouteByPathPattern, AppRoutes } from '@/shared/const/router';

export function useRouteChange() {
const location = useLocation();
const [appRoute, setAppRoute] = useState<AppRoutes>(AppRoutes.MAIN);

useEffect(() => {
Object.entries(AppRouteByPathPattern).forEach(([pattern, route]) => {
if (matchPath(pattern, location.pathname)) {
setAppRoute(route);
}
});
}, [location.pathname]);

return appRoute;
}
1 change: 1 addition & 0 deletions src/widgets/ScrollToolbar/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { ScrollToolbar } from './ui/ScrollToolbar/ScrollToolbar';
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.ScrollToolbar {
height: 100%;
}
24 changes: 24 additions & 0 deletions src/widgets/ScrollToolbar/ui/ScrollToolbar/ScrollToolbar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { memo } from 'react';
import { classNames } from '@/shared/lib/classNames/classNames';
import cls from './ScrollToolbar.module.scss';
import { VStack } from '@/shared/ui/redesigned/Stack';
import { ScrollToTopButton } from '@/features/scrollToTopButton';

interface ScrollToolbarProps {
className?: string;
}

export const ScrollToolbar = memo((props: ScrollToolbarProps) => {
const { className } = props;

return (
<VStack
justify="center"
align="center"
max
className={classNames(cls.ScrollToolbar, {}, [className])}
>
<ScrollToTopButton />
</VStack>
);
});

0 comments on commit ee7f820

Please sign in to comment.