# Introduction (/exabase/design/docs)
## Overview [#overview]
This site provides code snippets for UI components based on the exaBase Design System. Exabase Design System is a comprehensive collection of reusable components, design tokens, and guidelines that help you build consistent and accessible user interfaces.
Developers and designers can copy the code snippets and paste them into their own applications to immediately use the sophisticated UI baseline. If product-specific behavior is needed to improve the UX, you can customize the pasted code.
## Features [#features]
* 🎨 **Theming Support** - Customize colors, typography, and more
* 🌙 **Dark Mode** - Built-in dark mode support
* ♿ **Accessible** - WCAG compliant components
* 📦 **Tree-shakeable** - Import only what you need
* 🎯 **TypeScript** - Full TypeScript support
## Getting Started [#getting-started]
To get started with Exabase Design System, choose your installation method:
* [Next.js Installation](/docs/getting-started/installation/next)
* [Vite Installation](/docs/getting-started/installation/vite)
* [Manual Installation](/docs/getting-started/installation/manual)
After installation, you can explore:
* [Theming](/docs/getting-started/theming)
* [Dark Mode](/docs/getting-started/dark-mode)
* [Components](/docs/components)
* [Icons](/icons)
## Inspirations and Dependencies [#inspirations-and-dependencies]
The components and snippets here are based on and compatible with the innovative [shadcn/ui](https://ui.shadcn.com/).
[Tailwind CSS](https://tailwindcss.com/) is used for styling, and many components are built on [Base UI](https://base-ui.com/) for accessible, dynamic interaction. [exaBase Design System Icons](https://exawizards.com/exabase/icons) are used for the icons.
## License [#license]
Most of the content including snippets in this site were taken from [shadcn/ui](https://ui.shadcn.com/). Our own changes and additions are licensed under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/).
# Accordion (/exabase/design/docs/components/accordion)
```tsx
import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from "@/components/ui/accordion"
export function AccordionDemo() {
return (
What are your shipping options?
We offer standard (5-7 days), express (2-3 days), and overnight
shipping. Free shipping on international orders.
What is your return policy?
Returns accepted within 30 days. Items must be unused and in original
packaging. Refunds processed within 5-7 business days.
How can I contact customer support?
Reach us via email, live chat, or phone. We respond within 24 hours
during business days.
)
}
```
## Installation [#installation]
### CLI [#cli]
npm
pnpm
yarn
bun
```bash
npx shadcn@latest add https://exawizards.com/exabase/design/registry/accordion.json
```
```bash
pnpm dlx shadcn@latest add https://exawizards.com/exabase/design/registry/accordion.json
```
```bash
yarn dlx shadcn@latest add https://exawizards.com/exabase/design/registry/accordion.json
```
```bash
bun x shadcn@latest add https://exawizards.com/exabase/design/registry/accordion.json
```
### Manual [#manual]
Copy and paste the following code into your project.
```tsx
import { Accordion as AccordionPrimitive } from "@base-ui/react/accordion"
import {
ChevronDownIcon,
ChevronUpIcon,
} from "@exawizards/exabase-design-system-icons-react"
import { cn } from "@/lib/utils"
function Accordion({ className, ...props }: AccordionPrimitive.Root.Props) {
return (
)
}
function AccordionItem({ className, ...props }: AccordionPrimitive.Item.Props) {
return (
)
}
function AccordionTrigger({
className,
children,
...props
}: AccordionPrimitive.Trigger.Props) {
return (
{children}
)
}
function AccordionContent({
className,
children,
...props
}: AccordionPrimitive.Panel.Props) {
return (
{children}
)
}
export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }
```
## Usage [#usage]
```tsx
import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from "@/components/ui/accordion"
```
```tsx
Is it accessible?
Yes. It adheres to the WAI-ARIA design pattern.
```
## Examples [#examples]
### Multiple [#multiple]
Use the `multiple` prop to allow multiple items to be open at the same time.
```tsx
import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from "@/components/ui/accordion"
const items = [
{
value: "notifications",
trigger: "Notification Settings",
content:
"Manage how you receive notifications. You can enable email alerts for updates or push notifications for mobile devices.",
},
{
value: "privacy",
trigger: "Privacy & Security",
content:
"Control your privacy settings and security preferences. Enable two-factor authentication, manage connected devices, review active sessions, and configure data sharing preferences. You can also download your data or delete your account.",
},
{
value: "billing",
trigger: "Billing & Subscription",
content:
"View your current plan, payment history, and upcoming invoices. Update your payment method, change your subscription tier, or cancel your subscription.",
},
]
export function AccordionMultiple() {
return (
{items.map((item) => (
{item.trigger}{item.content}
))}
)
}
```
### Disabled [#disabled]
Use the `disabled` prop on `AccordionItem` to disable individual items.
```tsx
import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from "@/components/ui/accordion"
export function AccordionDisabled() {
return (
Can I access my account history?
Yes, you can view your complete account history including all
transactions, plan changes, and support tickets in the Account History
section of your dashboard.
Premium feature information
This section contains information about premium features. Upgrade your
plan to access this content.
How do I update my email address?
You can update your email address in your account settings.
You'll receive a verification email at your new address to
confirm the change.
)
}
```
### Borders [#borders]
```tsx
import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from "@/components/ui/accordion"
const items = [
{
value: "billing",
trigger: "How does billing work?",
content:
"We offer monthly and annual subscription plans. Billing is charged at the beginning of each cycle, and you can cancel anytime. All plans include automatic backups, 24/7 support, and unlimited team members.",
},
{
value: "security",
trigger: "Is my data secure?",
content:
"Yes. We use end-to-end encryption, SOC 2 Type II compliance, and regular third-party security audits. All data is encrypted at rest and in transit using industry-standard protocols.",
},
{
value: "integration",
trigger: "What integrations do you support?",
content:
"We integrate with 500+ popular tools including Slack, Zapier, Salesforce, HubSpot, and more. You can also build custom integrations using our REST API and webhooks.",
},
]
export function AccordionBorders() {
return (
{items.map((item) => (
{item.trigger}{item.content}
))}
)
}
```
### Card [#card]
Wrap the `Accordion` in a `Card` component.
```tsx
import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from "@/components/ui/accordion"
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card"
const items = [
{
value: "plans",
trigger: "What subscription plans do you offer?",
content:
"We offer three subscription tiers: Starter ($9/month), Professional ($29/month), and Enterprise ($99/month). Each plan includes increasing storage limits, API access, priority support, and team collaboration features.",
},
{
value: "billing",
trigger: "How does billing work?",
content:
"Billing occurs automatically at the start of each billing cycle. We accept all major credit cards, PayPal, and ACH transfers for enterprise customers. You'll receive an invoice via email after each payment.",
},
{
value: "cancel",
trigger: "How do I cancel my subscription?",
content:
"You can cancel your subscription anytime from your account settings. There are no cancellation fees or penalties. Your access will continue until the end of your current billing period.",
},
]
export function AccordionCard() {
return (
Subscription & Billing
Common questions about your account, plans, payments and
cancellations.
{items.map((item) => (
{item.trigger}{item.content}
))}
)
}
```
## API [#api]
See the [Base UI](https://base-ui.com/react/components/accordion#api-reference) documentation for more information.
# Alert Dialog (/exabase/design/docs/components/alert-dialog)
```tsx
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
AlertDialogTrigger,
} from "@/components/ui/alert-dialog"
import { Button } from "@/components/ui/button"
export function AlertDialogDemo() {
return (
Show Dialog}
/>
Are you absolutely sure?
This action cannot be undone. This will permanently delete your
account and remove your data from our servers.
CancelContinue
)
}
```
## Installation [#installation]
### CLI [#cli]
npm
pnpm
yarn
bun
```bash
npx shadcn@latest add https://exawizards.com/exabase/design/registry/alert-dialog.json
```
```bash
pnpm dlx shadcn@latest add https://exawizards.com/exabase/design/registry/alert-dialog.json
```
```bash
yarn dlx shadcn@latest add https://exawizards.com/exabase/design/registry/alert-dialog.json
```
```bash
bun x shadcn@latest add https://exawizards.com/exabase/design/registry/alert-dialog.json
```
### Manual [#manual]
Copy and paste the following code into your project.
```tsx
"use client"
import * as React from "react"
import { AlertDialog as AlertDialogPrimitive } from "@base-ui/react/alert-dialog"
import { cn } from "@/lib/utils"
import { Button } from "@/components/ui/button"
import { ScrollArea, ScrollContent } from "@/components/ui/scroll-area"
function AlertDialog({ ...props }: AlertDialogPrimitive.Root.Props) {
return
}
function AlertDialogTrigger({ ...props }: AlertDialogPrimitive.Trigger.Props) {
return (
)
}
function AlertDialogPortal({ ...props }: AlertDialogPrimitive.Portal.Props) {
return (
)
}
function AlertDialogOverlay({
className,
...props
}: AlertDialogPrimitive.Backdrop.Props) {
return (
)
}
function AlertDialogContent({
className,
...props
}: AlertDialogPrimitive.Popup.Props) {
return (
)
}
function AlertDialogHeader({
className,
...props
}: React.ComponentProps<"div">) {
return (
)
}
function AlertDialogFooter({
className,
showCloseButton = false,
children,
...props
}: React.ComponentProps<"div"> & {
showCloseButton?: boolean
}) {
return (
{children}
{showCloseButton && (
}>
Close
)}
)
}
function AlertDialogTitle({
className,
...props
}: AlertDialogPrimitive.Title.Props) {
return (
)
}
function AlertDialogDescription({
className,
...props
}: AlertDialogPrimitive.Description.Props) {
return (
)
}
function AlertDialogAction({
className,
...props
}: React.ComponentProps) {
return (
)
}
function AlertDialogCancel({
className,
variant = "outline",
size = "default",
...props
}: AlertDialogPrimitive.Close.Props &
Pick, "variant" | "size">) {
return (
}
{...props}
/>
)
}
export {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogOverlay,
AlertDialogPortal,
AlertDialogTitle,
AlertDialogTrigger,
}
```
## Usage [#usage]
```tsx
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
AlertDialogTrigger,
} from "@/components/ui/alert-dialog"
```
```tsx
OpenAre you absolutely sure?
This action cannot be undone. This will permanently delete your account
and remove your data from our servers.
CancelContinue
```
## Examples [#examples]
### Basic [#basic]
```tsx
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
AlertDialogTrigger,
} from "@/components/ui/alert-dialog"
import { Button } from "@/components/ui/button"
export function AlertDialogBasic() {
return (
Show Dialog}
/>
Are you absolutely sure?
This action cannot be undone. This will permanently delete your
account and remove your data from our servers.
CancelContinue
)
}
```
### Destructive [#destructive]
```tsx
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
AlertDialogTrigger,
} from "@/components/ui/alert-dialog"
import { Button } from "@/components/ui/button"
export function AlertDialogDestructive() {
return (
Show Dialog}
/>
Are you absolutely sure?
This action cannot be undone. This will permanently delete your
account and remove your data from our servers.
CancelContinue
)
}
```
## API [#api]
See the [Base UI](https://base-ui.com/react/components/alert-dialog#api-reference) documentation for more information.
# Alert (/exabase/design/docs/components/alert)
```tsx
import {
ExclamationmarkCircleFillIcon,
InformationmarkCircleIcon,
} from "@exawizards/exabase-design-system-icons-react"
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"
export function AlertDemo() {
return (
Heads up!
This is an alert with icon, title and description.
This Alert has a title and an icon. No description.
Unable to process your payment.
Please verify your billing information and try again.
Check your card details
Ensure sufficient funds
Verify billing address
)
}
```
## Installation [#installation]
### CLI [#cli]
npm
pnpm
yarn
bun
```bash
npx shadcn@latest add https://exawizards.com/exabase/design/registry/alert.json
```
```bash
pnpm dlx shadcn@latest add https://exawizards.com/exabase/design/registry/alert.json
```
```bash
yarn dlx shadcn@latest add https://exawizards.com/exabase/design/registry/alert.json
```
```bash
bun x shadcn@latest add https://exawizards.com/exabase/design/registry/alert.json
```
### Manual [#manual]
Copy and paste the following code into your project.
```tsx
import * as React from "react"
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
const alertVariants = cva(
"relative grid w-full grid-cols-[0_1fr] items-start gap-y-0.5 rounded-lg border px-3 py-2.5 text-sm text-foreground has-[>svg]:grid-cols-[auto_1fr] has-[>svg]:gap-x-2 *:[svg]:translate-y-0.5 *:[svg]:text-current *:[svg:not([class*='size-'])]:size-4",
{
variants: {
variant: {
default: "bg-muted/50",
info: "border-info-text/50 bg-info-muted *:[svg]:text-info",
success: "border-success-text/50 bg-success-muted *:[svg]:text-success",
warning: "border-warning-text/50 bg-warning-muted *:[svg]:text-warning",
error:
"border-destructive-text/50 bg-destructive-muted *:[svg]:text-destructive",
},
},
defaultVariants: {
variant: "default",
},
}
)
function Alert({
className,
variant,
...props
}: React.ComponentProps<"div"> & VariantProps) {
return (
)
}
function AlertTitle({ className, ...props }: React.ComponentProps<"div">) {
return (
)
}
function AlertDescription({
className,
...props
}: React.ComponentProps<"div">) {
return (
)
}
export { Alert, AlertTitle, AlertDescription }
```
## Usage [#usage]
```tsx
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
```
```tsx
Heads up!
You can add components and dependencies to your app using the cli.
```
## Examples [#examples]
### Variant [#variant]
```tsx
import {
CheckmarkCircleFillIcon,
ExclamationmarkCircleFillIcon,
ExclamationmarkTriangleFillIcon,
InformationmarkCircleFillIcon,
InformationmarkCircleIcon,
} from "@exawizards/exabase-design-system-icons-react"
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"
export function AlertVariant() {
return (
DefaultThis is a default alert.SuccessYour changes have been saved.InfoNew features are now available.WarningThis API will be deprecated soon.Error
Something went wrong. Please try again.
)
}
```
### Elements [#elements]
```tsx
import { InformationmarkCircleIcon } from "@exawizards/exabase-design-system-icons-react"
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"
export function AlertElements() {
return (
TitleTitleDescriptionTitleTitleDescription
)
}
```
### Action [#action]
shadcn/ui provides an `AlertAction` component, but we do not provide it due to its lack of layout flexibility.
Instead, place actions at any position you like.
```tsx
import { InformationmarkCircleIcon } from "@exawizards/exabase-design-system-icons-react"
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"
import { Button } from "@/components/ui/button"
export function AlertWithAction() {
return (
Dark mode is now available
Enable it under your profile settings to get started.
Dark mode is now available
Enable it under your profile settings to get started.
)
}
```
## API [#api]
### Alert [#alert]
`` renders as a `
` element.
| Prop | Type | Default | Description |
| --------- | ---------------------------------------------------------- | --------- | ------------------------- |
| `variant` | `"default" \| "success" \| "info" \| "warning" \| "error"` | `default` | The variant of the alert. |
# Aspect Ratio (/exabase/design/docs/components/aspect-ratio)
```tsx
import Image from "next/image"
import { AspectRatio } from "@/components/ui/aspect-ratio"
export function AspectRatioDemo() {
return (
)
}
```
## Installation [#installation]
### CLI [#cli]
npm
pnpm
yarn
bun
```bash
npx shadcn@latest add https://exawizards.com/exabase/design/registry/aspect-ratio.json
```
```bash
pnpm dlx shadcn@latest add https://exawizards.com/exabase/design/registry/aspect-ratio.json
```
```bash
yarn dlx shadcn@latest add https://exawizards.com/exabase/design/registry/aspect-ratio.json
```
```bash
bun x shadcn@latest add https://exawizards.com/exabase/design/registry/aspect-ratio.json
```
### Manual [#manual]
Copy and paste the following code into your project.
```tsx
import { cn } from "@/lib/utils"
function AspectRatio({
ratio,
className,
...props
}: React.ComponentProps<"div"> & { ratio: number }) {
return (
)
}
export { AspectRatio }
```
## Usage [#usage]
```tsx
import Image from "next/image"
import { AspectRatio } from "@/components/ui/aspect-ratio"
```
```tsx
)
}
```
## Installation [#installation]
### CLI [#cli]
npm
pnpm
yarn
bun
```bash
npx shadcn@latest add https://exawizards.com/exabase/design/registry/avatar.json
```
```bash
pnpm dlx shadcn@latest add https://exawizards.com/exabase/design/registry/avatar.json
```
```bash
yarn dlx shadcn@latest add https://exawizards.com/exabase/design/registry/avatar.json
```
```bash
bun x shadcn@latest add https://exawizards.com/exabase/design/registry/avatar.json
```
### Manual [#manual]
Copy and paste the following code into your project.
```tsx
"use client"
import * as React from "react"
import { Avatar as AvatarPrimitive } from "@base-ui/react/avatar"
import { mergeProps } from "@base-ui/react/merge-props"
import { useRender } from "@base-ui/react/use-render"
import { cn } from "@/lib/utils"
function Avatar({
className,
size = "default",
...props
}: AvatarPrimitive.Root.Props & {
size?: "default" | "sm" | "lg"
}) {
return (
)
}
function AvatarImage({ className, ...props }: AvatarPrimitive.Image.Props) {
return (
)
}
function AvatarFallback({
className,
...props
}: AvatarPrimitive.Fallback.Props) {
return (
)
}
function AvatarBadge({ className, ...props }: React.ComponentProps<"span">) {
return (
svg]:hidden",
"group-data-[size=default]/avatar:size-2.5 group-data-[size=default]/avatar:[&>svg]:size-2",
"group-data-[size=lg]/avatar:size-3 group-data-[size=lg]/avatar:[&>svg]:size-2",
className
)}
{...props}
/>
)
}
function AvatarGroup({ className, ...props }: React.ComponentProps<"div">) {
return (
)
}
function AvatarGroupCount({
className,
render,
...props
}: useRender.ComponentProps<"div">) {
return useRender({
defaultTagName: "div",
props: mergeProps<"div">(
{
className: cn(
"relative flex size-8 shrink-0 items-center justify-center rounded-full bg-muted text-sm text-muted-foreground ring-2 ring-background group-has-data-[size=lg]/avatar-group:size-10 group-has-data-[size=sm]/avatar-group:size-6 [&>svg]:size-4 group-has-data-[size=lg]/avatar-group:[&>svg]:size-5 group-has-data-[size=sm]/avatar-group:[&>svg]:size-3",
className
),
},
props
),
render,
state: {
slot: "avatar-group-count",
},
})
}
export {
Avatar,
AvatarImage,
AvatarFallback,
AvatarGroup,
AvatarGroupCount,
AvatarBadge,
}
```
## Usage [#usage]
```tsx
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
```
```tsx
EW
```
## Examples [#examples]
### Image [#image]
An avatar component with an image and a fallback.
```tsx
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
export function AvatarImageExample() {
return (
JM
)
}
```
### Text or Icon [#text-or-icon]
If you don't use an image, you can place text or an icon directly as a child of the Avatar.
```tsx
import { PersonCircleFillIcon } from "@exawizards/exabase-design-system-icons-react"
import { Avatar } from "@/components/ui/avatar"
export function AvatarText() {
return (
JM
)
}
```
### Badge [#badge]
Use the `AvatarBadge` component to add a badge to the avatar. The badge is positioned at the bottom right of the avatar.
```tsx
import { PlusIcon } from "@exawizards/exabase-design-system-icons-react"
import {
Avatar,
AvatarBadge,
AvatarFallback,
AvatarImage,
} from "@/components/ui/avatar"
export function AvatarBadgeExample() {
return (
JMJMJMJM
)
}
```
### Avatar Group [#avatar-group]
Use the `AvatarGroup` component to add a group of avatars.
```tsx
import {
Avatar,
AvatarFallback,
AvatarGroup,
AvatarImage,
} from "@/components/ui/avatar"
export function AvatarGroupExample() {
return (
JMDCEP
)
}
```
### Avatar Group Count [#avatar-group-count]
Use `` to add an extra content to the group.
```tsx
import { PlusIcon } from "@exawizards/exabase-design-system-icons-react"
import {
Avatar,
AvatarFallback,
AvatarGroup,
AvatarGroupCount,
AvatarImage,
} from "@/components/ui/avatar"
import { Button } from "@/components/ui/button"
export function AvatarGroupCountExample() {
return (
JMDCEP+3JMDCEP}>
)
}
```
### Size [#size]
Use the `size` prop to change the size of the avatar.
```tsx
import {
Avatar,
AvatarFallback,
AvatarGroup,
AvatarImage,
} from "@/components/ui/avatar"
export function AvatarSizeExample() {
return (
JMJMJMJMDCEP
)
}
```
### Dropdown [#dropdown]
You can use the `Avatar` component as a trigger for a dropdown menu.
```tsx
"use client"
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
import { Button } from "@/components/ui/button"
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
export function AvatarDropdown() {
return (
JM
}
/>
ProfileBillingSettingsLog out
)
}
```
### Customize [#customize]
```tsx
import {
Avatar,
AvatarBadge,
AvatarFallback,
AvatarGroup,
AvatarImage,
} from "@/components/ui/avatar"
export function AvatarCustomize() {
return (
JMJMJMJMDCEP
)
}
```
## API [#api]
### Avatar [#avatar]
The `Avatar` component is the root component that wraps the avatar image and fallback.
| Prop | Type | Default |
| ------ | --------------------------- | ----------- |
| `size` | `"default" \| "sm" \| "lg"` | `"default"` |
See the [Base UI](https://base-ui.com/react/components/avatar#api-reference) documentation for more information.
# Badge (/exabase/design/docs/components/badge)
```tsx
import { Badge } from "@/components/ui/badge"
export function BadgeDemo() {
return Badge
}
```
## Installation [#installation]
### CLI [#cli]
npm
pnpm
yarn
bun
```bash
npx shadcn@latest add https://exawizards.com/exabase/design/registry/badge.json
```
```bash
pnpm dlx shadcn@latest add https://exawizards.com/exabase/design/registry/badge.json
```
```bash
yarn dlx shadcn@latest add https://exawizards.com/exabase/design/registry/badge.json
```
```bash
bun x shadcn@latest add https://exawizards.com/exabase/design/registry/badge.json
```
### Manual [#manual]
Copy and paste the following code into your project.
```tsx
import { mergeProps } from "@base-ui/react/merge-props"
import { useRender } from "@base-ui/react/use-render"
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
const badgeVariants = cva(
"group/badge inline-flex h-5 w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-full border border-transparent px-2 py-0.5 text-xs font-medium whitespace-nowrap transition-all focus-visible:ring-3 focus-visible:ring-ring/50 focus-visible:outline-none has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&>svg]:pointer-events-none [&>svg]:size-3!",
{
variants: {
variant: {
default: "bg-primary text-primary-foreground",
secondary: "bg-secondary text-secondary-foreground",
info: "bg-info text-info-foreground",
success: "bg-success text-success-foreground",
warning: "bg-warning text-warning-foreground",
error: "bg-destructive text-destructive-foreground",
outline: "border-border bg-background text-foreground",
},
},
defaultVariants: {
variant: "default",
},
}
)
function Badge({
className,
variant = "default",
render,
...props
}: useRender.ComponentProps<"span"> & VariantProps) {
return useRender({
defaultTagName: "span",
props: mergeProps<"span">(
{
className: cn(badgeVariants({ variant }), className),
},
props
),
render,
state: {
slot: "badge",
variant,
},
})
}
export { Badge, badgeVariants }
```
## Usage [#usage]
```tsx
import { Badge } from "@/components/ui/badge"
```
```tsx
Badge
```
### Link [#link]
Use the `render` prop to render a link as a badge.
```tsx
import Link from "next/link"
import { Badge } from "@/components/ui/badge"
export function BadgeLink() {
return (
)
}
```
### Count [#count]
```tsx
import {
BellIcon,
MailIcon,
} from "@exawizards/exabase-design-system-icons-react"
import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
export function BadgeCount() {
return (
)
}
```
### Dot [#dot]
```tsx
import { BellIcon } from "@exawizards/exabase-design-system-icons-react"
import { Badge } from "@/components/ui/badge"
import { Button } from "@/components/ui/button"
export function BadgeDot() {
return (
)
}
```
### With Icon [#with-icon]
You can render an icon inside the badge. Use `data-icon="inline-start"` to render the icon on the left and `data-icon="inline-end"` to render the icon on the right.
```tsx
import {
CheckmarkIcon,
RectangleArrowUpRightIcon,
} from "@exawizards/exabase-design-system-icons-react"
import { Badge } from "@/components/ui/badge"
import { Spinner } from "@/components/ui/spinner"
export function BadgeWithIcon() {
return (
Verified
Document
Generating
)
}
```
## API [#api]
### Badge [#badge]
| Prop | Type | Default | Description |
| --------- | -------------------------------------------------------------------------------------- | --------- | ------------------------- |
| `variant` | `"default" \| "outline" \| "secondary" \| "info" \| "success" \| "warning" \| "error"` | `default` | The variant of the badge. |
# Breadcrumb (/exabase/design/docs/components/breadcrumb)
```tsx
import {
Breadcrumb,
BreadcrumbItem,
BreadcrumbLink,
BreadcrumbList,
BreadcrumbPage,
BreadcrumbSeparator,
} from "@/components/ui/breadcrumb"
export function BreadcrumbDemo() {
return (
HomeComponentsBreadcrumb
)
}
```
## Installation [#installation]
### CLI [#cli]
npm
pnpm
yarn
bun
```bash
npx shadcn@latest add https://exawizards.com/exabase/design/registry/breadcrumb.json
```
```bash
pnpm dlx shadcn@latest add https://exawizards.com/exabase/design/registry/breadcrumb.json
```
```bash
yarn dlx shadcn@latest add https://exawizards.com/exabase/design/registry/breadcrumb.json
```
```bash
bun x shadcn@latest add https://exawizards.com/exabase/design/registry/breadcrumb.json
```
### Manual [#manual]
Copy and paste the following code into your project.
```tsx
import * as React from "react"
import { mergeProps } from "@base-ui/react/merge-props"
import { useRender } from "@base-ui/react/use-render"
import {
ChevronRightIcon,
DotsHorizontalIcon,
} from "@exawizards/exabase-design-system-icons-react"
import { cn } from "@/lib/utils"
function Breadcrumb({ className, ...props }: React.ComponentProps<"nav">) {
return (
)
}
function BreadcrumbList({ className, ...props }: React.ComponentProps<"ol">) {
return (
)
}
function BreadcrumbItem({ className, ...props }: React.ComponentProps<"li">) {
return (
)
}
function BreadcrumbLink({
className,
render,
...props
}: useRender.ComponentProps<"a">) {
return useRender({
defaultTagName: "a",
props: mergeProps<"a">(
{
className: cn("transition-colors hover:text-foreground", className),
},
props
),
render,
state: {
slot: "breadcrumb-link",
},
})
}
function BreadcrumbPage({ className, ...props }: React.ComponentProps<"span">) {
return (
)
}
function BreadcrumbSeparator({
children,
className,
...props
}: React.ComponentProps<"li">) {
return (