mirror of
https://github.com/shadcn-ui/ui.git
synced 2026-06-11 09:51:40 +00:00
Compare commits
67 Commits
shadcn@4.0
...
shadcn/fro
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f5a0945caf | ||
|
|
eecffac153 | ||
|
|
93b1b012f1 | ||
|
|
113be481d5 | ||
|
|
90952b1b0c | ||
|
|
c470caca45 | ||
|
|
63ad095a34 | ||
|
|
d3b3ecde53 | ||
|
|
f337ccef13 | ||
|
|
818c060efc | ||
|
|
528b27a63f | ||
|
|
a7bd5d2d22 | ||
|
|
62b1b89bcc | ||
|
|
97371b578e | ||
|
|
d6878556ba | ||
|
|
e7d802fc07 | ||
|
|
572e5d4532 | ||
|
|
90f8057a24 | ||
|
|
151ae29653 | ||
|
|
40e5bf5eff | ||
|
|
1fd52c41f9 | ||
|
|
63c28a1496 | ||
|
|
6a9d68cc2c | ||
|
|
587c76f46f | ||
|
|
52a4b1d466 | ||
|
|
7ecba59894 | ||
|
|
4073811f64 | ||
|
|
5f966a282a | ||
|
|
ff3c1e1d95 | ||
|
|
068f7c22aa | ||
|
|
b1b25fe15d | ||
|
|
689b4c6b41 | ||
|
|
66637058fc | ||
|
|
da07cf6ffe | ||
|
|
1a5b9ce036 | ||
|
|
1ce874edd2 | ||
|
|
45480505d8 | ||
|
|
bd4ef8e08c | ||
|
|
5a897b7765 | ||
|
|
3f62e7dee0 | ||
|
|
f2d4395233 | ||
|
|
3ab7d04824 | ||
|
|
58f73f62a0 | ||
|
|
d9061d64aa | ||
|
|
4784f264c5 | ||
|
|
7031141cf3 | ||
|
|
d0fe494491 | ||
|
|
be0b798e21 | ||
|
|
953107e7f9 | ||
|
|
c880796bf2 | ||
|
|
48b069c453 | ||
|
|
b5c7a014c8 | ||
|
|
aee10914fe | ||
|
|
aadba2f859 | ||
|
|
dced7f6045 | ||
|
|
cbe672151a | ||
|
|
62aef1117f | ||
|
|
cbc9ed8688 | ||
|
|
b309b1a060 | ||
|
|
e003cf74d2 | ||
|
|
34f1061c6b | ||
|
|
ed28a348c7 | ||
|
|
38bcb3c2eb | ||
|
|
e9acf86c24 | ||
|
|
2f829db41d | ||
|
|
413dc4c01f | ||
|
|
eb098f87d2 |
@@ -1,10 +1,8 @@
|
||||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
import { IconMinus, IconPlus } from "@tabler/icons-react"
|
||||
|
||||
import { Button } from "@/registry/new-york-v4/ui/button"
|
||||
import { ButtonGroup } from "@/registry/new-york-v4/ui/button-group"
|
||||
import { Button } from "@/examples/radix/ui/button"
|
||||
import { ButtonGroup } from "@/examples/radix/ui/button-group"
|
||||
import {
|
||||
Field,
|
||||
FieldContent,
|
||||
@@ -15,13 +13,11 @@ import {
|
||||
FieldSeparator,
|
||||
FieldSet,
|
||||
FieldTitle,
|
||||
} from "@/registry/new-york-v4/ui/field"
|
||||
import { Input } from "@/registry/new-york-v4/ui/input"
|
||||
import {
|
||||
RadioGroup,
|
||||
RadioGroupItem,
|
||||
} from "@/registry/new-york-v4/ui/radio-group"
|
||||
import { Switch } from "@/registry/new-york-v4/ui/switch"
|
||||
} from "@/examples/radix/ui/field"
|
||||
import { Input } from "@/examples/radix/ui/input"
|
||||
import { RadioGroup, RadioGroupItem } from "@/examples/radix/ui/radio-group"
|
||||
import { Switch } from "@/examples/radix/ui/switch"
|
||||
import { IconMinus, IconPlus } from "@tabler/icons-react"
|
||||
|
||||
export function AppearanceSettings() {
|
||||
const [gpuCount, setGpuCount] = React.useState(8)
|
||||
|
||||
@@ -1,20 +1,8 @@
|
||||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
import {
|
||||
ArchiveIcon,
|
||||
ArrowLeftIcon,
|
||||
CalendarPlusIcon,
|
||||
ClockIcon,
|
||||
ListFilterIcon,
|
||||
MailCheckIcon,
|
||||
MoreHorizontalIcon,
|
||||
TagIcon,
|
||||
Trash2Icon,
|
||||
} from "lucide-react"
|
||||
|
||||
import { Button } from "@/registry/new-york-v4/ui/button"
|
||||
import { ButtonGroup } from "@/registry/new-york-v4/ui/button-group"
|
||||
import { Button } from "@/examples/radix/ui/button"
|
||||
import { ButtonGroup } from "@/examples/radix/ui/button-group"
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
@@ -27,7 +15,18 @@ import {
|
||||
DropdownMenuSubContent,
|
||||
DropdownMenuSubTrigger,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/registry/new-york-v4/ui/dropdown-menu"
|
||||
} from "@/examples/radix/ui/dropdown-menu"
|
||||
import {
|
||||
ArchiveIcon,
|
||||
ArrowLeftIcon,
|
||||
CalendarPlusIcon,
|
||||
ClockIcon,
|
||||
ListFilterIcon,
|
||||
MailCheckIcon,
|
||||
MoreHorizontalIcon,
|
||||
TagIcon,
|
||||
Trash2Icon,
|
||||
} from "lucide-react"
|
||||
|
||||
export function ButtonGroupDemo() {
|
||||
const [label, setLabel] = React.useState("personal")
|
||||
|
||||
@@ -1,21 +1,20 @@
|
||||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
import { AudioLinesIcon, PlusIcon } from "lucide-react"
|
||||
|
||||
import { Button } from "@/registry/new-york-v4/ui/button"
|
||||
import { ButtonGroup } from "@/registry/new-york-v4/ui/button-group"
|
||||
import { Button } from "@/examples/radix/ui/button"
|
||||
import { ButtonGroup } from "@/examples/radix/ui/button-group"
|
||||
import {
|
||||
InputGroup,
|
||||
InputGroupAddon,
|
||||
InputGroupButton,
|
||||
InputGroupInput,
|
||||
} from "@/registry/new-york-v4/ui/input-group"
|
||||
} from "@/examples/radix/ui/input-group"
|
||||
import {
|
||||
Tooltip,
|
||||
TooltipContent,
|
||||
TooltipTrigger,
|
||||
} from "@/registry/new-york-v4/ui/tooltip"
|
||||
} from "@/examples/radix/ui/tooltip"
|
||||
import { AudioLinesIcon, PlusIcon } from "lucide-react"
|
||||
|
||||
export function ButtonGroupInputGroup() {
|
||||
const [voiceEnabled, setVoiceEnabled] = React.useState(false)
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
"use client"
|
||||
|
||||
import { Button } from "@/examples/radix/ui/button"
|
||||
import { ButtonGroup } from "@/examples/radix/ui/button-group"
|
||||
import { ArrowLeftIcon, ArrowRightIcon } from "lucide-react"
|
||||
|
||||
import { Button } from "@/registry/new-york-v4/ui/button"
|
||||
import { ButtonGroup } from "@/registry/new-york-v4/ui/button-group"
|
||||
|
||||
export function ButtonGroupNested() {
|
||||
return (
|
||||
<ButtonGroup>
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
import { BotIcon, ChevronDownIcon } from "lucide-react"
|
||||
|
||||
import { Button } from "@/registry/new-york-v4/ui/button"
|
||||
import { ButtonGroup } from "@/registry/new-york-v4/ui/button-group"
|
||||
import { Button } from "@/examples/radix/ui/button"
|
||||
import { ButtonGroup } from "@/examples/radix/ui/button-group"
|
||||
import {
|
||||
Popover,
|
||||
PopoverContent,
|
||||
PopoverTrigger,
|
||||
} from "@/registry/new-york-v4/ui/popover"
|
||||
import { Separator } from "@/registry/new-york-v4/ui/separator"
|
||||
import { Textarea } from "@/registry/new-york-v4/ui/textarea"
|
||||
} from "@/examples/radix/ui/popover"
|
||||
import { Separator } from "@/examples/radix/ui/separator"
|
||||
import { Textarea } from "@/examples/radix/ui/textarea"
|
||||
import { BotIcon, ChevronDownIcon } from "lucide-react"
|
||||
|
||||
export function ButtonGroupPopover() {
|
||||
return (
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
import { PlusIcon } from "lucide-react"
|
||||
|
||||
import {
|
||||
Avatar,
|
||||
AvatarFallback,
|
||||
AvatarImage,
|
||||
} from "@/registry/new-york-v4/ui/avatar"
|
||||
import { Button } from "@/registry/new-york-v4/ui/button"
|
||||
import { Avatar, AvatarFallback, AvatarImage } from "@/examples/radix/ui/avatar"
|
||||
import { Button } from "@/examples/radix/ui/button"
|
||||
import {
|
||||
Empty,
|
||||
EmptyContent,
|
||||
@@ -13,7 +7,8 @@ import {
|
||||
EmptyHeader,
|
||||
EmptyMedia,
|
||||
EmptyTitle,
|
||||
} from "@/registry/new-york-v4/ui/empty"
|
||||
} from "@/examples/radix/ui/empty"
|
||||
import { PlusIcon } from "lucide-react"
|
||||
|
||||
export function EmptyAvatarGroup() {
|
||||
return (
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Checkbox } from "@/registry/new-york-v4/ui/checkbox"
|
||||
import { Field, FieldLabel } from "@/registry/new-york-v4/ui/field"
|
||||
import { Checkbox } from "@/examples/radix/ui/checkbox"
|
||||
import { Field, FieldLabel } from "@/examples/radix/ui/field"
|
||||
|
||||
export function FieldCheckbox() {
|
||||
return (
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Button } from "@/registry/new-york-v4/ui/button"
|
||||
import { Checkbox } from "@/registry/new-york-v4/ui/checkbox"
|
||||
import { Button } from "@/examples/radix/ui/button"
|
||||
import { Checkbox } from "@/examples/radix/ui/checkbox"
|
||||
import {
|
||||
Field,
|
||||
FieldDescription,
|
||||
@@ -8,16 +8,16 @@ import {
|
||||
FieldLegend,
|
||||
FieldSeparator,
|
||||
FieldSet,
|
||||
} from "@/registry/new-york-v4/ui/field"
|
||||
import { Input } from "@/registry/new-york-v4/ui/input"
|
||||
} from "@/examples/radix/ui/field"
|
||||
import { Input } from "@/examples/radix/ui/input"
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/registry/new-york-v4/ui/select"
|
||||
import { Textarea } from "@/registry/new-york-v4/ui/textarea"
|
||||
} from "@/examples/radix/ui/select"
|
||||
import { Textarea } from "@/examples/radix/ui/textarea"
|
||||
|
||||
export function FieldDemo() {
|
||||
return (
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Card, CardContent } from "@/registry/new-york-v4/ui/card"
|
||||
import { Checkbox } from "@/registry/new-york-v4/ui/checkbox"
|
||||
import { Card, CardContent } from "@/examples/radix/ui/card"
|
||||
import { Checkbox } from "@/examples/radix/ui/checkbox"
|
||||
import {
|
||||
Field,
|
||||
FieldDescription,
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
FieldLegend,
|
||||
FieldSet,
|
||||
FieldTitle,
|
||||
} from "@/registry/new-york-v4/ui/field"
|
||||
} from "@/examples/radix/ui/field"
|
||||
|
||||
const options = [
|
||||
{
|
||||
|
||||
@@ -1,13 +1,8 @@
|
||||
"use client"
|
||||
|
||||
import { useState } from "react"
|
||||
|
||||
import {
|
||||
Field,
|
||||
FieldDescription,
|
||||
FieldTitle,
|
||||
} from "@/registry/new-york-v4/ui/field"
|
||||
import { Slider } from "@/registry/new-york-v4/ui/slider"
|
||||
import { Field, FieldDescription, FieldTitle } from "@/examples/radix/ui/field"
|
||||
import { Slider } from "@/examples/radix/ui/slider"
|
||||
|
||||
export function FieldSlider() {
|
||||
const [value, setValue] = useState([200, 800])
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { FieldSeparator } from "@/registry/new-york-v4/ui/field"
|
||||
import { FieldSeparator } from "@/examples/radix/ui/field"
|
||||
|
||||
import { AppearanceSettings } from "./appearance-settings"
|
||||
import { ButtonGroupDemo } from "./button-group-demo"
|
||||
|
||||
@@ -1,20 +1,19 @@
|
||||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
import { IconInfoCircle, IconStar } from "@tabler/icons-react"
|
||||
|
||||
import {
|
||||
InputGroup,
|
||||
InputGroupAddon,
|
||||
InputGroupButton,
|
||||
InputGroupInput,
|
||||
} from "@/registry/new-york-v4/ui/input-group"
|
||||
import { Label } from "@/registry/new-york-v4/ui/label"
|
||||
} from "@/examples/radix/ui/input-group"
|
||||
import { Label } from "@/examples/radix/ui/label"
|
||||
import {
|
||||
Popover,
|
||||
PopoverContent,
|
||||
PopoverTrigger,
|
||||
} from "@/registry/new-york-v4/ui/popover"
|
||||
} from "@/examples/radix/ui/popover"
|
||||
import { IconInfoCircle, IconStar } from "@tabler/icons-react"
|
||||
|
||||
export function InputGroupButtonExample() {
|
||||
const [isFavorite, setIsFavorite] = React.useState(false)
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
import { IconCheck, IconInfoCircle, IconPlus } from "@tabler/icons-react"
|
||||
import { ArrowUpIcon, Search } from "lucide-react"
|
||||
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/registry/new-york-v4/ui/dropdown-menu"
|
||||
} from "@/examples/radix/ui/dropdown-menu"
|
||||
import {
|
||||
InputGroup,
|
||||
InputGroupAddon,
|
||||
@@ -14,13 +11,15 @@ import {
|
||||
InputGroupInput,
|
||||
InputGroupText,
|
||||
InputGroupTextarea,
|
||||
} from "@/registry/new-york-v4/ui/input-group"
|
||||
import { Separator } from "@/registry/new-york-v4/ui/separator"
|
||||
} from "@/examples/radix/ui/input-group"
|
||||
import { Separator } from "@/examples/radix/ui/separator"
|
||||
import {
|
||||
Tooltip,
|
||||
TooltipContent,
|
||||
TooltipTrigger,
|
||||
} from "@/registry/new-york-v4/ui/tooltip"
|
||||
} from "@/examples/radix/ui/tooltip"
|
||||
import { IconCheck, IconInfoCircle, IconPlus } from "@tabler/icons-react"
|
||||
import { ArrowUpIcon, Search } from "lucide-react"
|
||||
|
||||
export function InputGroupDemo() {
|
||||
return (
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
import { BadgeCheckIcon, ChevronRightIcon } from "lucide-react"
|
||||
|
||||
import { Button } from "@/registry/new-york-v4/ui/button"
|
||||
import { Button } from "@/examples/radix/ui/button"
|
||||
import {
|
||||
Item,
|
||||
ItemActions,
|
||||
@@ -8,7 +6,8 @@ import {
|
||||
ItemDescription,
|
||||
ItemMedia,
|
||||
ItemTitle,
|
||||
} from "@/registry/new-york-v4/ui/item"
|
||||
} from "@/examples/radix/ui/item"
|
||||
import { BadgeCheckIcon, ChevronRightIcon } from "lucide-react"
|
||||
|
||||
export function ItemDemo() {
|
||||
return (
|
||||
|
||||
@@ -1,24 +1,8 @@
|
||||
"use client"
|
||||
|
||||
import { useMemo, useState } from "react"
|
||||
import {
|
||||
IconApps,
|
||||
IconArrowUp,
|
||||
IconAt,
|
||||
IconBook,
|
||||
IconCircleDashedPlus,
|
||||
IconPaperclip,
|
||||
IconPlus,
|
||||
IconWorld,
|
||||
IconX,
|
||||
} from "@tabler/icons-react"
|
||||
|
||||
import {
|
||||
Avatar,
|
||||
AvatarFallback,
|
||||
AvatarImage,
|
||||
} from "@/registry/new-york-v4/ui/avatar"
|
||||
import { Badge } from "@/registry/new-york-v4/ui/badge"
|
||||
import { Avatar, AvatarFallback, AvatarImage } from "@/examples/radix/ui/avatar"
|
||||
import { Badge } from "@/examples/radix/ui/badge"
|
||||
import {
|
||||
Command,
|
||||
CommandEmpty,
|
||||
@@ -26,7 +10,7 @@ import {
|
||||
CommandInput,
|
||||
CommandItem,
|
||||
CommandList,
|
||||
} from "@/registry/new-york-v4/ui/command"
|
||||
} from "@/examples/radix/ui/command"
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuCheckboxItem,
|
||||
@@ -39,25 +23,36 @@ import {
|
||||
DropdownMenuSubContent,
|
||||
DropdownMenuSubTrigger,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/registry/new-york-v4/ui/dropdown-menu"
|
||||
import { Field, FieldLabel } from "@/registry/new-york-v4/ui/field"
|
||||
} from "@/examples/radix/ui/dropdown-menu"
|
||||
import { Field, FieldLabel } from "@/examples/radix/ui/field"
|
||||
import {
|
||||
InputGroup,
|
||||
InputGroupAddon,
|
||||
InputGroupButton,
|
||||
InputGroupTextarea,
|
||||
} from "@/registry/new-york-v4/ui/input-group"
|
||||
} from "@/examples/radix/ui/input-group"
|
||||
import {
|
||||
Popover,
|
||||
PopoverContent,
|
||||
PopoverTrigger,
|
||||
} from "@/registry/new-york-v4/ui/popover"
|
||||
import { Switch } from "@/registry/new-york-v4/ui/switch"
|
||||
} from "@/examples/radix/ui/popover"
|
||||
import { Switch } from "@/examples/radix/ui/switch"
|
||||
import {
|
||||
Tooltip,
|
||||
TooltipContent,
|
||||
TooltipTrigger,
|
||||
} from "@/registry/new-york-v4/ui/tooltip"
|
||||
} from "@/examples/radix/ui/tooltip"
|
||||
import {
|
||||
IconApps,
|
||||
IconArrowUp,
|
||||
IconAt,
|
||||
IconBook,
|
||||
IconCircleDashedPlus,
|
||||
IconPaperclip,
|
||||
IconPlus,
|
||||
IconWorld,
|
||||
IconX,
|
||||
} from "@tabler/icons-react"
|
||||
|
||||
const SAMPLE_DATA = {
|
||||
mentionable: [
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Badge } from "@/registry/new-york-v4/ui/badge"
|
||||
import { Spinner } from "@/registry/new-york-v4/ui/spinner"
|
||||
import { Badge } from "@/examples/radix/ui/badge"
|
||||
import { Spinner } from "@/examples/radix/ui/spinner"
|
||||
|
||||
export function SpinnerBadge() {
|
||||
return (
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Button } from "@/registry/new-york-v4/ui/button"
|
||||
import { Button } from "@/examples/radix/ui/button"
|
||||
import {
|
||||
Empty,
|
||||
EmptyContent,
|
||||
@@ -6,8 +6,8 @@ import {
|
||||
EmptyHeader,
|
||||
EmptyMedia,
|
||||
EmptyTitle,
|
||||
} from "@/registry/new-york-v4/ui/empty"
|
||||
import { Spinner } from "@/registry/new-york-v4/ui/spinner"
|
||||
} from "@/examples/radix/ui/empty"
|
||||
import { Spinner } from "@/examples/radix/ui/spinner"
|
||||
|
||||
export function SpinnerEmpty() {
|
||||
return (
|
||||
|
||||
@@ -64,7 +64,7 @@ export default function ChartsLayout({
|
||||
<PageNav id="charts">
|
||||
<ChartsNav />
|
||||
</PageNav>
|
||||
<div className="container-wrapper section-soft flex-1">
|
||||
<div className="container-wrapper flex-1">
|
||||
<div className="container pb-6">
|
||||
<section className="theme-container">{children}</section>
|
||||
</div>
|
||||
|
||||
@@ -1,21 +1,15 @@
|
||||
import Link from "next/link"
|
||||
import { notFound } from "next/navigation"
|
||||
import { mdxComponents } from "@/mdx-components"
|
||||
import {
|
||||
IconArrowLeft,
|
||||
IconArrowRight,
|
||||
IconArrowUpRight,
|
||||
} from "@tabler/icons-react"
|
||||
import fm from "front-matter"
|
||||
import { IconArrowLeft, IconArrowRight } from "@tabler/icons-react"
|
||||
import { findNeighbour } from "fumadocs-core/page-tree"
|
||||
import z from "zod"
|
||||
|
||||
import { source } from "@/lib/source"
|
||||
import { absoluteUrl } from "@/lib/utils"
|
||||
import { DocsBaseSwitcher } from "@/components/docs-base-switcher"
|
||||
import { DocsCopyPage } from "@/components/docs-copy-page"
|
||||
import { DocsTableOfContents } from "@/components/docs-toc"
|
||||
import { OpenInV0Cta } from "@/components/open-in-v0-cta"
|
||||
import { Badge } from "@/registry/new-york-v4/ui/badge"
|
||||
import { Button } from "@/registry/new-york-v4/ui/button"
|
||||
|
||||
export const revalidate = false
|
||||
@@ -86,126 +80,110 @@ export default async function Page(props: {
|
||||
const doc = page.data
|
||||
const MDX = doc.body
|
||||
const neighbours = findNeighbour(source.pageTree, page.url)
|
||||
|
||||
const raw = await page.data.getText("raw")
|
||||
const { attributes } = fm(raw)
|
||||
const { links } = z
|
||||
.object({
|
||||
links: z
|
||||
.object({
|
||||
doc: z.string().optional(),
|
||||
api: z.string().optional(),
|
||||
})
|
||||
.optional(),
|
||||
})
|
||||
.parse(attributes)
|
||||
|
||||
return (
|
||||
<div className="flex items-stretch text-[1.05rem] sm:text-[15px] xl:w-full">
|
||||
<div
|
||||
data-slot="docs"
|
||||
className="flex scroll-mt-24 items-stretch pb-8 text-[1.05rem] sm:text-[15px] xl:w-full"
|
||||
>
|
||||
<div className="flex min-w-0 flex-1 flex-col">
|
||||
<div className="h-(--top-spacing) shrink-0" />
|
||||
<div className="mx-auto flex w-full max-w-2xl min-w-0 flex-1 flex-col gap-8 px-4 py-6 text-neutral-800 md:px-0 lg:py-8 dark:text-neutral-300">
|
||||
<div className="mx-auto flex w-full max-w-[40rem] min-w-0 flex-1 flex-col gap-6 px-4 py-6 text-neutral-800 md:px-0 lg:py-8 dark:text-neutral-300">
|
||||
<div className="flex flex-col gap-2">
|
||||
<div className="flex flex-col gap-2">
|
||||
<div className="flex items-start justify-between">
|
||||
<h1 className="scroll-m-20 text-4xl font-semibold tracking-tight sm:text-3xl xl:text-4xl">
|
||||
<h1 className="scroll-m-24 text-4xl font-semibold tracking-tight sm:text-3xl">
|
||||
{doc.title}
|
||||
</h1>
|
||||
<div className="docs-nav bg-background/80 border-border/50 fixed inset-x-0 bottom-0 isolate z-50 flex items-center gap-2 border-t px-6 py-4 backdrop-blur-sm sm:static sm:z-0 sm:border-t-0 sm:bg-transparent sm:px-0 sm:pt-1.5 sm:backdrop-blur-none">
|
||||
<div className="docs-nav bg-background/80 border-border/50 fixed inset-x-0 bottom-0 isolate z-50 flex items-center gap-2 border-t px-6 py-4 backdrop-blur-sm sm:static sm:z-0 sm:border-t-0 sm:bg-transparent sm:px-0 sm:py-1.5 sm:backdrop-blur-none">
|
||||
<DocsCopyPage page={raw} url={absoluteUrl(page.url)} />
|
||||
{neighbours.previous && (
|
||||
<Button
|
||||
variant="secondary"
|
||||
size="icon"
|
||||
className="extend-touch-target ml-auto size-8 shadow-none md:size-7"
|
||||
asChild
|
||||
>
|
||||
<Link href={neighbours.previous.url}>
|
||||
<IconArrowLeft />
|
||||
<span className="sr-only">Previous</span>
|
||||
</Link>
|
||||
</Button>
|
||||
)}
|
||||
{neighbours.next && (
|
||||
<Button
|
||||
variant="secondary"
|
||||
size="icon"
|
||||
className="extend-touch-target size-8 shadow-none md:size-7"
|
||||
asChild
|
||||
>
|
||||
<Link href={neighbours.next.url}>
|
||||
<span className="sr-only">Next</span>
|
||||
<IconArrowRight />
|
||||
</Link>
|
||||
</Button>
|
||||
)}
|
||||
<div className="ml-auto flex gap-2">
|
||||
{neighbours.previous && (
|
||||
<Button
|
||||
variant="secondary"
|
||||
size="icon"
|
||||
className="extend-touch-target size-8 shadow-none md:size-7"
|
||||
asChild
|
||||
>
|
||||
<Link href={neighbours.previous.url}>
|
||||
<IconArrowLeft />
|
||||
<span className="sr-only">Previous</span>
|
||||
</Link>
|
||||
</Button>
|
||||
)}
|
||||
{neighbours.next && (
|
||||
<Button
|
||||
variant="secondary"
|
||||
size="icon"
|
||||
className="extend-touch-target size-8 shadow-none md:size-7"
|
||||
asChild
|
||||
>
|
||||
<Link href={neighbours.next.url}>
|
||||
<span className="sr-only">Next</span>
|
||||
<IconArrowRight />
|
||||
</Link>
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{doc.description && (
|
||||
<p className="text-muted-foreground text-[1.05rem] text-balance sm:text-base">
|
||||
<p className="text-muted-foreground text-[1.05rem] sm:text-base sm:text-balance md:max-w-[80%]">
|
||||
{doc.description}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
{links ? (
|
||||
<div className="flex items-center gap-2 pt-4">
|
||||
{links?.doc && (
|
||||
<Badge asChild variant="secondary" className="rounded-full">
|
||||
<a href={links.doc} target="_blank" rel="noreferrer">
|
||||
Docs <IconArrowUpRight />
|
||||
</a>
|
||||
</Badge>
|
||||
)}
|
||||
{links?.api && (
|
||||
<Badge asChild variant="secondary" className="rounded-full">
|
||||
<a href={links.api} target="_blank" rel="noreferrer">
|
||||
API Reference <IconArrowUpRight />
|
||||
</a>
|
||||
</Badge>
|
||||
)}
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
<div className="w-full flex-1 *:data-[slot=alert]:first:mt-0">
|
||||
<div className="w-full flex-1 pb-16 *:data-[slot=alert]:first:mt-0 sm:pb-0">
|
||||
{params.slug &&
|
||||
params.slug[0] === "components" &&
|
||||
params.slug[1] &&
|
||||
params.slug[2] && (
|
||||
<DocsBaseSwitcher
|
||||
base={params.slug[1]}
|
||||
component={params.slug[2]}
|
||||
className="mb-4"
|
||||
/>
|
||||
)}
|
||||
<MDX components={mdxComponents} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="mx-auto hidden h-16 w-full max-w-2xl items-center gap-2 px-4 sm:flex md:px-0">
|
||||
{neighbours.previous && (
|
||||
<Button
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
asChild
|
||||
className="shadow-none"
|
||||
>
|
||||
<Link href={neighbours.previous.url}>
|
||||
<IconArrowLeft /> {neighbours.previous.name}
|
||||
</Link>
|
||||
</Button>
|
||||
)}
|
||||
{neighbours.next && (
|
||||
<Button
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
className="ml-auto shadow-none"
|
||||
asChild
|
||||
>
|
||||
<Link href={neighbours.next.url}>
|
||||
{neighbours.next.name} <IconArrowRight />
|
||||
</Link>
|
||||
</Button>
|
||||
)}
|
||||
<div className="hidden h-16 w-full items-center gap-2 px-4 sm:flex sm:px-0">
|
||||
{neighbours.previous && (
|
||||
<Button
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
asChild
|
||||
className="shadow-none"
|
||||
>
|
||||
<Link href={neighbours.previous.url}>
|
||||
<IconArrowLeft /> {neighbours.previous.name}
|
||||
</Link>
|
||||
</Button>
|
||||
)}
|
||||
{neighbours.next && (
|
||||
<Button
|
||||
variant="secondary"
|
||||
size="sm"
|
||||
className="ml-auto shadow-none"
|
||||
asChild
|
||||
>
|
||||
<Link href={neighbours.next.url}>
|
||||
{neighbours.next.name} <IconArrowRight />
|
||||
</Link>
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="sticky top-[calc(var(--header-height)+1px)] z-30 ml-auto hidden h-[calc(100svh-var(--footer-height)+2rem)] w-72 flex-col gap-4 overflow-hidden overscroll-none pb-8 xl:flex">
|
||||
<div className="h-(--top-spacing) shrink-0" />
|
||||
<div className="sticky top-[calc(var(--header-height)+1px)] z-30 ml-auto hidden h-[90svh] w-72 flex-col gap-4 overflow-hidden overscroll-none pb-8 lg:flex">
|
||||
<div className="h-(--top-spacing) shrink-0"></div>
|
||||
{doc.toc?.length ? (
|
||||
<div className="no-scrollbar overflow-y-auto px-8">
|
||||
<div className="no-scrollbar flex flex-col gap-8 overflow-y-auto px-8">
|
||||
<DocsTableOfContents toc={doc.toc} />
|
||||
<div className="h-12" />
|
||||
</div>
|
||||
) : null}
|
||||
<div className="flex flex-1 flex-col gap-12 px-6">
|
||||
<div className="hidden flex-1 flex-col gap-6 px-6 xl:flex">
|
||||
<OpenInV0Cta />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -9,7 +9,10 @@ export default function DocsLayout({
|
||||
}) {
|
||||
return (
|
||||
<div className="container-wrapper flex flex-1 flex-col px-2">
|
||||
<SidebarProvider className="3xl:fixed:container 3xl:fixed:px-3 min-h-min flex-1 items-start px-0 [--sidebar-width:220px] [--top-spacing:0] lg:grid lg:grid-cols-[var(--sidebar-width)_minmax(0,1fr)] lg:[--sidebar-width:240px] lg:[--top-spacing:calc(var(--spacing)*4)]">
|
||||
<SidebarProvider
|
||||
className="3xl:fixed:container 3xl:fixed:px-3 min-h-min flex-1 items-start px-0 [--top-spacing:0] lg:grid lg:grid-cols-[var(--sidebar-width)_minmax(0,1fr)] lg:[--top-spacing:calc(var(--spacing)*4)]"
|
||||
style={{ "--sidebar-width": "220px" } as React.CSSProperties}
|
||||
>
|
||||
<DocsSidebar tree={source.pageTree} />
|
||||
<div className="h-full w-full">{children}</div>
|
||||
</SidebarProvider>
|
||||
|
||||
@@ -3,10 +3,23 @@ import { NextResponse, type NextRequest } from "next/server"
|
||||
|
||||
import { processMdxForLLMs } from "@/lib/llm"
|
||||
import { source } from "@/lib/source"
|
||||
import { getActiveStyle } from "@/registry/_legacy-styles"
|
||||
import { getActiveStyle, type Style } from "@/registry/_legacy-styles"
|
||||
|
||||
export const revalidate = false
|
||||
|
||||
function getStyleFromSlug(slug: string[] | undefined, fallbackStyle: string) {
|
||||
// Detect base from URL: /docs/components/base/... or /docs/components/radix/...
|
||||
if (slug && slug[0] === "components" && slug[1]) {
|
||||
if (slug[1] === "base") {
|
||||
return "base-nova"
|
||||
}
|
||||
if (slug[1] === "radix") {
|
||||
return "new-york-v4"
|
||||
}
|
||||
}
|
||||
return fallbackStyle
|
||||
}
|
||||
|
||||
export async function GET(
|
||||
_req: NextRequest,
|
||||
{ params }: { params: Promise<{ slug?: string[] }> }
|
||||
@@ -19,9 +32,11 @@ export async function GET(
|
||||
notFound()
|
||||
}
|
||||
|
||||
const effectiveStyle = getStyleFromSlug(slug, activeStyle.name)
|
||||
|
||||
const processedContent = processMdxForLLMs(
|
||||
await page.data.getText("raw"),
|
||||
activeStyle.name
|
||||
effectiveStyle as Style["name"]
|
||||
)
|
||||
|
||||
return new NextResponse(processedContent, {
|
||||
|
||||
@@ -99,7 +99,7 @@ export function ItemPicker({
|
||||
variant="outline"
|
||||
aria-label="Select item"
|
||||
size="sm"
|
||||
className="data-popup-open:bg-muted dark:data-popup-open:bg-muted/50 bg-muted/50 sm:bg-background md:dark:bg-background border-foreground/10 dark:bg-muted/50 h-[calc(--spacing(13.5))] flex-1 touch-manipulation justify-between gap-2 rounded-xl pr-4! pl-2.5 text-left shadow-none select-none *:data-[slot=combobox-trigger-icon]:hidden sm:h-8 sm:max-w-56 sm:rounded-lg sm:pr-2! xl:max-w-md"
|
||||
className="data-popup-open:bg-muted dark:data-popup-open:bg-muted/50 bg-muted/50 sm:bg-background md:dark:bg-background border-foreground/10 dark:bg-muted/50 h-[calc(--spacing(13.5))] flex-1 touch-manipulation justify-between gap-2 rounded-xl pr-4! pl-2.5 text-left shadow-none select-none *:data-[slot=combobox-trigger-icon]:hidden sm:h-8 sm:max-w-56 sm:rounded-lg sm:pr-2! xl:max-w-64"
|
||||
/>
|
||||
}
|
||||
>
|
||||
@@ -123,9 +123,9 @@ export function ItemPicker({
|
||||
<HugeiconsIcon icon={Search01Icon} />
|
||||
</ComboboxTrigger>
|
||||
<ComboboxContent
|
||||
className="ring-foreground/10 min-w-[calc(var(--available-width)---spacing(4))] translate-x-2 animate-none rounded-xl border-0 ring-1 data-open:animate-none sm:min-w-[calc(var(--anchor-width)+--spacing(7))] sm:translate-x-0"
|
||||
className="ring-foreground/10 min-w-[calc(var(--available-width)---spacing(4))] translate-x-2 animate-none rounded-xl border-0 ring-1 data-open:animate-none sm:min-w-[calc(var(--anchor-width)+--spacing(7))] sm:translate-x-0 xl:w-96"
|
||||
side="bottom"
|
||||
align="center"
|
||||
align="end"
|
||||
>
|
||||
<ComboboxInput
|
||||
showTrigger={false}
|
||||
|
||||
@@ -56,7 +56,7 @@ export function ShareButton() {
|
||||
<Button
|
||||
size="sm"
|
||||
variant="outline"
|
||||
className="rounded-lg shadow-none"
|
||||
className="rounded-lg shadow-none lg:w-8 xl:w-fit"
|
||||
onClick={handleCopy}
|
||||
>
|
||||
{hasCopied ? (
|
||||
@@ -64,7 +64,7 @@ export function ShareButton() {
|
||||
) : (
|
||||
<HugeiconsIcon icon={Share03Icon} strokeWidth={2} />
|
||||
)}
|
||||
Share
|
||||
<span className="lg:hidden xl:block">Share</span>
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>Copy Link</TooltipContent>
|
||||
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
import { useDesignSystemSearchParams } from "@/app/(create)/lib/search-params"
|
||||
|
||||
export function V0Button({ className }: { className?: string }) {
|
||||
const [params, setParams] = useDesignSystemSearchParams()
|
||||
const [params] = useDesignSystemSearchParams()
|
||||
const isMobile = useIsMobile()
|
||||
const isMounted = useMounted()
|
||||
|
||||
@@ -32,7 +32,7 @@ export function V0Button({ className }: { className?: string }) {
|
||||
size="sm"
|
||||
variant={isMobile ? "default" : "outline"}
|
||||
className={cn(
|
||||
"w-24 rounded-lg shadow-none data-[variant=default]:h-[31px]",
|
||||
"w-24 rounded-lg shadow-none data-[variant=default]:h-[31px] lg:w-8 xl:w-24",
|
||||
className
|
||||
)}
|
||||
asChild
|
||||
@@ -41,7 +41,8 @@ export function V0Button({ className }: { className?: string }) {
|
||||
href={`${process.env.NEXT_PUBLIC_V0_URL}/chat/api/open?url=${encodeURIComponent(url)}&title=${params.item}`}
|
||||
target="_blank"
|
||||
>
|
||||
Open in <Icons.v0 className="size-5" />
|
||||
<span className="lg:hidden xl:block">Open in</span>
|
||||
<Icons.v0 className="size-5" />
|
||||
</a>
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
|
||||
@@ -4,7 +4,11 @@ import { ArrowLeftIcon } from "lucide-react"
|
||||
import type { SearchParams } from "nuqs/server"
|
||||
|
||||
import { siteConfig } from "@/lib/config"
|
||||
import { source } from "@/lib/source"
|
||||
import { absoluteUrl } from "@/lib/utils"
|
||||
import { Icons } from "@/components/icons"
|
||||
import { MainNav } from "@/components/main-nav"
|
||||
import { MobileNav } from "@/components/mobile-nav"
|
||||
import { ModeSwitcher } from "@/components/mode-switcher"
|
||||
import { SiteConfig } from "@/components/site-config"
|
||||
import { BASES } from "@/registry/config"
|
||||
@@ -64,6 +68,7 @@ export default async function CreatePage({
|
||||
const params = await loadDesignSystemSearchParams(searchParams)
|
||||
const base = BASES.find((b) => b.name === params.base) ?? BASES[0]
|
||||
|
||||
const pageTree = source.pageTree
|
||||
const items = await getItemsForBase(base.name)
|
||||
|
||||
const filteredItems = items
|
||||
@@ -82,38 +87,34 @@ export default async function CreatePage({
|
||||
<header className="sticky top-0 z-50 w-full">
|
||||
<div className="container-wrapper 3xl:fixed:px-0 px-6">
|
||||
<div className="3xl:fixed:container flex h-(--header-height) items-center **:data-[slot=separator]:!h-4">
|
||||
<div className="flex items-center xl:w-1/3">
|
||||
<div className="3xl:fixed:container flex h-(--header-height) items-center **:data-[slot=separator]:!h-4">
|
||||
<MobileNav
|
||||
tree={pageTree}
|
||||
items={siteConfig.navItems}
|
||||
className="flex lg:hidden"
|
||||
/>
|
||||
<Button
|
||||
asChild
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="rounded-lg shadow-none"
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className="hidden size-8 lg:flex"
|
||||
>
|
||||
<Link href="/">
|
||||
<ArrowLeftIcon />
|
||||
Back
|
||||
<Icons.logo className="size-5" />
|
||||
<span className="sr-only">{siteConfig.name}</span>
|
||||
</Link>
|
||||
</Button>
|
||||
<Separator
|
||||
orientation="vertical"
|
||||
className="mx-2 hidden sm:mx-4 lg:flex"
|
||||
/>
|
||||
<div className="text-muted-foreground hidden text-sm font-medium lg:flex">
|
||||
New Project
|
||||
</div>
|
||||
<MainNav items={siteConfig.navItems} className="hidden lg:flex" />
|
||||
</div>
|
||||
<div className="fixed inset-x-0 bottom-0 ml-auto flex flex-1 items-center gap-2 px-4.5 pb-4 sm:static sm:justify-end sm:p-0 lg:ml-0 xl:justify-center">
|
||||
<div className="fixed inset-x-0 bottom-0 ml-auto flex flex-1 items-center justify-end gap-2 px-4.5 pb-4 sm:static sm:p-0 lg:ml-0">
|
||||
<ItemPicker items={filteredItems} />
|
||||
<div className="items-center gap-0 sm:hidden">
|
||||
<RandomButton />
|
||||
<ResetButton />
|
||||
</div>
|
||||
<Separator
|
||||
orientation="vertical"
|
||||
className="mr-2 hidden sm:flex xl:hidden"
|
||||
/>
|
||||
<Separator orientation="vertical" className="mr-2 flex" />
|
||||
</div>
|
||||
<div className="ml-auto flex items-center gap-2 sm:ml-0 md:justify-end xl:ml-auto xl:w-1/3">
|
||||
<div className="ml-auto flex items-center gap-2 sm:ml-0 md:justify-end">
|
||||
<SiteConfig className="3xl:flex hidden" />
|
||||
<Separator orientation="vertical" className="3xl:flex hidden" />
|
||||
<ModeSwitcher />
|
||||
|
||||
@@ -4,7 +4,11 @@ import { type Metadata } from "next"
|
||||
import { notFound } from "next/navigation"
|
||||
|
||||
import { siteConfig } from "@/lib/config"
|
||||
import { getRegistryComponent, getRegistryItem } from "@/lib/registry"
|
||||
import {
|
||||
getDemoItem,
|
||||
getRegistryComponent,
|
||||
getRegistryItem,
|
||||
} from "@/lib/registry"
|
||||
import { absoluteUrl } from "@/lib/utils"
|
||||
import { getStyle, legacyStyles, type Style } from "@/registry/_legacy-styles"
|
||||
|
||||
@@ -18,7 +22,12 @@ export const dynamicParams = false
|
||||
|
||||
const getCachedRegistryItem = React.cache(
|
||||
async (name: string, styleName: Style["name"]) => {
|
||||
return await getRegistryItem(name, styleName)
|
||||
// Try registry item first, then fallback to demo item (for examples).
|
||||
const item = await getRegistryItem(name, styleName)
|
||||
if (item) {
|
||||
return item
|
||||
}
|
||||
return await getDemoItem(name, styleName)
|
||||
}
|
||||
)
|
||||
|
||||
@@ -75,9 +84,54 @@ export async function generateMetadata({
|
||||
|
||||
export async function generateStaticParams() {
|
||||
const { Index } = await import("@/registry/__index__")
|
||||
// const { Index: BasesIndex } = await import("@/registry/bases/__index__")
|
||||
const { ExamplesIndex } = await import("@/examples/__index__")
|
||||
const params: Array<{ style: string; name: string }> = []
|
||||
|
||||
for (const style of legacyStyles) {
|
||||
// Check if this is a base-prefixed style (e.g., base-nova, radix-nova).
|
||||
const baseMatch = style.name.match(/^(base|radix)-/)
|
||||
if (baseMatch) {
|
||||
const baseName = baseMatch[1]
|
||||
|
||||
// Add examples from ExamplesIndex.
|
||||
const examples = ExamplesIndex[baseName]
|
||||
if (examples) {
|
||||
for (const exampleName of Object.keys(examples)) {
|
||||
if (exampleName.startsWith("sidebar-")) {
|
||||
params.push({
|
||||
style: style.name,
|
||||
name: exampleName,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// // Add UI components from BasesIndex.
|
||||
// const baseIndex = BasesIndex[baseName]
|
||||
// if (baseIndex) {
|
||||
// for (const itemName in baseIndex) {
|
||||
// const item = baseIndex[itemName]
|
||||
// if (
|
||||
// [
|
||||
// "registry:block",
|
||||
// "registry:component",
|
||||
// "registry:example",
|
||||
// "registry:internal",
|
||||
// ].includes(item.type)
|
||||
// ) {
|
||||
// params.push({
|
||||
// style: style.name,
|
||||
// name: item.name,
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
// Handle legacy styles (e.g., new-york-v4).
|
||||
if (!Index[style.name]) {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -3,12 +3,27 @@ import { ArrowRightIcon } from "lucide-react"
|
||||
|
||||
import { Badge } from "@/registry/new-york-v4/ui/badge"
|
||||
|
||||
function BaseUILogo() {
|
||||
return (
|
||||
<svg width="17" height="24" viewBox="0 0 17 24" className="size-3">
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M9.5001 7.01537C9.2245 6.99837 9 7.22385 9 7.49999V23C13.4183 23 17 19.4183 17 15C17 10.7497 13.6854 7.27351 9.5001 7.01537Z"
|
||||
/>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M8 9.8V12V23C3.58172 23 0 19.0601 0 14.2V12V1C4.41828 1 8 4.93989 8 9.8Z"
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
export function Announcement() {
|
||||
return (
|
||||
<Badge asChild variant="secondary" className="bg-transparent">
|
||||
<Link href="/docs/changelog">
|
||||
<span className="flex size-2 rounded-full bg-blue-500" title="New" />
|
||||
npx shadcn create <ArrowRightIcon />
|
||||
<BaseUILogo />
|
||||
Base UI Documentation <ArrowRightIcon />
|
||||
</Link>
|
||||
</Badge>
|
||||
)
|
||||
|
||||
@@ -35,7 +35,7 @@ export function ChartDisplay({
|
||||
<div className="bg-background relative z-10 overflow-hidden rounded-xl">
|
||||
<ChartIframe
|
||||
src={`/view/${style}/${chart.name}`}
|
||||
height={430}
|
||||
height={460}
|
||||
title={chart.name}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -18,7 +18,7 @@ export function CodeTabs({ children }: React.ComponentProps<typeof Tabs>) {
|
||||
onValueChange={(value) =>
|
||||
setConfig({ ...config, installationType: value as "cli" | "manual" })
|
||||
}
|
||||
className="relative mt-6 w-full"
|
||||
className="relative mt-6 w-full *:data-[slot=tabs-list]:gap-6"
|
||||
>
|
||||
{children}
|
||||
</Tabs>
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
import { useRouter } from "next/navigation"
|
||||
import { usePathname, useRouter } from "next/navigation"
|
||||
import { type DialogProps } from "@radix-ui/react-dialog"
|
||||
import * as DialogPrimitive from "@radix-ui/react-dialog"
|
||||
import { IconArrowRight } from "@tabler/icons-react"
|
||||
import { useDocsSearch } from "fumadocs-core/search/client"
|
||||
import { CornerDownLeftIcon, SquareDashedIcon } from "lucide-react"
|
||||
import { CornerDownLeftIcon, SquareDashedIcon, XIcon } from "lucide-react"
|
||||
|
||||
import { type Color, type ColorPalette } from "@/lib/colors"
|
||||
import { trackEvent } from "@/lib/events"
|
||||
import { showMcpDocs } from "@/lib/flags"
|
||||
import { getCurrentBase, getPagesFromFolder } from "@/lib/page-tree"
|
||||
import { type source } from "@/lib/source"
|
||||
import { cn } from "@/lib/utils"
|
||||
import { useConfig } from "@/hooks/use-config"
|
||||
@@ -26,13 +28,13 @@ import {
|
||||
} from "@/registry/new-york-v4/ui/command"
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogHeader,
|
||||
DialogPortal,
|
||||
DialogTitle,
|
||||
DialogTrigger,
|
||||
} from "@/registry/new-york-v4/ui/dialog"
|
||||
import { Kbd, KbdGroup } from "@/registry/new-york-v4/ui/kbd"
|
||||
import { Kbd } from "@/registry/new-york-v4/ui/kbd"
|
||||
import { Separator } from "@/registry/new-york-v4/ui/separator"
|
||||
import { Spinner } from "@/registry/new-york-v4/ui/spinner"
|
||||
|
||||
@@ -49,7 +51,9 @@ export function CommandMenu({
|
||||
navItems?: { href: string; label: string }[]
|
||||
}) {
|
||||
const router = useRouter()
|
||||
const pathname = usePathname()
|
||||
const [config] = useConfig()
|
||||
const currentBase = getCurrentBase(pathname)
|
||||
const [open, setOpen] = React.useState(false)
|
||||
const [selectedType, setSelectedType] = React.useState<
|
||||
"color" | "page" | "component" | "block" | null
|
||||
@@ -138,10 +142,13 @@ export function CommandMenu({
|
||||
[setSelectedType, setCopyPayload, packageManager]
|
||||
)
|
||||
|
||||
const runCommand = React.useCallback((command: () => unknown) => {
|
||||
setOpen(false)
|
||||
command()
|
||||
}, [])
|
||||
const runCommand = React.useCallback(
|
||||
(command: () => unknown) => {
|
||||
setOpen(false)
|
||||
command()
|
||||
},
|
||||
[setOpen]
|
||||
)
|
||||
|
||||
React.useEffect(() => {
|
||||
const down = (e: KeyboardEvent) => {
|
||||
@@ -207,10 +214,7 @@ export function CommandMenu({
|
||||
</div>
|
||||
</Button>
|
||||
</DialogTrigger>
|
||||
<DialogContent
|
||||
showCloseButton={false}
|
||||
className="rounded-xl border-none bg-clip-padding p-2 pb-11 shadow-2xl ring-4 ring-neutral-200/80 dark:bg-neutral-900 dark:ring-neutral-800"
|
||||
>
|
||||
<DialogContent className="rounded-xl border-none bg-clip-padding p-2 pb-11 shadow-2xl ring-4 ring-neutral-200/80 dark:bg-neutral-900 dark:ring-neutral-800">
|
||||
<DialogHeader className="sr-only">
|
||||
<DialogTitle>Search documentation...</DialogTitle>
|
||||
<DialogDescription>Search for a command to run...</DialogDescription>
|
||||
@@ -269,40 +273,37 @@ export function CommandMenu({
|
||||
className="!p-0 [&_[cmdk-group-heading]]:scroll-mt-16 [&_[cmdk-group-heading]]:!p-3 [&_[cmdk-group-heading]]:!pb-1"
|
||||
>
|
||||
{group.type === "folder" &&
|
||||
group.children.map((item) => {
|
||||
if (item.type === "page") {
|
||||
const isComponent = item.url.includes("/components/")
|
||||
getPagesFromFolder(group, currentBase).map((item) => {
|
||||
const isComponent = item.url.includes("/components/")
|
||||
|
||||
if (!showMcpDocs && item.url.includes("/mcp")) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<CommandMenuItem
|
||||
key={item.url}
|
||||
value={
|
||||
item.name?.toString()
|
||||
? `${group.name} ${item.name}`
|
||||
: ""
|
||||
}
|
||||
keywords={isComponent ? ["component"] : undefined}
|
||||
onHighlight={() =>
|
||||
handlePageHighlight(isComponent, item)
|
||||
}
|
||||
onSelect={() => {
|
||||
runCommand(() => router.push(item.url))
|
||||
}}
|
||||
>
|
||||
{isComponent ? (
|
||||
<div className="border-muted-foreground aspect-square size-4 rounded-full border border-dashed" />
|
||||
) : (
|
||||
<IconArrowRight />
|
||||
)}
|
||||
{item.name}
|
||||
</CommandMenuItem>
|
||||
)
|
||||
if (!showMcpDocs && item.url.includes("/mcp")) {
|
||||
return null
|
||||
}
|
||||
return null
|
||||
|
||||
return (
|
||||
<CommandMenuItem
|
||||
key={item.url}
|
||||
value={
|
||||
item.name?.toString()
|
||||
? `${group.name} ${item.name}`
|
||||
: ""
|
||||
}
|
||||
keywords={isComponent ? ["component"] : undefined}
|
||||
onHighlight={() =>
|
||||
handlePageHighlight(isComponent, item)
|
||||
}
|
||||
onSelect={() => {
|
||||
runCommand(() => router.push(item.url))
|
||||
}}
|
||||
>
|
||||
{isComponent ? (
|
||||
<div className="border-muted-foreground aspect-square size-4 rounded-full border border-dashed" />
|
||||
) : (
|
||||
<IconArrowRight />
|
||||
)}
|
||||
{item.name}
|
||||
</CommandMenuItem>
|
||||
)
|
||||
})}
|
||||
</CommandGroup>
|
||||
))}
|
||||
@@ -523,3 +524,30 @@ function SearchResults({
|
||||
</CommandGroup>
|
||||
)
|
||||
}
|
||||
|
||||
function DialogContent({
|
||||
className,
|
||||
children,
|
||||
...props
|
||||
}: React.ComponentProps<typeof DialogPrimitive.Content> & {
|
||||
showCloseButton?: boolean
|
||||
}) {
|
||||
return (
|
||||
<DialogPortal data-slot="dialog-portal">
|
||||
<DialogPrimitive.Overlay
|
||||
data-slot="dialog-overlay"
|
||||
className="fixed inset-0 z-50 bg-black/50"
|
||||
/>
|
||||
<DialogPrimitive.Content
|
||||
data-slot="dialog-content"
|
||||
className={cn(
|
||||
"bg-background fixed top-[50%] left-[50%] z-50 grid w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-lg border p-6 shadow-lg duration-200 outline-none sm:max-w-lg",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</DialogPrimitive.Content>
|
||||
</DialogPortal>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3,9 +3,11 @@
|
||||
import * as React from "react"
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
import { Button } from "@/registry/new-york-v4/ui/button"
|
||||
|
||||
export function ComponentPreviewTabs({
|
||||
className,
|
||||
previewClassName,
|
||||
align = "center",
|
||||
hideCode = false,
|
||||
chromeLessOnMobile = false,
|
||||
@@ -13,16 +15,19 @@ export function ComponentPreviewTabs({
|
||||
source,
|
||||
...props
|
||||
}: React.ComponentProps<"div"> & {
|
||||
previewClassName?: string
|
||||
align?: "center" | "start" | "end"
|
||||
hideCode?: boolean
|
||||
chromeLessOnMobile?: boolean
|
||||
component: React.ReactNode
|
||||
source: React.ReactNode
|
||||
}) {
|
||||
const [isMobileCodeVisible, setIsMobileCodeVisible] = React.useState(false)
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"group relative mt-4 mb-12 flex flex-col gap-2 rounded-lg border",
|
||||
"group relative mt-4 mb-12 flex flex-col gap-2 overflow-hidden rounded-xl border",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
@@ -30,9 +35,10 @@ export function ComponentPreviewTabs({
|
||||
<div data-slot="preview">
|
||||
<div
|
||||
data-align={align}
|
||||
data-chromeless={chromeLessOnMobile}
|
||||
className={cn(
|
||||
"preview flex w-full justify-center data-[align=center]:items-center data-[align=end]:items-end data-[align=start]:items-start",
|
||||
chromeLessOnMobile ? "sm:p-10" : "h-[450px] p-10"
|
||||
"preview flex h-72 w-full justify-center p-10 data-[align=center]:items-center data-[align=end]:items-end data-[align=start]:items-start data-[chromeless=true]:h-auto data-[chromeless=true]:p-0",
|
||||
previewClassName
|
||||
)}
|
||||
>
|
||||
{component}
|
||||
@@ -40,9 +46,32 @@ export function ComponentPreviewTabs({
|
||||
{!hideCode && (
|
||||
<div
|
||||
data-slot="code"
|
||||
className="overflow-hidden [&_[data-rehype-pretty-code-figure]]:!m-0 [&_[data-rehype-pretty-code-figure]]:rounded-t-none [&_[data-rehype-pretty-code-figure]]:border-t [&_pre]:max-h-[400px]"
|
||||
data-mobile-code-visible={isMobileCodeVisible}
|
||||
className="relative overflow-hidden data-[mobile-code-visible=false]:max-h-24 md:max-h-none data-[mobile-code-visible=false]:md:max-h-none [&_[data-rehype-pretty-code-figure]]:!m-0 [&_[data-rehype-pretty-code-figure]]:rounded-t-none [&_[data-rehype-pretty-code-figure]]:border-t [&_pre]:max-h-72"
|
||||
>
|
||||
{source}
|
||||
{!isMobileCodeVisible && (
|
||||
<div className="absolute inset-0 flex items-center justify-center md:hidden">
|
||||
<div
|
||||
className="absolute inset-0"
|
||||
style={{
|
||||
background:
|
||||
"linear-gradient(to top, var(--color-code), color-mix(in oklab, var(--color-code) 60%, transparent), transparent)",
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
type="button"
|
||||
size="sm"
|
||||
variant="outline"
|
||||
className="bg-background text-foreground dark:bg-background dark:text-foreground relative z-10"
|
||||
onClick={() => {
|
||||
setIsMobileCodeVisible(true)
|
||||
}}
|
||||
>
|
||||
View Code
|
||||
</Button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -1,45 +1,33 @@
|
||||
import * as React from "react"
|
||||
import Image from "next/image"
|
||||
|
||||
import { getRegistryComponent } from "@/lib/registry"
|
||||
import { ComponentPreviewTabs } from "@/components/component-preview-tabs"
|
||||
import { ComponentSource } from "@/components/component-source"
|
||||
import { Index } from "@/registry/__index__"
|
||||
import { type Style } from "@/registry/_legacy-styles"
|
||||
|
||||
export function ComponentPreview({
|
||||
name,
|
||||
styleName = "new-york-v4",
|
||||
type,
|
||||
className,
|
||||
previewClassName,
|
||||
align = "center",
|
||||
hideCode = false,
|
||||
chromeLessOnMobile = false,
|
||||
styleName = "new-york-v4",
|
||||
...props
|
||||
}: React.ComponentProps<"div"> & {
|
||||
name: string
|
||||
styleName?: Style["name"]
|
||||
styleName?: string
|
||||
align?: "center" | "start" | "end"
|
||||
description?: string
|
||||
hideCode?: boolean
|
||||
type?: "block" | "component" | "example"
|
||||
chromeLessOnMobile?: boolean
|
||||
previewClassName?: string
|
||||
}) {
|
||||
const Component = Index[styleName]?.[name]?.component
|
||||
|
||||
if (!Component) {
|
||||
return (
|
||||
<p className="text-muted-foreground mt-6 text-sm">
|
||||
Component{" "}
|
||||
<code className="bg-muted relative rounded px-[0.3rem] py-[0.2rem] font-mono text-sm">
|
||||
{name}
|
||||
</code>{" "}
|
||||
not found in registry.
|
||||
</p>
|
||||
)
|
||||
}
|
||||
|
||||
if (type === "block") {
|
||||
return (
|
||||
<div className="relative aspect-[4/2.5] w-full overflow-hidden rounded-md border md:-mx-1">
|
||||
<div className="relative aspect-[4/2.5] w-full overflow-hidden rounded-xl border md:-mx-1">
|
||||
<Image
|
||||
src={`/r/styles/new-york-v4/${name}-light.png`}
|
||||
alt={name}
|
||||
@@ -61,12 +49,27 @@ export function ComponentPreview({
|
||||
)
|
||||
}
|
||||
|
||||
const Component = getRegistryComponent(name, styleName)
|
||||
|
||||
if (!Component) {
|
||||
return (
|
||||
<p className="text-muted-foreground mt-6 text-sm">
|
||||
Component{" "}
|
||||
<code className="bg-muted relative rounded px-[0.3rem] py-[0.2rem] font-mono text-sm">
|
||||
{name}
|
||||
</code>{" "}
|
||||
not found in registry.
|
||||
</p>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<ComponentPreviewTabs
|
||||
className={className}
|
||||
previewClassName={previewClassName}
|
||||
align={align}
|
||||
hideCode={hideCode}
|
||||
component={<Component />}
|
||||
component={<DynamicComponent name={name} styleName={styleName} />}
|
||||
source={
|
||||
<ComponentSource
|
||||
name={name}
|
||||
@@ -79,3 +82,22 @@ export function ComponentPreview({
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
function DynamicComponent({
|
||||
name,
|
||||
styleName,
|
||||
}: {
|
||||
name: string
|
||||
styleName: string
|
||||
}) {
|
||||
const Component = React.useMemo(
|
||||
() => getRegistryComponent(name, styleName),
|
||||
[name, styleName]
|
||||
)
|
||||
|
||||
if (!Component) {
|
||||
return null
|
||||
}
|
||||
|
||||
return React.createElement(Component)
|
||||
}
|
||||
|
||||
@@ -3,12 +3,12 @@ import path from "node:path"
|
||||
import * as React from "react"
|
||||
|
||||
import { highlightCode } from "@/lib/highlight-code"
|
||||
import { getRegistryItem } from "@/lib/registry"
|
||||
import { getDemoItem, getRegistryItem } from "@/lib/registry"
|
||||
import { formatCode } from "@/lib/rehype"
|
||||
import { cn } from "@/lib/utils"
|
||||
import { CodeCollapsibleWrapper } from "@/components/code-collapsible-wrapper"
|
||||
import { CopyButton } from "@/components/copy-button"
|
||||
import { getIconForLanguageExtension } from "@/components/icons"
|
||||
import { type Style } from "@/registry/_legacy-styles"
|
||||
|
||||
export async function ComponentSource({
|
||||
name,
|
||||
@@ -24,7 +24,7 @@ export async function ComponentSource({
|
||||
title?: string
|
||||
language?: string
|
||||
collapsible?: boolean
|
||||
styleName?: Style["name"]
|
||||
styleName?: string
|
||||
}) {
|
||||
if (!name && !src) {
|
||||
return null
|
||||
@@ -33,7 +33,9 @@ export async function ComponentSource({
|
||||
let code: string | undefined
|
||||
|
||||
if (name) {
|
||||
const item = await getRegistryItem(name, styleName)
|
||||
const item =
|
||||
(await getDemoItem(name, styleName)) ??
|
||||
(await getRegistryItem(name, styleName))
|
||||
code = item?.files?.[0]?.content
|
||||
}
|
||||
|
||||
@@ -46,12 +48,7 @@ export async function ComponentSource({
|
||||
return null
|
||||
}
|
||||
|
||||
// Fix imports.
|
||||
// Replace @/registry/${style}/ with @/components/.
|
||||
code = code.replaceAll(`@/registry/${styleName}/`, "@/components/")
|
||||
|
||||
// Replace export default with export.
|
||||
code = code.replaceAll("export default", "export")
|
||||
code = await formatCode(code, styleName)
|
||||
code = code.replaceAll("/* eslint-disable react/no-children-prop */\n", "")
|
||||
|
||||
const lang = language ?? title?.split(".").pop() ?? "tsx"
|
||||
|
||||
@@ -1,20 +1,16 @@
|
||||
import Link from "next/link"
|
||||
|
||||
import { PAGES_NEW } from "@/lib/docs"
|
||||
import { source } from "@/lib/source"
|
||||
import { getPagesFromFolder, type PageTreeFolder } from "@/lib/page-tree"
|
||||
|
||||
export function ComponentsList() {
|
||||
const components = source.pageTree.children.find(
|
||||
(page) => page.$id === "components"
|
||||
)
|
||||
|
||||
if (components?.type !== "folder") {
|
||||
return
|
||||
}
|
||||
|
||||
const list = components.children.filter(
|
||||
(component) => component.type === "page"
|
||||
)
|
||||
export function ComponentsList({
|
||||
componentsFolder,
|
||||
currentBase,
|
||||
}: {
|
||||
componentsFolder: PageTreeFolder
|
||||
currentBase: string
|
||||
}) {
|
||||
const list = getPagesFromFolder(componentsFolder, currentBase)
|
||||
|
||||
return (
|
||||
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 md:grid-cols-3 md:gap-x-8 lg:gap-x-16 lg:gap-y-6 xl:gap-x-20">
|
||||
|
||||
39
apps/v4/components/docs-base-switcher.tsx
Normal file
39
apps/v4/components/docs-base-switcher.tsx
Normal file
@@ -0,0 +1,39 @@
|
||||
import Link from "next/link"
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
import { BASES } from "@/registry/bases"
|
||||
|
||||
export function DocsBaseSwitcher({
|
||||
base,
|
||||
component,
|
||||
className,
|
||||
}: {
|
||||
base: string
|
||||
component: string
|
||||
className?: string
|
||||
}) {
|
||||
const activeBase = BASES.find((baseItem) => base === baseItem.name)
|
||||
|
||||
return (
|
||||
<div className={cn("inline-flex w-full items-center gap-6", className)}>
|
||||
{BASES.map((baseItem) => (
|
||||
<Link
|
||||
key={baseItem.name}
|
||||
href={`/docs/components/${baseItem.name}/${component}`}
|
||||
data-active={base === baseItem.name}
|
||||
className="text-muted-foreground hover:text-foreground data-[active=true]:text-foreground after:bg-foreground relative inline-flex items-center justify-center gap-1 pt-1 pb-0.5 text-base font-medium transition-colors after:absolute after:inset-x-0 after:bottom-[-4px] after:h-0.5 after:opacity-0 after:transition-opacity data-[active=true]:after:opacity-100"
|
||||
>
|
||||
{baseItem.title}
|
||||
</Link>
|
||||
))}
|
||||
{activeBase?.meta?.logo && (
|
||||
<div
|
||||
className="text-muted-foreground ml-auto size-4 shrink-0 opacity-80 [&_svg]:size-4"
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: activeBase.meta.logo,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -183,7 +183,10 @@ export function DocsCopyPage({ page, url }: { page: string; url: string }) {
|
||||
<DropdownMenuTrigger asChild className="hidden sm:flex">
|
||||
{trigger}
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end" className="shadow-none">
|
||||
<DropdownMenuContent
|
||||
align="end"
|
||||
className="animate-none! rounded-lg shadow-none"
|
||||
>
|
||||
{Object.entries(menuItems).map(([key, value]) => (
|
||||
<DropdownMenuItem key={key} asChild>
|
||||
{value(url)}
|
||||
@@ -193,13 +196,13 @@ export function DocsCopyPage({ page, url }: { page: string; url: string }) {
|
||||
</DropdownMenu>
|
||||
<Separator
|
||||
orientation="vertical"
|
||||
className="!bg-foreground/10 absolute top-0 right-8 z-0 !h-8 peer-focus-visible:opacity-0 sm:right-7 sm:!h-7"
|
||||
className="!bg-foreground/5 absolute top-1 right-8 z-0 !h-6 peer-focus-visible:opacity-0 sm:right-7 sm:!h-5"
|
||||
/>
|
||||
<PopoverTrigger asChild className="flex sm:hidden">
|
||||
{trigger}
|
||||
</PopoverTrigger>
|
||||
<PopoverContent
|
||||
className="bg-background/70 dark:bg-background/60 w-52 !origin-center rounded-lg p-1 shadow-sm backdrop-blur-sm"
|
||||
className="bg-background/70 dark:bg-background/60 w-52 !origin-center rounded-lg p-1 shadow-none backdrop-blur-sm"
|
||||
align="start"
|
||||
>
|
||||
{Object.entries(menuItems).map(([key, value]) => (
|
||||
|
||||
179
apps/v4/components/docs-page-links.tsx
Normal file
179
apps/v4/components/docs-page-links.tsx
Normal file
@@ -0,0 +1,179 @@
|
||||
"use client"
|
||||
|
||||
import { IconCheck, IconCopy } from "@tabler/icons-react"
|
||||
|
||||
import { useCopyToClipboard } from "@/hooks/use-copy-to-clipboard"
|
||||
|
||||
function getPromptUrl(baseURL: string, url: string) {
|
||||
return `${baseURL}?q=${encodeURIComponent(
|
||||
`I'm looking at this shadcn/ui documentation: ${url}.
|
||||
Help me understand how to use it. Be ready to explain concepts, give examples, or help debug based on it.
|
||||
`
|
||||
)}`
|
||||
}
|
||||
|
||||
export function DocsPageLinks({ page, url }: { page: string; url: string }) {
|
||||
const { copyToClipboard, isCopied } = useCopyToClipboard()
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-3 px-6">
|
||||
<ul className="text-muted-foreground flex flex-col gap-2 text-[0.8rem]">
|
||||
<li>
|
||||
<button
|
||||
onClick={() => copyToClipboard(page)}
|
||||
className="hover:text-foreground inline-flex items-center gap-2 transition-colors"
|
||||
>
|
||||
{isCopied ? (
|
||||
<IconCheck className="size-4" />
|
||||
) : (
|
||||
<IconCopy className="size-4" />
|
||||
)}
|
||||
Copy page
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href={`${url}.md`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="hover:text-foreground inline-flex items-center gap-2 transition-colors"
|
||||
>
|
||||
<svg strokeLinejoin="round" viewBox="0 0 22 16" className="size-4">
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M19.5 2.25H2.5C1.80964 2.25 1.25 2.80964 1.25 3.5V12.5C1.25 13.1904 1.80964 13.75 2.5 13.75H19.5C20.1904 13.75 20.75 13.1904 20.75 12.5V3.5C20.75 2.80964 20.1904 2.25 19.5 2.25ZM2.5 1C1.11929 1 0 2.11929 0 3.5V12.5C0 13.8807 1.11929 15 2.5 15H19.5C20.8807 15 22 13.8807 22 12.5V3.5C22 2.11929 20.8807 1 19.5 1H2.5ZM3 4.5H4H4.25H4.6899L4.98715 4.82428L7 7.02011L9.01285 4.82428L9.3101 4.5H9.75H10H11V5.5V11.5H9V7.79807L7.73715 9.17572L7 9.97989L6.26285 9.17572L5 7.79807V11.5H3V5.5V4.5ZM15 8V4.5H17V8H19.5L17 10.5L16 11.5L15 10.5L12.5 8H15Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
View as Markdown
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href={getPromptUrl("https://v0.dev", url)}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="hover:text-foreground inline-flex items-center gap-2 transition-colors"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 147 70"
|
||||
className="size-4"
|
||||
>
|
||||
<path d="M56 50.203V14h14v46.156C70 65.593 65.593 70 60.156 70c-2.596 0-5.158-1-7-2.843L0 14h19.797L56 50.203ZM147 56h-14V23.953L100.953 56H133v14H96.687C85.814 70 77 61.186 77 50.312V14h14v32.156L123.156 14H91V0h36.312C138.186 0 147 8.814 147 19.688V56Z" />
|
||||
</svg>
|
||||
Open in v0
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href={getPromptUrl("https://chatgpt.com", url)}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="hover:text-foreground inline-flex items-center gap-2 transition-colors"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
className="size-4"
|
||||
>
|
||||
<path
|
||||
d="M22.282 9.821a5.985 5.985 0 0 0-.516-4.91 6.046 6.046 0 0 0-6.51-2.9A6.065 6.065 0 0 0 4.981 4.18a5.985 5.985 0 0 0-3.998 2.9 6.046 6.046 0 0 0 .743 7.097 5.98 5.98 0 0 0 .51 4.911 6.051 6.051 0 0 0 6.515 2.9A5.985 5.985 0 0 0 13.26 24a6.056 6.056 0 0 0 5.772-4.206 5.99 5.99 0 0 0 3.997-2.9 6.056 6.056 0 0 0-.747-7.073zM13.26 22.43a4.476 4.476 0 0 1-2.876-1.04l.141-.081 4.779-2.758a.795.795 0 0 0 .392-.681v-6.737l2.02 1.168a.071.071 0 0 1 .038.052v5.583a4.504 4.504 0 0 1-4.494 4.494zM3.6 18.304a4.47 4.47 0 0 1-.535-3.014l.142.085 4.783 2.759a.771.771 0 0 0 .78 0l5.843-3.369v2.332a.08.08 0 0 1-.033.062L9.74 19.95a4.5 4.5 0 0 1-6.14-1.646zM2.34 7.896a4.485 4.485 0 0 1 2.366-1.973V11.6a.766.766 0 0 0 .388.676l5.815 3.355-2.02 1.168a.076.076 0 0 1-.071 0l-4.83-2.786A4.504 4.504 0 0 1 2.34 7.872zm16.597 3.855-5.833-3.387L15.119 7.2a.076.076 0 0 1 .071 0l4.83 2.791a4.494 4.494 0 0 1-.676 8.105v-5.678a.79.79 0 0 0-.407-.667zm2.01-3.023-.141-.085-4.774-2.782a.776.776 0 0 0-.785 0L9.409 9.23V6.897a.066.066 0 0 1 .028-.061l4.83-2.787a4.5 4.5 0 0 1 6.68 4.66zm-12.64 4.135-2.02-1.164a.08.08 0 0 1-.038-.057V6.075a4.5 4.5 0 0 1 7.375-3.453l-.142.08-4.778 2.758a.795.795 0 0 0-.393.681zm1.097-2.365 2.602-1.5 2.607 1.5v2.999l-2.597 1.5-2.607-1.5Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
Open in ChatGPT
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href={getPromptUrl("https://claude.ai/new", url)}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="hover:text-foreground inline-flex items-center gap-2 transition-colors"
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
className="size-4"
|
||||
>
|
||||
<path
|
||||
d="m4.714 15.956 4.718-2.648.079-.23-.08-.128h-.23l-.79-.048-2.695-.073-2.337-.097-2.265-.122-.57-.121-.535-.704.055-.353.48-.321.685.06 1.518.104 2.277.157 1.651.098 2.447.255h.389l.054-.158-.133-.097-.103-.098-2.356-1.596-2.55-1.688-1.336-.972-.722-.491L2 6.223l-.158-1.008.655-.722.88.06.225.061.893.686 1.906 1.476 2.49 1.833.364.304.146-.104.018-.072-.164-.274-1.354-2.446-1.445-2.49-.644-1.032-.17-.619a2.972 2.972 0 0 1-.103-.729L6.287.133 6.7 0l.995.134.42.364.619 1.415L9.735 4.14l1.555 3.03.455.898.243.832.09.255h.159V9.01l.127-1.706.237-2.095.23-2.695.08-.76.376-.91.747-.492.583.28.48.685-.067.444-.286 1.851-.558 2.903-.365 1.942h.213l.243-.242.983-1.306 1.652-2.064.728-.82.85-.904.547-.431h1.032l.759 1.129-.34 1.166-1.063 1.347-.88 1.142-1.263 1.7-.79 1.36.074.11.188-.02 2.853-.606 1.542-.28 1.84-.315.832.388.09.395-.327.807-1.967.486-2.307.462-3.436.813-.043.03.049.061 1.548.146.662.036h1.62l3.018.225.79.522.473.638-.08.485-1.213.62-1.64-.389-3.825-.91-1.31-.329h-.183v.11l1.093 1.068 2.003 1.81 2.508 2.33.127.578-.321.455-.34-.049-2.204-1.657-.85-.747-1.925-1.62h-.127v.17l.443.649 2.343 3.521.122 1.08-.17.353-.607.213-.668-.122-1.372-1.924-1.415-2.168-1.141-1.943-.14.08-.674 7.254-.316.37-.728.28-.607-.461-.322-.747.322-1.476.388-1.924.316-1.53.285-1.9.17-.632-.012-.042-.14.018-1.432 1.967-2.18 2.945-1.724 1.845-.413.164-.716-.37.066-.662.401-.589 2.386-3.036 1.439-1.882.929-1.086-.006-.158h-.055L4.138 18.56l-1.13.146-.485-.456.06-.746.231-.243 1.907-1.312Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
Open in Claude
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
href={getPromptUrl("https://scira.ai/", url)}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="hover:text-foreground inline-flex items-center gap-2 transition-colors"
|
||||
>
|
||||
<svg
|
||||
width="910"
|
||||
height="934"
|
||||
viewBox="0 0 910 934"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className="size-4"
|
||||
>
|
||||
<path
|
||||
d="M647.664 197.775C569.13 189.049 525.5 145.419 516.774 66.8849C508.048 145.419 464.418 189.049 385.884 197.775C464.418 206.501 508.048 250.131 516.774 328.665C525.5 250.131 569.13 206.501 647.664 197.775Z"
|
||||
fill="currentColor"
|
||||
stroke="currentColor"
|
||||
strokeWidth="8"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M516.774 304.217C510.299 275.491 498.208 252.087 480.335 234.214C462.462 216.341 439.058 204.251 410.333 197.775C439.059 191.3 462.462 179.209 480.335 161.336C498.208 143.463 510.299 120.06 516.774 91.334C523.25 120.059 535.34 143.463 553.213 161.336C571.086 179.209 594.49 191.3 623.216 197.775C594.49 204.251 571.086 216.341 553.213 234.214C535.34 252.087 523.25 275.491 516.774 304.217Z"
|
||||
fill="currentColor"
|
||||
stroke="currentColor"
|
||||
strokeWidth="8"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M857.5 508.116C763.259 497.644 710.903 445.288 700.432 351.047C689.961 445.288 637.605 497.644 543.364 508.116C637.605 518.587 689.961 570.943 700.432 665.184C710.903 570.943 763.259 518.587 857.5 508.116Z"
|
||||
stroke="currentColor"
|
||||
strokeWidth="20"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M700.432 615.957C691.848 589.05 678.575 566.357 660.383 548.165C642.191 529.973 619.499 516.7 592.593 508.116C619.499 499.533 642.191 486.258 660.383 468.066C678.575 449.874 691.848 427.181 700.432 400.274C709.015 427.181 722.289 449.874 740.481 468.066C758.673 486.258 781.365 499.533 808.271 508.116C781.365 516.7 758.673 529.973 740.481 548.165C722.289 566.357 709.015 589.05 700.432 615.957Z"
|
||||
stroke="currentColor"
|
||||
strokeWidth="20"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M889.949 121.237C831.049 114.692 798.326 81.9698 791.782 23.0692C785.237 81.9698 752.515 114.692 693.614 121.237C752.515 127.781 785.237 160.504 791.782 219.404C798.326 160.504 831.049 127.781 889.949 121.237Z"
|
||||
fill="currentColor"
|
||||
stroke="currentColor"
|
||||
strokeWidth="8"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M791.782 196.795C786.697 176.937 777.869 160.567 765.16 147.858C752.452 135.15 736.082 126.322 716.226 121.237C736.082 116.152 752.452 107.324 765.16 94.6152C777.869 81.9065 786.697 65.5368 791.782 45.6797C796.867 65.5367 805.695 81.9066 818.403 94.6152C831.112 107.324 847.481 116.152 867.338 121.237C847.481 126.322 831.112 135.15 818.403 147.858C805.694 160.567 796.867 176.937 791.782 196.795Z"
|
||||
fill="currentColor"
|
||||
stroke="currentColor"
|
||||
strokeWidth="8"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M760.632 764.337C720.719 814.616 669.835 855.1 611.872 882.692C553.91 910.285 490.404 924.255 426.213 923.533C362.022 922.812 298.846 907.419 241.518 878.531C184.19 849.643 134.228 808.026 95.4548 756.863C56.6815 705.7 30.1238 646.346 17.8129 583.343C5.50207 520.339 7.76433 455.354 24.4266 393.359C41.089 331.364 71.7099 274.001 113.947 225.658C156.184 177.315 208.919 139.273 268.117 114.442"
|
||||
stroke="currentColor"
|
||||
strokeWidth="30"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
Open in Scira
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import { usePathname } from "next/navigation"
|
||||
|
||||
import { PAGES_NEW } from "@/lib/docs"
|
||||
import { showMcpDocs } from "@/lib/flags"
|
||||
import { getCurrentBase, getPagesFromFolder } from "@/lib/page-tree"
|
||||
import type { source } from "@/lib/source"
|
||||
import {
|
||||
Sidebar,
|
||||
@@ -18,11 +19,15 @@ import {
|
||||
} from "@/registry/new-york-v4/ui/sidebar"
|
||||
|
||||
const TOP_LEVEL_SECTIONS = [
|
||||
{ name: "Get Started", href: "/docs" },
|
||||
{ name: "Introduction", href: "/docs" },
|
||||
{
|
||||
name: "Components",
|
||||
href: "/docs/components",
|
||||
},
|
||||
{
|
||||
name: "Installation",
|
||||
href: "/docs/installation",
|
||||
},
|
||||
{
|
||||
name: "Directory",
|
||||
href: "/docs/directory",
|
||||
@@ -31,6 +36,10 @@ const TOP_LEVEL_SECTIONS = [
|
||||
name: "MCP Server",
|
||||
href: "/docs/mcp",
|
||||
},
|
||||
{
|
||||
name: "Registry",
|
||||
href: "/docs/registry",
|
||||
},
|
||||
{
|
||||
name: "Forms",
|
||||
href: "/docs/forms",
|
||||
@@ -48,10 +57,11 @@ export function DocsSidebar({
|
||||
...props
|
||||
}: React.ComponentProps<typeof Sidebar> & { tree: typeof source.pageTree }) {
|
||||
const pathname = usePathname()
|
||||
const currentBase = getCurrentBase(pathname)
|
||||
|
||||
return (
|
||||
<Sidebar
|
||||
className="sticky top-[calc(var(--header-height)+1px)] z-30 hidden h-[calc(100svh-var(--footer-height)-4rem)] overscroll-none bg-transparent lg:flex"
|
||||
className="sticky top-[calc(var(--header-height)+1px)] z-30 hidden h-[calc(100svh-6rem)] overscroll-none bg-transparent lg:flex"
|
||||
collapsible="none"
|
||||
{...props}
|
||||
>
|
||||
@@ -102,37 +112,34 @@ export function DocsSidebar({
|
||||
<SidebarGroupContent>
|
||||
{item.type === "folder" && (
|
||||
<SidebarMenu className="gap-0.5">
|
||||
{item.children.map((item) => {
|
||||
if (
|
||||
!showMcpDocs &&
|
||||
item.type === "page" &&
|
||||
item.url?.includes("/mcp")
|
||||
) {
|
||||
{getPagesFromFolder(item, currentBase).map((page) => {
|
||||
if (!showMcpDocs && page.url.includes("/mcp")) {
|
||||
return null
|
||||
}
|
||||
|
||||
if (EXCLUDED_PAGES.includes(page.url)) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
item.type === "page" &&
|
||||
!EXCLUDED_PAGES.includes(item.url) && (
|
||||
<SidebarMenuItem key={item.url}>
|
||||
<SidebarMenuButton
|
||||
asChild
|
||||
isActive={item.url === pathname}
|
||||
className="data-[active=true]:bg-accent data-[active=true]:border-accent 3xl:fixed:w-full 3xl:fixed:max-w-48 relative h-[30px] w-fit overflow-visible border border-transparent text-[0.8rem] font-medium after:absolute after:inset-x-0 after:-inset-y-1 after:z-0 after:rounded-md"
|
||||
>
|
||||
<Link href={item.url}>
|
||||
<span className="absolute inset-0 flex w-(--sidebar-width) bg-transparent" />
|
||||
{item.name}
|
||||
{PAGES_NEW.includes(item.url) && (
|
||||
<span
|
||||
className="flex size-2 rounded-full bg-blue-500"
|
||||
title="New"
|
||||
/>
|
||||
)}
|
||||
</Link>
|
||||
</SidebarMenuButton>
|
||||
</SidebarMenuItem>
|
||||
)
|
||||
<SidebarMenuItem key={page.url}>
|
||||
<SidebarMenuButton
|
||||
asChild
|
||||
isActive={page.url === pathname}
|
||||
className="data-[active=true]:bg-accent data-[active=true]:border-accent 3xl:fixed:w-full 3xl:fixed:max-w-48 relative h-[30px] w-fit overflow-visible border border-transparent text-[0.8rem] font-medium after:absolute after:inset-x-0 after:-inset-y-1 after:z-0 after:rounded-md"
|
||||
>
|
||||
<Link href={page.url}>
|
||||
<span className="absolute inset-0 flex w-(--sidebar-width) bg-transparent" />
|
||||
{page.name}
|
||||
{PAGES_NEW.includes(page.url) && (
|
||||
<span
|
||||
className="flex size-2 rounded-full bg-blue-500"
|
||||
title="New"
|
||||
/>
|
||||
)}
|
||||
</Link>
|
||||
</SidebarMenuButton>
|
||||
</SidebarMenuItem>
|
||||
)
|
||||
})}
|
||||
</SidebarMenu>
|
||||
|
||||
@@ -107,7 +107,7 @@ export function DocsTableOfContents({
|
||||
|
||||
return (
|
||||
<div className={cn("flex flex-col gap-2 p-4 pt-0 text-sm", className)}>
|
||||
<p className="text-muted-foreground bg-background sticky top-0 h-6 text-xs">
|
||||
<p className="text-muted-foreground bg-background sticky top-0 h-6 text-xs font-medium">
|
||||
On This Page
|
||||
</p>
|
||||
{toc.map((item) => (
|
||||
|
||||
@@ -2,10 +2,11 @@
|
||||
|
||||
import * as React from "react"
|
||||
import Link, { type LinkProps } from "next/link"
|
||||
import { useRouter } from "next/navigation"
|
||||
import { usePathname, useRouter } from "next/navigation"
|
||||
|
||||
import { PAGES_NEW } from "@/lib/docs"
|
||||
import { showMcpDocs } from "@/lib/flags"
|
||||
import { getCurrentBase, getPagesFromFolder } from "@/lib/page-tree"
|
||||
import { type source } from "@/lib/source"
|
||||
import { cn } from "@/lib/utils"
|
||||
import { Button } from "@/registry/new-york-v4/ui/button"
|
||||
@@ -16,11 +17,15 @@ import {
|
||||
} from "@/registry/new-york-v4/ui/popover"
|
||||
|
||||
const TOP_LEVEL_SECTIONS = [
|
||||
{ name: "Get Started", href: "/docs" },
|
||||
{ name: "Introduction", href: "/docs" },
|
||||
{
|
||||
name: "Components",
|
||||
href: "/docs/components",
|
||||
},
|
||||
{
|
||||
name: "Installation",
|
||||
href: "/docs/installation",
|
||||
},
|
||||
{
|
||||
name: "Directory",
|
||||
href: "/docs/directory",
|
||||
@@ -29,6 +34,10 @@ const TOP_LEVEL_SECTIONS = [
|
||||
name: "MCP Server",
|
||||
href: "/docs/mcp",
|
||||
},
|
||||
{
|
||||
name: "Registry",
|
||||
href: "/docs/registry",
|
||||
},
|
||||
{
|
||||
name: "Forms",
|
||||
href: "/docs/forms",
|
||||
@@ -49,6 +58,8 @@ export function MobileNav({
|
||||
className?: string
|
||||
}) {
|
||||
const [open, setOpen] = React.useState(false)
|
||||
const pathname = usePathname()
|
||||
const currentBase = getCurrentBase(pathname)
|
||||
|
||||
return (
|
||||
<Popover open={open} onOpenChange={setOpen}>
|
||||
@@ -125,31 +136,30 @@ export function MobileNav({
|
||||
<div className="flex flex-col gap-8">
|
||||
{tree?.children?.map((group, index) => {
|
||||
if (group.type === "folder") {
|
||||
const pages = getPagesFromFolder(group, currentBase)
|
||||
return (
|
||||
<div key={index} className="flex flex-col gap-4">
|
||||
<div className="text-muted-foreground text-sm font-medium">
|
||||
{group.name}
|
||||
</div>
|
||||
<div className="flex flex-col gap-3">
|
||||
{group.children.map((item) => {
|
||||
if (item.type === "page") {
|
||||
if (!showMcpDocs && item.url.includes("/mcp")) {
|
||||
return null
|
||||
}
|
||||
return (
|
||||
<MobileLink
|
||||
key={`${item.url}-${index}`}
|
||||
href={item.url}
|
||||
onOpenChange={setOpen}
|
||||
className="flex items-center gap-2"
|
||||
>
|
||||
{item.name}{" "}
|
||||
{PAGES_NEW.includes(item.url) && (
|
||||
<span className="flex size-2 rounded-full bg-blue-500" />
|
||||
)}
|
||||
</MobileLink>
|
||||
)
|
||||
{pages.map((item) => {
|
||||
if (!showMcpDocs && item.url.includes("/mcp")) {
|
||||
return null
|
||||
}
|
||||
return (
|
||||
<MobileLink
|
||||
key={`${item.url}-${index}`}
|
||||
href={item.url}
|
||||
onOpenChange={setOpen}
|
||||
className="flex items-center gap-2"
|
||||
>
|
||||
{item.name}{" "}
|
||||
{PAGES_NEW.includes(item.url) && (
|
||||
<span className="flex size-2 rounded-full bg-blue-500" />
|
||||
)}
|
||||
</MobileLink>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2,7 +2,7 @@ import { siteConfig } from "@/lib/config"
|
||||
|
||||
export function SiteFooter() {
|
||||
return (
|
||||
<footer className="group-has-[.section-soft]/body:bg-surface/40 3xl:fixed:bg-transparent group-has-[.docs-nav]/body:pb-20 group-has-[[data-slot=designer]]/body:hidden group-has-[.docs-nav]/body:sm:pb-0 dark:bg-transparent">
|
||||
<footer className="group-has-[.section-soft]/body:bg-surface/40 3xl:fixed:bg-transparent group-has-[.docs-nav]/body:pb-20 group-has-[[data-slot=designer]]/body:hidden group-has-[[data-slot=docs]]/body:hidden group-has-[.docs-nav]/body:sm:pb-0 dark:bg-transparent dark:group-has-[.section-soft]/body:bg-surface/40">
|
||||
<div className="container-wrapper px-4 xl:px-6">
|
||||
<div className="flex h-(--footer-height) items-center justify-between">
|
||||
<div className="text-muted-foreground w-full px-1 text-center text-xs leading-loose sm:text-sm">
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
const SHOW = false
|
||||
const SHOW = true
|
||||
|
||||
export function TailwindIndicator({
|
||||
forceMount = false,
|
||||
|
||||
@@ -4,6 +4,50 @@ description: Latest updates and announcements.
|
||||
toc: false
|
||||
---
|
||||
|
||||
## January 2026 - Base UI Documentation
|
||||
|
||||
We've shipped full documentation for Base UI components.
|
||||
|
||||
<div className="bg-muted/50 mt-6 flex w-full items-center justify-center rounded-lg border py-32">
|
||||
<svg width="17" height="24" viewBox="0 0 17 24" className="size-12">
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M9.5001 7.01537C9.2245 6.99837 9 7.22385 9 7.49999V23C13.4183 23 17 19.4183 17 15C17 10.7497 13.6854 7.27351 9.5001 7.01537Z"
|
||||
/>
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M8 9.8V12V23C3.58172 23 0 19.0601 0 14.2V12V1C4.41828 1 8 4.93989 8 9.8Z"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
When we launched `npx shadcn create` in December, we introduced the ability to choose between Radix and Base UI as your component library. Today, we're following up with complete documentation for all Base UI components.
|
||||
|
||||
### What's New
|
||||
|
||||
- **Full Base UI docs** - Every component now has dedicated documentation for Base UI, covering usage, props, and examples.
|
||||
- **Rebuilt examples** - All component examples have been rebuilt for both Radix and Base UI. Switch between them to see the implementation differences.
|
||||
- **Side-by-side comparison** - The docs make it easy to compare how components work across both libraries.
|
||||
|
||||
### Same Abstraction, Different Primitives
|
||||
|
||||
The goal remains the same: give you a consistent API regardless of which primitive library you choose. The components look and behave the same way. Only the underlying implementation changes.
|
||||
|
||||
```tsx
|
||||
// Works the same whether you're using Radix or Base UI.
|
||||
import { Dialog, DialogContent, DialogTrigger } from "@/components/ui/dialog"
|
||||
```
|
||||
|
||||
If you're starting a new project, run `npx shadcn create` and pick your preferred library. The CLI handles the rest.
|
||||
|
||||
<Button asChild size="sm">
|
||||
<Link href="/create" className="mt-6 no-underline!">
|
||||
Try shadcn/create
|
||||
</Link>
|
||||
</Button>
|
||||
|
||||
---
|
||||
|
||||
## December 2025 - npx shadcn create
|
||||
|
||||
From the very first commit, the goal of shadcn/ui was to make it customizable.
|
||||
|
||||
@@ -9,12 +9,10 @@ These registries are built into the CLI with no additional configuration require
|
||||
|
||||
<Callout
|
||||
type="warning"
|
||||
icon={<TriangleAlertIcon />}
|
||||
className="gap-2! border-amber-200 bg-amber-50 p-2 font-semibold dark:border-amber-900 dark:bg-amber-950/80 *:[svg]:translate-y-1"
|
||||
className="border-amber-200 bg-amber-50 font-semibold dark:border-amber-900 dark:bg-amber-950"
|
||||
>
|
||||
Community registries are maintained by third-party developers and are not
|
||||
officially curated. Always review code on installation to ensure it meets your
|
||||
security and quality standards.
|
||||
Community registries are maintained by third-party developers. Always review
|
||||
code on installation to ensure it meets your security and quality standards.
|
||||
</Callout>
|
||||
|
||||
Don't see a registry? Learn how to [add it here](/docs/registry/registry-index).
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
---
|
||||
title: Accordion
|
||||
description: A vertically stacked set of interactive headings that each reveal a section of content.
|
||||
component: true
|
||||
links:
|
||||
doc: https://www.radix-ui.com/docs/primitives/components/accordion
|
||||
api: https://www.radix-ui.com/docs/primitives/components/accordion#api-reference
|
||||
---
|
||||
|
||||
<ComponentPreview
|
||||
name="accordion-demo"
|
||||
className="[&_.preview>[data-orientation=vertical]]:sm:max-w-[80%] **:[.preview]:min-h-[400px]"
|
||||
description="An accordion with three items"
|
||||
align="start"
|
||||
/>
|
||||
|
||||
## Installation
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">CLI</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
|
||||
<TabsContent value="cli">
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add accordion
|
||||
```
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps>
|
||||
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-accordion
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource name="accordion" title="components/ui/accordion.tsx" />
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
</CodeTabs>
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx showLineNumbers
|
||||
import {
|
||||
Accordion,
|
||||
AccordionContent,
|
||||
AccordionItem,
|
||||
AccordionTrigger,
|
||||
} from "@/components/ui/accordion"
|
||||
```
|
||||
|
||||
```tsx showLineNumbers
|
||||
<Accordion type="single" collapsible>
|
||||
<AccordionItem value="item-1">
|
||||
<AccordionTrigger>Is it accessible?</AccordionTrigger>
|
||||
<AccordionContent>
|
||||
Yes. It adheres to the WAI-ARIA design pattern.
|
||||
</AccordionContent>
|
||||
</AccordionItem>
|
||||
</Accordion>
|
||||
```
|
||||
@@ -1,88 +0,0 @@
|
||||
---
|
||||
title: Alert Dialog
|
||||
description: A modal dialog that interrupts the user with important content and expects a response.
|
||||
featured: true
|
||||
component: true
|
||||
links:
|
||||
doc: https://www.radix-ui.com/docs/primitives/components/alert-dialog
|
||||
api: https://www.radix-ui.com/docs/primitives/components/alert-dialog#api-reference
|
||||
---
|
||||
|
||||
<ComponentPreview
|
||||
name="alert-dialog-demo"
|
||||
title="An alert dialog with cancel and continue buttons."
|
||||
description="An alert dialog with cancel and continue buttons."
|
||||
/>
|
||||
|
||||
## Installation
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">CLI</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add alert-dialog
|
||||
```
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps>
|
||||
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-alert-dialog
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource name="alert-dialog" title="components/ui/alert-dialog.tsx" />
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
</CodeTabs>
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx showLineNumbers
|
||||
import {
|
||||
AlertDialog,
|
||||
AlertDialogAction,
|
||||
AlertDialogCancel,
|
||||
AlertDialogContent,
|
||||
AlertDialogDescription,
|
||||
AlertDialogFooter,
|
||||
AlertDialogHeader,
|
||||
AlertDialogTitle,
|
||||
AlertDialogTrigger,
|
||||
} from "@/components/ui/alert-dialog"
|
||||
```
|
||||
|
||||
```tsx showLineNumbers
|
||||
<AlertDialog>
|
||||
<AlertDialogTrigger>Open</AlertDialogTrigger>
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
|
||||
<AlertDialogDescription>
|
||||
This action cannot be undone. This will permanently delete your account
|
||||
and remove your data from our servers.
|
||||
</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel>Cancel</AlertDialogCancel>
|
||||
<AlertDialogAction>Continue</AlertDialogAction>
|
||||
</AlertDialogFooter>
|
||||
</AlertDialogContent>
|
||||
</AlertDialog>
|
||||
```
|
||||
@@ -1,59 +0,0 @@
|
||||
---
|
||||
title: Alert
|
||||
description: Displays a callout for user attention.
|
||||
component: true
|
||||
---
|
||||
|
||||
<ComponentPreview
|
||||
name="alert-demo"
|
||||
title="An alert with an icon, title and description."
|
||||
description="An alert with an icon, title and description. The title says 'Heads up!' and the description is 'You can add components to your app using the cli.'."
|
||||
/>
|
||||
|
||||
## Installation
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">CLI</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add alert
|
||||
```
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps>
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource name="alert" title="components/ui/alert.tsx" />
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
</CodeTabs>
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx showLineNumbers
|
||||
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"
|
||||
```
|
||||
|
||||
```tsx showLineNumbers
|
||||
<Alert variant="default | destructive">
|
||||
<Terminal />
|
||||
<AlertTitle>Heads up!</AlertTitle>
|
||||
<AlertDescription>
|
||||
You can add components and dependencies to your app using the cli.
|
||||
</AlertDescription>
|
||||
</Alert>
|
||||
```
|
||||
@@ -1,64 +0,0 @@
|
||||
---
|
||||
title: Aspect Ratio
|
||||
description: Displays content within a desired ratio.
|
||||
component: true
|
||||
links:
|
||||
doc: https://www.radix-ui.com/docs/primitives/components/aspect-ratio
|
||||
api: https://www.radix-ui.com/docs/primitives/components/aspect-ratio#api-reference
|
||||
---
|
||||
|
||||
<ComponentPreview
|
||||
name="aspect-ratio-demo"
|
||||
title="Aspect Ratio"
|
||||
description="A component that displays an image with a 16:9 aspect ratio."
|
||||
/>
|
||||
|
||||
## Installation
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">CLI</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add aspect-ratio
|
||||
```
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps>
|
||||
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-aspect-ratio
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource name="aspect-ratio" title="components/ui/aspect-ratio.tsx" />
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
</CodeTabs>
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx showLineNumbers
|
||||
import { AspectRatio } from "@/components/ui/aspect-ratio"
|
||||
```
|
||||
|
||||
```tsx showLineNumbers
|
||||
<AspectRatio ratio={16 / 9}>
|
||||
<Image src="..." alt="Image" className="rounded-md object-cover" />
|
||||
</AspectRatio>
|
||||
```
|
||||
@@ -1,65 +0,0 @@
|
||||
---
|
||||
title: Avatar
|
||||
description: An image element with a fallback for representing the user.
|
||||
component: true
|
||||
links:
|
||||
doc: https://www.radix-ui.com/docs/primitives/components/avatar
|
||||
api: https://www.radix-ui.com/docs/primitives/components/avatar#api-reference
|
||||
---
|
||||
|
||||
<ComponentPreview
|
||||
name="avatar-demo"
|
||||
title="Avatar"
|
||||
description="An avatar with a fallback."
|
||||
/>
|
||||
|
||||
## Installation
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">CLI</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add avatar
|
||||
```
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps>
|
||||
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-avatar
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource name="avatar" title="components/ui/avatar.tsx" />
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
</CodeTabs>
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx showLineNumbers
|
||||
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
|
||||
```
|
||||
|
||||
```tsx showLineNumbers
|
||||
<Avatar>
|
||||
<AvatarImage src="https://github.com/shadcn.png" />
|
||||
<AvatarFallback>CN</AvatarFallback>
|
||||
</Avatar>
|
||||
```
|
||||
@@ -1,71 +0,0 @@
|
||||
---
|
||||
title: Badge
|
||||
description: Displays a badge or a component that looks like a badge.
|
||||
component: true
|
||||
---
|
||||
|
||||
<ComponentPreview
|
||||
name="badge-demo"
|
||||
title="Badge"
|
||||
description="A default badge"
|
||||
/>
|
||||
|
||||
## Installation
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">CLI</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add badge
|
||||
```
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps>
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource name="badge" title="components/ui/badge.tsx" />
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
</CodeTabs>
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx
|
||||
import { Badge } from "@/components/ui/badge"
|
||||
```
|
||||
|
||||
```tsx
|
||||
<Badge variant="default | outline | secondary | destructive">Badge</Badge>
|
||||
```
|
||||
|
||||
### Link
|
||||
|
||||
You can use the `asChild` prop to make another component look like a badge. Here's an example of a link that looks like a badge.
|
||||
|
||||
```tsx showLineNumbers
|
||||
import Link from "next/link"
|
||||
|
||||
import { Badge } from "@/components/ui/badge"
|
||||
|
||||
export function LinkAsBadge() {
|
||||
return (
|
||||
<Badge asChild>
|
||||
<Link href="/">Badge</Link>
|
||||
</Badge>
|
||||
)
|
||||
}
|
||||
```
|
||||
142
apps/v4/content/docs/components/base/accordion.mdx
Normal file
142
apps/v4/content/docs/components/base/accordion.mdx
Normal file
@@ -0,0 +1,142 @@
|
||||
---
|
||||
title: Accordion
|
||||
description: A vertically stacked set of interactive headings that each reveal a section of content.
|
||||
base: base
|
||||
component: true
|
||||
links:
|
||||
doc: https://base-ui.com/react/components/accordion
|
||||
api: https://base-ui.com/react/components/accordion#api-reference
|
||||
---
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="accordion-demo"
|
||||
align="start"
|
||||
previewClassName="*:data-[slot=accordion]:max-w-sm h-[300px]"
|
||||
/>
|
||||
|
||||
## Installation
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">Command</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
|
||||
<TabsContent value="cli">
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add accordion
|
||||
```
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @base-ui/react
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource
|
||||
name="accordion"
|
||||
title="components/ui/accordion.tsx"
|
||||
styleName="base-nova"
|
||||
/>
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
</CodeTabs>
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx showLineNumbers
|
||||
import {
|
||||
Accordion,
|
||||
AccordionContent,
|
||||
AccordionItem,
|
||||
AccordionTrigger,
|
||||
} from "@/components/ui/accordion"
|
||||
```
|
||||
|
||||
```tsx showLineNumbers
|
||||
<Accordion defaultValue={["item-1"]}>
|
||||
<AccordionItem value="item-1">
|
||||
<AccordionTrigger>Is it accessible?</AccordionTrigger>
|
||||
<AccordionContent>
|
||||
Yes. It adheres to the WAI-ARIA design pattern.
|
||||
</AccordionContent>
|
||||
</AccordionItem>
|
||||
</Accordion>
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Basic
|
||||
|
||||
A basic accordion that shows one item at a time. The first item is open by default.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="accordion-basic"
|
||||
align="start"
|
||||
previewClassName="*:data-[slot=accordion]:max-w-sm h-[300px]"
|
||||
/>
|
||||
|
||||
### Multiple
|
||||
|
||||
Use the `multiple` prop to allow multiple items to be open at the same time.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="accordion-multiple"
|
||||
align="start"
|
||||
previewClassName="*:data-[slot=accordion]:max-w-sm h-[450px]"
|
||||
/>
|
||||
|
||||
### Disabled
|
||||
|
||||
Use the `disabled` prop on `AccordionItem` to disable individual items.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="accordion-disabled"
|
||||
align="start"
|
||||
previewClassName="*:data-[slot=accordion]:max-w-sm h-[300px]"
|
||||
/>
|
||||
|
||||
### Borders
|
||||
|
||||
Add `border` to the `Accordion` and `border-b last:border-b-0` to the `AccordionItem` to add borders to the items.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="accordion-borders"
|
||||
align="start"
|
||||
previewClassName="*:data-[slot=accordion]:max-w-sm h-[300px]"
|
||||
/>
|
||||
|
||||
### Card
|
||||
|
||||
Wrap the `Accordion` in a `Card` component.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="accordion-card"
|
||||
align="start"
|
||||
previewClassName="*:data-[slot=accordion]:max-w-sm h-[435px]"
|
||||
/>
|
||||
|
||||
## API Reference
|
||||
|
||||
See the [Base UI](https://base-ui.com/react/components/accordion#api-reference) documentation for more information.
|
||||
159
apps/v4/content/docs/components/base/alert-dialog.mdx
Normal file
159
apps/v4/content/docs/components/base/alert-dialog.mdx
Normal file
@@ -0,0 +1,159 @@
|
||||
---
|
||||
title: Alert Dialog
|
||||
description: A modal dialog that interrupts the user with important content and expects a response.
|
||||
featured: true
|
||||
base: base
|
||||
component: true
|
||||
links:
|
||||
doc: https://base-ui.com/react/components/alert-dialog
|
||||
api: https://base-ui.com/react/components/alert-dialog#api-reference
|
||||
---
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="alert-dialog-demo"
|
||||
previewClassName="h-56"
|
||||
/>
|
||||
|
||||
## Installation
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">Command</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add alert-dialog
|
||||
```
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @base-ui/react
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource
|
||||
name="alert-dialog"
|
||||
title="components/ui/alert-dialog.tsx"
|
||||
styleName="base-nova"
|
||||
/>
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
</CodeTabs>
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx showLineNumbers
|
||||
import {
|
||||
AlertDialog,
|
||||
AlertDialogAction,
|
||||
AlertDialogCancel,
|
||||
AlertDialogContent,
|
||||
AlertDialogDescription,
|
||||
AlertDialogFooter,
|
||||
AlertDialogHeader,
|
||||
AlertDialogTitle,
|
||||
AlertDialogTrigger,
|
||||
} from "@/components/ui/alert-dialog"
|
||||
```
|
||||
|
||||
```tsx showLineNumbers
|
||||
<AlertDialog>
|
||||
<AlertDialogTrigger render={<Button variant="outline" />}>
|
||||
Show Dialog
|
||||
</AlertDialogTrigger>
|
||||
<AlertDialogContent>
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
|
||||
<AlertDialogDescription>
|
||||
This action cannot be undone. This will permanently delete your account
|
||||
from our servers.
|
||||
</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel>Cancel</AlertDialogCancel>
|
||||
<AlertDialogAction>Continue</AlertDialogAction>
|
||||
</AlertDialogFooter>
|
||||
</AlertDialogContent>
|
||||
</AlertDialog>
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Basic
|
||||
|
||||
A basic alert dialog with a title, description, and cancel and continue buttons.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="alert-dialog-basic"
|
||||
previewClassName="h-56"
|
||||
/>
|
||||
|
||||
### Small
|
||||
|
||||
Use the `size="sm"` prop to make the alert dialog smaller.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="alert-dialog-small"
|
||||
previewClassName="h-56"
|
||||
/>
|
||||
|
||||
### Media
|
||||
|
||||
Use the `AlertDialogMedia` component to add a media element such as an icon or image to the alert dialog.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="alert-dialog-media"
|
||||
previewClassName="h-56"
|
||||
/>
|
||||
|
||||
### Small with Media
|
||||
|
||||
Use the `size="sm"` prop to make the alert dialog smaller and the `AlertDialogMedia` component to add a media element such as an icon or image to the alert dialog.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="alert-dialog-small-media"
|
||||
previewClassName="h-56"
|
||||
/>
|
||||
|
||||
### Destructive
|
||||
|
||||
Use the `AlertDialogAction` component to add a destructive action button to the alert dialog.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="alert-dialog-destructive"
|
||||
previewClassName="h-56"
|
||||
/>
|
||||
|
||||
## API Reference
|
||||
|
||||
### size
|
||||
|
||||
Use the `size` props on the `AlertDialogContent` component to control the size of the alert dialog. It accepts the following values:
|
||||
|
||||
| Prop | Type | Default |
|
||||
| ------ | ------------------- | ----------- |
|
||||
| `size` | `"default" \| "sm"` | `"default"` |
|
||||
|
||||
For more information about the other components and their props, see the [Base UI documentation](https://base-ui.com/react/components/alert-dialog#api-reference).
|
||||
144
apps/v4/content/docs/components/base/alert.mdx
Normal file
144
apps/v4/content/docs/components/base/alert.mdx
Normal file
@@ -0,0 +1,144 @@
|
||||
---
|
||||
title: Alert
|
||||
description: Displays a callout for user attention.
|
||||
base: base
|
||||
component: true
|
||||
---
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="alert-demo"
|
||||
previewClassName="h-auto sm:h-72 p-6"
|
||||
/>
|
||||
|
||||
## Installation
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">Command</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add alert
|
||||
```
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource name="alert" title="components/ui/alert.tsx" />
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
</CodeTabs>
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx showLineNumbers
|
||||
import {
|
||||
Alert,
|
||||
AlertAction,
|
||||
AlertDescription,
|
||||
AlertTitle,
|
||||
} from "@/components/ui/alert"
|
||||
```
|
||||
|
||||
```tsx showLineNumbers
|
||||
<Alert>
|
||||
<InfoIcon />
|
||||
<AlertTitle>Heads up!</AlertTitle>
|
||||
<AlertDescription>
|
||||
You can add components and dependencies to your app using the cli.
|
||||
</AlertDescription>
|
||||
<AlertAction>
|
||||
<Button variant="outline">Enable</Button>
|
||||
</AlertAction>
|
||||
</Alert>
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Basic
|
||||
|
||||
A basic alert with an icon, title and description.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="alert-basic"
|
||||
previewClassName="h-auto sm:h-72 p-6"
|
||||
/>
|
||||
|
||||
### Destructive
|
||||
|
||||
Use `variant="destructive"` to create a destructive alert.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="alert-destructive"
|
||||
previewClassName="h-auto sm:h-72 p-6"
|
||||
/>
|
||||
|
||||
### Action
|
||||
|
||||
Use `AlertAction` to add a button or other action element to the alert.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="alert-action"
|
||||
previewClassName="h-auto sm:h-72 p-6"
|
||||
/>
|
||||
|
||||
### Custom Colors
|
||||
|
||||
You can customize the alert colors by adding custom classes such as `bg-amber-50 dark:bg-amber-950` to the `Alert` component.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="alert-colors"
|
||||
previewClassName="h-auto sm:h-72 p-6"
|
||||
/>
|
||||
|
||||
## API Reference
|
||||
|
||||
### Alert
|
||||
|
||||
The `Alert` component displays a callout for user attention.
|
||||
|
||||
| Prop | Type | Default |
|
||||
| --------- | ---------------------------- | ----------- |
|
||||
| `variant` | `"default" \| "destructive"` | `"default"` |
|
||||
|
||||
### AlertTitle
|
||||
|
||||
The `AlertTitle` component displays the title of the alert.
|
||||
|
||||
| Prop | Type | Default |
|
||||
| ----------- | -------- | ------- |
|
||||
| `className` | `string` | - |
|
||||
|
||||
### AlertDescription
|
||||
|
||||
The `AlertDescription` component displays the description or content of the alert.
|
||||
|
||||
| Prop | Type | Default |
|
||||
| ----------- | -------- | ------- |
|
||||
| `className` | `string` | - |
|
||||
|
||||
### AlertAction
|
||||
|
||||
The `AlertAction` component displays an action element (like a button) positioned absolutely in the top-right corner of the alert.
|
||||
|
||||
| Prop | Type | Default |
|
||||
| ----------- | -------- | ------- |
|
||||
| `className` | `string` | - |
|
||||
93
apps/v4/content/docs/components/base/aspect-ratio.mdx
Normal file
93
apps/v4/content/docs/components/base/aspect-ratio.mdx
Normal file
@@ -0,0 +1,93 @@
|
||||
---
|
||||
title: Aspect Ratio
|
||||
description: Displays content within a desired ratio.
|
||||
base: base
|
||||
component: true
|
||||
---
|
||||
|
||||
<ComponentPreview name="aspect-ratio-demo" styleName="base-nova" />
|
||||
|
||||
## Installation
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">Command</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add aspect-ratio
|
||||
```
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @base-ui/react
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource
|
||||
name="aspect-ratio"
|
||||
title="components/ui/aspect-ratio.tsx"
|
||||
styleName="base-nova"
|
||||
/>
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
</CodeTabs>
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx showLineNumbers
|
||||
import { AspectRatio } from "@/components/ui/aspect-ratio"
|
||||
```
|
||||
|
||||
```tsx showLineNumbers
|
||||
<AspectRatio ratio={16 / 9}>
|
||||
<Image src="..." alt="Image" className="rounded-md object-cover" />
|
||||
</AspectRatio>
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Square
|
||||
|
||||
A square aspect ratio component using the `ratio={1 / 1}` prop. This is useful for displaying images in a square format.
|
||||
|
||||
<ComponentPreview name="aspect-ratio-square" styleName="base-nova" />
|
||||
|
||||
### Portrait
|
||||
|
||||
A portrait aspect ratio component using the `ratio={9 / 16}` prop. This is useful for displaying images in a portrait format.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="aspect-ratio-portrait"
|
||||
previewClassName="h-96"
|
||||
/>
|
||||
|
||||
## API Reference
|
||||
|
||||
### AspectRatio
|
||||
|
||||
The `AspectRatio` component displays content within a desired ratio.
|
||||
|
||||
| Prop | Type | Default | Required |
|
||||
| ----------- | -------- | ------- | -------- |
|
||||
| `ratio` | `number` | - | Yes |
|
||||
| `className` | `string` | - | No |
|
||||
|
||||
For more information, see the [Base UI documentation](https://base-ui.com/react/components/aspect-ratio#api-reference).
|
||||
185
apps/v4/content/docs/components/base/avatar.mdx
Normal file
185
apps/v4/content/docs/components/base/avatar.mdx
Normal file
@@ -0,0 +1,185 @@
|
||||
---
|
||||
title: Avatar
|
||||
description: An image element with a fallback for representing the user.
|
||||
base: base
|
||||
component: true
|
||||
links:
|
||||
doc: https://base-ui.com/react/components/avatar
|
||||
api: https://base-ui.com/react/components/avatar#api-reference
|
||||
---
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="avatar-demo"
|
||||
previewClassName="h-72"
|
||||
/>
|
||||
|
||||
## Installation
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">Command</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add avatar
|
||||
```
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @base-ui/react
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource
|
||||
name="avatar"
|
||||
title="components/ui/avatar.tsx"
|
||||
styleName="base-nova"
|
||||
/>
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
</CodeTabs>
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx showLineNumbers
|
||||
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
|
||||
```
|
||||
|
||||
```tsx showLineNumbers
|
||||
<Avatar>
|
||||
<AvatarImage src="https://github.com/shadcn.png" />
|
||||
<AvatarFallback>CN</AvatarFallback>
|
||||
</Avatar>
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Basic
|
||||
|
||||
A basic avatar component with an image and a fallback.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="avatar-basic" />
|
||||
|
||||
### Badge
|
||||
|
||||
Use the `AvatarBadge` component to add a badge to the avatar. The badge is positioned at the bottom right of the avatar.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="avatar-badge" />
|
||||
|
||||
Use the `className` prop to add custom styles to the badge such as custom colors, sizes, etc.
|
||||
|
||||
```tsx showLineNumbers
|
||||
<Avatar>
|
||||
<AvatarImage src="https://github.com/shadcn.png" alt="@shadcn" />
|
||||
<AvatarFallback>CN</AvatarFallback>
|
||||
<AvatarBadge className="bg-green-600 dark:bg-green-800" />
|
||||
</Avatar>
|
||||
```
|
||||
|
||||
### Badge with Icon
|
||||
|
||||
You can also use an icon inside `<AvatarBadge>`.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="avatar-badge-icon" />
|
||||
|
||||
### Avatar Group
|
||||
|
||||
Use the `AvatarGroup` component to add a group of avatars.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="avatar-group" />
|
||||
|
||||
### Avatar Group Count
|
||||
|
||||
Use `<AvatarGroupCount>` to add a count to the group.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="avatar-group-count" />
|
||||
|
||||
### Avatar Group with Icon
|
||||
|
||||
You can also use an icon inside `<AvatarGroupCount>`.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="avatar-group-count-icon" />
|
||||
|
||||
### Sizes
|
||||
|
||||
Use the `size` prop to change the size of the avatar.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="avatar-size" />
|
||||
|
||||
### Dropdown
|
||||
|
||||
You can use the `Avatar` component as a trigger for a dropdown menu.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="avatar-dropdown" />
|
||||
|
||||
## API Reference
|
||||
|
||||
### Avatar
|
||||
|
||||
The `Avatar` component is the root component that wraps the avatar image and fallback.
|
||||
|
||||
| Prop | Type | Default |
|
||||
| ----------- | --------------------------- | ----------- |
|
||||
| `size` | `"default" \| "sm" \| "lg"` | `"default"` |
|
||||
| `className` | `string` | - |
|
||||
|
||||
### AvatarImage
|
||||
|
||||
The `AvatarImage` component displays the avatar image. It accepts all Base UI Avatar Image props.
|
||||
|
||||
| Prop | Type | Default |
|
||||
| ----------- | -------- | ------- |
|
||||
| `src` | `string` | - |
|
||||
| `alt` | `string` | - |
|
||||
| `className` | `string` | - |
|
||||
|
||||
### AvatarFallback
|
||||
|
||||
The `AvatarFallback` component displays a fallback when the image fails to load. It accepts all Base UI Avatar Fallback props.
|
||||
|
||||
| Prop | Type | Default |
|
||||
| ----------- | -------- | ------- |
|
||||
| `className` | `string` | - |
|
||||
|
||||
### AvatarBadge
|
||||
|
||||
The `AvatarBadge` component displays a badge indicator on the avatar, typically positioned at the bottom right.
|
||||
|
||||
| Prop | Type | Default |
|
||||
| ----------- | -------- | ------- |
|
||||
| `className` | `string` | - |
|
||||
|
||||
### AvatarGroup
|
||||
|
||||
The `AvatarGroup` component displays a group of avatars with overlapping styling.
|
||||
|
||||
| Prop | Type | Default |
|
||||
| ----------- | -------- | ------- |
|
||||
| `className` | `string` | - |
|
||||
|
||||
### AvatarGroupCount
|
||||
|
||||
The `AvatarGroupCount` component displays a count indicator in an avatar group, typically showing the number of additional avatars.
|
||||
|
||||
| Prop | Type | Default |
|
||||
| ----------- | -------- | ------- |
|
||||
| `className` | `string` | - |
|
||||
|
||||
For more information about Base UI Avatar props, see the [Base UI documentation](https://base-ui.com/react/components/avatar#api-reference).
|
||||
97
apps/v4/content/docs/components/base/badge.mdx
Normal file
97
apps/v4/content/docs/components/base/badge.mdx
Normal file
@@ -0,0 +1,97 @@
|
||||
---
|
||||
title: Badge
|
||||
description: Displays a badge or a component that looks like a badge.
|
||||
base: base
|
||||
component: true
|
||||
---
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="badge-demo" />
|
||||
|
||||
## Installation
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">Command</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add badge
|
||||
```
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource
|
||||
name="badge"
|
||||
title="components/ui/badge.tsx"
|
||||
styleName="base-nova"
|
||||
/>
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
</CodeTabs>
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx
|
||||
import { Badge } from "@/components/ui/badge"
|
||||
```
|
||||
|
||||
```tsx
|
||||
<Badge variant="default | outline | secondary | destructive">Badge</Badge>
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Variants
|
||||
|
||||
Use the `variant` prop to change the variant of the badge.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="badge-variants" />
|
||||
|
||||
### 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.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="badge-icon" />
|
||||
|
||||
### With Spinner
|
||||
|
||||
You can render a spinner inside the badge. Remember to add the `data-icon="inline-start"` or `data-icon="inline-end"` prop to the spinner.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="badge-spinner" />
|
||||
|
||||
### Link
|
||||
|
||||
Use the `render` prop to render a link as a badge.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="badge-link" />
|
||||
|
||||
### Custom Colors
|
||||
|
||||
You can customize the colors of a badge by adding custom classes such as `bg-green-50 dark:bg-green-800` to the `Badge` component.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="badge-colors" />
|
||||
|
||||
## API Reference
|
||||
|
||||
### Badge
|
||||
|
||||
The `Badge` component displays a badge or a component that looks like a badge.
|
||||
|
||||
| Prop | Type | Default |
|
||||
| ----------- | ----------------------------------------------------------------------------- | ----------- |
|
||||
| `variant` | `"default" \| "secondary" \| "destructive" \| "outline" \| "ghost" \| "link"` | `"default"` |
|
||||
| `className` | `string` | - |
|
||||
176
apps/v4/content/docs/components/base/breadcrumb.mdx
Normal file
176
apps/v4/content/docs/components/base/breadcrumb.mdx
Normal file
@@ -0,0 +1,176 @@
|
||||
---
|
||||
title: Breadcrumb
|
||||
description: Displays the path to the current resource using a hierarchy of links.
|
||||
base: base
|
||||
component: true
|
||||
---
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="breadcrumb-demo"
|
||||
previewClassName="p-2"
|
||||
/>
|
||||
|
||||
## Installation
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">Command</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add breadcrumb
|
||||
```
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource
|
||||
name="breadcrumb"
|
||||
title="components/ui/breadcrumb.tsx"
|
||||
styleName="base-nova"
|
||||
/>
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
</CodeTabs>
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx showLineNumbers
|
||||
import {
|
||||
Breadcrumb,
|
||||
BreadcrumbItem,
|
||||
BreadcrumbLink,
|
||||
BreadcrumbList,
|
||||
BreadcrumbPage,
|
||||
BreadcrumbSeparator,
|
||||
} from "@/components/ui/breadcrumb"
|
||||
```
|
||||
|
||||
```tsx showLineNumbers
|
||||
<Breadcrumb>
|
||||
<BreadcrumbList>
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbLink render={<a href="/" />}>Home</BreadcrumbLink>
|
||||
</BreadcrumbItem>
|
||||
<BreadcrumbSeparator />
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbLink render={<a href="/components" />}>
|
||||
Components
|
||||
</BreadcrumbLink>
|
||||
</BreadcrumbItem>
|
||||
<BreadcrumbSeparator />
|
||||
<BreadcrumbItem>
|
||||
<BreadcrumbPage>Breadcrumb</BreadcrumbPage>
|
||||
</BreadcrumbItem>
|
||||
</BreadcrumbList>
|
||||
</Breadcrumb>
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Basic
|
||||
|
||||
A basic breadcrumb with a home link and a components link.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="breadcrumb-basic" />
|
||||
|
||||
### Custom separator
|
||||
|
||||
Use a custom component as `children` for `<BreadcrumbSeparator />` to create a custom separator.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="breadcrumb-separator" />
|
||||
|
||||
### Dropdown
|
||||
|
||||
You can compose `<BreadcrumbItem />` with a `<DropdownMenu />` to create a dropdown in the breadcrumb.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="breadcrumb-dropdown" />
|
||||
|
||||
### Collapsed
|
||||
|
||||
We provide a `<BreadcrumbEllipsis />` component to show a collapsed state when the breadcrumb is too long.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="breadcrumb-ellipsis"
|
||||
previewClassName="p-2"
|
||||
/>
|
||||
|
||||
### Link component
|
||||
|
||||
To use a custom link component from your routing library, you can use the `render` prop on `<BreadcrumbLink />`.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="breadcrumb-link" />
|
||||
|
||||
## API Reference
|
||||
|
||||
### Breadcrumb
|
||||
|
||||
The `Breadcrumb` component is the root navigation element that wraps all breadcrumb components.
|
||||
|
||||
| Prop | Type | Default |
|
||||
| ----------- | -------- | ------- |
|
||||
| `className` | `string` | - |
|
||||
|
||||
### BreadcrumbList
|
||||
|
||||
The `BreadcrumbList` component displays the ordered list of breadcrumb items.
|
||||
|
||||
| Prop | Type | Default |
|
||||
| ----------- | -------- | ------- |
|
||||
| `className` | `string` | - |
|
||||
|
||||
### BreadcrumbItem
|
||||
|
||||
The `BreadcrumbItem` component wraps individual breadcrumb items.
|
||||
|
||||
| Prop | Type | Default |
|
||||
| ----------- | -------- | ------- |
|
||||
| `className` | `string` | - |
|
||||
|
||||
### BreadcrumbLink
|
||||
|
||||
The `BreadcrumbLink` component displays a clickable link in the breadcrumb.
|
||||
|
||||
| Prop | Type | Default |
|
||||
| ----------- | -------- | ------- |
|
||||
| `className` | `string` | - |
|
||||
|
||||
### BreadcrumbPage
|
||||
|
||||
The `BreadcrumbPage` component displays the current page in the breadcrumb (non-clickable).
|
||||
|
||||
| Prop | Type | Default |
|
||||
| ----------- | -------- | ------- |
|
||||
| `className` | `string` | - |
|
||||
|
||||
### BreadcrumbSeparator
|
||||
|
||||
The `BreadcrumbSeparator` component displays a separator between breadcrumb items. You can pass custom children to override the default separator icon.
|
||||
|
||||
| Prop | Type | Default |
|
||||
| ----------- | ----------------- | ------- |
|
||||
| `children` | `React.ReactNode` | - |
|
||||
| `className` | `string` | - |
|
||||
|
||||
### BreadcrumbEllipsis
|
||||
|
||||
The `BreadcrumbEllipsis` component displays an ellipsis indicator for collapsed breadcrumb items.
|
||||
|
||||
| Prop | Type | Default |
|
||||
| ----------- | -------- | ------- |
|
||||
| `className` | `string` | - |
|
||||
@@ -1,17 +1,18 @@
|
||||
---
|
||||
title: Button Group
|
||||
description: A container that groups related buttons together with consistent styling.
|
||||
base: base
|
||||
component: true
|
||||
---
|
||||
|
||||
<ComponentPreview name="button-group-demo" />
|
||||
<ComponentPreview styleName="base-nova" name="button-group-demo" />
|
||||
|
||||
## Installation
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">CLI</TabsTrigger>
|
||||
<TabsTrigger value="cli">Command</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
@@ -24,17 +25,21 @@ npx shadcn@latest add button-group
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps>
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-slot
|
||||
npm install @base-ui/react
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource name="button-group" title="components/ui/button-group.tsx" />
|
||||
<ComponentSource
|
||||
name="button-group"
|
||||
title="components/ui/button-group.tsx"
|
||||
styleName="base-nova"
|
||||
/>
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
@@ -85,19 +90,19 @@ import {
|
||||
|
||||
Set the `orientation` prop to change the button group layout.
|
||||
|
||||
<ComponentPreview name="button-group-orientation" />
|
||||
<ComponentPreview styleName="base-nova" name="button-group-orientation" />
|
||||
|
||||
### Size
|
||||
|
||||
Control the size of buttons using the `size` prop on individual buttons.
|
||||
|
||||
<ComponentPreview name="button-group-size" />
|
||||
<ComponentPreview styleName="base-nova" name="button-group-size" />
|
||||
|
||||
### Nested
|
||||
|
||||
Nest `<ButtonGroup>` components to create button groups with spacing.
|
||||
|
||||
<ComponentPreview name="button-group-nested" />
|
||||
<ComponentPreview styleName="base-nova" name="button-group-nested" />
|
||||
|
||||
### Separator
|
||||
|
||||
@@ -105,43 +110,43 @@ The `ButtonGroupSeparator` component visually divides buttons within a group.
|
||||
|
||||
Buttons with variant `outline` do not need a separator since they have a border. For other variants, a separator is recommended to improve the visual hierarchy.
|
||||
|
||||
<ComponentPreview name="button-group-separator" />
|
||||
<ComponentPreview styleName="base-nova" name="button-group-separator" />
|
||||
|
||||
### Split
|
||||
|
||||
Create a split button group by adding two buttons separated by a `ButtonGroupSeparator`.
|
||||
|
||||
<ComponentPreview name="button-group-split" />
|
||||
<ComponentPreview styleName="base-nova" name="button-group-split" />
|
||||
|
||||
### Input
|
||||
|
||||
Wrap an `Input` component with buttons.
|
||||
|
||||
<ComponentPreview name="button-group-input" />
|
||||
<ComponentPreview styleName="base-nova" name="button-group-input" />
|
||||
|
||||
### Input Group
|
||||
|
||||
Wrap an `InputGroup` component to create complex input layouts.
|
||||
|
||||
<ComponentPreview name="button-group-input-group" />
|
||||
<ComponentPreview styleName="base-nova" name="button-group-input-group" />
|
||||
|
||||
### Dropdown Menu
|
||||
|
||||
Create a split button group with a `DropdownMenu` component.
|
||||
|
||||
<ComponentPreview name="button-group-dropdown" />
|
||||
<ComponentPreview styleName="base-nova" name="button-group-dropdown" />
|
||||
|
||||
### Select
|
||||
|
||||
Pair with a `Select` component.
|
||||
|
||||
<ComponentPreview name="button-group-select" />
|
||||
<ComponentPreview styleName="base-nova" name="button-group-select" />
|
||||
|
||||
### Popover
|
||||
|
||||
Use with a `Popover` component.
|
||||
|
||||
<ComponentPreview name="button-group-popover" />
|
||||
<ComponentPreview styleName="base-nova" name="button-group-popover" />
|
||||
|
||||
## API Reference
|
||||
|
||||
153
apps/v4/content/docs/components/base/button.mdx
Normal file
153
apps/v4/content/docs/components/base/button.mdx
Normal file
@@ -0,0 +1,153 @@
|
||||
---
|
||||
title: Button
|
||||
description: Displays a button or a component that looks like a button.
|
||||
featured: true
|
||||
base: base
|
||||
component: true
|
||||
---
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="button-demo" />
|
||||
|
||||
## Installation
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">Command</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add button
|
||||
```
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @base-ui/react
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource
|
||||
name="button"
|
||||
title="components/ui/button.tsx"
|
||||
styleName="base-nova"
|
||||
/>
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
</CodeTabs>
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx
|
||||
import { Button } from "@/components/ui/button"
|
||||
```
|
||||
|
||||
```tsx
|
||||
<Button variant="outline">Button</Button>
|
||||
```
|
||||
|
||||
## Cursor
|
||||
|
||||
Tailwind v4 [switched](https://tailwindcss.com/docs/upgrade-guide#buttons-use-the-default-cursor) from `cursor: pointer` to `cursor: default` for the button component.
|
||||
|
||||
If you want to keep the `cursor: pointer` behavior, add the following code to your CSS file:
|
||||
|
||||
```css showLineNumbers title="globals.css"
|
||||
@layer base {
|
||||
button:not(:disabled),
|
||||
[role="button"]:not(:disabled) {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Size
|
||||
|
||||
Use the `size` prop to change the size of the button.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="button-size" />
|
||||
|
||||
### Default
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="button-default" />
|
||||
|
||||
### Outline
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="button-outline" />
|
||||
|
||||
### Secondary
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="button-secondary" />
|
||||
|
||||
### Ghost
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="button-ghost" />
|
||||
|
||||
### Destructive
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="button-destructive" />
|
||||
|
||||
### Link
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="button-link" />
|
||||
|
||||
### Icon
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="button-icon" />
|
||||
|
||||
### With Icon
|
||||
|
||||
Remember to add the `data-icon="inline-start"` or `data-icon="inline-end"` attribute to the icon for the correct spacing.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="button-with-icon" />
|
||||
|
||||
### Rounded
|
||||
|
||||
Use the `rounded-full` class to make the button rounded.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="button-rounded" />
|
||||
|
||||
### Spinner
|
||||
|
||||
Render a `<Spinner />` component inside the button to show a loading state. Remember to add the `data-icon="inline-start"` or `data-icon="inline-end"` attribute to the spinner for the correct spacing.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="button-spinner" />
|
||||
|
||||
### Button Group
|
||||
|
||||
To create a button group, use the `ButtonGroup` component. See the [Button Group](/docs/components/base/button-group) documentation for more details.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="button-group-demo" />
|
||||
|
||||
### Link
|
||||
|
||||
You can use the `render` prop on `<Button />` to make another component look like a button. Here's an example of a link that looks like a button.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="button-render" />
|
||||
|
||||
## API Reference
|
||||
|
||||
### Button
|
||||
|
||||
The `Button` component is a wrapper around the `button` element that adds a variety of styles and functionality.
|
||||
|
||||
| Prop | Type | Default |
|
||||
| --------- | ------------------------------------------------------------------------------------ | ----------- |
|
||||
| `variant` | `"default" \| "outline" \| "ghost" \| "destructive" \| "secondary" \| "link"` | `"default"` |
|
||||
| `size` | `"default" \| "xs" \| "sm" \| "lg" \| "icon" \| "icon-xs" \| "icon-sm" \| "icon-lg"` | `"default"` |
|
||||
@@ -1,15 +1,16 @@
|
||||
---
|
||||
title: Calendar
|
||||
description: A date field component that allows users to enter and edit date.
|
||||
description: A calendar component that allows users to select a date or a range of dates.
|
||||
base: base
|
||||
component: true
|
||||
links:
|
||||
doc: https://react-day-picker.js.org
|
||||
---
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="calendar-demo"
|
||||
title="Calendar"
|
||||
description="A calendar showing the current date."
|
||||
previewClassName="h-96"
|
||||
/>
|
||||
|
||||
## Blocks
|
||||
@@ -23,7 +24,7 @@ See all calendar blocks in the [Blocks Library](/blocks/calendar) page.
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">CLI</TabsTrigger>
|
||||
<TabsTrigger value="cli">Command</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
@@ -36,7 +37,7 @@ npx shadcn@latest add calendar
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps>
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
@@ -50,7 +51,11 @@ The `Calendar` component uses the `Button` component. Make sure you have it inst
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource name="calendar" title="components/ui/calendar.tsx" />
|
||||
<ComponentSource
|
||||
name="calendar"
|
||||
title="components/ui/calendar.tsx"
|
||||
styleName="base-nova"
|
||||
/>
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
@@ -85,13 +90,9 @@ See the [React DayPicker](https://react-day-picker.js.org) documentation for mor
|
||||
|
||||
The `Calendar` component is built on top of [React DayPicker](https://react-day-picker.js.org).
|
||||
|
||||
## Customization
|
||||
|
||||
See the [React DayPicker](https://react-day-picker.js.org/docs/customization) documentation for more information on how to customize the `Calendar` component.
|
||||
|
||||
## Date Picker
|
||||
|
||||
You can use the `<Calendar>` component to build a date picker. See the [Date Picker](/docs/components/date-picker) page for more information.
|
||||
You can use the `<Calendar>` component to build a date picker. See the [Date Picker](/docs/components/base/date-picker) page for more information.
|
||||
|
||||
## Persian / Hijri / Jalali Calendar
|
||||
|
||||
@@ -103,9 +104,11 @@ To use the Persian calendar, edit `components/ui/calendar.tsx` and replace `reac
|
||||
```
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="calendar-hijri"
|
||||
title="Persian / Hijri / Jalali Calendar"
|
||||
description="A Persian calendar."
|
||||
previewClassName="h-[400px]"
|
||||
/>
|
||||
|
||||
## Selected Date (With TimeZone)
|
||||
@@ -138,53 +141,65 @@ export function CalendarWithTimezone() {
|
||||
|
||||
## Examples
|
||||
|
||||
### Range Calendar
|
||||
### Basic
|
||||
|
||||
A basic calendar component. We used `className="rounded-lg border"` to style the calendar.
|
||||
|
||||
<ComponentPreview
|
||||
name="calendar-05"
|
||||
title="Range Calendar"
|
||||
description="A calendar showing the current date and range selection."
|
||||
className="**:[.preview]:h-auto lg:**:[.preview]:h-[450px]"
|
||||
styleName="base-nova"
|
||||
name="calendar-basic"
|
||||
previewClassName="h-96"
|
||||
/>
|
||||
|
||||
### Range Calendar
|
||||
|
||||
Use the `mode="range"` prop to enable range selection.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="calendar-range"
|
||||
previewClassName="h-[36rem] md:h-96"
|
||||
/>
|
||||
|
||||
### Month and Year Selector
|
||||
|
||||
Use `captionLayout="dropdown"` to show month and year dropdowns.
|
||||
|
||||
<ComponentPreview
|
||||
name="calendar-13"
|
||||
title="Month and Year Selector"
|
||||
description="A calendar with month and year dropdowns."
|
||||
styleName="base-nova"
|
||||
name="calendar-caption"
|
||||
previewClassName="h-96"
|
||||
/>
|
||||
|
||||
### Date of Birth Picker
|
||||
### Presets
|
||||
|
||||
<ComponentPreview
|
||||
name="calendar-22"
|
||||
title="Date of Birth Picker"
|
||||
description="A calendar with date of birth picker."
|
||||
styleName="base-nova"
|
||||
name="calendar-presets"
|
||||
previewClassName="h-[650px]"
|
||||
/>
|
||||
|
||||
### Date and Time Picker
|
||||
|
||||
<ComponentPreview
|
||||
name="calendar-24"
|
||||
title="Date and Time Picker"
|
||||
description="A calendar with date and time picker."
|
||||
styleName="base-nova"
|
||||
name="calendar-time"
|
||||
previewClassName="h-[600px]"
|
||||
/>
|
||||
|
||||
### Natural Language Picker
|
||||
|
||||
This component uses the `chrono-node` library to parse natural language dates.
|
||||
### Booked dates
|
||||
|
||||
<ComponentPreview
|
||||
name="calendar-29"
|
||||
title="Natural Language Picker"
|
||||
description="A calendar with natural language picker."
|
||||
styleName="base-nova"
|
||||
name="calendar-booked-dates"
|
||||
previewClassName="h-96"
|
||||
/>
|
||||
|
||||
### Custom Cell Size
|
||||
|
||||
<ComponentPreview
|
||||
name="calendar-18"
|
||||
styleName="base-nova"
|
||||
name="calendar-custom-days"
|
||||
title="Custom Cell Size"
|
||||
description="A calendar with custom cell size that's responsive."
|
||||
className="**:[.preview]:h-[560px]"
|
||||
@@ -212,6 +227,16 @@ Or use fixed values:
|
||||
/>
|
||||
```
|
||||
|
||||
### Week Numbers
|
||||
|
||||
Use `showWeekNumber` to show week numbers.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="calendar-week-numbers"
|
||||
previewClassName="h-96"
|
||||
/>
|
||||
|
||||
## Upgrade Guide
|
||||
|
||||
### Tailwind v4
|
||||
@@ -448,7 +473,7 @@ function CalendarDayButton({
|
||||
data-range-end={modifiers.range_end}
|
||||
data-range-middle={modifiers.range_middle}
|
||||
className={cn(
|
||||
"data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground data-[range-middle=true]:bg-accent data-[range-middle=true]:text-accent-foreground data-[range-start=true]:bg-primary data-[range-start=true]:text-primary-foreground data-[range-end=true]:bg-primary data-[range-end=true]:text-primary-foreground group-data-[focused=true]/day:border-ring group-data-[focused=true]/day:ring-ring/50 flex aspect-square h-auto w-full min-w-[--cell-size] flex-col gap-1 font-normal leading-none data-[range-end=true]:rounded-md data-[range-middle=true]:rounded-none data-[range-start=true]:rounded-md group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:ring-[3px] [&>span]:text-xs [&>span]:opacity-70",
|
||||
"data-[selected-single=true]:bg-primary data-[selected-single=true]:text-primary-foreground data-[range-middle=true]:bg-accent data-[range-middle=true]:text-accent-foreground data-[range-start=true]:bg-primary data-[range-start=true]:text-primary-foreground data-[range-end=true]:bg-primary data-[range-end=true]:text-primary-foreground group-data-[focused=true]/day:border-ring group-data-[focused=true]/day:ring-ring/50 flex aspect-square h-auto w-full min-w-[--cell-size] flex-col gap-1 leading-none font-normal group-data-[focused=true]/day:relative group-data-[focused=true]/day:z-10 group-data-[focused=true]/day:ring-[3px] data-[range-end=true]:rounded-md data-[range-middle=true]:rounded-none data-[range-start=true]:rounded-md [&>span]:text-xs [&>span]:opacity-70",
|
||||
defaultClassNames.day,
|
||||
className
|
||||
)}
|
||||
@@ -476,24 +501,6 @@ npx shadcn@latest add calendar-02
|
||||
|
||||
This will install the latest version of the calendar blocks.
|
||||
|
||||
## Changelog
|
||||
## API Reference
|
||||
|
||||
### 2025-10-26 Fixed day radius with week numbers
|
||||
|
||||
We have fixed an issue where the selected day's left border radius was not applied correctly when week numbers were displayed. The fix ensures that when `showWeekNumber` is enabled, the first day (which is the second child due to the week number column) correctly receives the rounded left border.
|
||||
|
||||
To apply this fix, edit `components/ui/calendar.tsx` and update the `day` class in `classNames`:
|
||||
|
||||
```tsx showLineNumbers title="components/ui/calendar.tsx" {5-7}
|
||||
classNames={{
|
||||
// ... other classNames
|
||||
day: cn(
|
||||
"relative w-full h-full p-0 text-center [&:last-child[data-selected=true]_button]:rounded-r-md group/day aspect-square select-none",
|
||||
props.showWeekNumber
|
||||
? "[&:nth-child(2)[data-selected=true]_button]:rounded-l-md"
|
||||
: "[&:first-child[data-selected=true]_button]:rounded-l-md",
|
||||
defaultClassNames.day
|
||||
),
|
||||
// ... other classNames
|
||||
}}
|
||||
```
|
||||
See the [React DayPicker](https://react-day-picker.js.org) documentation for more information on the `Calendar` component API.
|
||||
159
apps/v4/content/docs/components/base/card.mdx
Normal file
159
apps/v4/content/docs/components/base/card.mdx
Normal file
@@ -0,0 +1,159 @@
|
||||
---
|
||||
title: Card
|
||||
description: Displays a card with header, content, and footer.
|
||||
base: base
|
||||
component: true
|
||||
---
|
||||
|
||||
<ComponentPreview
|
||||
name="card-demo"
|
||||
styleName="base-nova"
|
||||
previewClassName="h-[30rem]"
|
||||
/>
|
||||
|
||||
## Installation
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">Command</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add card
|
||||
```
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource
|
||||
name="card"
|
||||
title="components/ui/card.tsx"
|
||||
styleName="base-nova"
|
||||
/>
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
</CodeTabs>
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx showLineNumbers
|
||||
import {
|
||||
Card,
|
||||
CardAction,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardFooter,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/components/ui/card"
|
||||
```
|
||||
|
||||
```tsx showLineNumbers
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Card Title</CardTitle>
|
||||
<CardDescription>Card Description</CardDescription>
|
||||
<CardAction>Card Action</CardAction>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<p>Card Content</p>
|
||||
</CardContent>
|
||||
<CardFooter>
|
||||
<p>Card Footer</p>
|
||||
</CardFooter>
|
||||
</Card>
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Size
|
||||
|
||||
Use the `size="sm"` prop to set the size of the card to small. The small size variant uses smaller spacing.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="card-small"
|
||||
previewClassName="h-96"
|
||||
/>
|
||||
|
||||
### Image
|
||||
|
||||
Add an image before the card header to create a card with an image.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="card-image"
|
||||
previewClassName="h-[32rem]"
|
||||
/>
|
||||
|
||||
## API Reference
|
||||
|
||||
### Card
|
||||
|
||||
The `Card` component is the root container for card content.
|
||||
|
||||
| Prop | Type | Default |
|
||||
| ----------- | ------------------- | ----------- |
|
||||
| `size` | `"default" \| "sm"` | `"default"` |
|
||||
| `className` | `string` | - |
|
||||
|
||||
### CardHeader
|
||||
|
||||
The `CardHeader` component is used for a title, description, and optional action.
|
||||
|
||||
| Prop | Type | Default |
|
||||
| ----------- | -------- | ------- |
|
||||
| `className` | `string` | - |
|
||||
|
||||
### CardTitle
|
||||
|
||||
The `CardTitle` component is used for the card title.
|
||||
|
||||
| Prop | Type | Default |
|
||||
| ----------- | -------- | ------- |
|
||||
| `className` | `string` | - |
|
||||
|
||||
### CardDescription
|
||||
|
||||
The `CardDescription` component is used for helper text under the title.
|
||||
|
||||
| Prop | Type | Default |
|
||||
| ----------- | -------- | ------- |
|
||||
| `className` | `string` | - |
|
||||
|
||||
### CardAction
|
||||
|
||||
The `CardAction` component places content in the top-right of the header (for example, a button or a badge).
|
||||
|
||||
| Prop | Type | Default |
|
||||
| ----------- | -------- | ------- |
|
||||
| `className` | `string` | - |
|
||||
|
||||
### CardContent
|
||||
|
||||
The `CardContent` component is used for the main card body.
|
||||
|
||||
| Prop | Type | Default |
|
||||
| ----------- | -------- | ------- |
|
||||
| `className` | `string` | - |
|
||||
|
||||
### CardFooter
|
||||
|
||||
The `CardFooter` component is used for actions and secondary content at the bottom of the card.
|
||||
|
||||
| Prop | Type | Default |
|
||||
| ----------- | -------- | ------- |
|
||||
| `className` | `string` | - |
|
||||
@@ -1,6 +1,7 @@
|
||||
---
|
||||
title: Carousel
|
||||
description: A carousel with motion and swipe built using Embla.
|
||||
base: base
|
||||
component: true
|
||||
links:
|
||||
doc: https://www.embla-carousel.com/get-started/react
|
||||
@@ -8,9 +9,9 @@ links:
|
||||
---
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="carousel-demo"
|
||||
title="Carousel"
|
||||
description="A carousel with 5 items and a previous and next button."
|
||||
previewClassName="h-80 sm:h-[32rem]"
|
||||
/>
|
||||
|
||||
## About
|
||||
@@ -22,7 +23,7 @@ The carousel component is built using the [Embla Carousel](https://www.embla-car
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">CLI</TabsTrigger>
|
||||
<TabsTrigger value="cli">Command</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
|
||||
@@ -36,7 +37,7 @@ npx shadcn@latest add carousel
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps>
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
@@ -46,7 +47,11 @@ npm install embla-carousel-react
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource name="carousel" title="components/ui/carousel.tsx" />
|
||||
<ComponentSource
|
||||
name="carousel"
|
||||
title="components/ui/carousel.tsx"
|
||||
styleName="base-nova"
|
||||
/>
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
@@ -86,11 +91,7 @@ import {
|
||||
|
||||
To set the size of the items, you can use the `basis` utility class on the `<CarouselItem />`.
|
||||
|
||||
<ComponentPreview
|
||||
name="carousel-size"
|
||||
title="Carousel"
|
||||
description="A carousel with 3 active items of equal size."
|
||||
/>
|
||||
<ComponentPreview styleName="base-nova" name="carousel-size" />
|
||||
|
||||
```tsx showLineNumbers {4-6}
|
||||
// 33% of the carousel width.
|
||||
@@ -118,21 +119,7 @@ To set the size of the items, you can use the `basis` utility class on the `<Car
|
||||
|
||||
To set the spacing between the items, we use a `pl-[VALUE]` utility on the `<CarouselItem />` and a negative `-ml-[VALUE]` on the `<CarouselContent />`.
|
||||
|
||||
<Callout className="mt-6">
|
||||
**Why:** I tried to use the `gap` property or a `grid` layout on the `
|
||||
<CarouselContent />` but it required a lot of math and mental effort to get the
|
||||
spacing right. I found `pl-[VALUE]` and `-ml-[VALUE]` utilities much easier to
|
||||
use.
|
||||
|
||||
You can always adjust this in your own project if you need to.
|
||||
|
||||
</Callout>
|
||||
|
||||
<ComponentPreview
|
||||
name="carousel-spacing"
|
||||
title="Carousel"
|
||||
description="A carousel with 3 items with a spacing of 1rem."
|
||||
/>
|
||||
<ComponentPreview styleName="base-nova" name="carousel-spacing" />
|
||||
|
||||
```tsx showLineNumbers /-ml-4/ /pl-4/
|
||||
<Carousel>
|
||||
@@ -159,9 +146,9 @@ You can always adjust this in your own project if you need to.
|
||||
Use the `orientation` prop to set the orientation of the carousel.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="carousel-orientation"
|
||||
title="Carousel"
|
||||
description="A vertical carousel."
|
||||
previewClassName="h-[32rem]"
|
||||
/>
|
||||
|
||||
```tsx showLineNumbers /vertical | horizontal/
|
||||
@@ -198,9 +185,9 @@ You can pass options to the carousel using the `opts` prop. See the [Embla Carou
|
||||
Use a state and the `setApi` props to get an instance of the carousel API.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="carousel-api"
|
||||
title="Carousel"
|
||||
description="A carousel with a slide counter."
|
||||
previewClassName="sm:h-[32rem]"
|
||||
/>
|
||||
|
||||
```tsx showLineNumbers {1,4,22}
|
||||
@@ -293,9 +280,11 @@ export function Example() {
|
||||
```
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="carousel-plugin"
|
||||
title="Carousel"
|
||||
description="A carousel with the autoplay plugin."
|
||||
previewClassName="sm:h-[32rem]"
|
||||
/>
|
||||
|
||||
See the [Embla Carousel docs](https://www.embla-carousel.com/api/plugins/) for more information on using plugins.
|
||||
## API Reference
|
||||
|
||||
See the [Embla Carousel docs](https://www.embla-carousel.com/api/plugins/) for more information on props and plugins.
|
||||
@@ -1,6 +1,7 @@
|
||||
---
|
||||
title: Chart
|
||||
description: Beautiful charts. Built using Recharts. Copy and paste into your apps.
|
||||
base: base
|
||||
component: true
|
||||
---
|
||||
|
||||
@@ -11,7 +12,8 @@ component: true
|
||||
</Callout>
|
||||
|
||||
<ComponentPreview
|
||||
name="chart-bar-interactive"
|
||||
styleName="base-nova"
|
||||
name="chart-demo"
|
||||
className="theme-blue [&_.preview]:h-auto [&_.preview]:p-0 [&_.preview]:lg:min-h-[404px] [&_.preview>div]:w-full [&_.preview>div]:border-none [&_.preview>div]:shadow-none"
|
||||
hideCode
|
||||
/>
|
||||
@@ -51,57 +53,23 @@ We do not wrap Recharts. This means you're not locked into an abstraction. When
|
||||
|
||||
## Installation
|
||||
|
||||
<Callout className="mt-4">
|
||||
|
||||
**Note:** If you are using charts with **React 19** or the **Next.js 15**, see the note [here](/docs/react-19#recharts).
|
||||
|
||||
</Callout>
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">CLI</TabsTrigger>
|
||||
<TabsTrigger value="cli">Command</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
|
||||
<Steps>
|
||||
|
||||
<Step>Run the following command to install `chart.tsx`</Step>
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add chart
|
||||
```
|
||||
|
||||
<Step>Add the following colors to your CSS file</Step>
|
||||
|
||||
```css title="app/globals.css" showLineNumbers
|
||||
@layer base {
|
||||
:root {
|
||||
--chart-1: oklch(0.646 0.222 41.116);
|
||||
--chart-2: oklch(0.6 0.118 184.704);
|
||||
--chart-3: oklch(0.398 0.07 227.392);
|
||||
--chart-4: oklch(0.828 0.189 84.429);
|
||||
--chart-5: oklch(0.769 0.188 70.08);
|
||||
}
|
||||
|
||||
.dark {
|
||||
--chart-1: oklch(0.488 0.243 264.376);
|
||||
--chart-2: oklch(0.696 0.17 162.48);
|
||||
--chart-3: oklch(0.769 0.188 70.08);
|
||||
--chart-4: oklch(0.627 0.265 303.9);
|
||||
--chart-5: oklch(0.645 0.246 16.439);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</Steps>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps>
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
@@ -111,7 +79,11 @@ npm install recharts
|
||||
|
||||
<Step>Copy and paste the following code into `components/ui/chart.tsx`.</Step>
|
||||
|
||||
<ComponentSource name="chart" title="components/ui/chart.tsx" />
|
||||
<ComponentSource
|
||||
name="chart"
|
||||
title="components/ui/chart.tsx"
|
||||
styleName="base-nova"
|
||||
/>
|
||||
|
||||
<Step>Add the following colors to your CSS file</Step>
|
||||
|
||||
@@ -197,11 +169,10 @@ You can now build your chart using Recharts components.
|
||||
|
||||
</Callout>
|
||||
|
||||
<ComponentSource name="chart-bar-demo" title="components/example-chart.tsx" />
|
||||
|
||||
<ComponentPreview
|
||||
name="chart-bar-demo"
|
||||
className="[&_.preview]:min-h-[250px] [&_.preview]:p-4"
|
||||
styleName="base-nova"
|
||||
name="chart-example"
|
||||
previewClassName="h-80"
|
||||
/>
|
||||
|
||||
</Steps>
|
||||
@@ -210,7 +181,7 @@ You can now build your chart using Recharts components.
|
||||
|
||||
Let's add a grid to the chart.
|
||||
|
||||
<Steps>
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Import the `CartesianGrid` component.</Step>
|
||||
|
||||
@@ -231,8 +202,9 @@ import { Bar, BarChart, CartesianGrid } from "recharts"
|
||||
```
|
||||
|
||||
<ComponentPreview
|
||||
name="chart-bar-demo-grid"
|
||||
className="[&_.preview]:min-h-[250px] [&_.preview]:p-4"
|
||||
styleName="base-nova"
|
||||
name="chart-example-grid"
|
||||
previewClassName="h-80"
|
||||
/>
|
||||
|
||||
</Steps>
|
||||
@@ -241,7 +213,7 @@ import { Bar, BarChart, CartesianGrid } from "recharts"
|
||||
|
||||
To add an x-axis to the chart, we'll use the `XAxis` component.
|
||||
|
||||
<Steps>
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Import the `XAxis` component.</Step>
|
||||
|
||||
@@ -269,8 +241,9 @@ import { Bar, BarChart, CartesianGrid, XAxis } from "recharts"
|
||||
```
|
||||
|
||||
<ComponentPreview
|
||||
name="chart-bar-demo-axis"
|
||||
className="[&_.preview]:min-h-[250px] [&_.preview]:p-4"
|
||||
styleName="base-nova"
|
||||
name="chart-example-axis"
|
||||
previewClassName="h-80"
|
||||
/>
|
||||
|
||||
</Steps>
|
||||
@@ -281,7 +254,7 @@ So far we've only used components from Recharts. They look great out of the box
|
||||
|
||||
To add a tooltip, we'll use the custom `ChartTooltip` and `ChartTooltipContent` components from `chart`.
|
||||
|
||||
<Steps>
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Import the `ChartTooltip` and `ChartTooltipContent` components.</Step>
|
||||
|
||||
@@ -310,8 +283,9 @@ import { ChartTooltip, ChartTooltipContent } from "@/components/ui/chart"
|
||||
```
|
||||
|
||||
<ComponentPreview
|
||||
name="chart-bar-demo-tooltip"
|
||||
className="[&_.preview]:min-h-[250px] [&_.preview]:p-4"
|
||||
styleName="base-nova"
|
||||
name="chart-example-tooltip"
|
||||
previewClassName="h-80"
|
||||
/>
|
||||
|
||||
Hover to see the tooltips. Easy, right? Two components, and we've got a beautiful tooltip.
|
||||
@@ -322,7 +296,7 @@ Hover to see the tooltips. Easy, right? Two components, and we've got a beautifu
|
||||
|
||||
We'll do the same for the legend. We'll use the `ChartLegend` and `ChartLegendContent` components from `chart`.
|
||||
|
||||
<Steps>
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Import the `ChartLegend` and `ChartLegendContent` components.</Step>
|
||||
|
||||
@@ -352,8 +326,9 @@ import { ChartLegend, ChartLegendContent } from "@/components/ui/chart"
|
||||
```
|
||||
|
||||
<ComponentPreview
|
||||
name="chart-bar-demo-legend"
|
||||
className="[&_.preview]:min-h-[250px] [&_.preview]:p-4"
|
||||
styleName="base-nova"
|
||||
name="chart-example-legend"
|
||||
previewClassName="h-80"
|
||||
/>
|
||||
|
||||
</Steps>
|
||||
@@ -398,11 +373,11 @@ Charts have built-in support for theming. You can use css variables (recommended
|
||||
|
||||
### CSS Variables
|
||||
|
||||
<Steps>
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Define your colors in your css file</Step>
|
||||
|
||||
```css {6-7,14-15} title="app/globals.css" showLineNumbers
|
||||
```css title="app/globals.css" showLineNumbers
|
||||
@layer base {
|
||||
:root {
|
||||
--chart-1: oklch(0.646 0.222 41.116);
|
||||
@@ -418,7 +393,7 @@ Charts have built-in support for theming. You can use css variables (recommended
|
||||
|
||||
<Step>Add the color to your `chartConfig`</Step>
|
||||
|
||||
```tsx {4,8} showLineNumbers
|
||||
```tsx title="components/example-chart.tsx" showLineNumbers
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: "Desktop",
|
||||
@@ -437,12 +412,24 @@ const chartConfig = {
|
||||
|
||||
You can also define your colors directly in the chart config. Use the color format you prefer.
|
||||
|
||||
```tsx showLineNumbers
|
||||
```tsx title="components/example-chart.tsx" showLineNumbers
|
||||
const chartConfig = {
|
||||
desktop: {
|
||||
label: "Desktop",
|
||||
color: "#2563eb",
|
||||
},
|
||||
mobile: {
|
||||
label: "Mobile",
|
||||
color: "hsl(220, 98%, 61%)",
|
||||
},
|
||||
tablet: {
|
||||
label: "Tablet",
|
||||
color: "oklch(0.5 0.2 240)",
|
||||
},
|
||||
laptop: {
|
||||
label: "Laptop",
|
||||
color: "var(--chart-2)",
|
||||
},
|
||||
} satisfies ChartConfig
|
||||
```
|
||||
|
||||
@@ -458,7 +445,7 @@ To use the theme colors in your chart, reference the colors using the format `va
|
||||
|
||||
#### Chart Data
|
||||
|
||||
```tsx showLineNumbers
|
||||
```tsx title="components/example-chart.tsx" showLineNumbers
|
||||
const chartData = [
|
||||
{ browser: "chrome", visitors: 275, fill: "var(--color-chrome)" },
|
||||
{ browser: "safari", visitors: 200, fill: "var(--color-safari)" },
|
||||
@@ -467,7 +454,7 @@ const chartData = [
|
||||
|
||||
#### Tailwind
|
||||
|
||||
```tsx
|
||||
```tsx title="components/example-chart.tsx"
|
||||
<LabelList className="fill-[--color-desktop]" />
|
||||
```
|
||||
|
||||
@@ -475,11 +462,7 @@ const chartData = [
|
||||
|
||||
A chart tooltip contains a label, name, indicator and value. You can use a combination of these to customize your tooltip.
|
||||
|
||||
<ComponentPreview
|
||||
name="chart-tooltip-demo"
|
||||
className="[&_.preview]:py-0"
|
||||
hideCode
|
||||
/>
|
||||
<ComponentPreview styleName="base-nova" name="chart-tooltip" hideCode />
|
||||
|
||||
You can turn on/off any of these using the `hideLabel`, `hideIndicator` props and customize the indicator style using the `indicator` prop.
|
||||
|
||||
@@ -487,11 +470,11 @@ Use `labelKey` and `nameKey` to use a custom key for the tooltip label and name.
|
||||
|
||||
Chart comes with the `<ChartTooltip>` and `<ChartTooltipContent>` components. You can use these two components to add custom tooltips to your chart.
|
||||
|
||||
```tsx
|
||||
```tsx title="components/example-chart.tsx"
|
||||
import { ChartTooltip, ChartTooltipContent } from "@/components/ui/chart"
|
||||
```
|
||||
|
||||
```tsx
|
||||
```tsx title="components/example-chart.tsx"
|
||||
<ChartTooltip content={<ChartTooltipContent />} />
|
||||
```
|
||||
|
||||
@@ -536,7 +519,7 @@ const chartConfig = {
|
||||
} satisfies ChartConfig
|
||||
```
|
||||
|
||||
```tsx
|
||||
```tsx title="components/example-chart.tsx"
|
||||
<ChartTooltip
|
||||
content={<ChartTooltipContent labelKey="visitors" nameKey="browser" />}
|
||||
/>
|
||||
@@ -548,11 +531,11 @@ This will use `Total Visitors` for label and `Chrome` and `Safari` for the toolt
|
||||
|
||||
You can use the custom `<ChartLegend>` and `<ChartLegendContent>` components to add a legend to your chart.
|
||||
|
||||
```tsx
|
||||
```tsx title="components/example-chart.tsx"
|
||||
import { ChartLegend, ChartLegendContent } from "@/components/ui/chart"
|
||||
```
|
||||
|
||||
```tsx
|
||||
```tsx title="components/example-chart.tsx"
|
||||
<ChartLegend content={<ChartLegendContent />} />
|
||||
```
|
||||
|
||||
@@ -582,7 +565,7 @@ const chartConfig = {
|
||||
} satisfies ChartConfig
|
||||
```
|
||||
|
||||
```tsx
|
||||
```tsx title="components/example-chart.tsx"
|
||||
<ChartLegend content={<ChartLegendContent nameKey="browser" />} />
|
||||
```
|
||||
|
||||
@@ -594,6 +577,6 @@ You can turn on the `accessibilityLayer` prop to add an accessible layer to your
|
||||
|
||||
This prop adds keyboard access and screen reader support to your charts.
|
||||
|
||||
```tsx
|
||||
```tsx title="components/example-chart.tsx"
|
||||
<LineChart accessibilityLayer />
|
||||
```
|
||||
127
apps/v4/content/docs/components/base/checkbox.mdx
Normal file
127
apps/v4/content/docs/components/base/checkbox.mdx
Normal file
@@ -0,0 +1,127 @@
|
||||
---
|
||||
title: Checkbox
|
||||
description: A control that allows the user to toggle between checked and not checked.
|
||||
base: base
|
||||
component: true
|
||||
links:
|
||||
doc: https://base-ui.com/react/components/checkbox
|
||||
api: https://base-ui.com/react/components/checkbox#api-reference
|
||||
---
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="checkbox-demo"
|
||||
previewClassName="h-80"
|
||||
/>
|
||||
|
||||
## Installation
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">Command</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add checkbox
|
||||
```
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @base-ui/react
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource
|
||||
name="checkbox"
|
||||
title="components/ui/checkbox.tsx"
|
||||
styleName="base-nova"
|
||||
/>
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
</CodeTabs>
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx
|
||||
import { Checkbox } from "@/components/ui/checkbox"
|
||||
```
|
||||
|
||||
```tsx
|
||||
<Checkbox />
|
||||
```
|
||||
|
||||
## Checked State
|
||||
|
||||
Use `defaultChecked` for uncontrolled checkboxes, or `checked` and
|
||||
`onCheckedChange` to control the state.
|
||||
|
||||
```tsx showLineNumbers
|
||||
import * as React from "react"
|
||||
|
||||
export function Example() {
|
||||
const [checked, setChecked] = React.useState(false)
|
||||
|
||||
return <Checkbox checked={checked} onCheckedChange={setChecked} />
|
||||
}
|
||||
```
|
||||
|
||||
## Invalid State
|
||||
|
||||
Set `aria-invalid` on the checkbox and `data-invalid` on the field wrapper to
|
||||
show the invalid styles.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="checkbox-invalid" />
|
||||
|
||||
## Examples
|
||||
|
||||
### Basic
|
||||
|
||||
Pair the checkbox with `Field` and `FieldLabel` for proper layout and labeling.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="checkbox-basic" />
|
||||
|
||||
### Description
|
||||
|
||||
Use `FieldContent` and `FieldDescription` for helper text.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="checkbox-description" />
|
||||
|
||||
### Disabled
|
||||
|
||||
Use the `disabled` prop to prevent interaction and add the `data-disabled` attribute to the `<Field>` component for disabled styles.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="checkbox-disabled" />
|
||||
|
||||
### Group
|
||||
|
||||
Use multiple fields to create a checkbox list.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="checkbox-group" />
|
||||
|
||||
### Table
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="checkbox-table"
|
||||
previewClassName="p-4 md:p-8"
|
||||
/>
|
||||
|
||||
## API Reference
|
||||
|
||||
See the [Base UI](https://base-ui.com/react/components/checkbox#api-reference) documentation for more information.
|
||||
123
apps/v4/content/docs/components/base/collapsible.mdx
Normal file
123
apps/v4/content/docs/components/base/collapsible.mdx
Normal file
@@ -0,0 +1,123 @@
|
||||
---
|
||||
title: Collapsible
|
||||
description: An interactive component which expands/collapses a panel.
|
||||
base: base
|
||||
component: true
|
||||
featured: true
|
||||
links:
|
||||
doc: https://base-ui.com/react/components/collapsible
|
||||
api: https://base-ui.com/react/components/collapsible#api-reference
|
||||
---
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="collapsible-demo" align="start" />
|
||||
|
||||
## Installation
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">Command</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add collapsible
|
||||
```
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @base-ui/react
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource
|
||||
name="collapsible"
|
||||
title="components/ui/collapsible.tsx"
|
||||
styleName="base-nova"
|
||||
/>
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
</CodeTabs>
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx showLineNumbers
|
||||
import {
|
||||
Collapsible,
|
||||
CollapsibleContent,
|
||||
CollapsibleTrigger,
|
||||
} from "@/components/ui/collapsible"
|
||||
```
|
||||
|
||||
```tsx showLineNumbers
|
||||
<Collapsible>
|
||||
<CollapsibleTrigger>Can I use this in my project?</CollapsibleTrigger>
|
||||
<CollapsibleContent>
|
||||
Yes. Free to use for personal and commercial projects. No attribution
|
||||
required.
|
||||
</CollapsibleContent>
|
||||
</Collapsible>
|
||||
```
|
||||
|
||||
## Controlled State
|
||||
|
||||
Use the `open` and `onOpenChange` props to control the state.
|
||||
|
||||
```tsx showLineNumbers
|
||||
import * as React from "react"
|
||||
|
||||
export function Example() {
|
||||
const [open, setOpen] = React.useState(false)
|
||||
|
||||
return (
|
||||
<Collapsible open={open} onOpenChange={setOpen}>
|
||||
<CollapsibleTrigger>Toggle</CollapsibleTrigger>
|
||||
<CollapsibleContent>Content</CollapsibleContent>
|
||||
</Collapsible>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Basic
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="collapsible-basic"
|
||||
align="start"
|
||||
/>
|
||||
|
||||
### Settings Panel
|
||||
|
||||
Use a trigger button to reveal additional settings.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="collapsible-settings" />
|
||||
|
||||
### File Tree
|
||||
|
||||
Use nested collapsibles to build a file tree.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="collapsible-file-tree"
|
||||
previewClassName="h-[36rem]"
|
||||
/>
|
||||
|
||||
## API Reference
|
||||
|
||||
See the [Base UI](https://base-ui.com/react/components/collapsible#api-reference) documentation for more information.
|
||||
261
apps/v4/content/docs/components/base/combobox.mdx
Normal file
261
apps/v4/content/docs/components/base/combobox.mdx
Normal file
@@ -0,0 +1,261 @@
|
||||
---
|
||||
title: Combobox
|
||||
description: Autocomplete input with a list of suggestions.
|
||||
base: base
|
||||
component: true
|
||||
links:
|
||||
doc: https://base-ui.com/react/components/combobox
|
||||
api: https://base-ui.com/react/components/combobox#api-reference
|
||||
---
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="combobox-demo"
|
||||
description="A combobox with a list of frameworks."
|
||||
/>
|
||||
|
||||
## Installation
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">Command</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add combobox
|
||||
```
|
||||
|
||||
</TabsContent>
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @base-ui/react
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource
|
||||
name="combobox"
|
||||
title="components/ui/combobox.tsx"
|
||||
styleName="base-nova"
|
||||
/>
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
</CodeTabs>
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx showLineNumbers
|
||||
import {
|
||||
Combobox,
|
||||
ComboboxContent,
|
||||
ComboboxEmpty,
|
||||
ComboboxInput,
|
||||
ComboboxItem,
|
||||
ComboboxList,
|
||||
} from "@/components/ui/combobox"
|
||||
```
|
||||
|
||||
```tsx showLineNumbers
|
||||
const frameworks = ["Next.js", "SvelteKit", "Nuxt.js", "Remix", "Astro"]
|
||||
|
||||
export function ExampleCombobox() {
|
||||
return (
|
||||
<Combobox items={frameworks}>
|
||||
<ComboboxInput placeholder="Select a framework" />
|
||||
<ComboboxContent>
|
||||
<ComboboxEmpty>No items found.</ComboboxEmpty>
|
||||
<ComboboxList>
|
||||
{(item) => (
|
||||
<ComboboxItem key={item} value={item}>
|
||||
{item}
|
||||
</ComboboxItem>
|
||||
)}
|
||||
</ComboboxList>
|
||||
</ComboboxContent>
|
||||
</Combobox>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
## Custom Items
|
||||
|
||||
Use `itemToStringValue` when your items are objects.
|
||||
|
||||
```tsx showLineNumbers
|
||||
import * as React from "react"
|
||||
|
||||
import {
|
||||
Combobox,
|
||||
ComboboxContent,
|
||||
ComboboxEmpty,
|
||||
ComboboxInput,
|
||||
ComboboxItem,
|
||||
ComboboxList,
|
||||
} from "@/components/ui/combobox"
|
||||
|
||||
type Framework = {
|
||||
label: string
|
||||
value: string
|
||||
}
|
||||
|
||||
const frameworks: Framework[] = [
|
||||
{ label: "Next.js", value: "next" },
|
||||
{ label: "SvelteKit", value: "sveltekit" },
|
||||
{ label: "Nuxt", value: "nuxt" },
|
||||
]
|
||||
|
||||
export function ExampleComboboxCustomItems() {
|
||||
return (
|
||||
<Combobox
|
||||
items={frameworks}
|
||||
itemToStringValue={(framework) => framework.label}
|
||||
>
|
||||
<ComboboxInput placeholder="Select a framework" />
|
||||
<ComboboxContent>
|
||||
<ComboboxEmpty>No items found.</ComboboxEmpty>
|
||||
<ComboboxList>
|
||||
{(framework) => (
|
||||
<ComboboxItem key={framework.value} value={framework}>
|
||||
{framework.label}
|
||||
</ComboboxItem>
|
||||
)}
|
||||
</ComboboxList>
|
||||
</ComboboxContent>
|
||||
</Combobox>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
## Multiple Selection
|
||||
|
||||
Use `multiple` with chips for multi-select behavior.
|
||||
|
||||
```tsx showLineNumbers
|
||||
import * as React from "react"
|
||||
|
||||
import {
|
||||
Combobox,
|
||||
ComboboxChip,
|
||||
ComboboxChips,
|
||||
ComboboxChipsInput,
|
||||
ComboboxContent,
|
||||
ComboboxEmpty,
|
||||
ComboboxInput,
|
||||
ComboboxItem,
|
||||
ComboboxList,
|
||||
ComboboxValue,
|
||||
} from "@/components/ui/combobox"
|
||||
|
||||
const frameworks = ["Next.js", "SvelteKit", "Nuxt.js", "Remix", "Astro"]
|
||||
|
||||
export function ExampleComboboxMultiple() {
|
||||
const [value, setValue] = React.useState<string[]>([])
|
||||
|
||||
return (
|
||||
<Combobox
|
||||
items={frameworks}
|
||||
multiple
|
||||
value={value}
|
||||
onValueChange={setValue}
|
||||
>
|
||||
<ComboboxChips>
|
||||
<ComboboxValue>
|
||||
{value.map((item) => (
|
||||
<ComboboxChip key={item}>{item}</ComboboxChip>
|
||||
))}
|
||||
</ComboboxValue>
|
||||
<ComboboxChipsInput placeholder="Add framework" />
|
||||
</ComboboxChips>
|
||||
<ComboboxContent>
|
||||
<ComboboxEmpty>No items found.</ComboboxEmpty>
|
||||
<ComboboxList>
|
||||
{(item) => (
|
||||
<ComboboxItem key={item} value={item}>
|
||||
{item}
|
||||
</ComboboxItem>
|
||||
)}
|
||||
</ComboboxList>
|
||||
</ComboboxContent>
|
||||
</Combobox>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Basic
|
||||
|
||||
A simple combobox with a list of frameworks.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="combobox-basic" />
|
||||
|
||||
### Multiple
|
||||
|
||||
A combobox with multiple selection using `multiple` and `ComboboxChips`.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="combobox-multiple" />
|
||||
|
||||
### Clear Button
|
||||
|
||||
Use the `showClear` prop to show a clear button.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="combobox-clear" />
|
||||
|
||||
### Groups
|
||||
|
||||
Use `ComboboxGroup` and `ComboboxSeparator` to group items.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="combobox-groups" />
|
||||
|
||||
### Custom Items
|
||||
|
||||
You can render custom component inside `ComboboxItem`.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="combobox-custom" />
|
||||
|
||||
### Invalid
|
||||
|
||||
Use the `aria-invalid` prop to make the combobox invalid.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="combobox-invalid" />
|
||||
|
||||
### Disabled
|
||||
|
||||
Use the `disabled` prop to disable the combobox.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="combobox-disabled" />
|
||||
|
||||
### Auto Highlight
|
||||
|
||||
Use the `autoHighlight` prop automatically highlight the first item on filter.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="combobox-auto-highlight" />
|
||||
|
||||
### Popup
|
||||
|
||||
You can trigger the combobox from a button or any other component by using the `render` prop. Move the `ComboboxInput` inside the `ComboboxContent`.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="combobox-popup" />
|
||||
|
||||
### Input Group
|
||||
|
||||
You can add an addon to the combobox by using the `InputGroupAddon` component inside the `ComboboxInput`.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="combobox-input-group" />
|
||||
|
||||
## API Reference
|
||||
|
||||
See the [Base UI](https://base-ui.com/react/components/combobox#api-reference) documentation for more information.
|
||||
125
apps/v4/content/docs/components/base/command.mdx
Normal file
125
apps/v4/content/docs/components/base/command.mdx
Normal file
@@ -0,0 +1,125 @@
|
||||
---
|
||||
title: Command
|
||||
description: Command menu for search and quick actions.
|
||||
base: base
|
||||
component: true
|
||||
links:
|
||||
doc: https://github.com/dip/cmdk
|
||||
---
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="command-demo"
|
||||
align="start"
|
||||
previewClassName="h-[24.5rem]"
|
||||
/>
|
||||
|
||||
## About
|
||||
|
||||
The `<Command />` component uses the [`cmdk`](https://github.com/dip/cmdk) component by [Dip](https://www.dip.org/).
|
||||
|
||||
## Installation
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">Command</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add command
|
||||
```
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install cmdk
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource
|
||||
name="command"
|
||||
title="components/ui/command.tsx"
|
||||
styleName="base-nova"
|
||||
/>
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
</CodeTabs>
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx showLineNumbers
|
||||
import {
|
||||
Command,
|
||||
CommandDialog,
|
||||
CommandEmpty,
|
||||
CommandGroup,
|
||||
CommandInput,
|
||||
CommandItem,
|
||||
CommandList,
|
||||
CommandSeparator,
|
||||
CommandShortcut,
|
||||
} from "@/components/ui/command"
|
||||
```
|
||||
|
||||
```tsx showLineNumbers
|
||||
<Command className="max-w-sm rounded-lg border">
|
||||
<CommandInput placeholder="Type a command or search..." />
|
||||
<CommandList>
|
||||
<CommandEmpty>No results found.</CommandEmpty>
|
||||
<CommandGroup heading="Suggestions">
|
||||
<CommandItem>Calendar</CommandItem>
|
||||
<CommandItem>Search Emoji</CommandItem>
|
||||
<CommandItem>Calculator</CommandItem>
|
||||
</CommandGroup>
|
||||
<CommandSeparator />
|
||||
<CommandGroup heading="Settings">
|
||||
<CommandItem>Profile</CommandItem>
|
||||
<CommandItem>Billing</CommandItem>
|
||||
<CommandItem>Settings</CommandItem>
|
||||
</CommandGroup>
|
||||
</CommandList>
|
||||
</Command>
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Basic
|
||||
|
||||
A simple command menu in a dialog.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="command-basic" />
|
||||
|
||||
### Shortcuts
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="command-shortcuts" />
|
||||
|
||||
### Groups
|
||||
|
||||
A command menu with groups, icons and separators.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="command-groups" />
|
||||
|
||||
### Scrollable
|
||||
|
||||
Scrollable command menu with multiple items.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="command-scrollable" />
|
||||
|
||||
## API Reference
|
||||
|
||||
See the [cmdk](https://github.com/dip/cmdk) documentation for more information.
|
||||
140
apps/v4/content/docs/components/base/context-menu.mdx
Normal file
140
apps/v4/content/docs/components/base/context-menu.mdx
Normal file
@@ -0,0 +1,140 @@
|
||||
---
|
||||
title: Context Menu
|
||||
description: Displays a menu of actions triggered by a right click.
|
||||
base: base
|
||||
component: true
|
||||
links:
|
||||
doc: https://base-ui.com/react/components/context-menu
|
||||
api: https://base-ui.com/react/components/context-menu#api-reference
|
||||
---
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="context-menu-demo"
|
||||
description="A context menu with sub menu items."
|
||||
/>
|
||||
|
||||
## Installation
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">Command</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add context-menu
|
||||
```
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @base-ui/react
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource
|
||||
name="context-menu"
|
||||
title="components/ui/context-menu.tsx"
|
||||
styleName="base-nova"
|
||||
/>
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
</CodeTabs>
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx showLineNumbers
|
||||
import {
|
||||
ContextMenu,
|
||||
ContextMenuContent,
|
||||
ContextMenuItem,
|
||||
ContextMenuTrigger,
|
||||
} from "@/components/ui/context-menu"
|
||||
```
|
||||
|
||||
```tsx showLineNumbers
|
||||
<ContextMenu>
|
||||
<ContextMenuTrigger>Right click here</ContextMenuTrigger>
|
||||
<ContextMenuContent>
|
||||
<ContextMenuItem>Profile</ContextMenuItem>
|
||||
<ContextMenuItem>Billing</ContextMenuItem>
|
||||
<ContextMenuItem>Team</ContextMenuItem>
|
||||
<ContextMenuItem>Subscription</ContextMenuItem>
|
||||
</ContextMenuContent>
|
||||
</ContextMenu>
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Basic
|
||||
|
||||
A simple context menu with a few actions.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="context-menu-basic" />
|
||||
|
||||
### Submenu
|
||||
|
||||
Use `ContextMenuSub` to nest secondary actions.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="context-menu-submenu" />
|
||||
|
||||
### Shortcuts
|
||||
|
||||
Add `ContextMenuShortcut` to show keyboard hints.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="context-menu-shortcuts" />
|
||||
|
||||
### Groups
|
||||
|
||||
Group related actions and separate them with dividers.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="context-menu-groups" />
|
||||
|
||||
### Icons
|
||||
|
||||
Combine icons with labels for quick scanning.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="context-menu-icons" />
|
||||
|
||||
### Checkboxes
|
||||
|
||||
Use `ContextMenuCheckboxItem` for toggles.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="context-menu-checkboxes" />
|
||||
|
||||
### Radio
|
||||
|
||||
Use `ContextMenuRadioItem` for exclusive choices.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="context-menu-radio" />
|
||||
|
||||
### Destructive
|
||||
|
||||
Use `variant="destructive"` to style the menu item as destructive.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="context-menu-destructive" />
|
||||
|
||||
### Sides
|
||||
|
||||
Control submenu placement with side and align props.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="context-menu-sides" />
|
||||
|
||||
## API Reference
|
||||
|
||||
See the [Base UI](https://base-ui.com/react/components/context-menu#api-reference) documentation for more information.
|
||||
@@ -1,12 +1,18 @@
|
||||
---
|
||||
title: Data Table
|
||||
description: Powerful table and datagrids built using TanStack Table.
|
||||
base: base
|
||||
component: true
|
||||
links:
|
||||
doc: https://tanstack.com/table/v8/docs/introduction
|
||||
---
|
||||
|
||||
<ComponentPreview name="data-table-demo" className="[&_.preview]:items-start" />
|
||||
<ComponentPreview
|
||||
styleName="radix-nova"
|
||||
name="data-table-demo"
|
||||
align="start"
|
||||
previewClassName="items-start h-[28rem] px-4 md:px-8"
|
||||
/>
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -102,7 +108,7 @@ I'm using a Next.js example here but this works for any other React framework.
|
||||
|
||||
Let's start by building a basic table.
|
||||
|
||||
<Steps>
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
### Column Definitions
|
||||
|
||||
@@ -279,7 +285,7 @@ export default async function DemoPage() {
|
||||
|
||||
Let's format the amount cell to display the dollar amount. We'll also align the cell to the right.
|
||||
|
||||
<Steps>
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
### Update columns definition
|
||||
|
||||
@@ -311,7 +317,7 @@ You can use the same approach to format other cells and headers.
|
||||
|
||||
Let's add row actions to our table. We'll use a `<Dropdown />` component for this.
|
||||
|
||||
<Steps>
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
### Update columns definition
|
||||
|
||||
@@ -375,7 +381,7 @@ You can access the row data using `row.original` in the `cell` function. Use thi
|
||||
|
||||
Next, we'll add pagination to our table.
|
||||
|
||||
<Steps>
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
### Update `<DataTable>`
|
||||
|
||||
@@ -461,7 +467,7 @@ See [Reusable Components](#reusable-components) section for a more advanced pagi
|
||||
|
||||
Let's make the email column sortable.
|
||||
|
||||
<Steps>
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
### Update `<DataTable>`
|
||||
|
||||
@@ -543,7 +549,7 @@ This will automatically sort the table (asc and desc) when the user toggles on t
|
||||
|
||||
Let's add a search input to filter emails in our table.
|
||||
|
||||
<Steps>
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
### Update `<DataTable>`
|
||||
|
||||
@@ -618,7 +624,7 @@ Filtering is now enabled for the `email` column. You can add filters to other co
|
||||
|
||||
Adding column visibility is fairly simple using `@tanstack/react-table` visibility API.
|
||||
|
||||
<Steps>
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
### Update `<DataTable>`
|
||||
|
||||
@@ -731,7 +737,7 @@ This adds a dropdown menu that you can use to toggle column visibility.
|
||||
|
||||
Next, we're going to add row selection to our table.
|
||||
|
||||
<Steps>
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
### Update column definitions
|
||||
|
||||
@@ -856,7 +862,10 @@ export const columns = [
|
||||
|
||||
Add pagination controls to your table including page size and selection count.
|
||||
|
||||
<ComponentSource src="/app/(app)/examples/tasks/components/data-table-pagination.tsx" />
|
||||
<ComponentSource
|
||||
src="/app/(app)/examples/tasks/components/data-table-pagination.tsx"
|
||||
styleName="radix-nova"
|
||||
/>
|
||||
|
||||
```tsx
|
||||
<DataTablePagination table={table} />
|
||||
@@ -866,7 +875,10 @@ Add pagination controls to your table including page size and selection count.
|
||||
|
||||
A component to toggle column visibility.
|
||||
|
||||
<ComponentSource src="/app/(app)/examples/tasks/components/data-table-view-options.tsx" />
|
||||
<ComponentSource
|
||||
src="/app/(app)/examples/tasks/components/data-table-view-options.tsx"
|
||||
styleName="radix-nova"
|
||||
/>
|
||||
|
||||
```tsx
|
||||
<DataTableViewOptions table={table} />
|
||||
97
apps/v4/content/docs/components/base/date-picker.mdx
Normal file
97
apps/v4/content/docs/components/base/date-picker.mdx
Normal file
@@ -0,0 +1,97 @@
|
||||
---
|
||||
title: Date Picker
|
||||
description: A date picker component with range and presets.
|
||||
base: base
|
||||
component: true
|
||||
---
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="date-picker-demo" />
|
||||
|
||||
## Installation
|
||||
|
||||
The Date Picker is built using a composition of the `<Popover />` and the `<Calendar />` components.
|
||||
|
||||
See installation instructions for the [Popover](/docs/components/base/popover#installation) and the [Calendar](/docs/components/base/calendar#installation) components.
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx showLineNumbers title="components/example-date-picker.tsx"
|
||||
"use client"
|
||||
|
||||
import * as React from "react"
|
||||
import { format } from "date-fns"
|
||||
import { Calendar as CalendarIcon } from "lucide-react"
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { Calendar } from "@/components/ui/calendar"
|
||||
import {
|
||||
Popover,
|
||||
PopoverContent,
|
||||
PopoverTrigger,
|
||||
} from "@/components/ui/popover"
|
||||
|
||||
export function DatePickerDemo() {
|
||||
const [date, setDate] = React.useState<Date>()
|
||||
|
||||
return (
|
||||
<Popover>
|
||||
<PopoverTrigger
|
||||
render={
|
||||
<Button
|
||||
variant="outline"
|
||||
data-empty={!date}
|
||||
className="data-[empty=true]:text-muted-foreground justify-start text-left font-normal"
|
||||
/>
|
||||
}
|
||||
>
|
||||
<CalendarIcon />
|
||||
{date ? format(date, "PPP") : <span>Pick a date</span>}
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-auto p-0">
|
||||
<Calendar mode="single" selected={date} onSelect={setDate} />
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
See the [React DayPicker](https://react-day-picker.js.org) documentation for more information.
|
||||
|
||||
## Examples
|
||||
|
||||
### Basic
|
||||
|
||||
A basic date picker component.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="date-picker-basic" />
|
||||
|
||||
### Range Picker
|
||||
|
||||
A date picker component for selecting a range of dates.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="date-picker-range" />
|
||||
|
||||
### Date of Birth
|
||||
|
||||
A date picker component for selecting a date of birth. This component includes a dropdown caption layout for date and month selection.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="date-picker-dob" />
|
||||
|
||||
### Input
|
||||
|
||||
A date picker component with an input field for selecting a date.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="date-picker-input" />
|
||||
|
||||
### Time Picker
|
||||
|
||||
A date picker component with a time input field for selecting a time.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="date-picker-time" />
|
||||
|
||||
### Natural Language Picker
|
||||
|
||||
This component uses the `chrono-node` library to parse natural language dates.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="date-picker-natural-language" />
|
||||
116
apps/v4/content/docs/components/base/dialog.mdx
Normal file
116
apps/v4/content/docs/components/base/dialog.mdx
Normal file
@@ -0,0 +1,116 @@
|
||||
---
|
||||
title: Dialog
|
||||
description: A window overlaid on either the primary window or another dialog window, rendering the content underneath inert.
|
||||
featured: true
|
||||
base: base
|
||||
component: true
|
||||
links:
|
||||
doc: https://base-ui.com/react/components/dialog
|
||||
api: https://base-ui.com/react/components/dialog#api-reference
|
||||
---
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="dialog-demo"
|
||||
description="A dialog for editing profile details."
|
||||
/>
|
||||
|
||||
## Installation
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">Command</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add dialog
|
||||
```
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @base-ui/react
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource
|
||||
name="dialog"
|
||||
title="components/ui/dialog.tsx"
|
||||
styleName="base-nova"
|
||||
/>
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
</CodeTabs>
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx showLineNumbers
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
DialogTrigger,
|
||||
} from "@/components/ui/dialog"
|
||||
```
|
||||
|
||||
```tsx showLineNumbers
|
||||
<Dialog>
|
||||
<DialogTrigger>Open</DialogTrigger>
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
<DialogTitle>Are you absolutely sure?</DialogTitle>
|
||||
<DialogDescription>
|
||||
This action cannot be undone. This will permanently delete your account
|
||||
and remove your data from our servers.
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Custom Close Button
|
||||
|
||||
Replace the default close control with your own button.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="dialog-close-button" />
|
||||
|
||||
### No Close Button
|
||||
|
||||
Use `showCloseButton={false}` to hide the close button.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="dialog-no-close-button" />
|
||||
|
||||
### Sticky Footer
|
||||
|
||||
Keep actions visible while the content scrolls.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="dialog-sticky-footer" />
|
||||
|
||||
### Scrollable Content
|
||||
|
||||
Long content can scroll while the header stays in view.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="dialog-scrollable-content" />
|
||||
|
||||
## API Reference
|
||||
|
||||
See the [Base UI](https://base-ui.com/react/components/dialog#api-reference) documentation for more information.
|
||||
@@ -1,12 +1,13 @@
|
||||
---
|
||||
title: Drawer
|
||||
description: A drawer component for React.
|
||||
base: base
|
||||
component: true
|
||||
links:
|
||||
doc: https://vaul.emilkowal.ski/getting-started
|
||||
---
|
||||
|
||||
<ComponentPreview name="drawer-demo" description="A drawer component." />
|
||||
<ComponentPreview styleName="base-nova" name="drawer-demo" />
|
||||
|
||||
## About
|
||||
|
||||
@@ -17,7 +18,7 @@ Drawer is built on top of [Vaul](https://github.com/emilkowalski/vaul) by [emilk
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">CLI</TabsTrigger>
|
||||
<TabsTrigger value="cli">Command</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
@@ -30,7 +31,7 @@ npx shadcn@latest add drawer
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps>
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
@@ -40,7 +41,11 @@ npm install vaul
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource name="drawer" title="components/ui/drawer.tsx" />
|
||||
<ComponentSource
|
||||
name="drawer"
|
||||
title="components/ui/drawer.tsx"
|
||||
styleName="base-nova"
|
||||
/>
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
@@ -85,8 +90,24 @@ import {
|
||||
|
||||
## Examples
|
||||
|
||||
### Scrollable Content
|
||||
|
||||
Keep actions visible while the content scrolls.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="drawer-scrollable-content" />
|
||||
|
||||
### Sides
|
||||
|
||||
Use the `direction` prop to set the side of the drawer. Available options are `top`, `right`, `bottom`, and `left`.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="drawer-sides" />
|
||||
|
||||
### Responsive Dialog
|
||||
|
||||
You can combine the `Dialog` and `Drawer` components to create a responsive dialog. This renders a `Dialog` component on desktop and a `Drawer` on mobile.
|
||||
|
||||
<ComponentPreview name="drawer-dialog" />
|
||||
<ComponentPreview styleName="base-nova" name="drawer-dialog" />
|
||||
|
||||
## API Reference
|
||||
|
||||
See the [Vaul documentation](https://vaul.emilkowal.ski/components/drawer) for the full API reference.
|
||||
165
apps/v4/content/docs/components/base/dropdown-menu.mdx
Normal file
165
apps/v4/content/docs/components/base/dropdown-menu.mdx
Normal file
@@ -0,0 +1,165 @@
|
||||
---
|
||||
title: Dropdown Menu
|
||||
description: Displays a menu to the user — such as a set of actions or functions — triggered by a button.
|
||||
featured: true
|
||||
base: base
|
||||
component: true
|
||||
links:
|
||||
doc: https://base-ui.com/react/components/dropdown-menu
|
||||
api: https://base-ui.com/react/components/dropdown-menu#api-reference
|
||||
---
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="dropdown-menu-demo"
|
||||
description="A dropdown menu with icons, shortcuts and sub menu items."
|
||||
/>
|
||||
|
||||
## Installation
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">Command</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add dropdown-menu
|
||||
```
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @base-ui/react
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource
|
||||
name="dropdown-menu"
|
||||
title="components/ui/dropdown-menu.tsx"
|
||||
styleName="base-nova"
|
||||
/>
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
</CodeTabs>
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx showLineNumbers
|
||||
import { Button } from "@/components/ui/button"
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuGroup,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuLabel,
|
||||
DropdownMenuSeparator,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/components/ui/dropdown-menu"
|
||||
```
|
||||
|
||||
```tsx showLineNumbers
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger render={<Button variant="outline" />}>
|
||||
Open
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent>
|
||||
<DropdownMenuGroup>
|
||||
<DropdownMenuLabel>My Account</DropdownMenuLabel>
|
||||
<DropdownMenuItem>Profile</DropdownMenuItem>
|
||||
<DropdownMenuItem>Billing</DropdownMenuItem>
|
||||
<DropdownMenuSeparator />
|
||||
</DropdownMenuGroup>
|
||||
<DropdownMenuGroup>
|
||||
<DropdownMenuItem>Team</DropdownMenuItem>
|
||||
<DropdownMenuItem>Subscription</DropdownMenuItem>
|
||||
</DropdownMenuGroup>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Basic
|
||||
|
||||
A basic dropdown menu with labels and separators.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="dropdown-menu-basic" />
|
||||
|
||||
### Submenu
|
||||
|
||||
Use `DropdownMenuSub` to nest secondary actions.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="dropdown-menu-submenu" />
|
||||
|
||||
### Shortcuts
|
||||
|
||||
Add `DropdownMenuShortcut` to show keyboard hints.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="dropdown-menu-shortcuts" />
|
||||
|
||||
### Icons
|
||||
|
||||
Combine icons with labels for quick scanning.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="dropdown-menu-icons" />
|
||||
|
||||
### Checkboxes
|
||||
|
||||
Use `DropdownMenuCheckboxItem` for toggles.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="dropdown-menu-checkboxes" />
|
||||
|
||||
### Checkboxes Icons
|
||||
|
||||
Add icons to checkbox items.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="dropdown-menu-checkboxes-icons" />
|
||||
|
||||
### Radio Group
|
||||
|
||||
Use `DropdownMenuRadioGroup` for exclusive choices.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="dropdown-menu-radio-group" />
|
||||
|
||||
### Radio Icons
|
||||
|
||||
Show radio options with icons.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="dropdown-menu-radio-icons" />
|
||||
|
||||
### Destructive
|
||||
|
||||
Use `variant="destructive"` for irreversible actions.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="dropdown-menu-destructive" />
|
||||
|
||||
### Avatar
|
||||
|
||||
An account switcher dropdown triggered by an avatar.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="dropdown-menu-avatar" />
|
||||
|
||||
### Complex
|
||||
|
||||
A richer example combining groups, icons, and submenus.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="dropdown-menu-complex" />
|
||||
|
||||
## API Reference
|
||||
|
||||
See the [Base UI documentation](https://base-ui.com/react/components/dropdown-menu) for the full API reference.
|
||||
@@ -1,17 +1,22 @@
|
||||
---
|
||||
title: Empty
|
||||
description: Use the Empty component to display an empty state.
|
||||
base: base
|
||||
component: true
|
||||
---
|
||||
|
||||
<ComponentPreview name="empty-demo" className="[&_.preview]:p-0" />
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="empty-demo"
|
||||
previewClassName="h-96 p-0"
|
||||
/>
|
||||
|
||||
## Installation
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">CLI</TabsTrigger>
|
||||
<TabsTrigger value="cli">Command</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
@@ -24,11 +29,15 @@ npx shadcn@latest add empty
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps>
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource name="empty" title="components/ui/empty.tsx" />
|
||||
<ComponentSource
|
||||
name="empty"
|
||||
title="components/ui/empty.tsx"
|
||||
styleName="base-nova"
|
||||
/>
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
@@ -73,33 +82,50 @@ import {
|
||||
Use the `border` utility class to create an outline empty state.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="empty-outline"
|
||||
className="[&_.preview]:p-6 md:[&_.preview]:p-10"
|
||||
previewClassName="h-96 p-6 md:p-10"
|
||||
/>
|
||||
|
||||
### Background
|
||||
|
||||
Use the `bg-*` and `bg-gradient-*` utilities to add a background to the empty state.
|
||||
|
||||
<ComponentPreview name="empty-background" className="[&_.preview]:p-0" />
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="empty-background"
|
||||
previewClassName="h-96 p-0"
|
||||
/>
|
||||
|
||||
### Avatar
|
||||
|
||||
Use the `EmptyMedia` component to display an avatar in the empty state.
|
||||
|
||||
<ComponentPreview name="empty-avatar" className="[&_.preview]:p-0" />
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="empty-avatar"
|
||||
previewClassName="h-96 p-0"
|
||||
/>
|
||||
|
||||
### Avatar Group
|
||||
|
||||
Use the `EmptyMedia` component to display an avatar group in the empty state.
|
||||
|
||||
<ComponentPreview name="empty-avatar-group" className="[&_.preview]:p-0" />
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="empty-avatar-group"
|
||||
previewClassName="h-96 p-0"
|
||||
/>
|
||||
|
||||
### InputGroup
|
||||
|
||||
You can add an `InputGroup` component to the `EmptyContent` component.
|
||||
|
||||
<ComponentPreview name="empty-input-group" className="[&_.preview]:p-0" />
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="empty-input-group"
|
||||
previewClassName="h-96 p-0"
|
||||
/>
|
||||
|
||||
## API Reference
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
---
|
||||
title: Field
|
||||
description: Combine labels, controls, and help text to compose accessible form fields and grouped inputs.
|
||||
base: base
|
||||
component: true
|
||||
---
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="field-demo"
|
||||
className="[&_.preview]:h-[800px] [&_.preview]:p-6 md:[&_.preview]:h-[850px]"
|
||||
previewClassName="h-[800px] p-6 md:h-[850px]"
|
||||
/>
|
||||
|
||||
## Installation
|
||||
@@ -14,7 +16,7 @@ component: true
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">CLI</TabsTrigger>
|
||||
<TabsTrigger value="cli">Command</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
@@ -27,11 +29,15 @@ npx shadcn@latest add field
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps>
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource name="field" title="components/ui/field.tsx" />
|
||||
<ComponentSource
|
||||
name="field"
|
||||
title="components/ui/field.tsx"
|
||||
styleName="base-nova"
|
||||
/>
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
@@ -106,47 +112,55 @@ See the [Form](/docs/forms) documentation for building forms with the `Field` co
|
||||
|
||||
### Input
|
||||
|
||||
<ComponentPreview name="field-input" className="!mb-4 [&_.preview]:p-6" />
|
||||
<ComponentPreview styleName="base-nova" name="field-input" />
|
||||
|
||||
### Textarea
|
||||
|
||||
<ComponentPreview name="field-textarea" className="!mb-4 [&_.preview]:p-6" />
|
||||
<ComponentPreview styleName="base-nova" name="field-textarea" />
|
||||
|
||||
### Select
|
||||
|
||||
<ComponentPreview name="field-select" className="!mb-4 [&_.preview]:p-6" />
|
||||
<ComponentPreview styleName="base-nova" name="field-select" />
|
||||
|
||||
### Slider
|
||||
|
||||
<ComponentPreview name="field-slider" className="!mb-4 [&_.preview]:p-6" />
|
||||
<ComponentPreview styleName="base-nova" name="field-slider" />
|
||||
|
||||
### Fieldset
|
||||
|
||||
<ComponentPreview name="field-fieldset" className="!mb-4 [&_.preview]:p-6" />
|
||||
<ComponentPreview styleName="base-nova" name="field-fieldset" />
|
||||
|
||||
### Checkbox
|
||||
|
||||
<ComponentPreview name="field-checkbox" className="!mb-4 [&_.preview]:p-6" />
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="field-checkbox"
|
||||
previewClassName="h-[32rem]"
|
||||
/>
|
||||
|
||||
### Radio
|
||||
|
||||
<ComponentPreview name="field-radio" className="!mb-4 [&_.preview]:p-6" />
|
||||
<ComponentPreview styleName="base-nova" name="field-radio" />
|
||||
|
||||
### Switch
|
||||
|
||||
<ComponentPreview name="field-switch" className="!mb-4 [&_.preview]:p-6" />
|
||||
<ComponentPreview styleName="base-nova" name="field-switch" />
|
||||
|
||||
### Choice Card
|
||||
|
||||
Wrap `Field` components inside `FieldLabel` to create selectable field groups. This works with `RadioItem`, `Checkbox` and `Switch` components.
|
||||
|
||||
<ComponentPreview name="field-choice-card" className="!mb-4 [&_.preview]:p-6" />
|
||||
<ComponentPreview styleName="base-nova" name="field-choice-card" />
|
||||
|
||||
### Field Group
|
||||
|
||||
Stack `Field` components with `FieldGroup`. Add `FieldSeparator` to divide them.
|
||||
|
||||
<ComponentPreview name="field-group" className="!mb-4 [&_.preview]:p-6" />
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="field-group"
|
||||
previewClassName="h-96"
|
||||
/>
|
||||
|
||||
## Responsive Layout
|
||||
|
||||
@@ -155,8 +169,9 @@ Stack `Field` components with `FieldGroup`. Add `FieldSeparator` to divide them.
|
||||
- **Responsive fields:** Set `orientation="responsive"` for automatic column layouts inside container-aware parents. Apply `@container/field-group` classes on `FieldGroup` to switch orientations at specific breakpoints.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="field-responsive"
|
||||
className="!mb-4 [&_.preview]:h-[650px] [&_.preview]:p-6 [&_.preview]:md:h-[500px] [&_.preview]:md:p-10"
|
||||
previewClassName="h-[650px] p-6 md:h-[500px] md:p-10"
|
||||
/>
|
||||
|
||||
## Validation and Errors
|
||||
125
apps/v4/content/docs/components/base/hover-card.mdx
Normal file
125
apps/v4/content/docs/components/base/hover-card.mdx
Normal file
@@ -0,0 +1,125 @@
|
||||
---
|
||||
title: Hover Card
|
||||
description: For sighted users to preview content available behind a link.
|
||||
base: base
|
||||
component: true
|
||||
links:
|
||||
doc: https://base-ui.com/react/components/hover-card
|
||||
api: https://base-ui.com/react/components/hover-card#api-reference
|
||||
---
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="hover-card-demo"
|
||||
previewClassName="h-80"
|
||||
/>
|
||||
|
||||
## Installation
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">Command</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add hover-card
|
||||
```
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @base-ui/react
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource
|
||||
name="hover-card"
|
||||
title="components/ui/hover-card.tsx"
|
||||
styleName="base-nova"
|
||||
/>
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
</CodeTabs>
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx showLineNumbers
|
||||
import {
|
||||
HoverCard,
|
||||
HoverCardContent,
|
||||
HoverCardTrigger,
|
||||
} from "@/components/ui/hover-card"
|
||||
```
|
||||
|
||||
```tsx showLineNumbers
|
||||
<HoverCard>
|
||||
<HoverCardTrigger>Hover</HoverCardTrigger>
|
||||
<HoverCardContent>
|
||||
The React Framework – created and maintained by @vercel.
|
||||
</HoverCardContent>
|
||||
</HoverCard>
|
||||
```
|
||||
|
||||
## Trigger Delays
|
||||
|
||||
Use `delay` and `closeDelay` on the trigger to control when the card opens and
|
||||
closes.
|
||||
|
||||
```tsx showLineNumbers
|
||||
<HoverCard>
|
||||
<HoverCardTrigger delay={100} closeDelay={200}>
|
||||
Hover
|
||||
</HoverCardTrigger>
|
||||
<HoverCardContent>Content</HoverCardContent>
|
||||
</HoverCard>
|
||||
```
|
||||
|
||||
## Positioning
|
||||
|
||||
Use the `side` and `align` props on `HoverCardContent` to control placement.
|
||||
|
||||
```tsx showLineNumbers
|
||||
<HoverCard>
|
||||
<HoverCardTrigger>Hover</HoverCardTrigger>
|
||||
<HoverCardContent side="top" align="start">
|
||||
Content
|
||||
</HoverCardContent>
|
||||
</HoverCard>
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Basic
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="hover-card-demo"
|
||||
previewClassName="h-80"
|
||||
/>
|
||||
|
||||
### Sides
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="hover-card-sides"
|
||||
previewClassName="h-[22rem]"
|
||||
/>
|
||||
|
||||
## API Reference
|
||||
|
||||
See the [Base UI](https://base-ui.com/react/components/hover-card#api-reference) documentation for more information.
|
||||
295
apps/v4/content/docs/components/base/input-group.mdx
Normal file
295
apps/v4/content/docs/components/base/input-group.mdx
Normal file
@@ -0,0 +1,295 @@
|
||||
---
|
||||
title: Input Group
|
||||
description: Add addons, buttons, and helper content to inputs.
|
||||
base: base
|
||||
component: true
|
||||
---
|
||||
|
||||
import { IconInfoCircle } from "@tabler/icons-react"
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="input-group-demo"
|
||||
previewClassName="h-[26rem]"
|
||||
/>
|
||||
|
||||
## Installation
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">Command</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add input-group
|
||||
```
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource
|
||||
name="input-group"
|
||||
title="components/ui/input-group.tsx"
|
||||
styleName="base-nova"
|
||||
/>
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
</CodeTabs>
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx showLineNumbers
|
||||
import {
|
||||
InputGroup,
|
||||
InputGroupAddon,
|
||||
InputGroupButton,
|
||||
InputGroupInput,
|
||||
InputGroupText,
|
||||
InputGroupTextarea,
|
||||
} from "@/components/ui/input-group"
|
||||
```
|
||||
|
||||
```tsx showLineNumbers
|
||||
<InputGroup>
|
||||
<InputGroupInput placeholder="Search..." />
|
||||
<InputGroupAddon>
|
||||
<SearchIcon />
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
```
|
||||
|
||||
## Align
|
||||
|
||||
Use the `align` prop on `InputGroupAddon` to position the addon relative to the input.
|
||||
|
||||
<Callout>
|
||||
For proper focus management, `InputGroupAddon` should always be placed after
|
||||
`InputGroupInput` or `InputGroupTextarea` in the DOM. Use the `align` prop to
|
||||
visually position the addon.
|
||||
</Callout>
|
||||
|
||||
### inline-start
|
||||
|
||||
Use `align="inline-start"` to position the addon at the start of the input. This is the default.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="input-group-inline-start"
|
||||
previewClassName="h-48"
|
||||
/>
|
||||
|
||||
### inline-end
|
||||
|
||||
Use `align="inline-end"` to position the addon at the end of the input.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="input-group-inline-end"
|
||||
previewClassName="h-48"
|
||||
/>
|
||||
|
||||
### block-start
|
||||
|
||||
Use `align="block-start"` to position the addon above the input.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="input-group-block-start"
|
||||
previewClassName="h-96"
|
||||
/>
|
||||
|
||||
### block-end
|
||||
|
||||
Use `align="block-end"` to position the addon below the input.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="input-group-block-end"
|
||||
previewClassName="h-[26rem]"
|
||||
/>
|
||||
|
||||
## Examples
|
||||
|
||||
### Icon
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="input-group-icon"
|
||||
previewClassName="h-80"
|
||||
/>
|
||||
|
||||
### Text
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="input-group-text"
|
||||
previewClassName="h-80"
|
||||
/>
|
||||
|
||||
### Button
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="input-group-button"
|
||||
previewClassName="h-72"
|
||||
/>
|
||||
|
||||
### Kbd
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="input-group-kbd"
|
||||
previewClassName="h-40"
|
||||
/>
|
||||
|
||||
### Dropdown
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="input-group-dropdown"
|
||||
previewClassName="h-56"
|
||||
/>
|
||||
|
||||
### Spinner
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="input-group-spinner"
|
||||
previewClassName="h-80"
|
||||
/>
|
||||
|
||||
### Textarea
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="input-group-textarea"
|
||||
previewClassName="h-96"
|
||||
/>
|
||||
|
||||
### Custom Input
|
||||
|
||||
Add the `data-slot="input-group-control"` attribute to your custom input for automatic focus state handling.
|
||||
|
||||
Here's an example of a custom resizable textarea from a third-party library.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="input-group-custom"
|
||||
previewClassName="h-56"
|
||||
/>
|
||||
|
||||
## API Reference
|
||||
|
||||
### InputGroup
|
||||
|
||||
The main component that wraps inputs and addons.
|
||||
|
||||
| Prop | Type | Default |
|
||||
| ----------- | -------- | ------- |
|
||||
| `className` | `string` | |
|
||||
|
||||
```tsx
|
||||
<InputGroup>
|
||||
<InputGroupInput />
|
||||
<InputGroupAddon />
|
||||
</InputGroup>
|
||||
```
|
||||
|
||||
### InputGroupAddon
|
||||
|
||||
Displays icons, text, buttons, or other content alongside inputs.
|
||||
|
||||
<Callout icon={<IconInfoCircle />} title="Focus Navigation">
|
||||
For proper focus navigation, the `InputGroupAddon` component should be placed
|
||||
after the input. Set the `align` prop to position the addon.
|
||||
</Callout>
|
||||
|
||||
| Prop | Type | Default |
|
||||
| ----------- | ---------------------------------------------------------------- | ---------------- |
|
||||
| `align` | `"inline-start" \| "inline-end" \| "block-start" \| "block-end"` | `"inline-start"` |
|
||||
| `className` | `string` | |
|
||||
|
||||
```tsx
|
||||
<InputGroupAddon align="inline-end">
|
||||
<SearchIcon />
|
||||
</InputGroupAddon>
|
||||
```
|
||||
|
||||
**For `<InputGroupInput />`, use the `inline-start` or `inline-end` alignment. For `<InputGroupTextarea />`, use the `block-start` or `block-end` alignment.**
|
||||
|
||||
The `InputGroupAddon` component can have multiple `InputGroupButton` components and icons.
|
||||
|
||||
```tsx
|
||||
<InputGroupAddon>
|
||||
<InputGroupButton>Button</InputGroupButton>
|
||||
<InputGroupButton>Button</InputGroupButton>
|
||||
</InputGroupAddon>
|
||||
```
|
||||
|
||||
### InputGroupButton
|
||||
|
||||
Displays buttons within input groups.
|
||||
|
||||
| Prop | Type | Default |
|
||||
| ----------- | ----------------------------------------------------------------------------- | --------- |
|
||||
| `size` | `"xs" \| "icon-xs" \| "sm" \| "icon-sm"` | `"xs"` |
|
||||
| `variant` | `"default" \| "destructive" \| "outline" \| "secondary" \| "ghost" \| "link"` | `"ghost"` |
|
||||
| `className` | `string` | |
|
||||
|
||||
```tsx
|
||||
<InputGroupButton>Button</InputGroupButton>
|
||||
<InputGroupButton size="icon-xs" aria-label="Copy">
|
||||
<CopyIcon />
|
||||
</InputGroupButton>
|
||||
```
|
||||
|
||||
### InputGroupInput
|
||||
|
||||
Replacement for `<Input />` when building input groups. This component has the input group styles pre-applied and uses the unified `data-slot="input-group-control"` for focus state handling.
|
||||
|
||||
| Prop | Type | Default |
|
||||
| ----------- | -------- | ------- |
|
||||
| `className` | `string` | |
|
||||
|
||||
All other props are passed through to the underlying `<Input />` component.
|
||||
|
||||
```tsx
|
||||
<InputGroup>
|
||||
<InputGroupInput placeholder="Enter text..." />
|
||||
<InputGroupAddon>
|
||||
<SearchIcon />
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
```
|
||||
|
||||
### InputGroupTextarea
|
||||
|
||||
Replacement for `<Textarea />` when building input groups. This component has the textarea group styles pre-applied and uses the unified `data-slot="input-group-control"` for focus state handling.
|
||||
|
||||
| Prop | Type | Default |
|
||||
| ----------- | -------- | ------- |
|
||||
| `className` | `string` | |
|
||||
|
||||
All other props are passed through to the underlying `<Textarea />` component.
|
||||
|
||||
```tsx
|
||||
<InputGroup>
|
||||
<InputGroupTextarea placeholder="Enter message..." />
|
||||
<InputGroupAddon align="block-end">
|
||||
<InputGroupButton>Send</InputGroupButton>
|
||||
</InputGroupAddon>
|
||||
</InputGroup>
|
||||
```
|
||||
147
apps/v4/content/docs/components/base/input-otp.mdx
Normal file
147
apps/v4/content/docs/components/base/input-otp.mdx
Normal file
@@ -0,0 +1,147 @@
|
||||
---
|
||||
title: Input OTP
|
||||
description: Accessible one-time password component with copy paste functionality.
|
||||
base: base
|
||||
component: true
|
||||
links:
|
||||
doc: https://input-otp.rodz.dev
|
||||
---
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="input-otp-demo" />
|
||||
|
||||
## About
|
||||
|
||||
Input OTP is built on top of [input-otp](https://github.com/guilhermerodz/input-otp) by [@guilherme_rodz](https://twitter.com/guilherme_rodz).
|
||||
|
||||
## Installation
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">Command</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add input-otp
|
||||
```
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install input-otp
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource
|
||||
name="input-otp"
|
||||
title="components/ui/input-otp.tsx"
|
||||
styleName="base-nova"
|
||||
/>
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
</CodeTabs>
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx showLineNumbers
|
||||
import {
|
||||
InputOTP,
|
||||
InputOTPGroup,
|
||||
InputOTPSeparator,
|
||||
InputOTPSlot,
|
||||
} from "@/components/ui/input-otp"
|
||||
```
|
||||
|
||||
```tsx showLineNumbers
|
||||
<InputOTP maxLength={6}>
|
||||
<InputOTPGroup>
|
||||
<InputOTPSlot index={0} />
|
||||
<InputOTPSlot index={1} />
|
||||
<InputOTPSlot index={2} />
|
||||
</InputOTPGroup>
|
||||
<InputOTPSeparator />
|
||||
<InputOTPGroup>
|
||||
<InputOTPSlot index={3} />
|
||||
<InputOTPSlot index={4} />
|
||||
<InputOTPSlot index={5} />
|
||||
</InputOTPGroup>
|
||||
</InputOTP>
|
||||
```
|
||||
|
||||
## Pattern
|
||||
|
||||
Use the `pattern` prop to define a custom pattern for the OTP input.
|
||||
|
||||
```tsx showLineNumbers {1,5}
|
||||
import { REGEXP_ONLY_DIGITS_AND_CHARS } from "input-otp"
|
||||
|
||||
;<InputOTP maxLength={6} pattern={REGEXP_ONLY_DIGITS_AND_CHARS}>
|
||||
...
|
||||
</InputOTP>
|
||||
```
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="input-otp-pattern" />
|
||||
|
||||
## Examples
|
||||
|
||||
### Separator
|
||||
|
||||
Use the `<InputOTPSeparator />` component to add a separator between input groups.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="input-otp-separator" />
|
||||
|
||||
### Disabled
|
||||
|
||||
Use the `disabled` prop to disable the input.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="input-otp-disabled" />
|
||||
|
||||
### Controlled
|
||||
|
||||
Use the `value` and `onChange` props to control the input value.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="input-otp-controlled" />
|
||||
|
||||
### Invalid
|
||||
|
||||
Use `aria-invalid` on the slots to show an error state.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="input-otp-invalid" />
|
||||
|
||||
### Four Digits
|
||||
|
||||
A common pattern for PIN codes. This uses the `pattern={REGEXP_ONLY_DIGITS}` prop.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="input-otp-four-digits" />
|
||||
|
||||
### Alphanumeric
|
||||
|
||||
Use `REGEXP_ONLY_DIGITS_AND_CHARS` to accept both letters and numbers.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="input-otp-alphanumeric" />
|
||||
|
||||
### Form
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="input-otp-form"
|
||||
previewClassName="h-[30rem]"
|
||||
/>
|
||||
|
||||
## API Reference
|
||||
|
||||
See the [input-otp](https://input-otp.rodz.dev) documentation for more information.
|
||||
190
apps/v4/content/docs/components/base/input.mdx
Normal file
190
apps/v4/content/docs/components/base/input.mdx
Normal file
@@ -0,0 +1,190 @@
|
||||
---
|
||||
title: Input
|
||||
description: A text input component for forms and user data entry with built-in styling and accessibility features.
|
||||
base: base
|
||||
component: true
|
||||
---
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="input-demo"
|
||||
previewClassName="*:max-w-xs"
|
||||
/>
|
||||
|
||||
## Installation
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">Command</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add input
|
||||
```
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource
|
||||
name="input"
|
||||
title="components/ui/input.tsx"
|
||||
styleName="base-nova"
|
||||
/>
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
</CodeTabs>
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx
|
||||
import { Input } from "@/components/ui/input"
|
||||
```
|
||||
|
||||
```tsx
|
||||
<Input />
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Basic
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="input-basic"
|
||||
previewClassName="*:max-w-xs"
|
||||
/>
|
||||
|
||||
### Field
|
||||
|
||||
Use `Field`, `FieldLabel`, and `FieldDescription` to create an input with a
|
||||
label and description.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="input-field"
|
||||
previewClassName="*:max-w-xs"
|
||||
/>
|
||||
|
||||
### Field Group
|
||||
|
||||
Use `FieldGroup` to show multiple `Field` blocks and to build forms.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="input-fieldgroup"
|
||||
previewClassName="*:max-w-xs"
|
||||
/>
|
||||
|
||||
### Disabled
|
||||
|
||||
Use the `disabled` prop to disable the input. To style the disabled state, add the `data-disabled` attribute to the `Field` component.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="input-disabled"
|
||||
previewClassName="*:max-w-xs"
|
||||
/>
|
||||
|
||||
### Invalid
|
||||
|
||||
Use the `aria-invalid` prop to mark the input as invalid. To style the invalid state, add the `data-invalid` attribute to the `Field` component.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="input-invalid"
|
||||
previewClassName="*:max-w-xs"
|
||||
/>
|
||||
|
||||
### File
|
||||
|
||||
Use the `type="file"` prop to create a file input.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="input-file"
|
||||
previewClassName="*:max-w-xs"
|
||||
/>
|
||||
|
||||
### Inline
|
||||
|
||||
Use `Field` with `orientation="horizontal"` to create an inline input.
|
||||
Pair with `Button` to create a search input with a button.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="input-inline"
|
||||
previewClassName="*:max-w-xs"
|
||||
/>
|
||||
|
||||
### Grid
|
||||
|
||||
Use a grid layout to place multiple inputs side by side.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="input-grid"
|
||||
previewClassName="p-6"
|
||||
/>
|
||||
|
||||
### Required
|
||||
|
||||
Use the `required` attribute to indicate required inputs.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="input-required"
|
||||
previewClassName="*:max-w-xs"
|
||||
/>
|
||||
|
||||
### Badge
|
||||
|
||||
Use `Badge` in the label to highlight a recommended field.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="input-badge"
|
||||
previewClassName="*:max-w-xs"
|
||||
/>
|
||||
|
||||
### Input Group
|
||||
|
||||
To add icons, text, or buttons inside an input, use the `InputGroup` component. See the [Input Group](/docs/components/input-group) component for more examples.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="input-input-group"
|
||||
previewClassName="*:max-w-xs"
|
||||
/>
|
||||
|
||||
### Button Group
|
||||
|
||||
To add buttons to an input, use the `ButtonGroup` component. See the [Button Group](/docs/components/button-group) component for more examples.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="input-button-group"
|
||||
previewClassName="*:max-w-xs"
|
||||
/>
|
||||
|
||||
### Form
|
||||
|
||||
A full form example with multiple inputs, a select, and a button.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="input-form"
|
||||
previewClassName="h-[32rem]"
|
||||
/>
|
||||
276
apps/v4/content/docs/components/base/item.mdx
Normal file
276
apps/v4/content/docs/components/base/item.mdx
Normal file
@@ -0,0 +1,276 @@
|
||||
---
|
||||
title: Item
|
||||
description: A versatile component for displaying content with media, title, description, and actions.
|
||||
base: base
|
||||
component: true
|
||||
---
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="item-demo" />
|
||||
|
||||
The `Item` component is a straightforward flex container that can house nearly any type of content. Use it to display a title, description, and actions. Group it with the `ItemGroup` component to create a list of items.
|
||||
|
||||
## Installation
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">Command</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add item
|
||||
```
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource
|
||||
name="item"
|
||||
title="components/ui/item.tsx"
|
||||
styleName="base-nova"
|
||||
/>
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
</CodeTabs>
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx showLineNumbers
|
||||
import {
|
||||
Item,
|
||||
ItemActions,
|
||||
ItemContent,
|
||||
ItemDescription,
|
||||
ItemMedia,
|
||||
ItemTitle,
|
||||
} from "@/components/ui/item"
|
||||
```
|
||||
|
||||
```tsx showLineNumbers
|
||||
<Item>
|
||||
<ItemMedia variant="icon">
|
||||
<Icon />
|
||||
</ItemMedia>
|
||||
<ItemContent>
|
||||
<ItemTitle>Title</ItemTitle>
|
||||
<ItemDescription>Description</ItemDescription>
|
||||
</ItemContent>
|
||||
<ItemActions>
|
||||
<Button>Action</Button>
|
||||
</ItemActions>
|
||||
</Item>
|
||||
```
|
||||
|
||||
## Item vs Field
|
||||
|
||||
Use `Field` if you need to display a form input such as a checkbox, input, radio, or select.
|
||||
|
||||
If you only need to display content such as a title, description, and actions, use `Item`.
|
||||
|
||||
## Variant
|
||||
|
||||
Use the `variant` prop to change the visual style of the item.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="item-variant"
|
||||
previewClassName="h-96"
|
||||
/>
|
||||
|
||||
## Size
|
||||
|
||||
Use the `size` prop to change the size of the item. Available sizes are `default`, `sm`, and `xs`.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="item-size"
|
||||
previewClassName="h-96"
|
||||
/>
|
||||
|
||||
## Examples
|
||||
|
||||
### Icon
|
||||
|
||||
Use `ItemMedia` with `variant="icon"` to display an icon.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="item-icon" />
|
||||
|
||||
### Avatar
|
||||
|
||||
You can use `ItemMedia` with `variant="avatar"` to display an avatar.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="item-avatar" />
|
||||
|
||||
### Image
|
||||
|
||||
Use `ItemMedia` with `variant="image"` to display an image.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="item-image" />
|
||||
|
||||
### Group
|
||||
|
||||
Use `ItemGroup` to group related items together.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="item-group"
|
||||
previewClassName="h-96"
|
||||
/>
|
||||
|
||||
### Header
|
||||
|
||||
Use `ItemHeader` to add a header above the item content.
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="item-header"
|
||||
previewClassName="h-96"
|
||||
/>
|
||||
|
||||
### Link
|
||||
|
||||
Use the `render` prop to render the item as a link. The hover and focus states will be applied to the anchor element.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="item-link" />
|
||||
|
||||
```tsx showLineNumbers
|
||||
<Item render={<a href="/dashboard" />}>
|
||||
<ItemMedia variant="icon">
|
||||
<HomeIcon />
|
||||
</ItemMedia>
|
||||
<ItemContent>
|
||||
<ItemTitle>Dashboard</ItemTitle>
|
||||
<ItemDescription>Overview of your account and activity.</ItemDescription>
|
||||
</ItemContent>
|
||||
</Item>
|
||||
```
|
||||
|
||||
### Dropdown
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="item-dropdown" />
|
||||
|
||||
## API Reference
|
||||
|
||||
### Item
|
||||
|
||||
The main component for displaying content with media, title, description, and actions.
|
||||
|
||||
| Prop | Type | Default |
|
||||
| --------- | ----------------------------------- | ----------- |
|
||||
| `variant` | `"default" \| "outline" \| "muted"` | `"default"` |
|
||||
| `size` | `"default" \| "sm" \| "xs"` | `"default"` |
|
||||
| `render` | `React.ReactElement` | |
|
||||
|
||||
### ItemGroup
|
||||
|
||||
A container that groups related items together with consistent styling.
|
||||
|
||||
```tsx
|
||||
<ItemGroup>
|
||||
<Item />
|
||||
<Item />
|
||||
</ItemGroup>
|
||||
```
|
||||
|
||||
### ItemSeparator
|
||||
|
||||
A separator between items in a group.
|
||||
|
||||
```tsx
|
||||
<ItemGroup>
|
||||
<Item />
|
||||
<ItemSeparator />
|
||||
<Item />
|
||||
</ItemGroup>
|
||||
```
|
||||
|
||||
### ItemMedia
|
||||
|
||||
Use `ItemMedia` to display media content such as icons, images, or avatars.
|
||||
|
||||
| Prop | Type | Default |
|
||||
| --------- | -------------------------------- | ----------- |
|
||||
| `variant` | `"default" \| "icon" \| "image"` | `"default"` |
|
||||
|
||||
```tsx
|
||||
<ItemMedia variant="icon">
|
||||
<Icon />
|
||||
</ItemMedia>
|
||||
```
|
||||
|
||||
```tsx
|
||||
<ItemMedia variant="image">
|
||||
<img src="..." alt="..." />
|
||||
</ItemMedia>
|
||||
```
|
||||
|
||||
### ItemContent
|
||||
|
||||
Wraps the title and description of the item.
|
||||
|
||||
```tsx
|
||||
<ItemContent>
|
||||
<ItemTitle>Title</ItemTitle>
|
||||
<ItemDescription>Description</ItemDescription>
|
||||
</ItemContent>
|
||||
```
|
||||
|
||||
### ItemTitle
|
||||
|
||||
Displays the title of the item.
|
||||
|
||||
```tsx
|
||||
<ItemTitle>Item Title</ItemTitle>
|
||||
```
|
||||
|
||||
### ItemDescription
|
||||
|
||||
Displays the description of the item.
|
||||
|
||||
```tsx
|
||||
<ItemDescription>Item description</ItemDescription>
|
||||
```
|
||||
|
||||
### ItemActions
|
||||
|
||||
Container for action buttons or other interactive elements.
|
||||
|
||||
```tsx
|
||||
<ItemActions>
|
||||
<Button>Action</Button>
|
||||
</ItemActions>
|
||||
```
|
||||
|
||||
### ItemHeader
|
||||
|
||||
Displays a header above the item content.
|
||||
|
||||
```tsx
|
||||
<Item>
|
||||
<ItemHeader>Header</ItemHeader>
|
||||
<ItemContent>...</ItemContent>
|
||||
</Item>
|
||||
```
|
||||
|
||||
### ItemFooter
|
||||
|
||||
Displays a footer below the item content.
|
||||
|
||||
```tsx
|
||||
<Item>
|
||||
<ItemContent>...</ItemContent>
|
||||
<ItemFooter>Footer</ItemFooter>
|
||||
</Item>
|
||||
```
|
||||
@@ -1,17 +1,18 @@
|
||||
---
|
||||
title: Kbd
|
||||
description: Used to display textual user input from keyboard.
|
||||
base: base
|
||||
component: true
|
||||
---
|
||||
|
||||
<ComponentPreview name="kbd-demo" />
|
||||
<ComponentPreview styleName="base-nova" name="kbd-demo" />
|
||||
|
||||
## Installation
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">CLI</TabsTrigger>
|
||||
<TabsTrigger value="cli">Command</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
@@ -24,11 +25,15 @@ npx shadcn@latest add kbd
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps>
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource name="kbd" title="components/ui/kbd.tsx" />
|
||||
<ComponentSource
|
||||
name="kbd"
|
||||
title="components/ui/kbd.tsx"
|
||||
styleName="base-nova"
|
||||
/>
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
@@ -54,25 +59,25 @@ import { Kbd } from "@/components/ui/kbd"
|
||||
|
||||
Use the `KbdGroup` component to group keyboard keys together.
|
||||
|
||||
<ComponentPreview name="kbd-group" />
|
||||
<ComponentPreview styleName="base-nova" name="kbd-group" />
|
||||
|
||||
### Button
|
||||
|
||||
Use the `Kbd` component inside a `Button` component to display a keyboard key inside a button.
|
||||
|
||||
<ComponentPreview name="kbd-button" />
|
||||
<ComponentPreview styleName="base-nova" name="kbd-button" />
|
||||
|
||||
### Tooltip
|
||||
|
||||
You can use the `Kbd` component inside a `Tooltip` component to display a tooltip with a keyboard key.
|
||||
|
||||
<ComponentPreview name="kbd-tooltip" />
|
||||
<ComponentPreview styleName="base-nova" name="kbd-tooltip" />
|
||||
|
||||
### Input Group
|
||||
|
||||
You can use the `Kbd` component inside a `InputGroupAddon` component to display a keyboard key inside an input group.
|
||||
|
||||
<ComponentPreview name="kbd-input-group" />
|
||||
<ComponentPreview styleName="base-nova" name="kbd-input-group" />
|
||||
|
||||
## API Reference
|
||||
|
||||
90
apps/v4/content/docs/components/base/label.mdx
Normal file
90
apps/v4/content/docs/components/base/label.mdx
Normal file
@@ -0,0 +1,90 @@
|
||||
---
|
||||
title: Label
|
||||
description: Renders an accessible label associated with controls.
|
||||
base: base
|
||||
component: true
|
||||
links:
|
||||
doc: https://base-ui.com/react/components/label
|
||||
api: https://base-ui.com/react/components/label#api-reference
|
||||
---
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="label-demo" />
|
||||
|
||||
<Callout>
|
||||
For form fields, use the [Field](/docs/components/base/field) component which
|
||||
includes built-in label, description, and error handling.
|
||||
</Callout>
|
||||
|
||||
## Installation
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">Command</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add label
|
||||
```
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @base-ui/react
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource
|
||||
name="label"
|
||||
title="components/ui/label.tsx"
|
||||
styleName="base-nova"
|
||||
/>
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
</CodeTabs>
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx
|
||||
import { Label } from "@/components/ui/label"
|
||||
```
|
||||
|
||||
```tsx
|
||||
<Label htmlFor="email">Your email address</Label>
|
||||
```
|
||||
|
||||
## Label in Field
|
||||
|
||||
For form fields, use the [Field](/docs/components/base/field) component which
|
||||
includes built-in `FieldLabel`, `FieldDescription`, and `FieldError` components.
|
||||
|
||||
```tsx
|
||||
<Field>
|
||||
<FieldLabel htmlFor="email">Your email address</FieldLabel>
|
||||
<Input id="email" />
|
||||
</Field>
|
||||
```
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="field-demo"
|
||||
previewClassName="h-[44rem]"
|
||||
/>
|
||||
|
||||
## API Reference
|
||||
|
||||
See the [Base UI Label](https://base-ui.com/react/components/label#api-reference) documentation for more information.
|
||||
117
apps/v4/content/docs/components/base/menubar.mdx
Normal file
117
apps/v4/content/docs/components/base/menubar.mdx
Normal file
@@ -0,0 +1,117 @@
|
||||
---
|
||||
title: Menubar
|
||||
description: A visually persistent menu common in desktop applications that provides quick access to a consistent set of commands.
|
||||
base: base
|
||||
component: true
|
||||
links:
|
||||
doc: https://base-ui.com/react/components/menubar
|
||||
api: https://base-ui.com/react/components/menubar#api-reference
|
||||
---
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="menubar-demo" />
|
||||
|
||||
## Installation
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">Command</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add menubar
|
||||
```
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @base-ui/react
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource
|
||||
name="menubar"
|
||||
title="components/ui/menubar.tsx"
|
||||
styleName="base-nova"
|
||||
/>
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
</CodeTabs>
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx showLineNumbers
|
||||
import {
|
||||
Menubar,
|
||||
MenubarContent,
|
||||
MenubarGroup,
|
||||
MenubarItem,
|
||||
MenubarMenu,
|
||||
MenubarSeparator,
|
||||
MenubarShortcut,
|
||||
MenubarTrigger,
|
||||
} from "@/components/ui/menubar"
|
||||
```
|
||||
|
||||
```tsx showLineNumbers
|
||||
<Menubar>
|
||||
<MenubarMenu>
|
||||
<MenubarTrigger>File</MenubarTrigger>
|
||||
<MenubarContent>
|
||||
<MenubarGroup>
|
||||
<MenubarItem>
|
||||
New Tab <MenubarShortcut>⌘T</MenubarShortcut>
|
||||
</MenubarItem>
|
||||
<MenubarItem>New Window</MenubarItem>
|
||||
</MenubarGroup>
|
||||
<MenubarSeparator />
|
||||
<MenubarGroup>
|
||||
<MenubarItem>Share</MenubarItem>
|
||||
<MenubarItem>Print</MenubarItem>
|
||||
</MenubarGroup>
|
||||
</MenubarContent>
|
||||
</MenubarMenu>
|
||||
</Menubar>
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Checkbox
|
||||
|
||||
Use `MenubarCheckboxItem` for toggleable options.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="menubar-checkbox" />
|
||||
|
||||
### Radio
|
||||
|
||||
Use `MenubarRadioGroup` and `MenubarRadioItem` for single-select options.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="menubar-radio" />
|
||||
|
||||
### Submenu
|
||||
|
||||
Use `MenubarSub`, `MenubarSubTrigger`, and `MenubarSubContent` for nested menus.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="menubar-submenu" />
|
||||
|
||||
### With Icons
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="menubar-icons" />
|
||||
|
||||
## API Reference
|
||||
|
||||
See the [Base UI Menubar](https://base-ui.com/react/components/menubar#api-reference) documentation.
|
||||
64
apps/v4/content/docs/components/base/meta.json
Normal file
64
apps/v4/content/docs/components/base/meta.json
Normal file
@@ -0,0 +1,64 @@
|
||||
{
|
||||
"title": "Base UI",
|
||||
"pages": [
|
||||
"accordion",
|
||||
"alert",
|
||||
"alert-dialog",
|
||||
"aspect-ratio",
|
||||
"avatar",
|
||||
"badge",
|
||||
"breadcrumb",
|
||||
"button",
|
||||
"button-group",
|
||||
"calendar",
|
||||
"card",
|
||||
"carousel",
|
||||
"chart",
|
||||
"checkbox",
|
||||
"collapsible",
|
||||
"combobox",
|
||||
"command",
|
||||
"context-menu",
|
||||
"data-table",
|
||||
"date-picker",
|
||||
"dialog",
|
||||
"drawer",
|
||||
"dropdown-menu",
|
||||
"empty",
|
||||
"field",
|
||||
"form",
|
||||
"hover-card",
|
||||
"input",
|
||||
"input-group",
|
||||
"input-otp",
|
||||
"item",
|
||||
"kbd",
|
||||
"label",
|
||||
"menubar",
|
||||
"native-select",
|
||||
"navigation-menu",
|
||||
"pagination",
|
||||
"popover",
|
||||
"progress",
|
||||
"radio-group",
|
||||
"resizable",
|
||||
"scroll-area",
|
||||
"select",
|
||||
"separator",
|
||||
"sheet",
|
||||
"sidebar",
|
||||
"skeleton",
|
||||
"slider",
|
||||
"sonner",
|
||||
"spinner",
|
||||
"switch",
|
||||
"table",
|
||||
"tabs",
|
||||
"textarea",
|
||||
"toast",
|
||||
"toggle",
|
||||
"toggle-group",
|
||||
"tooltip",
|
||||
"typography"
|
||||
]
|
||||
}
|
||||
134
apps/v4/content/docs/components/base/native-select.mdx
Normal file
134
apps/v4/content/docs/components/base/native-select.mdx
Normal file
@@ -0,0 +1,134 @@
|
||||
---
|
||||
title: Native Select
|
||||
description: A styled native HTML select element with consistent design system integration.
|
||||
base: base
|
||||
component: true
|
||||
---
|
||||
|
||||
import { InfoIcon } from "lucide-react"
|
||||
|
||||
<Callout variant="info" icon={<InfoIcon className="!translate-y-[3px]" />}>
|
||||
For a styled select component, see the [Select](/docs/components/select)
|
||||
component.
|
||||
</Callout>
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="native-select-demo" />
|
||||
|
||||
## Installation
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">Command</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add native-select
|
||||
```
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource
|
||||
name="native-select"
|
||||
title="components/ui/native-select.tsx"
|
||||
styleName="base-nova"
|
||||
/>
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
</CodeTabs>
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx showLineNumbers
|
||||
import {
|
||||
NativeSelect,
|
||||
NativeSelectOptGroup,
|
||||
NativeSelectOption,
|
||||
} from "@/components/ui/native-select"
|
||||
```
|
||||
|
||||
```tsx showLineNumbers
|
||||
<NativeSelect>
|
||||
<NativeSelectOption value="">Select a fruit</NativeSelectOption>
|
||||
<NativeSelectOption value="apple">Apple</NativeSelectOption>
|
||||
<NativeSelectOption value="banana">Banana</NativeSelectOption>
|
||||
<NativeSelectOption value="blueberry">Blueberry</NativeSelectOption>
|
||||
<NativeSelectOption value="pineapple">Pineapple</NativeSelectOption>
|
||||
</NativeSelect>
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Groups
|
||||
|
||||
Use `NativeSelectOptGroup` to organize options into categories.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="native-select-groups" />
|
||||
|
||||
### Disabled
|
||||
|
||||
Add the `disabled` prop to the `NativeSelect` component to disable the select.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="native-select-disabled" />
|
||||
|
||||
### Invalid
|
||||
|
||||
Use `aria-invalid` to show validation errors and the `data-invalid` attribute to the `Field` component for styling.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="native-select-invalid" />
|
||||
|
||||
## Native Select vs Select
|
||||
|
||||
- Use `NativeSelect` for native browser behavior, better performance, or mobile-optimized dropdowns.
|
||||
- Use `Select` for custom styling, animations, or complex interactions.
|
||||
|
||||
## API Reference
|
||||
|
||||
### NativeSelect
|
||||
|
||||
The main select component that wraps the native HTML select element.
|
||||
|
||||
```tsx
|
||||
<NativeSelect>
|
||||
<NativeSelectOption value="option1">Option 1</NativeSelectOption>
|
||||
<NativeSelectOption value="option2">Option 2</NativeSelectOption>
|
||||
</NativeSelect>
|
||||
```
|
||||
|
||||
### NativeSelectOption
|
||||
|
||||
Represents an individual option within the select.
|
||||
|
||||
| Prop | Type | Default |
|
||||
| ---------- | --------- | ------- |
|
||||
| `value` | `string` | |
|
||||
| `disabled` | `boolean` | `false` |
|
||||
|
||||
### NativeSelectOptGroup
|
||||
|
||||
Groups related options together for better organization.
|
||||
|
||||
| Prop | Type | Default |
|
||||
| ---------- | --------- | ------- |
|
||||
| `label` | `string` | |
|
||||
| `disabled` | `boolean` | `false` |
|
||||
|
||||
```tsx
|
||||
<NativeSelectOptGroup label="Fruits">
|
||||
<NativeSelectOption value="apple">Apple</NativeSelectOption>
|
||||
<NativeSelectOption value="banana">Banana</NativeSelectOption>
|
||||
</NativeSelectOptGroup>
|
||||
```
|
||||
113
apps/v4/content/docs/components/base/navigation-menu.mdx
Normal file
113
apps/v4/content/docs/components/base/navigation-menu.mdx
Normal file
@@ -0,0 +1,113 @@
|
||||
---
|
||||
title: Navigation Menu
|
||||
description: A collection of links for navigating websites.
|
||||
base: base
|
||||
component: true
|
||||
links:
|
||||
doc: https://base-ui.com/react/components/navigation-menu
|
||||
api: https://base-ui.com/react/components/navigation-menu#api-reference
|
||||
---
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="navigation-menu-demo"
|
||||
previewClassName="h-96"
|
||||
/>
|
||||
|
||||
## Installation
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">Command</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add navigation-menu
|
||||
```
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @base-ui-components/react
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource
|
||||
name="navigation-menu"
|
||||
title="components/ui/navigation-menu.tsx"
|
||||
/>
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
</CodeTabs>
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx showLineNumbers
|
||||
import {
|
||||
NavigationMenu,
|
||||
NavigationMenuContent,
|
||||
NavigationMenuItem,
|
||||
NavigationMenuLink,
|
||||
NavigationMenuList,
|
||||
NavigationMenuTrigger,
|
||||
} from "@/components/ui/navigation-menu"
|
||||
```
|
||||
|
||||
```tsx showLineNumbers
|
||||
<NavigationMenu>
|
||||
<NavigationMenuList>
|
||||
<NavigationMenuItem>
|
||||
<NavigationMenuTrigger>Item One</NavigationMenuTrigger>
|
||||
<NavigationMenuContent>
|
||||
<NavigationMenuLink>Link</NavigationMenuLink>
|
||||
</NavigationMenuContent>
|
||||
</NavigationMenuItem>
|
||||
</NavigationMenuList>
|
||||
</NavigationMenu>
|
||||
```
|
||||
|
||||
## Link Component
|
||||
|
||||
Use the `render` prop to compose a custom link component such as Next.js `Link`.
|
||||
|
||||
```tsx showLineNumbers
|
||||
import Link from "next/link"
|
||||
|
||||
import {
|
||||
NavigationMenuItem,
|
||||
NavigationMenuLink,
|
||||
navigationMenuTriggerStyle,
|
||||
} from "@/components/ui/navigation-menu"
|
||||
|
||||
export function NavigationMenuDemo() {
|
||||
return (
|
||||
<NavigationMenuItem>
|
||||
<NavigationMenuLink
|
||||
render={<Link href="/docs" />}
|
||||
className={navigationMenuTriggerStyle()}
|
||||
>
|
||||
Documentation
|
||||
</NavigationMenuLink>
|
||||
</NavigationMenuItem>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
See the [Base UI Navigation Menu](https://base-ui.com/react/components/navigation-menu#api-reference) documentation for more information.
|
||||
@@ -1,20 +1,18 @@
|
||||
---
|
||||
title: Pagination
|
||||
description: Pagination with page navigation, next and previous links.
|
||||
base: base
|
||||
component: true
|
||||
---
|
||||
|
||||
<ComponentPreview
|
||||
name="pagination-demo"
|
||||
description="A pagination with previous and next links."
|
||||
/>
|
||||
<ComponentPreview styleName="base-nova" name="pagination-demo" />
|
||||
|
||||
## Installation
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">CLI</TabsTrigger>
|
||||
<TabsTrigger value="cli">Command</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
@@ -27,11 +25,15 @@ npx shadcn@latest add pagination
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps>
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource name="pagination" title="components/ui/pagination.tsx" />
|
||||
<ComponentSource
|
||||
name="pagination"
|
||||
title="components/ui/pagination.tsx"
|
||||
styleName="base-nova"
|
||||
/>
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
@@ -64,6 +66,14 @@ import {
|
||||
<PaginationItem>
|
||||
<PaginationLink href="#">1</PaginationLink>
|
||||
</PaginationItem>
|
||||
<PaginationItem>
|
||||
<PaginationLink href="#" isActive>
|
||||
2
|
||||
</PaginationLink>
|
||||
</PaginationItem>
|
||||
<PaginationItem>
|
||||
<PaginationLink href="#">3</PaginationLink>
|
||||
</PaginationItem>
|
||||
<PaginationItem>
|
||||
<PaginationEllipsis />
|
||||
</PaginationItem>
|
||||
@@ -74,7 +84,21 @@ import {
|
||||
</Pagination>
|
||||
```
|
||||
|
||||
### Next.js
|
||||
## Examples
|
||||
|
||||
### Simple
|
||||
|
||||
A simple pagination with only page numbers.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="pagination-simple" />
|
||||
|
||||
### Icons Only
|
||||
|
||||
Use just the previous and next buttons without page numbers. This is useful for data tables with a rows per page selector.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="pagination-icons-only" />
|
||||
|
||||
## Next.js
|
||||
|
||||
By default the `<PaginationLink />` component will render an `<a />` tag.
|
||||
|
||||
104
apps/v4/content/docs/components/base/popover.mdx
Normal file
104
apps/v4/content/docs/components/base/popover.mdx
Normal file
@@ -0,0 +1,104 @@
|
||||
---
|
||||
title: Popover
|
||||
description: Displays rich content in a portal, triggered by a button.
|
||||
base: base
|
||||
component: true
|
||||
links:
|
||||
doc: https://base-ui.com/react/components/popover
|
||||
api: https://base-ui.com/react/components/popover#api-reference
|
||||
---
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="popover-demo" />
|
||||
|
||||
## Installation
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">Command</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add popover
|
||||
```
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @base-ui/react
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource
|
||||
name="popover"
|
||||
title="components/ui/popover.tsx"
|
||||
styleName="base-nova"
|
||||
/>
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
</CodeTabs>
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx showLineNumbers
|
||||
import {
|
||||
Popover,
|
||||
PopoverContent,
|
||||
PopoverDescription,
|
||||
PopoverHeader,
|
||||
PopoverTitle,
|
||||
PopoverTrigger,
|
||||
} from "@/components/ui/popover"
|
||||
```
|
||||
|
||||
```tsx showLineNumbers
|
||||
<Popover>
|
||||
<PopoverTrigger render={<Button variant="outline" />}>
|
||||
Open Popover
|
||||
</PopoverTrigger>
|
||||
<PopoverContent>
|
||||
<PopoverHeader>
|
||||
<PopoverTitle>Title</PopoverTitle>
|
||||
<PopoverDescription>Description text here.</PopoverDescription>
|
||||
</PopoverHeader>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Basic
|
||||
|
||||
A simple popover with a header, title, and description.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="popover-basic" />
|
||||
|
||||
### Align
|
||||
|
||||
Use the `align` prop on `PopoverContent` to control the horizontal alignment.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="popover-alignments" />
|
||||
|
||||
### With Form
|
||||
|
||||
A popover with form fields inside.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="popover-form" />
|
||||
|
||||
## API Reference
|
||||
|
||||
See the [Base UI Popover](https://base-ui.com/react/components/popover#api-reference) documentation.
|
||||
81
apps/v4/content/docs/components/base/progress.mdx
Normal file
81
apps/v4/content/docs/components/base/progress.mdx
Normal file
@@ -0,0 +1,81 @@
|
||||
---
|
||||
title: Progress
|
||||
description: Displays an indicator showing the completion progress of a task, typically displayed as a progress bar.
|
||||
base: base
|
||||
component: true
|
||||
links:
|
||||
doc: https://base-ui.com/react/components/progress
|
||||
api: https://base-ui.com/react/components/progress#api-reference
|
||||
---
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="progress-demo" />
|
||||
|
||||
## Installation
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">Command</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add progress
|
||||
```
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @base-ui/react
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource
|
||||
name="progress"
|
||||
title="components/ui/progress.tsx"
|
||||
styleName="base-nova"
|
||||
/>
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
</CodeTabs>
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx showLineNumbers
|
||||
import { Progress } from "@/components/ui/progress"
|
||||
```
|
||||
|
||||
```tsx showLineNumbers
|
||||
<Progress value={33} />
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Label
|
||||
|
||||
Use `ProgressLabel` and `ProgressValue` to add a label and value display.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="progress-label" />
|
||||
|
||||
### Controlled
|
||||
|
||||
A progress bar that can be controlled by a slider.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="progress-controlled" />
|
||||
|
||||
## API Reference
|
||||
|
||||
See the [Base UI Progress](https://base-ui.com/react/components/progress#api-reference) documentation.
|
||||
109
apps/v4/content/docs/components/base/radio-group.mdx
Normal file
109
apps/v4/content/docs/components/base/radio-group.mdx
Normal file
@@ -0,0 +1,109 @@
|
||||
---
|
||||
title: Radio Group
|
||||
description: A set of checkable buttons—known as radio buttons—where no more than one of the buttons can be checked at a time.
|
||||
base: base
|
||||
component: true
|
||||
links:
|
||||
doc: https://base-ui.com/react/components/radio-group
|
||||
api: https://base-ui.com/react/components/radio-group#api-reference
|
||||
---
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="radio-group-demo" />
|
||||
|
||||
## Installation
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">Command</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add radio-group
|
||||
```
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @base-ui/react
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource
|
||||
name="radio-group"
|
||||
title="components/ui/radio-group.tsx"
|
||||
styleName="base-nova"
|
||||
/>
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
</CodeTabs>
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx showLineNumbers
|
||||
import { Label } from "@/components/ui/label"
|
||||
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"
|
||||
```
|
||||
|
||||
```tsx showLineNumbers
|
||||
<RadioGroup defaultValue="option-one">
|
||||
<div className="flex items-center gap-3">
|
||||
<RadioGroupItem value="option-one" id="option-one" />
|
||||
<Label htmlFor="option-one">Option One</Label>
|
||||
</div>
|
||||
<div className="flex items-center gap-3">
|
||||
<RadioGroupItem value="option-two" id="option-two" />
|
||||
<Label htmlFor="option-two">Option Two</Label>
|
||||
</div>
|
||||
</RadioGroup>
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Description
|
||||
|
||||
Radio group items with a description using the `Field` component.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="radio-group-description" />
|
||||
|
||||
### Choice Card
|
||||
|
||||
Use `FieldLabel` to wrap the entire `Field` for a clickable card-style selection.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="radio-group-choice-card" />
|
||||
|
||||
### Fieldset
|
||||
|
||||
Use `FieldSet` and `FieldLegend` to group radio items with a label and description.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="radio-group-fieldset" />
|
||||
|
||||
### Disabled
|
||||
|
||||
Use the `disabled` prop on `RadioGroup` to disable all items.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="radio-group-disabled" />
|
||||
|
||||
### Invalid
|
||||
|
||||
Use `aria-invalid` on `RadioGroupItem` and `data-invalid` on `Field` to show validation errors.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="radio-group-invalid" />
|
||||
|
||||
## API Reference
|
||||
|
||||
See the [Base UI Radio Group](https://base-ui.com/react/components/radio-group#api-reference) documentation.
|
||||
@@ -1,6 +1,7 @@
|
||||
---
|
||||
title: Resizable
|
||||
description: Accessible resizable panel groups and layouts with keyboard support.
|
||||
base: base
|
||||
component: true
|
||||
links:
|
||||
doc: https://github.com/bvaughn/react-resizable-panels
|
||||
@@ -8,8 +9,9 @@ links:
|
||||
---
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="resizable-demo"
|
||||
description="A group of resizable horizontal and vertical panels."
|
||||
previewClassName="h-80"
|
||||
/>
|
||||
|
||||
## About
|
||||
@@ -21,7 +23,7 @@ The `Resizable` component is built on top of [react-resizable-panels](https://gi
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">CLI</TabsTrigger>
|
||||
<TabsTrigger value="cli">Command</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
@@ -34,7 +36,7 @@ npx shadcn@latest add resizable
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps>
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
@@ -44,7 +46,11 @@ npm install react-resizable-panels
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource name="resizable" title="components/ui/resizable.tsx" />
|
||||
<ComponentSource
|
||||
name="resizable"
|
||||
title="components/ui/resizable.tsx"
|
||||
styleName="base-nova"
|
||||
/>
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
@@ -76,54 +82,16 @@ import {
|
||||
|
||||
### Vertical
|
||||
|
||||
Use the `direction` prop to set the direction of the resizable panels.
|
||||
Use `direction="vertical"` for vertical resizing.
|
||||
|
||||
<ComponentPreview
|
||||
name="resizable-vertical"
|
||||
description="A group of resizable vertical panels."
|
||||
/>
|
||||
|
||||
```tsx showLineNumbers {9}
|
||||
import {
|
||||
ResizableHandle,
|
||||
ResizablePanel,
|
||||
ResizablePanelGroup,
|
||||
} from "@/components/ui/resizable"
|
||||
|
||||
export default function Example() {
|
||||
return (
|
||||
<ResizablePanelGroup direction="vertical">
|
||||
<ResizablePanel>One</ResizablePanel>
|
||||
<ResizableHandle />
|
||||
<ResizablePanel>Two</ResizablePanel>
|
||||
</ResizablePanelGroup>
|
||||
)
|
||||
}
|
||||
```
|
||||
<ComponentPreview styleName="base-nova" name="resizable-vertical" />
|
||||
|
||||
### Handle
|
||||
|
||||
You can set or hide the handle by using the `withHandle` prop on the `ResizableHandle` component.
|
||||
Use the `withHandle` prop on `ResizableHandle` to show a visible handle.
|
||||
|
||||
<ComponentPreview
|
||||
name="resizable-handle"
|
||||
description="A group of resizable panels with a handle."
|
||||
/>
|
||||
<ComponentPreview styleName="base-nova" name="resizable-handle" />
|
||||
|
||||
```tsx showLineNumbers {11}
|
||||
import {
|
||||
ResizableHandle,
|
||||
ResizablePanel,
|
||||
ResizablePanelGroup,
|
||||
} from "@/components/ui/resizable"
|
||||
## API Reference
|
||||
|
||||
export default function Example() {
|
||||
return (
|
||||
<ResizablePanelGroup direction="horizontal">
|
||||
<ResizablePanel>One</ResizablePanel>
|
||||
<ResizableHandle withHandle />
|
||||
<ResizablePanel>Two</ResizablePanel>
|
||||
</ResizablePanelGroup>
|
||||
)
|
||||
}
|
||||
```
|
||||
See the [react-resizable-panels](https://github.com/bvaughn/react-resizable-panels/tree/main/packages/react-resizable-panels) documentation.
|
||||
81
apps/v4/content/docs/components/base/scroll-area.mdx
Normal file
81
apps/v4/content/docs/components/base/scroll-area.mdx
Normal file
@@ -0,0 +1,81 @@
|
||||
---
|
||||
title: Scroll Area
|
||||
description: Augments native scroll functionality for custom, cross-browser styling.
|
||||
base: base
|
||||
component: true
|
||||
links:
|
||||
doc: https://base-ui.com/react/components/scroll-area
|
||||
api: https://base-ui.com/react/components/scroll-area#api-reference
|
||||
---
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="scroll-area-demo"
|
||||
previewClassName="h-96"
|
||||
/>
|
||||
|
||||
## Installation
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">Command</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add scroll-area
|
||||
```
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @base-ui/react
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource
|
||||
name="scroll-area"
|
||||
title="components/ui/scroll-area.tsx"
|
||||
styleName="base-nova"
|
||||
/>
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
</CodeTabs>
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx showLineNumbers
|
||||
import { ScrollArea } from "@/components/ui/scroll-area"
|
||||
```
|
||||
|
||||
```tsx showLineNumbers
|
||||
<ScrollArea className="h-[200px] w-[350px] rounded-md border p-4">
|
||||
Your scrollable content here.
|
||||
</ScrollArea>
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Horizontal
|
||||
|
||||
Use `ScrollBar` with `orientation="horizontal"` for horizontal scrolling.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="scroll-area-horizontal-demo" />
|
||||
|
||||
## API Reference
|
||||
|
||||
See the [Base UI Scroll Area](https://base-ui.com/react/components/scroll-area#api-reference) documentation.
|
||||
122
apps/v4/content/docs/components/base/select.mdx
Normal file
122
apps/v4/content/docs/components/base/select.mdx
Normal file
@@ -0,0 +1,122 @@
|
||||
---
|
||||
title: Select
|
||||
description: Displays a list of options for the user to pick from—triggered by a button.
|
||||
base: base
|
||||
component: true
|
||||
featured: true
|
||||
links:
|
||||
doc: https://base-ui.com/react/components/select
|
||||
api: https://base-ui.com/react/components/select#api-reference
|
||||
---
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="select-demo" />
|
||||
|
||||
## Installation
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">Command</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add select
|
||||
```
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @base-ui/react
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource
|
||||
name="select"
|
||||
title="components/ui/select.tsx"
|
||||
styleName="base-nova"
|
||||
/>
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
</CodeTabs>
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx showLineNumbers
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/components/ui/select"
|
||||
```
|
||||
|
||||
```tsx showLineNumbers
|
||||
<Select>
|
||||
<SelectTrigger className="w-[180px]">
|
||||
<SelectValue placeholder="Theme" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="light">Light</SelectItem>
|
||||
<SelectItem value="dark">Dark</SelectItem>
|
||||
<SelectItem value="system">System</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Align Item With Trigger
|
||||
|
||||
Use `alignItemWithTrigger` on `SelectContent` to control whether the selected item aligns with the trigger. When `true` (default), the popup positions so the selected item appears over the trigger. When `false`, the popup aligns to the trigger edge.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="select-align-item" />
|
||||
|
||||
### Groups
|
||||
|
||||
Use `SelectGroup`, `SelectLabel`, and `SelectSeparator` to organize items.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="select-groups" />
|
||||
|
||||
### Scrollable
|
||||
|
||||
A select with many items that scrolls.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="select-scrollable" />
|
||||
|
||||
### Disabled
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="select-disabled" />
|
||||
|
||||
### Invalid
|
||||
|
||||
Add the `data-invalid` attribute to the `Field` component and the `aria-invalid` attribute to the `SelectTrigger` component to show an error state.
|
||||
|
||||
```tsx showLineNumbers /data-invalid/ /aria-invalid/
|
||||
<Field data-invalid>
|
||||
<FieldLabel>Fruit</FieldLabel>
|
||||
<SelectTrigger aria-invalid>
|
||||
<SelectValue />
|
||||
</SelectTrigger>
|
||||
</Field>
|
||||
```
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="select-invalid" />
|
||||
|
||||
## API Reference
|
||||
|
||||
See the [Base UI Select](https://base-ui.com/react/components/select#api-reference) documentation.
|
||||
87
apps/v4/content/docs/components/base/separator.mdx
Normal file
87
apps/v4/content/docs/components/base/separator.mdx
Normal file
@@ -0,0 +1,87 @@
|
||||
---
|
||||
title: Separator
|
||||
description: Visually or semantically separates content.
|
||||
base: base
|
||||
component: true
|
||||
links:
|
||||
doc: https://base-ui.com/react/components/separator
|
||||
api: https://base-ui.com/react/components/separator#api-reference
|
||||
---
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="separator-demo" />
|
||||
|
||||
## Installation
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">Command</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add separator
|
||||
```
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @base-ui/react
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource
|
||||
name="separator"
|
||||
title="components/ui/separator.tsx"
|
||||
styleName="base-nova"
|
||||
/>
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
</CodeTabs>
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx showLineNumbers
|
||||
import { Separator } from "@/components/ui/separator"
|
||||
```
|
||||
|
||||
```tsx showLineNumbers
|
||||
<Separator />
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Vertical
|
||||
|
||||
Use `orientation="vertical"` for a vertical separator.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="separator-vertical" />
|
||||
|
||||
### Menu
|
||||
|
||||
Vertical separators between menu items with descriptions.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="separator-menu" />
|
||||
|
||||
### List
|
||||
|
||||
Horizontal separators between list items.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="separator-list" />
|
||||
|
||||
## API Reference
|
||||
|
||||
See the [Base UI Separator](https://base-ui.com/react/components/separator#api-reference) documentation.
|
||||
98
apps/v4/content/docs/components/base/sheet.mdx
Normal file
98
apps/v4/content/docs/components/base/sheet.mdx
Normal file
@@ -0,0 +1,98 @@
|
||||
---
|
||||
title: Sheet
|
||||
description: Extends the Dialog component to display content that complements the main content of the screen.
|
||||
base: base
|
||||
component: true
|
||||
links:
|
||||
doc: https://base-ui.com/react/components/dialog
|
||||
api: https://base-ui.com/react/components/dialog#api-reference
|
||||
---
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="sheet-demo" />
|
||||
|
||||
## Installation
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">Command</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add sheet
|
||||
```
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @base-ui/react
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource
|
||||
name="sheet"
|
||||
title="components/ui/sheet.tsx"
|
||||
styleName="base-nova"
|
||||
/>
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
</CodeTabs>
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx showLineNumbers
|
||||
import {
|
||||
Sheet,
|
||||
SheetClose,
|
||||
SheetContent,
|
||||
SheetDescription,
|
||||
SheetFooter,
|
||||
SheetHeader,
|
||||
SheetTitle,
|
||||
SheetTrigger,
|
||||
} from "@/components/ui/sheet"
|
||||
```
|
||||
|
||||
```tsx showLineNumbers
|
||||
<Sheet>
|
||||
<SheetTrigger>Open</SheetTrigger>
|
||||
<SheetContent>
|
||||
<SheetHeader>
|
||||
<SheetTitle>Are you absolutely sure?</SheetTitle>
|
||||
<SheetDescription>This action cannot be undone.</SheetDescription>
|
||||
</SheetHeader>
|
||||
</SheetContent>
|
||||
</Sheet>
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Side
|
||||
|
||||
Use the `side` prop on `SheetContent` to set the edge of the screen where the sheet appears. Values are `top`, `right`, `bottom`, or `left`.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="sheet-side" />
|
||||
|
||||
### No Close Button
|
||||
|
||||
Use `showCloseButton={false}` on `SheetContent` to hide the close button.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="sheet-no-close-button" />
|
||||
|
||||
## API Reference
|
||||
|
||||
See the [Base UI Dialog](https://base-ui.com/react/components/dialog#api-reference) documentation.
|
||||
1325
apps/v4/content/docs/components/base/sidebar.mdx
Normal file
1325
apps/v4/content/docs/components/base/sidebar.mdx
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,17 +1,18 @@
|
||||
---
|
||||
title: Skeleton
|
||||
description: Use to show a placeholder while content is loading.
|
||||
base: base
|
||||
component: true
|
||||
---
|
||||
|
||||
<ComponentPreview name="skeleton-demo" description="A skeleton component." />
|
||||
<ComponentPreview styleName="base-nova" name="skeleton-demo" />
|
||||
|
||||
## Installation
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">CLI</TabsTrigger>
|
||||
<TabsTrigger value="cli">Command</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
@@ -24,11 +25,15 @@ npx shadcn@latest add skeleton
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps>
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource name="skeleton" title="components/ui/skeleton.tsx" />
|
||||
<ComponentSource
|
||||
name="skeleton"
|
||||
title="components/ui/skeleton.tsx"
|
||||
styleName="base-nova"
|
||||
/>
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
@@ -50,9 +55,26 @@ import { Skeleton } from "@/components/ui/skeleton"
|
||||
|
||||
## Examples
|
||||
|
||||
### Avatar
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="skeleton-avatar" />
|
||||
|
||||
### Card
|
||||
|
||||
<ComponentPreview
|
||||
styleName="base-nova"
|
||||
name="skeleton-card"
|
||||
description="A card with skeleton showing a loading state."
|
||||
previewClassName="h-80"
|
||||
/>
|
||||
|
||||
### Text
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="skeleton-text" />
|
||||
|
||||
### Form
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="skeleton-form" />
|
||||
|
||||
### Table
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="skeleton-table" />
|
||||
97
apps/v4/content/docs/components/base/slider.mdx
Normal file
97
apps/v4/content/docs/components/base/slider.mdx
Normal file
@@ -0,0 +1,97 @@
|
||||
---
|
||||
title: Slider
|
||||
description: An input where the user selects a value from within a given range.
|
||||
base: base
|
||||
component: true
|
||||
links:
|
||||
doc: https://base-ui.com/react/components/slider
|
||||
api: https://base-ui.com/react/components/slider#api-reference
|
||||
---
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="slider-demo" />
|
||||
|
||||
## Installation
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">Command</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add slider
|
||||
```
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @base-ui/react
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource
|
||||
name="slider"
|
||||
title="components/ui/slider.tsx"
|
||||
styleName="base-nova"
|
||||
/>
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
</CodeTabs>
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx
|
||||
import { Slider } from "@/components/ui/slider"
|
||||
```
|
||||
|
||||
```tsx
|
||||
<Slider defaultValue={[33]} max={100} step={1} />
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Range
|
||||
|
||||
Use an array with two values for a range slider.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="slider-range" />
|
||||
|
||||
### Multiple Thumbs
|
||||
|
||||
Use an array with multiple values for multiple thumbs.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="slider-multiple" />
|
||||
|
||||
### Vertical
|
||||
|
||||
Use `orientation="vertical"` for a vertical slider.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="slider-vertical" />
|
||||
|
||||
### Controlled
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="slider-controlled" />
|
||||
|
||||
### Disabled
|
||||
|
||||
Use the `disabled` prop to disable the slider.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="slider-disabled" />
|
||||
|
||||
## API Reference
|
||||
|
||||
See the [Base UI Slider](https://base-ui.com/react/components/slider#api-reference) documentation.
|
||||
126
apps/v4/content/docs/components/base/sonner.mdx
Normal file
126
apps/v4/content/docs/components/base/sonner.mdx
Normal file
@@ -0,0 +1,126 @@
|
||||
---
|
||||
title: Sonner
|
||||
description: An opinionated toast component for React.
|
||||
base: base
|
||||
component: true
|
||||
links:
|
||||
doc: https://sonner.emilkowal.ski
|
||||
---
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="sonner-demo" />
|
||||
|
||||
## About
|
||||
|
||||
Sonner is built and maintained by [emilkowalski](https://twitter.com/emilkowalski).
|
||||
|
||||
## Installation
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">Command</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Run the following command:</Step>
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add sonner
|
||||
```
|
||||
|
||||
<Step>Add the Toaster component</Step>
|
||||
|
||||
```tsx title="app/layout.tsx" {1,9} showLineNumbers
|
||||
import { Toaster } from "@/components/ui/sonner"
|
||||
|
||||
export default function RootLayout({ children }) {
|
||||
return (
|
||||
<html lang="en">
|
||||
<head />
|
||||
<body>
|
||||
<main>{children}</main>
|
||||
<Toaster />
|
||||
</body>
|
||||
</html>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
</Steps>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install sonner next-themes
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource
|
||||
name="sonner"
|
||||
title="components/ui/sonner.tsx"
|
||||
styleName="base-nova"
|
||||
/>
|
||||
|
||||
<Step>Add the Toaster component</Step>
|
||||
|
||||
```tsx showLineNumbers title="app/layout.tsx" {1,8}
|
||||
import { Toaster } from "@/components/ui/sonner"
|
||||
|
||||
export default function RootLayout({ children }) {
|
||||
return (
|
||||
<html lang="en">
|
||||
<head />
|
||||
<body>
|
||||
<Toaster />
|
||||
<main>{children}</main>
|
||||
</body>
|
||||
</html>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
</Steps>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
</CodeTabs>
|
||||
|
||||
## Usage
|
||||
|
||||
```tsx
|
||||
import { toast } from "sonner"
|
||||
```
|
||||
|
||||
```tsx
|
||||
toast("Event has been created.")
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Types
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="sonner-types" />
|
||||
|
||||
### Description
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="sonner-description" />
|
||||
|
||||
### Position
|
||||
|
||||
Use the `position` prop to change the position of the toast.
|
||||
|
||||
<ComponentPreview styleName="base-nova" name="sonner-position" />
|
||||
|
||||
## API Reference
|
||||
|
||||
See the [Sonner API Reference](https://sonner.emilkowal.ski/api) for more information.
|
||||
@@ -1,17 +1,18 @@
|
||||
---
|
||||
title: Spinner
|
||||
description: An indicator that can be used to show a loading state.
|
||||
base: base
|
||||
component: true
|
||||
---
|
||||
|
||||
<ComponentPreview name="spinner-demo" className="[&_.preview]:p-6" />
|
||||
<ComponentPreview styleName="base-nova" name="spinner-demo" />
|
||||
|
||||
## Installation
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">CLI</TabsTrigger>
|
||||
<TabsTrigger value="cli">Command</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
@@ -24,11 +25,15 @@ npx shadcn@latest add spinner
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps>
|
||||
<Steps className="mb-0 pt-2">
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource name="spinner" title="components/ui/spinner.tsx" />
|
||||
<ComponentSource
|
||||
name="spinner"
|
||||
title="components/ui/spinner.tsx"
|
||||
styleName="base-nova"
|
||||
/>
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
@@ -52,7 +57,7 @@ import { Spinner } from "@/components/ui/spinner"
|
||||
|
||||
You can replace the default spinner icon with any other icon by editing the `Spinner` component.
|
||||
|
||||
<ComponentPreview name="spinner-custom" />
|
||||
<ComponentPreview styleName="base-nova" name="spinner-custom" />
|
||||
|
||||
```tsx showLineNumbers title="components/ui/spinner.tsx"
|
||||
import { LoaderIcon } from "lucide-react"
|
||||
@@ -79,52 +84,24 @@ export { Spinner }
|
||||
|
||||
Use the `size-*` utility class to change the size of the spinner.
|
||||
|
||||
<ComponentPreview name="spinner-size" />
|
||||
|
||||
### Color
|
||||
|
||||
Use the `text-` utility class to change the color of the spinner.
|
||||
|
||||
<ComponentPreview name="spinner-color" />
|
||||
<ComponentPreview styleName="base-nova" name="spinner-size" />
|
||||
|
||||
### Button
|
||||
|
||||
Add a spinner to a button to indicate a loading state. The `<Button />` will handle the spacing between the spinner and the text.
|
||||
Add a spinner to a button to indicate a loading state. Remember to use the `data-icon="inline-start"` prop to add the spinner to the start of the button and the `data-icon="inline-end"` prop to add the spinner to the end of the button.
|
||||
|
||||
<ComponentPreview name="spinner-button" />
|
||||
<ComponentPreview styleName="base-nova" name="spinner-button" />
|
||||
|
||||
### Badge
|
||||
|
||||
You can also use a spinner inside a badge.
|
||||
Add a spinner to a badge to indicate a loading state. Remember to use the `data-icon="inline-start"` prop to add the spinner to the start of the badge and the `data-icon="inline-end"` prop to add the spinner to the end of the badge.
|
||||
|
||||
<ComponentPreview name="spinner-badge" />
|
||||
<ComponentPreview styleName="base-nova" name="spinner-badge" />
|
||||
|
||||
### Input Group
|
||||
|
||||
Input Group can have spinners inside `<InputGroupAddon>`.
|
||||
|
||||
<ComponentPreview name="spinner-input-group" />
|
||||
<ComponentPreview styleName="base-nova" name="spinner-input-group" />
|
||||
|
||||
### Empty
|
||||
|
||||
<ComponentPreview name="spinner-empty" />
|
||||
|
||||
### Item
|
||||
|
||||
Use the spinner inside `<ItemMedia>` to indicate a loading state.
|
||||
|
||||
<ComponentPreview name="spinner-item" />
|
||||
|
||||
## API Reference
|
||||
|
||||
### Spinner
|
||||
|
||||
Use the `Spinner` component to display a spinner.
|
||||
|
||||
| Prop | Type | Default |
|
||||
| ----------- | -------- | ------- |
|
||||
| `className` | `string` | `` |
|
||||
|
||||
```tsx
|
||||
<Spinner />
|
||||
```
|
||||
<ComponentPreview styleName="base-nova" name="spinner-empty" />
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user