diff --git a/src/components/Modal/index.tsx b/src/components/Modal/index.tsx
index b74909b..e2129d5 100644
--- a/src/components/Modal/index.tsx
+++ b/src/components/Modal/index.tsx
@@ -3,11 +3,22 @@ import {createPortal} from 'react-dom';
import {TModalProps} from './types';
-const Modal = ({refItem, className, children}: TModalProps) => {
+const Modal = ({refItem, className, children, onClose}: TModalProps) => {
+ const handleClose = (e: React.MouseEvent) => {
+ e.stopPropagation();
+
+ if (refItem?.current?.contains(e.target as Node)) {
+ return;
+ }
+
+ onClose();
+ };
+
return (
<>
{createPortal(
;
- onClose: (refId: string) => void;
+ onClose: () => void;
className?: string;
}>;
diff --git a/src/components/inputs/Dropdown/index.tsx b/src/components/inputs/Dropdown/index.tsx
index 229dca5..209c3b5 100644
--- a/src/components/inputs/Dropdown/index.tsx
+++ b/src/components/inputs/Dropdown/index.tsx
@@ -19,7 +19,7 @@ const Dropdown = ({
}: TDropdownProps) => {
const [currentValue, setCurrentValue] = useState(selectedOption);
- const {ref, isOpen, handleClose, handleToggle} = useOpeningItem();
+ const {isOpen, handleClose, handleToggle} = useOpeningItem();
const activeOptionRef = useRef
(null);
const handleChange = useCallback(
@@ -29,9 +29,7 @@ const Dropdown = ({
setCurrentValue(option);
- setTimeout(() => {
- handleClose();
- }, 0);
+ handleClose();
},
[field, handleClose, onChange],
);
@@ -54,10 +52,10 @@ const Dropdown = ({
}, [isOpen, activeOptionRef]);
return (
-
+
{isOpen && (
-
- {options.map(option => (
- - handleChange(option)}>
- {option}
- {currentValue === option && }
-
- ))}
-
+ <>
+
{
+ e.stopPropagation();
+
+ handleClose();
+ }}
+ className="fixed w-full h-full inset-0 z-20"
+ />
+
+
+ {options.map(option => (
+ - handleChange(option)}>
+ {option}
+ {currentValue === option && }
+
+ ))}
+
+ >
)}
);
diff --git a/src/hooks/useBodyClick.ts b/src/hooks/useBodyClick.ts
deleted file mode 100644
index 5002a80..0000000
--- a/src/hooks/useBodyClick.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-import {useCallback, useEffect, useRef} from 'react';
-
-export const useBodyClick = ({
- refId,
- isOpen,
- onClick,
-}: {
- refId: string;
- isOpen: boolean;
- onClick: (refId: string) => void;
-}) => {
- const ref = useRef
(null);
-
- const onBodyClick = useCallback(
- (event: MouseEvent) => {
- if (ref.current?.contains(event.target as Node)) {
- return;
- }
-
- if (isOpen) {
- onClick(refId);
- }
- },
- [onClick, refId, isOpen],
- );
-
- useEffect(() => {
- const timeout = setTimeout(() => {
- document.body.addEventListener('click', onBodyClick);
- }, 0);
-
- return () => {
- clearTimeout(timeout);
- document.body.removeEventListener('click', onBodyClick);
- };
- }, [onBodyClick]);
-
- return {ref};
-};
diff --git a/src/hooks/useOpeningItem.ts b/src/hooks/useOpeningItem.ts
index 4338e7d..376f43a 100644
--- a/src/hooks/useOpeningItem.ts
+++ b/src/hooks/useOpeningItem.ts
@@ -1,24 +1,25 @@
-import {useCallback, useRef} from 'react';
+import {useCallback, useRef, useState} from 'react';
import {uid} from 'uid';
-import {useRegisteredItem} from '@/hooks/useRegisteredItem';
import {onCloseItem, onOpenItem} from '@/redux/overflow/overflowSlice';
import {useAppDispatch} from '@/redux/store';
-import {useBodyClick} from './useBodyClick';
-
export const useOpeningItem = () => {
const dispatch = useAppDispatch();
+ const ref = useRef(null);
const refId = useRef(uid()).current;
- const isOpen = useRegisteredItem({refId});
+
+ const [isOpen, setIsOpen] = useState(false);
const handleClose = useCallback(() => {
+ setIsOpen(false);
+
dispatch(onCloseItem(refId));
}, [dispatch, refId]);
- const {ref} = useBodyClick({refId, isOpen, onClick: handleClose});
-
const handleOpen = useCallback(() => {
+ setIsOpen(true);
+
dispatch(onOpenItem(refId));
}, [dispatch, refId]);
diff --git a/src/hooks/useRegisteredItem.tsx b/src/hooks/useRegisteredItem.tsx
deleted file mode 100644
index e971dd6..0000000
--- a/src/hooks/useRegisteredItem.tsx
+++ /dev/null
@@ -1,24 +0,0 @@
-import {useEffect} from 'react';
-import {useSelector} from 'react-redux';
-
-import {addItemToOpen, removeItemFromOpen} from '@/redux/overflow/overflowSlice';
-import {selectIsItemCurrentlyOpened} from '@/redux/overflow/selectors';
-import {useAppDispatch} from '@/redux/store';
-
-// TODO: investigate and optimize it
-export const useRegisteredItem = ({refId, defaultIsOpen}: {refId: string; defaultIsOpen?: boolean}) => {
- const defaultIsOpenValue = defaultIsOpen ?? false;
-
- const dispatch = useAppDispatch();
- const isOpen = useSelector(selectIsItemCurrentlyOpened(refId));
-
- useEffect(() => {
- dispatch(addItemToOpen({id: refId, isOpen: defaultIsOpenValue}));
-
- return () => {
- dispatch(removeItemFromOpen(refId));
- };
- }, [dispatch, refId, defaultIsOpenValue]);
-
- return isOpen;
-};
diff --git a/src/pages/Main/components/Calendar/Day/DayEventsList/Event/index.tsx b/src/pages/Main/components/Calendar/Day/DayEventsList/Event/index.tsx
index 4762914..9c47a32 100644
--- a/src/pages/Main/components/Calendar/Day/DayEventsList/Event/index.tsx
+++ b/src/pages/Main/components/Calendar/Day/DayEventsList/Event/index.tsx
@@ -1,3 +1,5 @@
+import {memo} from 'react';
+
import EventForm from '@/components/EventForm';
import {FormActionType} from '@/components/EventForm/types';
import Modal from '@/components/Modal';
@@ -38,4 +40,4 @@ const Event = ({event, eventRef}: TEventProps) => {
);
};
-export default Event;
+export default memo(Event);
diff --git a/src/redux/overflow/overflowSlice.ts b/src/redux/overflow/overflowSlice.ts
index 4995ef6..bcbdbc4 100644
--- a/src/redux/overflow/overflowSlice.ts
+++ b/src/redux/overflow/overflowSlice.ts
@@ -1,45 +1,23 @@
import {PayloadAction, createSlice} from '@reduxjs/toolkit';
import {SliceNames} from '../types';
-import {TOpeningItem, TOverflowState} from './types';
-import {toggleOverflowItem} from './utils';
+import {TOverflowState} from './types';
const reducers = {
onOpenItem: (state: TOverflowState, action: PayloadAction) => {
const {payload} = action;
state.currentlyOpened.push(payload);
- state.itemsToOpen = toggleOverflowItem(state.itemsToOpen, payload, true);
},
onCloseItem: (state: TOverflowState, action: PayloadAction) => {
const {payload} = action;
state.currentlyOpened = state.currentlyOpened.filter(item => item !== payload);
- state.itemsToOpen = toggleOverflowItem(state.itemsToOpen, payload, false);
- },
- addItemToOpen: (state: TOverflowState, action: PayloadAction) => {
- const {payload} = action;
-
- const newItem = {
- id: payload.id,
- isOpen: payload.isOpen,
- };
-
- if (payload && !state.itemsToOpen.some(item => item.id === payload.id)) {
- state.itemsToOpen.push(newItem);
- }
- },
- removeItemFromOpen: (state: TOverflowState, action: PayloadAction) => {
- const {payload} = action;
-
- state.currentlyOpened = state.currentlyOpened.filter(item => item !== payload);
- state.itemsToOpen = state.itemsToOpen.filter(item => item.id !== payload);
},
};
const initialState: TOverflowState = {
currentlyOpened: [],
- itemsToOpen: [],
};
const overflowSlice = createSlice({
@@ -48,5 +26,5 @@ const overflowSlice = createSlice({
reducers,
});
-export const {addItemToOpen, removeItemFromOpen, onOpenItem, onCloseItem} = overflowSlice.actions;
+export const {onOpenItem, onCloseItem} = overflowSlice.actions;
export default overflowSlice;
diff --git a/src/redux/overflow/types.ts b/src/redux/overflow/types.ts
index 4df64b3..35a311a 100644
--- a/src/redux/overflow/types.ts
+++ b/src/redux/overflow/types.ts
@@ -1,9 +1,3 @@
-export type TOpeningItem = {
- id: string;
- isOpen: boolean;
-};
-
export type TOverflowState = {
currentlyOpened: string[];
- itemsToOpen: TOpeningItem[];
};
diff --git a/src/redux/overflow/utils.ts b/src/redux/overflow/utils.ts
deleted file mode 100644
index 02b00ca..0000000
--- a/src/redux/overflow/utils.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-import {TOpeningItem} from './types';
-
-export const toggleOverflowItem = (items: TOpeningItem[], payload: string, isOpen: boolean) => {
- return items.map(item => {
- if (item.id === payload) {
- return {
- ...item,
- isOpen,
- };
- }
-
- return item;
- });
-};