T
TanStack•3y ago
stormy-gold

activeProps Paintpoint for classname priority

So i'm setting up navigation and noticed i'm running into a painpoint with the activeProps concept and class name order. for example, if i have something like this:
<Link
to={item.href}
className={cn(
"text-secondary-foreground hover:text-primary hover:bg-gray-50",
"group flex gap-x-3 rounded-md p-2 text-sm leading-6 font-semibold"
)}
activeProps={{
className: "bg-card text-primary",
}}
>
<item.icon
className={cn("h-6 w-6 shrink-0")}
aria-hidden="true"
/>
{item.name}
</Link>
<Link
to={item.href}
className={cn(
"text-secondary-foreground hover:text-primary hover:bg-gray-50",
"group flex gap-x-3 rounded-md p-2 text-sm leading-6 font-semibold"
)}
activeProps={{
className: "bg-card text-primary",
}}
>
<item.icon
className={cn("h-6 w-6 shrink-0")}
aria-hidden="true"
/>
{item.name}
</Link>
text-primary will get added but will not take priority because text-secondary-foreground beats it out because i can't include it in my cn() on my regular classname. i have a couple ideas here, but not ideal to have to come up with a workaround here. anyone else run into something like this before?
8 Replies
stormy-gold
stormy-goldOP•3y ago
wonder if it would be reasonable to just have activeProps.className take priority over regular className @Tanner Linsley 🤔 actually nvm. even as above the prop is technically after but can't win out best option i have right now is something like the below, which works, but still isn't ideal so wanted to call it out
interface ExtendedAnchorProps extends AnchorHTMLAttributes<HTMLAnchorElement> {
"data-state"?: string;
}


<Link
to={item.href}
className={cn(
"data-[state=inactive]:text-secondary-foreground hover:text-primary hover:bg-gray-50",
"group flex gap-x-3 rounded-md p-2 text-sm leading-6 font-semibold"
)}
activeProps={
{
"data-state": "active",
className: cn("bg-card text-primary"),
} as ExtendedAnchorProps
}
>
<item.icon
className={cn("h-6 w-6 shrink-0")}
aria-hidden="true"
/>
{item.name}
</Link>
interface ExtendedAnchorProps extends AnchorHTMLAttributes<HTMLAnchorElement> {
"data-state"?: string;
}


<Link
to={item.href}
className={cn(
"data-[state=inactive]:text-secondary-foreground hover:text-primary hover:bg-gray-50",
"group flex gap-x-3 rounded-md p-2 text-sm leading-6 font-semibold"
)}
activeProps={
{
"data-state": "active",
className: cn("bg-card text-primary"),
} as ExtendedAnchorProps
}
>
<item.icon
className={cn("h-6 w-6 shrink-0")}
aria-hidden="true"
/>
{item.name}
</Link>
e oo just notice you have data-status -- is this reliable enough to use in this case? yeah it does work. if anyone runs into this and is curious i'm running with the below unless tanner calls it out as unstable
<Link
to={item.href}
className={cn(
"text-secondary-foreground hover:text-primary hover:bg-gray-50",
"group flex gap-x-3 rounded-md p-2 text-sm leading-6 font-semibold",
"data-[status=active]:bg-card data-[status=active]:text-primary"
)}
>
<item.icon
className={cn("h-6 w-6 shrink-0")}
aria-hidden="true"
/>
{item.name}
</Link>
<Link
to={item.href}
className={cn(
"text-secondary-foreground hover:text-primary hover:bg-gray-50",
"group flex gap-x-3 rounded-md p-2 text-sm leading-6 font-semibold",
"data-[status=active]:bg-card data-[status=active]:text-primary"
)}
>
<item.icon
className={cn("h-6 w-6 shrink-0")}
aria-hidden="true"
/>
{item.name}
</Link>
automatic-azure
automatic-azure•3y ago
or you can use router state or urlparams and see if active and do a conditional with cn that could work fine @pdevito3
stormy-gold
stormy-goldOP•3y ago
Hmm. Then I’d be reimplementing that active derivation though @Bachitter
ugly-tan
ugly-tan•3y ago
I think it's just a subject of class specifity and order of classes in Tailwind stylesheet and it's not solvable at the library level. I'm personally just using inactiveProps and activeProps together to apply classes that would conflict with each other. and standard className only to apply shared classes. Something like this:
<Link
activeProps={{
"aria-current": "page",
className: "bg-astral-500 hover:bg-astral-400 text-plain",
}}
className={cn(
"group flex items-center gap-2 rounded-md p-4 text-sm font-medium outline-2 -outline-offset-2 outline-scorpion-950 transition-colors focus-visible:outline",
className,
)}
inactiveProps={{
className: "hover:bg-scorpion-100",
}}
onClick={() => onClick?.()}
to={path}
>
{...}
</Link>
<Link
activeProps={{
"aria-current": "page",
className: "bg-astral-500 hover:bg-astral-400 text-plain",
}}
className={cn(
"group flex items-center gap-2 rounded-md p-4 text-sm font-medium outline-2 -outline-offset-2 outline-scorpion-950 transition-colors focus-visible:outline",
className,
)}
inactiveProps={{
className: "hover:bg-scorpion-100",
}}
onClick={() => onClick?.()}
to={path}
>
{...}
</Link>
Using data status is also fine and intended for usage afaik, E.g. I'm using it to style child elements based on Link activeness. I'm finding activeProps inactiveProps combo easier to handle for the Link itself styling
automatic-azure
automatic-azure•3y ago
yeah
provincial-silver
provincial-silver•2y ago
@Paweł Błaszczyk How can you check for the data status for child components, and not the Link component?
ugly-tan
ugly-tan•2y ago
I've used Tailwind group feature for this one
wise-white
wise-white•2y ago
I've just been using [.active]:token Is that not enough?

Did you find this page helpful?