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
50 changes: 50 additions & 0 deletions components/SnackBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
interface SnackBarProps {
state: 'fail' | 'success' | 'info' | 'null';
}

// state props styles object
const stateConfig = {
fail: {
style:
'bg-red-50 border-red-100 fixed left-1/2 transform -translate-x-1/2 top-[120px] mx-auto mo:bottom-[80px] mo:top-auto w-[384px] mo:w-[328px] whitespace-nowrap',
text: '다른 친구가 편집하고 있어요. 나중에 다시 시도해 주세요.',
icon: '/icon/icon-fail.svg',
textStyle: 'text-red-100 text-14sb mo:text-12sb',
},
success: {
style:
'bg-green-100 border-green-200 fixed left-1/2 transform -translate-x-1/2 top-[120px] mx-auto mo:bottom-[80px] mo:top-auto w-[247px] mo:w-[210px] whitespace-nowrap',
text: '내 위키 링크가 복사되었습니다.',
icon: '/icon/icon-success.svg',
textStyle: 'text-green-300 text-14sb mo:text-12sb',
},
info: {
style: 'bg-background border-white',
text: '앞 사람의 편집이 끝나면 위키 참여가 가능합니다.',
icon: '/icon/icon-info.svg',
textStyle: 'text-gray-500 text-14 mo:text-12',
},
null: {
style: 'hidden',
text: '',
icon: '',
textStyle: '',
},
};

/**
* SnackBar 컴포넌트
* @param {SnackBarProps} { state } - state: 'fail' | 'success' | 'info' | 'null'
*/
export default function SnackBar({ state }: SnackBarProps) {
const { style, text, icon, textStyle } = stateConfig[state];

return (
<div
className={`rounded-custom ${style} animate-fadeIn flex items-center gap-[15px] border px-5 py-[11px] shadow-custom mo:px-[15px] mo:py-[11px]`}
>
{icon && <img src={icon} alt="snackbar icon" className="h-5 w-5" />}
<p className={`${textStyle} break-words mo:break-words`}>{text}</p>
</div>
);
}
30 changes: 29 additions & 1 deletion pages/test/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,29 @@
import { useState } from 'react';

import Button from '@/components/Button';
import LinkBar from '@/components/LinkBar';
import SnackBar from '@/components/SnackBar';

export default function Test() {
const commonCellClass = 'border-r border-gray-300';
const commonRowClass = 'flex flex-wrap items-end gap-2';

// ----snackBar(start)----
const [snackState, setSnackState] = useState<
'fail' | 'success' | 'info' | 'null'
>('null');

const handleSuccess = () => {
setSnackState('success');
setTimeout(() => setSnackState('null'), 1500);
};

const handleFail = () => {
setSnackState('fail');
setTimeout(() => setSnackState('null'), 1500);
};
// ----snackBar(end)----

return (
<div className="px-4 py-10">
<table className="w-full border-collapse border border-gray-300">
Expand Down Expand Up @@ -33,7 +52,16 @@ export default function Test() {
</Button>
</td>
</tr>
<tr>
<tr className="border-b border-gray-300">
<td className={commonCellClass}>SnackBar</td>
<td className={commonRowClass}>
<SnackBar state="info" />
<Button onClick={handleSuccess}>복사</Button>
<Button onClick={handleFail}>에러</Button>
{snackState !== 'null' && <SnackBar state={snackState} />}
</td>
</tr>
<tr className="border-b border-gray-300">
<td className={commonCellClass}>LinkBar</td>
<td className={commonRowClass}>
<LinkBar link="https://www.google.com" />
Expand Down
3 changes: 3 additions & 0 deletions public/icon/icon-fail.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions public/icon/icon-info.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions public/icon/icon-success.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading