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
119 changes: 119 additions & 0 deletions app/docs/components/empty/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import { Metadata } from "next";

import { IconBrandAmongUs } from "@tabler/icons-react";

import { emptyMetaData } from "@/lib/metadata";

import { Button } from "@/components/ui/8bit/button";
import {
Empty,
EmptyContent,
EmptyDescription,
EmptyHeader,
EmptyMedia,
EmptyTitle,
} from "@/components/ui/8bit/empty";
import { Separator } from "@/components/ui/separator";

import CodeSnippet from "@/app/docs/components/code-snippet";
import CopyCommandButton from "@/app/docs/components/copy-command-button";
import InstallationCommands from "@/app/docs/components/installation-commands";
import { OpenInV0Button } from "@/app/docs/components/open-in-v0-button";

export const metadata: Metadata = {
title: "8-bit Empty",
description: "Displays an 8-bit empty component.",
openGraph: {
images: emptyMetaData,
},
};

export default function EmptyPage() {
return (
<div className="flex flex-col gap-4">
<div className="flex flex-col md:flex-row items-center justify-between gap-2">
<h1 className="text-3xl font-bold">Empty</h1>
<CopyCommandButton
copyCommand="pnpm dlx shadcn@latest add @8bitcn/empty"
command="pnpm dlx shadcn@latest add @8bitcn/empty"
/>
</div>

<p className="text-muted-foreground">
Displays an 8-bit empty component.
</p>

<div className="flex flex-col gap-4 border rounded-lg p-4 min-h-[450px]">
<div className="flex items-center justify-between">
<h2 className="text-sm text-muted-foreground sm:pl-3">
8-bit empty component
</h2>

<div className="flex items-center gap-2">
<OpenInV0Button name="8bit-empty" className="w-fit" />
</div>
</div>

<div className="flex items-center justify-center min-h-[400px] relative">
<Empty>
<EmptyHeader>
<EmptyMedia variant="icon">
<IconBrandAmongUs />
</EmptyMedia>
<EmptyTitle>No Characters Yet</EmptyTitle>
<EmptyDescription>
You haven&apos;t created any Characters yet. Get started by
creating your first character.
</EmptyDescription>
</EmptyHeader>
<EmptyContent>
<div className="flex gap-6">
<Button>Create Character</Button>
<Button variant="outline">Import Character</Button>
</div>
</EmptyContent>
</Empty>
</div>
</div>

<h3 className="text-lg font-bold">Installation</h3>

<Separator />

<InstallationCommands packageName="empty" />

<h3 className="text-lg font-bold mt-10">Usage</h3>

<Separator />

<CodeSnippet>{`import { IconBrandAmongUs } from "@tabler/icons-react"
import {
Empty,
EmptyContent,
EmptyDescription,
EmptyHeader,
EmptyMedia,
EmptyTitle,
} from "@/components/ui/8bit/empty"`}</CodeSnippet>
<CodeSnippet>{`<Empty>
<EmptyHeader>
<EmptyMedia variant="icon">
<IconBrandAmongUs />
</EmptyMedia>
<EmptyTitle>No Characters Yet</EmptyTitle>
<EmptyDescription>
You haven&apos;t created any Characters yet. Get started by creating
your first character.
</EmptyDescription>
</EmptyHeader>
<EmptyContent>
<div className="flex gap-6">
<Button>Create Character</Button>
<Button variant="outline">Import Character</Button>
</div>
</EmptyContent>
</Empty>
`}</CodeSnippet>
</div>
);
}
130 changes: 130 additions & 0 deletions components/ui/8bit/empty.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
"use client";

import { type VariantProps, cva } from "class-variance-authority";

import { cn } from "@/lib/utils";

import "./styles/retro.css";

const emptyMediaVariants = cva(
"flex shrink-0 items-center justify-center [&_svg]:pointer-events-none [&_svg]:shrink-0",
{
variants: {
variant: {
default: "bg-transparent",
icon: "relative bg-muted text-foreground flex size-12 shrink-0 items-center justify-center",
},
font: {
normal: "",
retro: "retro",
},
},
defaultVariants: {
variant: "default",
font: "retro",
},
}
);

function Empty({
className,
font,
...props
}: React.ComponentProps<"div"> & { font?: "normal" | "retro" }) {
return (
<div
data-slot="empty"
className={cn(
"flex min-w-0 flex-1 flex-col items-center justify-center gap-6 rounded-lg border-dashed p-6 text-center text-balance md:p-12",
font !== "default" && "retro",
className
)}
{...props}
/>
);
}

function EmptyHeader({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="empty-header"
className={cn(
"flex max-w-sm flex-col items-center gap-2 text-center",
className
)}
{...props}
/>
);
}

function EmptyMedia({
className,
variant = "default",
...props
}: React.ComponentProps<"div"> & VariantProps<typeof emptyMediaVariants>) {
return (
<div className={cn("relative size-max", className)}>
<div
data-slot="empty-icon"
data-variant={variant}
className={cn(emptyMediaVariants({ variant, className }))}
{...props}
/>
{variant !== "default" && (
<>
<div className="absolute top-0 left-0 w-full h-1.5 bg-foreground dark:bg-ring pointer-events-none" />
<div className="absolute bottom-0 w-full h-1.5 bg-foreground dark:bg-ring pointer-events-none" />
<div className="absolute top-1.5 -left-1.5 w-1.5 h-1/2 bg-foreground dark:bg-ring pointer-events-none" />
<div className="absolute bottom-1.5 -left-1.5 w-1.5 h-1/2 bg-foreground dark:bg-ring pointer-events-none" />
<div className="absolute top-1.5 -right-1.5 w-1.5 h-1/2 bg-foreground dark:bg-ring pointer-events-none" />
<div className="absolute bottom-1.5 -right-1.5 w-1.5 h-1/2 bg-foreground dark:bg-ring pointer-events-none" />
</>
)}
</div>
);
}

function EmptyTitle({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="empty-title"
className={cn("text-lg font-medium tracking-tight", className)}
{...props}
/>
);
}

function EmptyDescription({ className, ...props }: React.ComponentProps<"p">) {
return (
<p
data-slot="empty-description"
className={cn(
"text-muted-foreground [&>a:hover]:text-primary text-sm/relaxed [&>a]:underline [&>a]:underline-offset-4",
className
)}
{...props}
/>
);
}

function EmptyContent({ className, ...props }: React.ComponentProps<"div">) {
return (
<div
data-slot="empty-content"
className={cn(
"flex w-full max-w-sm min-w-0 flex-col items-center gap-4 text-sm text-balance",
className
)}
{...props}
/>
);
}

export {
Empty,
EmptyHeader,
EmptyTitle,
EmptyDescription,
EmptyContent,
EmptyMedia,
};
5 changes: 5 additions & 0 deletions config/nav-items.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ const components = [
title: "Dropdown Menu",
url: "/docs/components/dropdown-menu",
},
{
title: "Empty",
url: "/docs/components/empty",
new: true,
},
{
title: "Enemy Health",
url: "/docs/components/enemy-health-display",
Expand Down
1 change: 1 addition & 0 deletions lib/metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,4 @@ export const spinnerMetaData = "/assets/8bitcn-spinner-light.png";
export const kbdMetaData = "/assets/8bitcn-kbd-light.png";

export const profileCreatorMetaData = "/assets/8bitcn-profile-creator.png";
export const emptyMetaData = "/assets/8bitcn-empty-light.png";
Binary file added public/assets/8bitcn-empty-dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/assets/8bitcn-empty-light.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 16 additions & 0 deletions public/r/empty.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"$schema": "https://ui.shadcn.com/schema/registry-item.json",
"name": "empty",
"type": "registry:component",
"title": "8-bit Empty",
"description": "Displays an 8-bit empty component.",
"registryDependencies": [],
"files": [
{
"path": "components/ui/8bit/empty.tsx",
"content": "\"use client\";\n\nimport { type VariantProps, cva } from \"class-variance-authority\";\n\nimport { cn } from \"@/lib/utils\";\n\nimport \"./styles/retro.css\";\n\nconst emptyMediaVariants = cva(\n \"flex shrink-0 items-center justify-center [&_svg]:pointer-events-none [&_svg]:shrink-0\",\n {\n variants: {\n variant: {\n default: \"bg-transparent\",\n icon: \"relative bg-muted text-foreground flex size-12 shrink-0 items-center justify-center\",\n },\n font: {\n normal: \"\",\n retro: \"retro\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n font: \"retro\",\n },\n }\n);\n\nfunction Empty({\n className,\n font,\n ...props\n}: React.ComponentProps<\"div\"> & { font?: \"normal\" | \"retro\" }) {\n return (\n <div\n data-slot=\"empty\"\n className={cn(\n \"flex min-w-0 flex-1 flex-col items-center justify-center gap-6 rounded-lg border-dashed p-6 text-center text-balance md:p-12\",\n font !== \"default\" && \"retro\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction EmptyHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"empty-header\"\n className={cn(\n \"flex max-w-sm flex-col items-center gap-2 text-center\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction EmptyMedia({\n className,\n variant = \"default\",\n ...props\n}: React.ComponentProps<\"div\"> & VariantProps<typeof emptyMediaVariants>) {\n return (\n <div className={cn(\"relative size-max\", className)}>\n <div\n data-slot=\"empty-icon\"\n data-variant={variant}\n className={cn(emptyMediaVariants({ variant, className }))}\n {...props}\n />\n {variant !== \"default\" && (\n <>\n <div className=\"absolute top-0 left-0 w-full h-1.5 bg-foreground dark:bg-ring pointer-events-none\" />\n <div className=\"absolute bottom-0 w-full h-1.5 bg-foreground dark:bg-ring pointer-events-none\" />\n <div className=\"absolute top-1.5 -left-1.5 w-1.5 h-1/2 bg-foreground dark:bg-ring pointer-events-none\" />\n <div className=\"absolute bottom-1.5 -left-1.5 w-1.5 h-1/2 bg-foreground dark:bg-ring pointer-events-none\" />\n <div className=\"absolute top-1.5 -right-1.5 w-1.5 h-1/2 bg-foreground dark:bg-ring pointer-events-none\" />\n <div className=\"absolute bottom-1.5 -right-1.5 w-1.5 h-1/2 bg-foreground dark:bg-ring pointer-events-none\" />\n </>\n )}\n </div>\n );\n}\n\nfunction EmptyTitle({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"empty-title\"\n className={cn(\"text-lg font-medium tracking-tight\", className)}\n {...props}\n />\n );\n}\n\nfunction EmptyDescription({ className, ...props }: React.ComponentProps<\"p\">) {\n return (\n <p\n data-slot=\"empty-description\"\n className={cn(\n \"text-muted-foreground [&>a:hover]:text-primary text-sm/relaxed [&>a]:underline [&>a]:underline-offset-4\",\n className\n )}\n {...props}\n />\n );\n}\n\nfunction EmptyContent({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"empty-content\"\n className={cn(\n \"flex w-full max-w-sm min-w-0 flex-col items-center gap-4 text-sm text-balance\",\n className\n )}\n {...props}\n />\n );\n}\n\nexport {\n Empty,\n EmptyHeader,\n EmptyTitle,\n EmptyDescription,\n EmptyContent,\n EmptyMedia,\n};\n",
"type": "registry:component",
"target": "components/ui/8bit/empty.tsx"
}
]
}
14 changes: 14 additions & 0 deletions public/r/registry.json
Original file line number Diff line number Diff line change
Expand Up @@ -1822,6 +1822,20 @@
"target": "components/ui/8bit/styles/retro.css"
}
]
},
{
"name": "empty",
"type": "registry:component",
"title": "8-bit Empty",
"description": "Displays an 8-bit empty component.",
"registryDependencies": [],
"files": [
{
"path": "components/ui/8bit/empty.tsx",
"type": "registry:component",
"target": "components/ui/8bit/empty.tsx"
}
]
}
]
}
14 changes: 14 additions & 0 deletions registry.json
Original file line number Diff line number Diff line change
Expand Up @@ -1822,6 +1822,20 @@
"target": "components/ui/8bit/styles/retro.css"
}
]
},
{
"name": "empty",
"type": "registry:component",
"title": "8-bit Empty",
"description": "Displays an 8-bit empty component.",
"registryDependencies": [],
"files": [
{
"path": "components/ui/8bit/empty.tsx",
"type": "registry:component",
"target": "components/ui/8bit/empty.tsx"
}
]
}
]
}