Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion src/components/Modal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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(
<div
onClick={handleClose}
className={cn(
'fixed top-0 left-0 w-screen h-screen flex items-center justify-center bg-secondaryBackgroundColor bg-opacity-80 z-20',
className,
Expand Down
2 changes: 1 addition & 1 deletion src/components/Modal/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ import {PropsWithChildren, RefObject} from 'react';

export type TModalProps = PropsWithChildren<{
refItem: RefObject<HTMLDivElement>;
onClose: (refId: string) => void;
onClose: () => void;
className?: string;
}>;
55 changes: 32 additions & 23 deletions src/components/inputs/Dropdown/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<HTMLLIElement>(null);

const handleChange = useCallback(
Expand All @@ -29,9 +29,7 @@ const Dropdown = ({

setCurrentValue(option);

setTimeout(() => {
handleClose();
}, 0);
handleClose();
},
[field, handleClose, onChange],
);
Expand All @@ -54,10 +52,10 @@ const Dropdown = ({
}, [isOpen, activeOptionRef]);

return (
<div ref={ref} className={cn('w-full relative', className)}>
<div className={cn('w-full relative', className)}>
<Button
className={twMerge(
cn('py-2 w-full h-full text-left border-secondaryBackgroundColor', {
cn('py-2 w-full h-full text-left border-secondaryBackgroundColor z-30', {
'border-sky-500 text-sky-500': isOpen,
}),
)}
Expand All @@ -75,23 +73,34 @@ const Dropdown = ({
/>

{isOpen && (
<ul className="absolute z-10 mt-1 w-full bg-mainBackgroundColor border border-secondaryBackgroundColor shadow-lg max-h-[220px] rounded-md text-sm ring-opacity-5 overflow-auto focus:outline-none">
{options.map(option => (
<li
ref={currentValue === option ? activeOptionRef : null}
key={option}
className={cn(
{
'bg-secondaryBackgroundColor': currentValue === option,
},
'transition-all flex items-center justify-between gap-1 cursor-pointer text-white select-none relative py-2 px-3 hover:bg-secondaryBackgroundColor',
)}
onClick={() => handleChange(option)}>
<span className="font-normal block truncate">{option}</span>
{currentValue === option && <CheckIcon size="size-3" />}
</li>
))}
</ul>
<>
<div
onClick={e => {
e.stopPropagation();

handleClose();
}}
className="fixed w-full h-full inset-0 z-20"
/>

<ul className="absolute mt-1 w-full bg-mainBackgroundColor border border-secondaryBackgroundColor shadow-lg max-h-[220px] rounded-md text-sm ring-opacity-5 overflow-auto focus:outline-none z-30">
{options.map(option => (
<li
ref={currentValue === option ? activeOptionRef : null}
key={option}
className={cn(
{
'bg-secondaryBackgroundColor': currentValue === option,
},
'transition-all flex items-center justify-between gap-1 cursor-pointer text-white select-none relative py-2 px-3 hover:bg-secondaryBackgroundColor',
)}
onClick={() => handleChange(option)}>
<span className="font-normal block truncate">{option}</span>
{currentValue === option && <CheckIcon size="size-3" />}
</li>
))}
</ul>
</>
)}
</div>
);
Expand Down
39 changes: 0 additions & 39 deletions src/hooks/useBodyClick.ts

This file was deleted.

15 changes: 8 additions & 7 deletions src/hooks/useOpeningItem.ts
Original file line number Diff line number Diff line change
@@ -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<HTMLDivElement>(null);
const refId = useRef<string>(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]);

Expand Down
24 changes: 0 additions & 24 deletions src/hooks/useRegisteredItem.tsx

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import {memo} from 'react';

import EventForm from '@/components/EventForm';
import {FormActionType} from '@/components/EventForm/types';
import Modal from '@/components/Modal';
Expand Down Expand Up @@ -38,4 +40,4 @@ const Event = ({event, eventRef}: TEventProps) => {
);
};

export default Event;
export default memo(Event);
26 changes: 2 additions & 24 deletions src/redux/overflow/overflowSlice.ts
Original file line number Diff line number Diff line change
@@ -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<string>) => {
const {payload} = action;

state.currentlyOpened.push(payload);
state.itemsToOpen = toggleOverflowItem(state.itemsToOpen, payload, true);
},
onCloseItem: (state: TOverflowState, action: PayloadAction<string>) => {
const {payload} = action;

state.currentlyOpened = state.currentlyOpened.filter(item => item !== payload);
state.itemsToOpen = toggleOverflowItem(state.itemsToOpen, payload, false);
},
addItemToOpen: (state: TOverflowState, action: PayloadAction<TOpeningItem>) => {
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<string | null>) => {
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({
Expand All @@ -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;
6 changes: 0 additions & 6 deletions src/redux/overflow/types.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
export type TOpeningItem = {
id: string;
isOpen: boolean;
};

export type TOverflowState = {
currentlyOpened: string[];
itemsToOpen: TOpeningItem[];
};
14 changes: 0 additions & 14 deletions src/redux/overflow/utils.ts

This file was deleted.