Styling any component
twc
can be used on all your own or third-party components as long as they accept a className
prop.
Usage
Sometime you may want to style components from libraries like Radix (opens in a new tab) or React Aria Components (opens in a new tab) or your own cooked components.
In this example, we style a HoverCard
from Radix:
import * as HoverCard from "@radix-ui/react-hover-card";
import { twc } from "react-twc";
const HoverCardContent = twc(
HoverCard.Content,
)`data-[side=bottom]:animate-slideUpAndFade data-[side=right]:animate-slideLeftAndFade data-[side=left]:animate-slideRightAndFade data-[side=top]:animate-slideDownAndFade w-[300px] rounded-md bg-white p-5 shadow-[hsl(206_22%_7%_/_35%)_0px_10px_38px_-10px,hsl(206_22%_7%_/_20%)_0px_10px_20px_-15px] data-[state=open]:transition-all`;
export default () => (
<HoverCard.Root>
<HoverCard.Trigger>Hover me</HoverCard.Trigger>
<HoverCard.Portal>
<HoverCardContent>Hello from hover card</HoverCardContent>
</HoverCard.Portal>
</HoverCard.Root>
);
If you need to specify some default props, you can use additional props. For example you can define the sideOffset
by default using attrs
constructor:
const HoverCardContent = twc(HoverCard.Content).attrs({
sideOffset: 5,
})`data-[side=bottom]:animate-slideUpAndFade data-[side=right]:animate-slideLeftAndFade data-[side=left]:animate-slideRightAndFade data-[side=top]:animate-slideDownAndFade w-[300px] rounded-md bg-white p-5 shadow-[hsl(206_22%_7%_/_35%)_0px_10px_38px_-10px,hsl(206_22%_7%_/_20%)_0px_10px_20px_-15px] data-[state=open]:transition-all`;
Specify props
When you wrap a component with twc
, it infers the component's props automatically. However, this can sometimes result in unpredictable behavior. In such scenarios, it's better to define the props manually.
For example, with the @radix-ui/react-accordion
(opens in a new tab) component, its complex props like type
and collapsible
might not be inferred correctly by twc. To prevent issues, explicitly declare these props when using twc
. This explicit declaration ensures accurate prop handling, avoiding potential problems.
import * as React from 'react'
import * as AccordionPrimitive from "@radix-ui/react-accordion";
import { twc } from "react-twc";
const Accordion = twc(AccordionPrimitive.Root)<React.ComponentProps<typeof AccordionPrimitive.Root>>`py-2`;
export default () => {
return (
{/* This work without any type error, `collapsible` is authorized when `type="single"` */}
<Accordion type="single" collapsible>
</Accordion>
);
}