4๊ฐ์ง ์ผ์ด์ค
- First-time: ์ ๊ท ์ฌ์ฉ์๊ฐ ์ฒ์ ๋ค์ด์์ ๋ ๋ณด์ฌ์ค์. ๊ฐ์ด๋ ์นด๋์ ์ฒซ ์ก์
CTA๋ก ๊ตฌ์ฑํฉ๋๋ค.
- No-results: ๊ฒ์์ด๋ ํํฐ ๊ฒฐ๊ณผ๊ฐ 0๊ฑด์ผ ๋ ๋์๋๋ค. ๊ฒ์์ด ๋ณ๊ฒฝ์ด๋ ํํฐ ์ด๊ธฐํ๋ฅผ ์ ์ํด์.
- No-permission: ๊ถํ์ด ์์ ๋ ๋ณด์ฌ์ค๋๋ค. ๊ถํ ์์ฒญ์ด๋ ๋ค๋ฅธ ํ๋ฉด ์ด๋์ ์ ์ํด์.
- Error-recovery: ๋ฐ์ดํฐ ๋ก๋์ ์คํจํ์ ๋ ๋์์. '๋ค์ ์๋' ๋ฒํผ๊ณผ ์ง์ ์ฑ๋ ๋งํฌ๋ฅผ ํจ๊ป ๋ก๋๋ค.
์ฌ์ฌ์ฉ ์ปดํฌ๋ํธ ๊ณจ๊ฒฉ
type EmptyStateProps = {
icon: LucideIcon
title: string
description?: string
action?: React.ReactNode
}
export function EmptyState({ icon: Icon, title, description, action }: EmptyStateProps) {
return (
<div role="status" aria-live="polite" className="flex flex-col items-center gap-3 py-16 text-center">
<Icon className="h-14 w-14 text-muted-foreground/60" />
<p className="text-base font-semibold">{title}</p>
{description && <p className="text-sm text-muted-foreground">{description}</p>}
{action && <div className="mt-2">{action}</div>}
</div>
)
}