feat(button): support render delegation with asChild parameter (#174)

This commit is contained in:
Evan Rosenfeld
2023-04-30 04:01:41 -04:00
committed by GitHub
parent 7dc67be1ad
commit d99b992e27
4 changed files with 36 additions and 3 deletions

View File

@@ -0,0 +1,11 @@
import Link from "next/link"
import { Button } from "@/components/ui/button"
export function ButtonAsChild() {
return (
<Button asChild>
<Link href="/login">Login</Link>
</Button>
)
}

View File

@@ -8,6 +8,7 @@ import { BadgeDemo } from "@/components/examples/badge/demo"
import { BadgeDestructive } from "@/components/examples/badge/destructive"
import { BadgeOutline } from "@/components/examples/badge/outline"
import { BadgeSecondary } from "@/components/examples/badge/secondary"
import { ButtonAsChild } from "@/components/examples/button/as-child"
import { ButtonDemo } from "@/components/examples/button/demo"
import { ButtonDestructive } from "@/components/examples/button/destructive"
import { ButtonGhost } from "@/components/examples/button/ghost"
@@ -110,6 +111,7 @@ export const examples = {
ButtonOutline,
ButtonSecondary,
ButtonWithIcon,
ButtonAsChild,
CalendarDemo,
CalendarDatePicker,
CalendarDateRangePicker,

View File

@@ -1,4 +1,5 @@
import * as React from "react"
import { Slot } from "@radix-ui/react-slot"
import { VariantProps, cva } from "class-variance-authority"
import { cn } from "@/lib/utils"
@@ -33,12 +34,15 @@ const buttonVariants = cva(
export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {}
VariantProps<typeof buttonVariants> {
asChild?: boolean
}
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant, size, ...props }, ref) => {
({ className, variant, size, asChild = false, ...props }, ref) => {
const Comp = asChild ? Slot : "button"
return (
<button
<Comp
className={cn(buttonVariants({ variant, size, className }))}
ref={ref}
{...props}

View File

@@ -56,6 +56,14 @@ import { buttonVariants } from "@/components/ui/button"
<Link className={buttonVariants({ variant: "outline" })}>Click here</Link>
```
Alternatively, you can set the `asChild` parameter and nest the link component.
```tsx
<Button asChild>
<Link href="/login">Login</Link>
</Button>
```
## Examples
### Primary
@@ -119,3 +127,11 @@ import { buttonVariants } from "@/components/ui/button"
<ComponentExample src="/components/examples/button/loading.tsx">
<ButtonLoading />
</ComponentExample>
---
### As Child
<ComponentExample src="/components/examples/button/as-child.tsx">
<ButtonAsChild />
</ComponentExample>