Skip to content

Commit

Permalink
feat: add toast component (#38)
Browse files Browse the repository at this point in the history
* feat: add toast component

* refactor: update toast css

* fix: fix merge conflict

* fix: fix toast exit animation

timolins/react-hot-toast#165 (comment)

* fix: update toast position

* fix: fix translateY causing scrollbar

- width를 유연하게 조절하기 위해서 toast container의 position을 'sticky'로 설정하니까, translateY 애니메이션으로 인해 스크롤바가 잠시 표시되는 이슈 발생
- toast의 maxWidth를 최대 viewport width - 2 * marginX로 설정해서 임시 해결
  • Loading branch information
hee-suh authored Jul 4, 2024
1 parent e760fa2 commit c01943f
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 1 deletion.
25 changes: 24 additions & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"next": "14.2.3",
"react": "^18",
"react-dom": "^18",
"react-hot-toast": "^2.4.1",
"react-qrcode-logo": "^3.0.0",
"tailwind-merge": "^2.3.0"
},
Expand Down
2 changes: 2 additions & 0 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type { Metadata } from 'next'
import Script from 'next/script'

import './globals.css'
import { CustomToaster } from '@/components/common/custom-toast'
import { pretendard } from '@/styles/fonts'

export const metadata: Metadata = {
Expand All @@ -29,6 +30,7 @@ export default function RootLayout({
/>
<main className="relative w-full max-w-[420px] min-h-dvh">
{children}
<CustomToaster />
</main>
</body>
</html>
Expand Down
68 changes: 68 additions & 0 deletions src/components/common/custom-toast.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import toast, { Toaster, type ToastOptions } from 'react-hot-toast'
import Icon from './icon'
import Typography from './typography'

type ToastType = 'success' | 'error'

const toastCustom = ({
type,
message,
options,
}: {
type: ToastType
message: string
options?: ToastOptions
}) => {
toast.custom(
(t) => (
<div
className={`${t.visible ? 'animate-enter' : 'animate-leave'} bg-opacity-70 bg-[#212124] w-full max-w-[calc(420px-2*25px)] flex items-center justify-center gap-2 px-6 py-[14px] rounded-full leading-tight`}
>
{type === 'success' ? (
<Icon type="info" fill="profile-sky-blue" aria-hidden />
) : (
<Icon type="infoCircle" fill="orange-400" aria-hidden />
)}
<Typography size="h6" color="neutral-100">
{message}
</Typography>
</div>
),
options,
)
}

const notify = {
success: (message: string, options?: ToastOptions) =>
toastCustom({
type: 'success',
message,
options: { id: 'toast-success', ...options },
}),
error: (message: string, options?: ToastOptions) =>
toastCustom({
type: 'error',
message,
options: { id: 'toast-error', ...options },
}),
}

const CustomToaster = () => {
return (
<Toaster
position="bottom-center"
toastOptions={{
duration: 3000,
}}
containerStyle={{
top: 20,
left: 25,
bottom: 20,
right: 25,
position: 'fixed',
}}
/>
)
}

export { CustomToaster, notify }
23 changes: 23 additions & 0 deletions tailwind.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,29 @@ const config: Config = {
borderRadius: {
'3xl': '20px',
},
keyframes: {
enter: {
'0%': {
transform: 'translateY(20px)',
},
'100%': {
transform: 'translateY(0)',
},
},
leave: {
'0%': {
transform: 'translateY(0)',
},
'100%': {
transform: 'translateY(20px)',
opacity: '0',
},
},
},
animation: {
enter: 'enter 300ms ease-out',
leave: 'leave 300ms ease-in forwards',
},
},
},
plugins: [],
Expand Down

0 comments on commit c01943f

Please sign in to comment.