Skip to content

Commit

Permalink
add drawer + device detected
Browse files Browse the repository at this point in the history
  • Loading branch information
Bender101 committed Nov 1, 2023
1 parent 03c8a5f commit bff9c6c
Show file tree
Hide file tree
Showing 11 changed files with 227 additions and 33 deletions.
48 changes: 48 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@
"i18next-browser-languagedetector": "^6.1.3",
"i18next-http-backend": "^1.3.2",
"react": "^18.2.0",
"react-device-detect": "^2.2.3",
"react-dom": "^18.2.0",
"react-i18next": "^11.18.3",
"react-redux": "^7.2.6",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,30 +1,53 @@
import { classNames } from 'shared/lib/classNames/classNames';
import React, { memo } from 'react';
import { Button, ButtonTheme } from 'shared/ui/Button/Button';
import { Icon } from 'shared/ui/Icon/Icon';
import NotificationIcon from 'shared/assets/icons/notification-20-20.svg';
import { NotificationList } from 'entities/Notification';
import { Popover } from 'shared/ui/Popups';
import cls from './NotificationButton.module.scss';
import { classNames } from "shared/lib/classNames/classNames";
import React, { memo, useCallback, useState } from "react";
import { Button, ButtonTheme } from "shared/ui/Button/Button";
import { Icon } from "shared/ui/Icon/Icon";
import NotificationIcon from "shared/assets/icons/notification-20-20.svg";
import { NotificationList } from "entities/Notification";
import { Popover } from "shared/ui/Popups";
import { Drawer } from "shared/ui/Drawer/Drawer";
import { BrowserView, MobileView } from "react-device-detect";
import cls from "./NotificationButton.module.scss";

interface NotificationButtonProps {
className?: string;
className?: string;
}

export const NotificationButton = memo((props: NotificationButtonProps) => {
const { className } = props;
const { className } = props;
const [isOpen, setIsOpen] = useState(false);

return (
const onOpenDrawer = useCallback(() => {
setIsOpen(true);
}, []);

const onCloseDrawer = useCallback(() => {
setIsOpen(false);
}, []);

const trigger = (
<Button onClick={onOpenDrawer} theme={ButtonTheme.CLEAR}>
<Icon Svg={NotificationIcon} inverted />
</Button>
);

return (
<div>
<BrowserView>
<Popover
className={classNames(cls.NotificationButton, {}, [className])}
direction="bottom left"
trigger={(
<Button theme={ButtonTheme.CLEAR}>
<Icon Svg={NotificationIcon} inverted />
</Button>
)}
className={classNames(cls.NotificationButton, {}, [className])}
direction="bottom left"
trigger={trigger}
>
<NotificationList className={cls.notifications} />
<NotificationList className={cls.notifications} />
</Popover>
);
</BrowserView>
<MobileView>
{trigger}
<Drawer isOpen={isOpen} onClose={onCloseDrawer}>
<NotificationList />
</Drawer>
</MobileView>
</div>
);
});
51 changes: 51 additions & 0 deletions src/shared/ui/Drawer/Drawer.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
.Drawer {
position: fixed;
top: 0;
bottom: 0;
right: 0;
left: 0;
opacity: 0;
pointer-events: none;
z-index: -1;
display: flex;
align-items: flex-end;
}

.content {
height: 70%;
background: var(--bg-color);
bottom: 0;
border-top-left-radius: 12px;
border-top-right-radius: 12px;
position: relative;
width: 100%;
min-height: 100px;
padding: 20px;
transition: 0.3s transform;
transform: translateY(100%);
overflow-y: auto;
overflow-x: hidden;
z-index: 10000;
}

.content::before {
content: "";
position: relative;
display: block;
width: 100px;
height: 10px;
background: var(--bg-color);
margin: auto;
bottom: 40px;
border-radius: 12px;
}

.opened {
pointer-events: auto;
opacity: 1;
z-index: var(--modal-z-index);

.content {
transform: translateY(0%);
}
}
40 changes: 40 additions & 0 deletions src/shared/ui/Drawer/Drawer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { classNames, Mods } from 'shared/lib/classNames/classNames';
import React, { memo, ReactNode } from 'react';
import { useTheme } from 'app/providers/ThemeProvider';
import { Overlay } from '../Overlay/Overlay';
import cls from './Drawer.module.scss';
import { Portal } from '../Portal/Portal';

interface DrawerProps {
className?: string;
children: ReactNode;
isOpen?: boolean;
onClose?: () => void;
}

export const Drawer = memo((props: DrawerProps) => {
const {
className,
children,
onClose,
isOpen,
} = props;
const { theme } = useTheme();

const mods: Mods = {
[cls.opened]: isOpen,
};

return (
<Portal>
<div className={classNames(cls.Drawer, mods, [className, theme, 'app_drawer'])}>
<Overlay onClick={onClose} />
<div
className={cls.content}
>
{children}
</div>
</div>
</Portal>
);
});
3 changes: 3 additions & 0 deletions src/shared/ui/Modal/Modal.module.scss
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
.Modal {
position: fixed;
display: flex;
justify-content: center;
align-items: center;
top: 0;
bottom: 0;
right: 0;
Expand Down
13 changes: 7 additions & 6 deletions src/shared/ui/Modal/Modal.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import {classNames, Mods} from "shared/lib/classNames/classNames";
import { classNames, Mods } from "shared/lib/classNames/classNames";
import {
ReactNode,
useCallback,
useEffect,
useRef,
useState,
MouseEvent, MutableRefObject,
MouseEvent,
MutableRefObject,
} from "react";
import { Portal } from "../Portal/Portal";
import { useTheme } from "app/providers/ThemeProvider";
import cls from "./Modal.module.scss";
import { Overlay } from "../Overlay/Overlay";

interface ModalProps {
className?: string;
Expand Down Expand Up @@ -84,10 +86,9 @@ export const Modal = (props: ModalProps) => {
<div
className={classNames(cls.Modal, mods, [className, theme, "app_modal"])}
>
<div className={cls.overlay} onClick={closeHandler}>
<div className={cls.content} onClick={onContentClick}>
{children}
</div>
<Overlay onClick={closeHandler} />
<div className={cls.content} onClick={onContentClick}>
{children}
</div>
</div>
</Portal>
Expand Down
13 changes: 13 additions & 0 deletions src/shared/ui/Overlay/Overlay.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
.Overlay {
background: var(--overlay-color);
display: flex;
align-items: center;
justify-content: center;
position: fixed;
top: 0;
bottom: 0;
right: 0;
left: 0;
z-index: -1;
cursor: pointer;
}
16 changes: 16 additions & 0 deletions src/shared/ui/Overlay/Overlay.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { classNames } from 'shared/lib/classNames/classNames';
import { memo } from 'react';
import cls from './Overlay.module.scss';

interface OverlayProps {
className?: string;
onClick?: () => void;
}

export const Overlay = memo((props: OverlayProps) => {
const { className, onClick } = props;

return (
<div onClick={onClick} className={classNames(cls.Overlay, {}, [className])} />
);
});
10 changes: 4 additions & 6 deletions src/shared/ui/Stack/VStack/VStack.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import { Flex, FlexProps } from '../Flex/Flex';
import { Flex, FlexProps } from "../Flex/Flex";

type VStackProps = Omit<FlexProps, 'direction'>
type VStackProps = Omit<FlexProps, "direction">;

export const VStack = (props: VStackProps) => {
const { align = 'start' } = props;
return (
<Flex {...props} direction="column" align={align} />
);
const { align = "start" } = props;
return <Flex {...props} direction="column" align={align} />;
};
2 changes: 1 addition & 1 deletion src/widgets/SideBar/ui/SideBar/SideBar.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
position: absolute;
right: -32px;
bottom: 32px;
z-index: 100000;
z-index: 10;
}

.switchers {
Expand Down

0 comments on commit bff9c6c

Please sign in to comment.