mirror of
https://github.com/shadcn-ui/ui.git
synced 2026-06-29 07:34:11 +00:00
fix
This commit is contained in:
@@ -149,8 +149,12 @@ export default async function Page(props: {
|
||||
)}
|
||||
</div>
|
||||
{params.slug?.[0] === "components" &&
|
||||
(params.slug?.[1] === "radix" || params.slug?.[1] === "base") && (
|
||||
<DocsBaseSwitcher />
|
||||
(params.slug?.[1] === "radix" || params.slug?.[1] === "base") &&
|
||||
params.slug?.[2] && (
|
||||
<DocsBaseSwitcher
|
||||
base={params.slug[1]}
|
||||
component={params.slug[2]}
|
||||
/>
|
||||
)}
|
||||
{links ? (
|
||||
<div className="flex items-center gap-2 pt-4">
|
||||
|
||||
@@ -1,38 +1,29 @@
|
||||
"use client"
|
||||
|
||||
import Link from "next/link"
|
||||
import { usePathname } from "next/navigation"
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
import { BASES } from "@/registry/bases"
|
||||
|
||||
const BASES = [
|
||||
{ name: "radix", label: "Radix UI" },
|
||||
{ name: "base", label: "Base UI" },
|
||||
]
|
||||
|
||||
export function DocsBaseSwitcher() {
|
||||
const pathname = usePathname()
|
||||
|
||||
// Extract base and component from /docs/components/{base}/{component}.
|
||||
const match = pathname.match(/\/docs\/components\/(radix|base)\/(.+)/)
|
||||
if (!match) return null
|
||||
|
||||
const [, currentBase, component] = match
|
||||
|
||||
export function DocsBaseSwitcher({
|
||||
base,
|
||||
component,
|
||||
}: {
|
||||
base: string
|
||||
component: string
|
||||
}) {
|
||||
return (
|
||||
<div className="flex gap-1 rounded-md border p-1">
|
||||
{BASES.map((base) => (
|
||||
{BASES.map((baseItem) => (
|
||||
<Link
|
||||
key={base.name}
|
||||
href={`/docs/components/${base.name}/${component}`}
|
||||
key={baseItem.name}
|
||||
href={`/docs/components/${baseItem.name}/${component}`}
|
||||
className={cn(
|
||||
"rounded px-3 py-1 text-sm transition-colors",
|
||||
currentBase === base.name
|
||||
base === baseItem.name
|
||||
? "bg-primary text-primary-foreground"
|
||||
: "hover:bg-muted"
|
||||
)}
|
||||
>
|
||||
{base.label}
|
||||
{baseItem.title}
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
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"
|
||||
@@ -19,7 +19,7 @@ const TOP_LEVEL_SECTIONS = [
|
||||
{ name: "Get Started", href: "/docs" },
|
||||
{
|
||||
name: "Components",
|
||||
href: "/docs/components",
|
||||
href: "/docs/components/radix",
|
||||
},
|
||||
{
|
||||
name: "Directory",
|
||||
@@ -39,6 +39,61 @@ const TOP_LEVEL_SECTIONS = [
|
||||
},
|
||||
]
|
||||
|
||||
type PageTreeNode = (typeof source.pageTree)["children"][number]
|
||||
type PageTreeFolder = Extract<PageTreeNode, { type: "folder" }>
|
||||
type PageTreePage = Extract<PageTreeNode, { type: "page" }>
|
||||
|
||||
// Recursively find all pages in a folder tree.
|
||||
function getAllPagesFromFolder(folder: PageTreeFolder): PageTreePage[] {
|
||||
const pages: PageTreePage[] = []
|
||||
|
||||
for (const child of folder.children) {
|
||||
if (child.type === "page") {
|
||||
pages.push(child)
|
||||
} else if (child.type === "folder") {
|
||||
pages.push(...getAllPagesFromFolder(child))
|
||||
}
|
||||
}
|
||||
|
||||
return pages
|
||||
}
|
||||
|
||||
// Get the pages from a folder, handling nested base folders (radix/base).
|
||||
function getPagesFromFolder(
|
||||
folder: PageTreeFolder,
|
||||
currentBase: string
|
||||
): PageTreePage[] {
|
||||
// For the components folder, find the base subfolder.
|
||||
if (folder.$id === "components" || folder.name === "Components") {
|
||||
for (const child of folder.children) {
|
||||
if (child.type === "folder") {
|
||||
// Match by $id or by name.
|
||||
const isRadix = child.$id === "radix" || child.name === "Radix UI"
|
||||
const isBase = child.$id === "base" || child.name === "Base UI"
|
||||
|
||||
if (
|
||||
(currentBase === "radix" && isRadix) ||
|
||||
(currentBase === "base" && isBase)
|
||||
) {
|
||||
return child.children.filter(
|
||||
(c): c is PageTreePage => c.type === "page"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: return all pages from nested folders.
|
||||
return getAllPagesFromFolder(folder).filter(
|
||||
(page) => !page.url.endsWith("/components")
|
||||
)
|
||||
}
|
||||
|
||||
// For other folders, return direct page children.
|
||||
return folder.children.filter(
|
||||
(child): child is PageTreePage => child.type === "page"
|
||||
)
|
||||
}
|
||||
|
||||
export function MobileNav({
|
||||
tree,
|
||||
items,
|
||||
@@ -49,6 +104,12 @@ export function MobileNav({
|
||||
className?: string
|
||||
}) {
|
||||
const [open, setOpen] = React.useState(false)
|
||||
const pathname = usePathname()
|
||||
|
||||
// Determine current base from pathname.
|
||||
const currentBase = pathname.includes("/docs/components/base/")
|
||||
? "base"
|
||||
: "radix"
|
||||
|
||||
return (
|
||||
<Popover open={open} onOpenChange={setOpen}>
|
||||
@@ -125,31 +186,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>
|
||||
|
||||
@@ -40,7 +40,7 @@ npx shadcn@latest add accordion
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-accordion
|
||||
npm install @base-ui/react
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -39,7 +39,7 @@ npx shadcn@latest add alert-dialog
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-alert-dialog
|
||||
npm install @base-ui/react
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -38,7 +38,7 @@ npx shadcn@latest add aspect-ratio
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-aspect-ratio
|
||||
npm install @base-ui/react
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -38,7 +38,7 @@ npx shadcn@latest add avatar
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-avatar
|
||||
npm install @base-ui/react
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -30,7 +30,7 @@ npx shadcn@latest add button-group
|
||||
<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>
|
||||
|
||||
@@ -52,7 +52,7 @@ npx shadcn@latest add button
|
||||
<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>
|
||||
|
||||
@@ -37,7 +37,7 @@ npx shadcn@latest add checkbox
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-checkbox
|
||||
npm install @base-ui/react
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -38,7 +38,7 @@ npx shadcn@latest add collapsible
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-collapsible
|
||||
npm install @base-ui/react
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -37,7 +37,7 @@ npx shadcn@latest add context-menu
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-context-menu
|
||||
npm install @base-ui/react
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -38,7 +38,7 @@ npx shadcn@latest add dialog
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-dialog
|
||||
npm install @base-ui/react
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -38,7 +38,7 @@ npx shadcn@latest add dropdown-menu
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-dropdown-menu
|
||||
npm install @base-ui/react
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -1,245 +0,0 @@
|
||||
---
|
||||
title: Form
|
||||
description: Building forms with React Hook Form and Zod.
|
||||
links:
|
||||
doc: https://react-hook-form.com
|
||||
---
|
||||
|
||||
import { InfoIcon } from "lucide-react"
|
||||
|
||||
<Callout icon={<InfoIcon />} title="We are not actively developing this component anymore.">
|
||||
|
||||
The Form component is an abstraction over the `react-hook-form` library. Going forward, we recommend using the [`<Field />`](/docs/components/field) component to build forms. See the [Form](/docs/forms) documentation for more information.
|
||||
|
||||
</Callout>
|
||||
|
||||
Forms are tricky. They are one of the most common things you'll build in a web application, but also one of the most complex.
|
||||
|
||||
Well-designed HTML forms are:
|
||||
|
||||
- Well-structured and semantically correct.
|
||||
- Easy to use and navigate (keyboard).
|
||||
- Accessible with ARIA attributes and proper labels.
|
||||
- Has support for client and server side validation.
|
||||
- Well-styled and consistent with the rest of the application.
|
||||
|
||||
In this guide, we will take a look at building forms with [`react-hook-form`](https://react-hook-form.com/) and [`zod`](https://zod.dev). We're going to use a `<FormField>` component to compose accessible forms using Radix UI components.
|
||||
|
||||
## Features
|
||||
|
||||
The `<Form />` component is a wrapper around the `react-hook-form` library. It provides a few things:
|
||||
|
||||
- Composable components for building forms.
|
||||
- A `<FormField />` component for building controlled form fields.
|
||||
- Form validation using `zod`.
|
||||
- Handles accessibility and error messages.
|
||||
- Uses `React.useId()` for generating unique IDs.
|
||||
- Applies the correct `aria` attributes to form fields based on states.
|
||||
- Built to work with all Radix UI components.
|
||||
- Bring your own schema library. We use `zod` but you can use anything you want.
|
||||
- **You have full control over the markup and styling.**
|
||||
|
||||
## Anatomy
|
||||
|
||||
```tsx showLineNumbers
|
||||
<Form>
|
||||
<FormField
|
||||
control={...}
|
||||
name="..."
|
||||
render={() => (
|
||||
<FormItem>
|
||||
<FormLabel />
|
||||
<FormControl>
|
||||
{ /* Your form field */}
|
||||
</FormControl>
|
||||
<FormDescription />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</Form>
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
```tsx showLineNumbers
|
||||
const form = useForm()
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="username"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Username</FormLabel>
|
||||
<FormControl>
|
||||
<Input placeholder="shadcn" {...field} />
|
||||
</FormControl>
|
||||
<FormDescription>This is your public display name.</FormDescription>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">CLI</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
|
||||
<Steps>
|
||||
|
||||
### Command
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add form
|
||||
```
|
||||
|
||||
</Steps>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps>
|
||||
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-label @radix-ui/react-slot react-hook-form @hookform/resolvers zod
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource
|
||||
name="form"
|
||||
title="components/ui/form.tsx"
|
||||
styleName="base-nova"
|
||||
/>
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
</CodeTabs>
|
||||
|
||||
## Usage
|
||||
|
||||
### Create a form schema
|
||||
|
||||
Define the shape of your form using a Zod schema. You can read more about using Zod in the [Zod documentation](https://zod.dev).
|
||||
|
||||
```tsx showLineNumbers title="components/example-form.tsx" {3,5-7}
|
||||
"use client"
|
||||
|
||||
import { z } from "zod"
|
||||
|
||||
const formSchema = z.object({
|
||||
username: z.string().min(2).max(50),
|
||||
})
|
||||
```
|
||||
|
||||
### Define a form
|
||||
|
||||
Use the `useForm` hook from `react-hook-form` to create a form.
|
||||
|
||||
```tsx showLineNumbers title="components/example-form.tsx" {3-4,14-20,22-27}
|
||||
"use client"
|
||||
|
||||
import { zodResolver } from "@hookform/resolvers/zod"
|
||||
import { useForm } from "react-hook-form"
|
||||
import { z } from "zod"
|
||||
|
||||
const formSchema = z.object({
|
||||
username: z.string().min(2, {
|
||||
message: "Username must be at least 2 characters.",
|
||||
}),
|
||||
})
|
||||
|
||||
export function ProfileForm() {
|
||||
// 1. Define your form.
|
||||
const form = useForm<z.infer<typeof formSchema>>({
|
||||
resolver: zodResolver(formSchema),
|
||||
defaultValues: {
|
||||
username: "",
|
||||
},
|
||||
})
|
||||
|
||||
// 2. Define a submit handler.
|
||||
function onSubmit(values: z.infer<typeof formSchema>) {
|
||||
// Do something with the form values.
|
||||
// ✅ This will be type-safe and validated.
|
||||
console.log(values)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Since `FormField` is using a controlled component, you need to provide a default value for the field. See the [React Hook Form docs](https://react-hook-form.com/docs/usecontroller) to learn more about controlled components.
|
||||
|
||||
### Build your form
|
||||
|
||||
We can now use the `<Form />` components to build our form.
|
||||
|
||||
```tsx showLineNumbers title="components/example-form.tsx" {7-17,28-50}
|
||||
"use client"
|
||||
|
||||
import { zodResolver } from "@hookform/resolvers/zod"
|
||||
import { useForm } from "react-hook-form"
|
||||
import { z } from "zod"
|
||||
|
||||
import { Button } from "@/components/ui/button"
|
||||
import {
|
||||
Form,
|
||||
FormControl,
|
||||
FormDescription,
|
||||
FormField,
|
||||
FormItem,
|
||||
FormLabel,
|
||||
FormMessage,
|
||||
} from "@/components/ui/form"
|
||||
import { Input } from "@/components/ui/input"
|
||||
|
||||
const formSchema = z.object({
|
||||
username: z.string().min(2, {
|
||||
message: "Username must be at least 2 characters.",
|
||||
}),
|
||||
})
|
||||
|
||||
export function ProfileForm() {
|
||||
// ...
|
||||
|
||||
return (
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="username"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Username</FormLabel>
|
||||
<FormControl>
|
||||
<Input placeholder="shadcn" {...field} />
|
||||
</FormControl>
|
||||
<FormDescription>
|
||||
This is your public display name.
|
||||
</FormDescription>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<Button type="submit">Submit</Button>
|
||||
</form>
|
||||
</Form>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
### Done
|
||||
|
||||
That's it. You now have a fully accessible form that is type-safe with client-side validation.
|
||||
@@ -35,7 +35,7 @@ npx shadcn@latest add hover-card
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-hover-card
|
||||
npm install @base-ui/react
|
||||
```
|
||||
|
||||
<Steps>
|
||||
|
||||
@@ -37,7 +37,7 @@ npx shadcn@latest add label
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-label
|
||||
npm install @base-ui/react
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -37,7 +37,7 @@ npx shadcn@latest add menubar
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-menubar
|
||||
npm install @base-ui/react
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -37,7 +37,7 @@ npx shadcn@latest add navigation-menu
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-navigation-menu
|
||||
npm install @base-ui/react
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -37,7 +37,7 @@ npx shadcn@latest add popover
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-popover
|
||||
npm install @base-ui/react
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -37,7 +37,7 @@ npx shadcn@latest add progress
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-progress
|
||||
npm install @base-ui/react
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -37,7 +37,7 @@ npx shadcn@latest add radio-group
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-radio-group
|
||||
npm install @base-ui/react
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -37,7 +37,7 @@ npx shadcn@latest add scroll-area
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-scroll-area
|
||||
npm install @base-ui/react
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -38,7 +38,7 @@ npx shadcn@latest add select
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-select
|
||||
npm install @base-ui/react
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -36,7 +36,7 @@ npx shadcn@latest add separator
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-separator
|
||||
npm install @base-ui/react
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -37,7 +37,7 @@ npx shadcn@latest add sheet
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-dialog
|
||||
npm install @base-ui/react
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -37,7 +37,7 @@ npx shadcn@latest add slider
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-slider
|
||||
npm install @base-ui/react
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -37,7 +37,7 @@ npx shadcn@latest add switch
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-switch
|
||||
npm install @base-ui/react
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -37,7 +37,7 @@ npx shadcn@latest add tabs
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-tabs
|
||||
npm install @base-ui/react
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -33,7 +33,7 @@ npx shadcn@latest add toggle-group
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-toggle-group
|
||||
npm install @base-ui/react
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -37,7 +37,7 @@ npx shadcn@latest add toggle
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-toggle
|
||||
npm install @base-ui/react
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -37,7 +37,7 @@ npx shadcn@latest add tooltip
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-tooltip
|
||||
npm install @base-ui/react
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -40,7 +40,7 @@ npx shadcn@latest add accordion
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-accordion
|
||||
npm install radix-ui
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -39,7 +39,7 @@ npx shadcn@latest add alert-dialog
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-alert-dialog
|
||||
npm install radix-ui
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -38,7 +38,7 @@ npx shadcn@latest add aspect-ratio
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-aspect-ratio
|
||||
npm install radix-ui
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -38,7 +38,7 @@ npx shadcn@latest add avatar
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-avatar
|
||||
npm install radix-ui
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -30,7 +30,7 @@ npx shadcn@latest add button-group
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-slot
|
||||
npm install radix-ui
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -52,7 +52,7 @@ npx shadcn@latest add button
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-slot
|
||||
npm install radix-ui
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -37,7 +37,7 @@ npx shadcn@latest add checkbox
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-checkbox
|
||||
npm install radix-ui
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -38,7 +38,7 @@ npx shadcn@latest add collapsible
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-collapsible
|
||||
npm install radix-ui
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -37,7 +37,7 @@ npx shadcn@latest add context-menu
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-context-menu
|
||||
npm install radix-ui
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -38,7 +38,7 @@ npx shadcn@latest add dialog
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-dialog
|
||||
npm install radix-ui
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -38,7 +38,7 @@ npx shadcn@latest add dropdown-menu
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-dropdown-menu
|
||||
npm install radix-ui
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -1,245 +0,0 @@
|
||||
---
|
||||
title: Form
|
||||
description: Building forms with React Hook Form and Zod.
|
||||
links:
|
||||
doc: https://react-hook-form.com
|
||||
---
|
||||
|
||||
import { InfoIcon } from "lucide-react"
|
||||
|
||||
<Callout icon={<InfoIcon />} title="We are not actively developing this component anymore.">
|
||||
|
||||
The Form component is an abstraction over the `react-hook-form` library. Going forward, we recommend using the [`<Field />`](/docs/components/field) component to build forms. See the [Form](/docs/forms) documentation for more information.
|
||||
|
||||
</Callout>
|
||||
|
||||
Forms are tricky. They are one of the most common things you'll build in a web application, but also one of the most complex.
|
||||
|
||||
Well-designed HTML forms are:
|
||||
|
||||
- Well-structured and semantically correct.
|
||||
- Easy to use and navigate (keyboard).
|
||||
- Accessible with ARIA attributes and proper labels.
|
||||
- Has support for client and server side validation.
|
||||
- Well-styled and consistent with the rest of the application.
|
||||
|
||||
In this guide, we will take a look at building forms with [`react-hook-form`](https://react-hook-form.com/) and [`zod`](https://zod.dev). We're going to use a `<FormField>` component to compose accessible forms using Radix UI components.
|
||||
|
||||
## Features
|
||||
|
||||
The `<Form />` component is a wrapper around the `react-hook-form` library. It provides a few things:
|
||||
|
||||
- Composable components for building forms.
|
||||
- A `<FormField />` component for building controlled form fields.
|
||||
- Form validation using `zod`.
|
||||
- Handles accessibility and error messages.
|
||||
- Uses `React.useId()` for generating unique IDs.
|
||||
- Applies the correct `aria` attributes to form fields based on states.
|
||||
- Built to work with all Radix UI components.
|
||||
- Bring your own schema library. We use `zod` but you can use anything you want.
|
||||
- **You have full control over the markup and styling.**
|
||||
|
||||
## Anatomy
|
||||
|
||||
```tsx showLineNumbers
|
||||
<Form>
|
||||
<FormField
|
||||
control={...}
|
||||
name="..."
|
||||
render={() => (
|
||||
<FormItem>
|
||||
<FormLabel />
|
||||
<FormControl>
|
||||
{ /* Your form field */}
|
||||
</FormControl>
|
||||
<FormDescription />
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</Form>
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
```tsx showLineNumbers
|
||||
const form = useForm()
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="username"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Username</FormLabel>
|
||||
<FormControl>
|
||||
<Input placeholder="shadcn" {...field} />
|
||||
</FormControl>
|
||||
<FormDescription>This is your public display name.</FormDescription>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
||||
<CodeTabs>
|
||||
|
||||
<TabsList>
|
||||
<TabsTrigger value="cli">CLI</TabsTrigger>
|
||||
<TabsTrigger value="manual">Manual</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="cli">
|
||||
|
||||
<Steps>
|
||||
|
||||
### Command
|
||||
|
||||
```bash
|
||||
npx shadcn@latest add form
|
||||
```
|
||||
|
||||
</Steps>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="manual">
|
||||
|
||||
<Steps>
|
||||
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-label @radix-ui/react-slot react-hook-form @hookform/resolvers zod
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
<ComponentSource
|
||||
name="form"
|
||||
title="components/ui/form.tsx"
|
||||
styleName="radix-nova"
|
||||
/>
|
||||
|
||||
<Step>Update the import paths to match your project setup.</Step>
|
||||
|
||||
</Steps>
|
||||
|
||||
</TabsContent>
|
||||
|
||||
</CodeTabs>
|
||||
|
||||
## Usage
|
||||
|
||||
### Create a form schema
|
||||
|
||||
Define the shape of your form using a Zod schema. You can read more about using Zod in the [Zod documentation](https://zod.dev).
|
||||
|
||||
```tsx showLineNumbers title="components/example-form.tsx" {3,5-7}
|
||||
"use client"
|
||||
|
||||
import { z } from "zod"
|
||||
|
||||
const formSchema = z.object({
|
||||
username: z.string().min(2).max(50),
|
||||
})
|
||||
```
|
||||
|
||||
### Define a form
|
||||
|
||||
Use the `useForm` hook from `react-hook-form` to create a form.
|
||||
|
||||
```tsx showLineNumbers title="components/example-form.tsx" {3-4,14-20,22-27}
|
||||
"use client"
|
||||
|
||||
import { zodResolver } from "@hookform/resolvers/zod"
|
||||
import { useForm } from "react-hook-form"
|
||||
import { z } from "zod"
|
||||
|
||||
const formSchema = z.object({
|
||||
username: z.string().min(2, {
|
||||
message: "Username must be at least 2 characters.",
|
||||
}),
|
||||
})
|
||||
|
||||
export function ProfileForm() {
|
||||
// 1. Define your form.
|
||||
const form = useForm<z.infer<typeof formSchema>>({
|
||||
resolver: zodResolver(formSchema),
|
||||
defaultValues: {
|
||||
username: "",
|
||||
},
|
||||
})
|
||||
|
||||
// 2. Define a submit handler.
|
||||
function onSubmit(values: z.infer<typeof formSchema>) {
|
||||
// Do something with the form values.
|
||||
// ✅ This will be type-safe and validated.
|
||||
console.log(values)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Since `FormField` is using a controlled component, you need to provide a default value for the field. See the [React Hook Form docs](https://react-hook-form.com/docs/usecontroller) to learn more about controlled components.
|
||||
|
||||
### Build your form
|
||||
|
||||
We can now use the `<Form />` components to build our form.
|
||||
|
||||
```tsx showLineNumbers title="components/example-form.tsx" {7-17,28-50}
|
||||
"use client"
|
||||
|
||||
import { zodResolver } from "@hookform/resolvers/zod"
|
||||
import { useForm } from "react-hook-form"
|
||||
import { z } from "zod"
|
||||
|
||||
import { Button } from "@/components/ui/button"
|
||||
import {
|
||||
Form,
|
||||
FormControl,
|
||||
FormDescription,
|
||||
FormField,
|
||||
FormItem,
|
||||
FormLabel,
|
||||
FormMessage,
|
||||
} from "@/components/ui/form"
|
||||
import { Input } from "@/components/ui/input"
|
||||
|
||||
const formSchema = z.object({
|
||||
username: z.string().min(2, {
|
||||
message: "Username must be at least 2 characters.",
|
||||
}),
|
||||
})
|
||||
|
||||
export function ProfileForm() {
|
||||
// ...
|
||||
|
||||
return (
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-8">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="username"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>Username</FormLabel>
|
||||
<FormControl>
|
||||
<Input placeholder="shadcn" {...field} />
|
||||
</FormControl>
|
||||
<FormDescription>
|
||||
This is your public display name.
|
||||
</FormDescription>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<Button type="submit">Submit</Button>
|
||||
</form>
|
||||
</Form>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
### Done
|
||||
|
||||
That's it. You now have a fully accessible form that is type-safe with client-side validation.
|
||||
@@ -35,7 +35,7 @@ npx shadcn@latest add hover-card
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-hover-card
|
||||
npm install radix-ui
|
||||
```
|
||||
|
||||
<Steps>
|
||||
|
||||
@@ -37,7 +37,7 @@ npx shadcn@latest add label
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-label
|
||||
npm install radix-ui
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -37,7 +37,7 @@ npx shadcn@latest add menubar
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-menubar
|
||||
npm install radix-ui
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -37,7 +37,7 @@ npx shadcn@latest add navigation-menu
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-navigation-menu
|
||||
npm install radix-ui
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -37,7 +37,7 @@ npx shadcn@latest add popover
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-popover
|
||||
npm install radix-ui
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -37,7 +37,7 @@ npx shadcn@latest add progress
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-progress
|
||||
npm install radix-ui
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -37,7 +37,7 @@ npx shadcn@latest add radio-group
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-radio-group
|
||||
npm install radix-ui
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -37,7 +37,7 @@ npx shadcn@latest add scroll-area
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-scroll-area
|
||||
npm install radix-ui
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -38,7 +38,7 @@ npx shadcn@latest add select
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-select
|
||||
npm install radix-ui
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -36,7 +36,7 @@ npx shadcn@latest add separator
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-separator
|
||||
npm install radix-ui
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -37,7 +37,7 @@ npx shadcn@latest add sheet
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-dialog
|
||||
npm install radix-ui
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -37,7 +37,7 @@ npx shadcn@latest add slider
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-slider
|
||||
npm install radix-ui
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -37,7 +37,7 @@ npx shadcn@latest add switch
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-switch
|
||||
npm install radix-ui
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -37,7 +37,7 @@ npx shadcn@latest add tabs
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-tabs
|
||||
npm install radix-ui
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -33,7 +33,7 @@ npx shadcn@latest add toggle-group
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-toggle-group
|
||||
npm install radix-ui
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -37,7 +37,7 @@ npx shadcn@latest add toggle
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-toggle
|
||||
npm install radix-ui
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -37,7 +37,7 @@ npx shadcn@latest add tooltip
|
||||
<Step>Install the following dependencies:</Step>
|
||||
|
||||
```bash
|
||||
npm install @radix-ui/react-tooltip
|
||||
npm install radix-ui
|
||||
```
|
||||
|
||||
<Step>Copy and paste the following code into your project.</Step>
|
||||
|
||||
@@ -3,7 +3,7 @@ title: Forms
|
||||
description: Build forms with React and shadcn/ui.
|
||||
---
|
||||
|
||||
import { ClipboardListIcon, InfoIcon } from "lucide-react"
|
||||
import { ClipboardListIcon } from "lucide-react"
|
||||
|
||||
## Pick Your Framework
|
||||
|
||||
@@ -40,6 +40,5 @@ Start by selecting your framework. Then follow the instructions to learn how to
|
||||
</svg>
|
||||
<p className="mt-2 font-medium">useActionState</p>
|
||||
<p className="text-muted-foreground mt-1 text-xs">(Coming Soon)</p>
|
||||
|
||||
</LinkedCard>
|
||||
</div>
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
import { NextResponse } from "next/server"
|
||||
import type { NextRequest } from "next/server"
|
||||
|
||||
// List of all component names.
|
||||
const COMPONENT_NAMES = [
|
||||
"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",
|
||||
]
|
||||
|
||||
export function middleware(request: NextRequest) {
|
||||
const { pathname } = request.nextUrl
|
||||
|
||||
// Match /docs/components/:component (not /docs/components/radix/:component or /docs/components/base/:component).
|
||||
const match = pathname.match(/^\/docs\/components\/([^/]+)$/)
|
||||
|
||||
if (match) {
|
||||
const segment = match[1]
|
||||
// Redirect component pages to radix version (default).
|
||||
if (COMPONENT_NAMES.includes(segment)) {
|
||||
return NextResponse.redirect(
|
||||
new URL(`/docs/components/radix/${segment}`, request.url),
|
||||
301
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return NextResponse.next()
|
||||
}
|
||||
|
||||
export const config = {
|
||||
matcher: "/docs/components/:path*",
|
||||
}
|
||||
@@ -1,5 +1,67 @@
|
||||
import { createMDX } from "fumadocs-mdx/next"
|
||||
|
||||
// List of all component names for redirects.
|
||||
const COMPONENT_NAMES = [
|
||||
"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",
|
||||
"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",
|
||||
]
|
||||
|
||||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {
|
||||
devIndicators: false,
|
||||
@@ -29,7 +91,33 @@ const nextConfig = {
|
||||
turbopackFileSystemCacheForDev: true,
|
||||
},
|
||||
redirects() {
|
||||
// Generate redirects for all components: /docs/components/:name → /docs/components/radix/:name.
|
||||
const componentRedirects = COMPONENT_NAMES.map((name) => ({
|
||||
source: `/docs/components/${name}`,
|
||||
destination: `/docs/components/radix/${name}`,
|
||||
permanent: true,
|
||||
}))
|
||||
|
||||
return [
|
||||
// Form redirects to /docs/forms.
|
||||
{
|
||||
source: "/docs/components/form",
|
||||
destination: "/docs/forms",
|
||||
permanent: true,
|
||||
},
|
||||
{
|
||||
source: "/docs/components/radix/form",
|
||||
destination: "/docs/forms",
|
||||
permanent: true,
|
||||
},
|
||||
{
|
||||
source: "/docs/components/base/form",
|
||||
destination: "/docs/forms",
|
||||
permanent: true,
|
||||
},
|
||||
// Component redirects (default to radix).
|
||||
...componentRedirects,
|
||||
// Other redirects.
|
||||
{
|
||||
source: "/components",
|
||||
destination: "/docs/components",
|
||||
|
||||
Reference in New Issue
Block a user