Zaidan

Command Palette

Search for a command to run...

GitHub43

Empty

Use the Empty component to display an empty state.

Installation

CLI

Manual

Copy and paste the following code into your project.

import { cva, type VariantProps } from "class-variance-authority";
import type { ComponentProps } from "solid-js";
import { splitProps } from "solid-js";
import { cn } from "~/lib/utils";
type EmptyProps = ComponentProps<"div">;
const Empty = (props: EmptyProps) => {
const [local, others] = splitProps(props, ["class"]);
return (
<div
data-slot="empty"
class={cn(
"z-empty flex w-full min-w-0 flex-1 flex-col items-center justify-center text-balance text-center",
local.class,
)}
{...others}
/>
);
};
type EmptyHeaderProps = ComponentProps<"div">;
const EmptyHeader = (props: EmptyHeaderProps) => {
const [local, others] = splitProps(props, ["class"]);
return (
<div
data-slot="empty-header"
class={cn("z-empty-header flex max-w-sm flex-col items-center", local.class)}
{...others}
/>
);
};
const emptyMediaVariants = cva(
"z-empty-media flex shrink-0 items-center justify-center [&_svg]:pointer-events-none [&_svg]:shrink-0",
{
variants: {
variant: {
default: "z-empty-media-default",
icon: "z-empty-media-icon",
},
},
defaultVariants: {
variant: "default",
},
},
);
type EmptyMediaProps = ComponentProps<"div"> & VariantProps<typeof emptyMediaVariants>;
const EmptyMedia = (props: EmptyMediaProps) => {
const [local, others] = splitProps(props, ["class", "variant"]);
return (
<div
data-slot="empty-icon"
data-variant={local.variant}
class={cn(emptyMediaVariants({ variant: local.variant }), local.class)}
{...others}
/>
);
};
type EmptyTitleProps = ComponentProps<"div">;
const EmptyTitle = (props: EmptyTitleProps) => {
const [local, others] = splitProps(props, ["class"]);
return <div data-slot="empty-title" class={cn("z-empty-title", local.class)} {...others} />;
};
type EmptyDescriptionProps = ComponentProps<"p">;
const EmptyDescription = (props: EmptyDescriptionProps) => {
const [local, others] = splitProps(props, ["class"]);
return (
<div
data-slot="empty-description"
class={cn(
"z-empty-description text-muted-foreground [&>a:hover]:text-primary [&>a]:underline [&>a]:underline-offset-4",
local.class,
)}
{...others}
/>
);
};
type EmptyContentProps = ComponentProps<"div">;
const EmptyContent = (props: EmptyContentProps) => {
const [local, others] = splitProps(props, ["class"]);
return (
<div
data-slot="empty-content"
class={cn(
"z-empty-content flex w-full min-w-0 max-w-sm flex-col items-center text-balance",
local.class,
)}
{...others}
/>
);
};
export { Empty, EmptyHeader, EmptyTitle, EmptyDescription, EmptyContent, EmptyMedia };

Examples

Here are the source code of all the examples from the preview page:

Basic

import { ArrowUpRight } from "lucide-solid";
import {
Empty,
EmptyContent,
EmptyDescription,
EmptyHeader,
EmptyTitle,
} from "~/components/ui/empty";
import { Button } from "~/components/ui/button";
function EmptyBasic() {
return (
<Example title="Basic">
<Empty>
<EmptyHeader>
<EmptyTitle>No projects yet</EmptyTitle>
<EmptyDescription>
You haven&apos;t created any projects yet. Get started by creating your first project.
</EmptyDescription>
</EmptyHeader>
<EmptyContent>
<div class="flex gap-2">
<Button as="a" href="#">
Create project
</Button>
<Button variant="outline">Import project</Button>
</div>
<Button variant="link" as="a" href="#" class="text-muted-foreground">
Learn more <ArrowUpRight />
</Button>
</EmptyContent>
</Empty>
</Example>
);
}

With Muted Background

import { ArrowUpRight } from "lucide-solid";
import {
Empty,
EmptyContent,
EmptyDescription,
EmptyHeader,
EmptyTitle,
} from "~/components/ui/empty";
import { Button } from "~/components/ui/button";
function EmptyWithMutedBackground() {
return (
<Example title="With Muted Background">
<Empty class="bg-muted">
<EmptyHeader>
<EmptyTitle>No results found</EmptyTitle>
<EmptyDescription>
No results found for your search. Try adjusting your search terms.
</EmptyDescription>
</EmptyHeader>
<EmptyContent>
<Button>Try again</Button>
<Button variant="link" as="a" href="#" class="text-muted-foreground">
Learn more <ArrowUpRight />
</Button>
</EmptyContent>
</Empty>
</Example>
);
}

With Border

import { CircleDashed } from "lucide-solid";
import {
Empty,
EmptyContent,
EmptyDescription,
EmptyHeader,
EmptyTitle,
} from "~/components/ui/empty";
import { InputGroup, InputGroupAddon, InputGroupInput } from "~/components/ui/input-group";
import { Kbd } from "~/components/ui/kbd";
function EmptyWithBorder() {
return (
<Example title="With Border">
<Empty class="border">
<EmptyHeader>
<EmptyTitle>404 - Not Found</EmptyTitle>
<EmptyDescription>
The page you&apos;re looking for doesn&apos;t exist. Try searching for what you need
below.
</EmptyDescription>
</EmptyHeader>
<EmptyContent>
<InputGroup class="w-3/4">
<InputGroupInput placeholder="Try searching for pages..." />
<InputGroupAddon>
<CircleDashed />
</InputGroupAddon>
<InputGroupAddon align="inline-end">
<Kbd>/</Kbd>
</InputGroupAddon>
</InputGroup>
<EmptyDescription>
Need help? <a href="#">Contact support</a>
</EmptyDescription>
</EmptyContent>
</Empty>
</Example>
);
}

With Icon

import { Folder, Plus } from "lucide-solid";
import {
Empty,
EmptyContent,
EmptyDescription,
EmptyHeader,
EmptyMedia,
EmptyTitle,
} from "~/components/ui/empty";
import { Button } from "~/components/ui/button";
function EmptyWithIcon() {
return (
<Example title="With Icon">
<Empty class="border">
<EmptyHeader>
<EmptyMedia variant="icon">
<Folder />
</EmptyMedia>
<EmptyTitle>Nothing to see here</EmptyTitle>
<EmptyDescription>
No posts have been created yet. Get started by <a href="#">creating your first post</a>.
</EmptyDescription>
</EmptyHeader>
<EmptyContent>
<Button variant="outline">
<Plus />
New Post
</Button>
</EmptyContent>
</Empty>
</Example>
);
}

With Muted Background Alt

import { CircleDashed } from "lucide-solid";
import {
Empty,
EmptyContent,
EmptyDescription,
EmptyHeader,
EmptyTitle,
} from "~/components/ui/empty";
import { InputGroup, InputGroupAddon, InputGroupInput } from "~/components/ui/input-group";
import { Kbd } from "~/components/ui/kbd";
function EmptyWithMutedBackgroundAlt() {
return (
<Example title="With Muted Background Alt">
<Empty class="bg-muted/50">
<EmptyHeader>
<EmptyTitle>404 - Not Found</EmptyTitle>
<EmptyDescription>
The page you&apos;re looking for doesn&apos;t exist. Try searching for what you need
below.
</EmptyDescription>
</EmptyHeader>
<EmptyContent>
<InputGroup class="w-3/4">
<InputGroupInput placeholder="Try searching for pages..." />
<InputGroupAddon>
<CircleDashed />
</InputGroupAddon>
<InputGroupAddon align="inline-end">
<Kbd>/</Kbd>
</InputGroupAddon>
</InputGroup>
<EmptyDescription>
Need help? <a href="#">Contact support</a>
</EmptyDescription>
</EmptyContent>
</Empty>
</Example>
);
}

In Card

import { ArrowUpRight, Folder } from "lucide-solid";
import {
Empty,
EmptyContent,
EmptyDescription,
EmptyHeader,
EmptyMedia,
EmptyTitle,
} from "~/components/ui/empty";
import { Button } from "~/components/ui/button";
function EmptyInCard() {
return (
<Example title="In Card">
<Empty>
<EmptyHeader>
<EmptyMedia variant="icon">
<Folder />
</EmptyMedia>
<EmptyTitle>No projects yet</EmptyTitle>
<EmptyDescription>
You haven&apos;t created any projects yet. Get started by creating your first project.
</EmptyDescription>
</EmptyHeader>
<EmptyContent>
<div class="flex gap-2">
<Button as="a" href="#">
Create project
</Button>
<Button variant="outline">Import project</Button>
</div>
<Button variant="link" as="a" href="#" class="text-muted-foreground">
Learn more <ArrowUpRight />
</Button>
</EmptyContent>
</Empty>
</Example>
);
}