Thoughtful fallback states for the quiet parts of an app. Tailor the message and next action to the situation.
No projects
A dashed empty frame with an icon, title, and create or import actions.
tsx
"use client";import { Button } from "@/components/ui/button";import { Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle,} from "@/components/ui/empty";import { cn } from "@/lib/utils";type EmptyStates01Props = { className?: string;};function FolderIcon({ className }: { className?: string }) { return ( <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true" className={className} > <path d="M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z" /> <path d="M12 10v6" /> <path d="M9 13h6" /> </svg> );}export function EmptyStates01({ className }: EmptyStates01Props) { return ( <section className={cn("@container w-full bg-background", className)}> <div className="mx-auto flex w-full max-w-3xl items-center justify-center px-4 py-10 @[32rem]:px-6 @[32rem]:py-14"> <Empty className="w-full border border-dashed border-border"> <EmptyHeader> <EmptyMedia variant="icon"> <FolderIcon /> </EmptyMedia> <EmptyTitle>No projects yet</EmptyTitle> <EmptyDescription> Create your first project to start shipping blocks and pages. </EmptyDescription> </EmptyHeader> <EmptyContent> <div className="flex flex-wrap items-center justify-center gap-2"> <Button type="button" size="sm"> Create project </Button> <Button type="button" size="sm" variant="secondary"> Import </Button> </div> </EmptyContent> </Empty> </div> </section> );}Installation
npx @arctis-sh/@arctis-sh/ui@latest add empty-states-01Usage
import { EmptyStates01 } from "@/components/blocks/empty-states/empty-states-01"<EmptyStates01 />No results
A no-results state with a direct way to clear the search.
tsx
"use client";import { Button } from "@/components/ui/button";import { Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle,} from "@/components/ui/empty";import { cn } from "@/lib/utils";type EmptyStates02Props = { className?: string;};function SearchIcon({ className }: { className?: string }) { return ( <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true" className={className} > <circle cx="11" cy="11" r="7" /> <path d="m20 20-3.5-3.5" /> </svg> );}export function EmptyStates02({ className }: EmptyStates02Props) { return ( <section className={cn("@container w-full bg-background", className)}> <div className="mx-auto flex w-full max-w-3xl items-center justify-center px-4 py-10 @[32rem]:px-6 @[32rem]:py-14"> <Empty className="w-full"> <EmptyHeader> <EmptyMedia variant="icon"> <SearchIcon /> </EmptyMedia> <EmptyTitle>No results found</EmptyTitle> <EmptyDescription> Nothing matched your search. Try a different keyword or clear filters. </EmptyDescription> </EmptyHeader> <EmptyContent> <Button type="button" size="sm" variant="outline"> Clear search </Button> </EmptyContent> </Empty> </div> </section> );}Installation
npx @arctis-sh/@arctis-sh/ui@latest add empty-states-02Usage
import { EmptyStates02 } from "@/components/blocks/empty-states/empty-states-02"<EmptyStates02 />Error
A filled error state with retry and home actions.
tsx
"use client";import { Button } from "@/components/ui/button";import { Empty, EmptyContent, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle,} from "@/components/ui/empty";import { cn } from "@/lib/utils";type EmptyStates03Props = { className?: string;};function AlertIcon({ className }: { className?: string }) { return ( <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true" className={className} > <path d="M12 9v4" /> <path d="M12 17h.01" /> <path d="M10.3 3.9 1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0Z" /> </svg> );}export function EmptyStates03({ className }: EmptyStates03Props) { return ( <section className={cn("@container w-full bg-background", className)}> <div className="mx-auto w-full max-w-3xl px-4 py-10 @[32rem]:px-6 @[32rem]:py-14"> <Empty className="w-full rounded-xl bg-muted"> <EmptyHeader> <EmptyMedia variant="icon" className="bg-transparent text-destructive"> <AlertIcon /> </EmptyMedia> <EmptyTitle>Couldn’t load this page</EmptyTitle> <EmptyDescription> Something went wrong on our side. Retry in a moment or come back later. </EmptyDescription> </EmptyHeader> <EmptyContent> <div className="flex flex-wrap items-center justify-center gap-2"> <Button type="button" size="sm"> Try again </Button> <Button type="button" size="sm" variant="ghost"> Go home </Button> </div> </EmptyContent> </Empty> </div> </section> );}Installation
npx @arctis-sh/@arctis-sh/ui@latest add empty-states-03Usage
import { EmptyStates03 } from "@/components/blocks/empty-states/empty-states-03"<EmptyStates03 />