Skip to content

Commit

Permalink
fix: 토스트 버그 수정
Browse files Browse the repository at this point in the history
  • Loading branch information
jikwan0327 committed Jul 24, 2023
1 parent c83d9f0 commit 583c028
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 125 deletions.
51 changes: 22 additions & 29 deletions src/components/toast/Toast.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -20,54 +20,40 @@ export const Toast = ({
title,
message = 'Message',
}: ToastProps) => {
const [num, setNum] = useState<number>(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="">
<div style={{ padding: 17 }}>
<Icon icon={IconName(type)} size={38} color="gray10" />
</div>
<div>
<Text color="gray10" size="Heading6">
{title}
{id}
</Text>
<Text color="gray10" size="Body2">
{message}
</Text>
</div>
<Delete onClick={deleteToast}>
<Delete onClick={() => deleteToast(id)}>
<Icon cursor="pointer" icon="Close" size={24} color="gray10" />
</Delete>
<Progress progress={progress}></Progress>
<Progress />
</_Wrapper>
);
};
Expand All @@ -81,7 +67,7 @@ const _Wrapper = styled.div<ToastProps & { isOut: boolean }>`
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;
Expand Down Expand Up @@ -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) => {
Expand Down
4 changes: 3 additions & 1 deletion src/components/toast/ToastContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ export const ToastContainer = () => {
<_Container>
{toastState.map((list) => {
const { title, id, type, message } = list;
return <Toast id={id} type={type} title={title} message={message} />;
return (
id && <Toast id={id} type={type} title={title} message={message} />
);
})}
</_Container>
);
Expand Down
76 changes: 14 additions & 62 deletions src/context/ToastContext.tsx
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -11,79 +13,29 @@ export interface ToastState {

interface BearState {
list: ToastState[];
append: (by: ToastState) => void;
delete: (by: ToastState) => void;
append: (by: Omit<ToastState, 'id'>) => void;
delete: (id: string) => void;
}

export const useToastStore = create<BearState>()((set) => ({
list: [],
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<ToastAction>;

// export const toastDispatchContext = createContext<ToastDispatch>(() => 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 (
// <toastStateContext.Provider value={toast}>
// <toastDispatchContext.Provider value={toastDispatch}>
// {children}
// </toastDispatchContext.Provider>
// </toastStateContext.Provider>
// );
// };
50 changes: 17 additions & 33 deletions src/stories/toast/ToastContainer.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,39 +17,23 @@ const Template: ComponentStory<typeof ToastContainer> = (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 <div></div>;
const { append } = useToastStore();

return (
<div>
<button
onClick={() => {
append({
type: 'YELLOW',
message: '정보',
title: '안녕하세요',
});
}}
>
정지관
</button>
</div>
);
};

export const Default = Template.bind({});
Expand Down

0 comments on commit 583c028

Please sign in to comment.