On extending primitives #2117
-
Do I need to use Is there any problem with extending primitives like this? import * as React from "react";
import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog";
import { type VariantProps } from "class-variance-authority";
import { twMerge } from "tailwind-merge";
import * as variants from "@/ui/radix/alert-dialog/variants";
type TitleProps = React.ComponentProps<typeof AlertDialogPrimitive.Title> &
VariantProps<typeof variants.title>;
function Title({ className, color, ...props }: TitleProps) {
return (
<AlertDialogPrimitive.Title
{...props}
className={twMerge(variants.title({ color }), className)}
/>
);
} Here I'm creating a new I get no errors when doing this, but I was wondering if there is an edge that I haven't taken into account. For example, I realized that if I extend the Alert Dialog
Note: This is how I would have created this component using const AlertDialogTitle = React.forwardRef<
React.ElementRef<typeof AlertDialogPrimitive.Title>,
React.ComponentPropsWithoutRef<typeof AlertDialogPrimitive.Title> &
VariantProps<typeof variants.title>
>(({ className, color, ...props }, ref) => (
<AlertDialogPrimitive.Title
{...props}
ref={ref}
className={twMerge(variants.title({ color }), className)}
/>
));
AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName; Is |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
I would say yes, but to be honest this is not really a Radix thing, but rather a React thing. If you want your leaf components to remain as compatible/composable as possible with any other React components, you need to ensure they behave like their lower level DOM counterpart. That means ensuring all props are passed in/merged, as well as forwarding ref as you have no idea when other components/abstractions will pass props or attach refs to it. |
Beta Was this translation helpful? Give feedback.
I would say yes, but to be honest this is not really a Radix thing, but rather a React thing. If you want your leaf components to remain as compatible/composable as possible with any other React components, you need to ensure they behave like their lower level DOM counterpart. That means ensuring all props are passed in/merged, as well as forwarding ref as you have no idea when other components/abstractions will pass props or attach refs to it.