From 583c028ab35654fad756b81389c7f893b461f062 Mon Sep 17 00:00:00 2001 From: jikwan Date: Mon, 24 Jul 2023 18:59:54 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20=ED=86=A0=EC=8A=A4=ED=8A=B8=20=EB=B2=84?= =?UTF-8?q?=EA=B7=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/toast/Toast.tsx | 51 ++++++------- src/components/toast/ToastContainer.tsx | 4 +- src/context/ToastContext.tsx | 76 ++++---------------- src/stories/toast/ToastContainer.stories.tsx | 50 +++++-------- 4 files changed, 56 insertions(+), 125 deletions(-) diff --git a/src/components/toast/Toast.tsx b/src/components/toast/Toast.tsx index 01f8561..9dadd88 100644 --- a/src/components/toast/Toast.tsx +++ b/src/components/toast/Toast.tsx @@ -8,8 +8,8 @@ import { useToastStore } from '../../context/ToastContext'; export type ColorType = 'GREEN' | 'RED' | 'YELLOW' | 'BLUE'; export interface ToastProps { - id?: number; - type?: ColorType; + id: string; + type: ColorType; title?: string; message: string; } @@ -20,54 +20,40 @@ export const Toast = ({ title, message = 'Message', }: ToastProps) => { - const [num, setNum] = useState(5); const [isOut, setIsOut] = useState(false); - const progress = Math.floor((num / 5) * 100); - useEffect(() => { - setTimeout(() => { - setNum((prev) => prev - 0.1); - }, 100); - }, [num]); + const { delete: del, list } = useToastStore(); useEffect(() => { setTimeout(() => { setIsOut(true); - }, 5000); + }, 4500); setTimeout(() => { - deleteToast(); + del(id); }, 5000); }, []); - const [list, del] = useToastStore((state) => [state.list, state.delete]); - - const deleteToast = async () => { - setIsOut(true); - setTimeout(() => { - del({ - id, - type: type as ColorType, - message, - }); - }, 500); + const deleteToast = async (id: string) => { + del(id); }; return ( - <_Wrapper isOut={isOut} type={type} message=""> + <_Wrapper id={id} isOut={isOut} type={type} message="">
{title} + {id} {message}
- + deleteToast(id)}> - + ); }; @@ -81,7 +67,7 @@ const _Wrapper = styled.div` margin-bottom: 20px; border-radius: 3px; z-index: 200; - background-color: ${({ type }) => BackGroundColor(type ?? 'GREEN')}; + background-color: ${({ type }) => BackGroundColor(type)}; opacity: 0.8; box-shadow: 0px 2px 10px rgba(0, 0, 0, 0.25); opacity: 0.8; @@ -111,14 +97,21 @@ const Delete = styled.div` right: 12px; `; -const Progress = styled.div<{ progress?: number }>` +const Progress = styled.div` position: absolute; bottom: 0; - width: ${(props) => props.progress + '%'}; height: 5px; background-color: #000000; opacity: 0.2; - transition: 0.2s; + animation: progressBar 5s linear; + @keyframes progressBar { + 0% { + width: 100%; + } + 100% { + width: 0%; + } + } `; const BackGroundColor = (type: ColorType) => { diff --git a/src/components/toast/ToastContainer.tsx b/src/components/toast/ToastContainer.tsx index b78cbcc..72bd4f4 100644 --- a/src/components/toast/ToastContainer.tsx +++ b/src/components/toast/ToastContainer.tsx @@ -9,7 +9,9 @@ export const ToastContainer = () => { <_Container> {toastState.map((list) => { const { title, id, type, message } = list; - return ; + return ( + id && + ); })} ); diff --git a/src/context/ToastContext.tsx b/src/context/ToastContext.tsx index 8272630..6769bba 100644 --- a/src/context/ToastContext.tsx +++ b/src/context/ToastContext.tsx @@ -1,8 +1,10 @@ +import { randomUUID } from 'crypto'; import { ColorType } from '../components/toast/Toast'; import { create } from 'zustand'; +import { v4 as uuidv4 } from 'uuid'; export interface ToastState { - id?: number; + id: string; title?: string; type: ColorType; message: string; @@ -11,8 +13,8 @@ export interface ToastState { interface BearState { list: ToastState[]; - append: (by: ToastState) => void; - delete: (by: ToastState) => void; + append: (by: Omit) => void; + delete: (id: string) => void; } export const useToastStore = create()((set) => ({ @@ -20,70 +22,20 @@ export const useToastStore = create()((set) => ({ append: (by) => set((state) => ({ list: state.list.concat({ - id: state.list.length + 1, + id: uuidv4(), title: by.title, message: by.message, type: by.type, }), })), - delete: (by) => + delete: (deleteId) => set((state) => ({ - list: state.list.filter((res) => res.id !== by.id), + list: state.list.map(({ id, title, type, message }) => { + if (deleteId === id) { + return { id: '', title: '', type: 'GREEN', message: '' }; + } else { + return { id, title: title, type: type, message: message }; + } + }), })), })); - -// interface ToastList { -// lists: ToastState[]; -// } - -// type ToastAction = { -// actionType: 'APPEND_TOAST' | 'DELETE_TOAST'; -// id?: number; -// toastType: ColorType; -// message: string; -// title?: string; -// time?: number; -// }; - -// const toastDefaultValue: ToastList = { -// lists: [], -// }; - -// export const toastStateContext = createContext(toastDefaultValue); - -// type ToastDispatch = Dispatch; - -// export const toastDispatchContext = createContext(() => null); - -// const toastReducer = (state: ToastList, action: ToastAction): ToastList => { -// switch (action.actionType) { -// case 'APPEND_TOAST': -// return { -// lists: state.lists.concat({ -// id: state.lists.length + 1, -// title: action.title, -// message: action.message, -// type: action.toastType, -// }), -// }; -// case 'DELETE_TOAST': -// return { -// lists: state.lists.filter((res) => res.id !== action.id), -// }; -// default: -// return state; -// } -// }; - -// export const ToastProvider: FunctionComponent<{ -// children: ReactNode; -// }> = ({ children }) => { -// const [toast, toastDispatch] = useReducer(toastReducer, toastDefaultValue); -// return ( -// -// -// {children} -// -// -// ); -// }; diff --git a/src/stories/toast/ToastContainer.stories.tsx b/src/stories/toast/ToastContainer.stories.tsx index 783c963..61102fe 100644 --- a/src/stories/toast/ToastContainer.stories.tsx +++ b/src/stories/toast/ToastContainer.stories.tsx @@ -17,39 +17,23 @@ const Template: ComponentStory = (args) => ( ); const Test = () => { - const [list, append] = useToastStore((state) => [state.list, state.append]); - useEffect(() => { - append({ - type: 'YELLOW', - message: '정보', - title: '안녕하세요', - }); - setTimeout( - () => - append({ - type: 'GREEN', - message: '성공', - }), - 1000 - ); - setTimeout( - () => - append({ - type: 'RED', - message: '에러', - }), - 2000 - ); - setTimeout( - () => - append({ - type: 'RED', - message: '에러', - }), - 8000 - ); - }, []); - return
; + const { append } = useToastStore(); + + return ( +
+ +
+ ); }; export const Default = Template.bind({});