Skip to content

Instantly share code, notes, and snippets.

@sethdavis512
Last active May 24, 2024 17:43
Show Gist options
  • Save sethdavis512/8fa025b98f37ef9dbcd3b3c0e66f74a6 to your computer and use it in GitHub Desktop.
Save sethdavis512/8fa025b98f37ef9dbcd3b3c0e66f74a6 to your computer and use it in GitHub Desktop.
asChild example
import { Slot, type AsChildProps } from "./slot.tsx"
type ButtonProps = AsChildProps<
React.ButtonHTMLAttributes<HTMLButtonElement>
> & {
style?: React.CSSProperties
className?: string
}
function Button({ asChild, ...props }: ButtonProps) {
const Comp = asChild ? Slot : "button"
return <Comp {...props} />
}
// ============================
import { twMerge } from "tailwind-merge"
export type AsChildProps<DefaultElementProps> =
| ({ asChild?: false } & DefaultElementProps)
| { asChild: true; children: React.ReactNode }
function Slot({
children,
...props
}: React.HTMLAttributes<HTMLElement> & {
children?: React.ReactNode
}) {
if (React.isValidElement(children)) {
return React.cloneElement(children, {
...props,
...children.props,
style: {
...props.style,
...children.props.style,
},
className: twMerge(
props.className,
children.props.className,
),
})
}
if (React.Children.count(children) > 1) {
React.Children.only(null)
}
return null
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment