Trying to style a parent div for a child's Link
if the Link
has the applied aria-current="page"
or an active
class name.
code (stripped):
<NavBody>
{items.map((subItem, key) => {
const { title, link } = subItem
return (
<NavLinkContainer key={key}>
<NavLink
onClick={closeMobileMenu}
to={`/docs${link}`}
activeClassName="active"
>
{title}
</NavLink>
</NavLinkContainer>
)
})}
</NavBody>
Styled Components:
const NavBody = styled(Accordion.Body)`
margin-left: ${({ theme }) => theme.spacings.small};
padding: 0 !important;
`
const NavLinkContainer = styled.div`
padding-top: ${({ theme }) => theme.spacings.xSmall};
padding-bottom: ${({ theme }) => theme.spacings.xSmall};
border-left: 1px solid ${({ theme }) => theme.colors.color7};
padding-left: ${({ theme }) => theme.spacings.small} !important;
`
const NavLink = styled(Link)`
color: ${({ theme }) => theme.colors.color3};
text-decoration: none;
padding-bottom: ${({ theme }) => theme.spacings.xxSmall};
&.active {
color: ${({ theme }) => theme.colors.color1};
}
&:hover {
color: inherit;
opacity: 0.7;
text-decoration: none;
border-bottom: 1px solid ${({ theme }) => theme.colors.color1};
}
`
I tried:
const NavLinkContainer = styled.div`
padding-top: ${({ theme }) => theme.spacings.xSmall};
padding-bottom: ${({ theme }) => theme.spacings.xSmall};
border-left: 1px solid ${({ theme }) => theme.colors.color7};
padding-left: ${({ theme }) => theme.spacings.small} !important;
&.active {
border-left: 1px solid ${({ theme }) => theme.colors.color1};
}
`
but that's incorrectly applied due to the padding-left
. Another attempt:
<NavBody>
{items.map((subItem, key) => {
const { title, link } = subItem
return (
<NavLinkContainer key={key} activeClassName="active">
<NavLink
onClick={closeMobileMenu}
to={`/docs${link}`}
activeClassName="active"
>
{title}
</NavLink>
</NavLinkContainer>
)
})}
</NavBody>
the applied activeClassName
doesn't render on the div
and:
const NavLinkContainer = styled.div`
padding-top: ${({ theme }) => theme.spacings.xSmall};
padding-bottom: ${({ theme }) => theme.spacings.xSmall};
border-left: 1px solid ${({ theme }) => theme.colors.color7};
padding-left: ${({ theme }) => theme.spacings.small} !important;
&[aria-current='page'] {
border-left: 3px solid ${({ theme }) => theme.colors.color1} !important;
}
`
doesn't render the color.
In Styled Components is there a way to style the parent based wether the child has a className of active
or aria-current="page"
?
I figured out how to modify my parent NavLinkContainer
. In Reach Router I have access to pathname
from useLocation
:
const { pathname } = useLocation()
using link
from my map and useMemo
I was able to find if the link
existed by setting to a variable:
const active = useMemo(() => {
return pathname.toString().includes(link)
}, [pathname, link])
by doing so I could pass a boolean to NavLinkContainer
:
<NavLinkContainer border={active}>
// Further code
</NavLinkContainer>
and in the Styled Component I could do:
const NavLinkContainer = styled.div`
border-color: ${({ border, theme }) =>
border ? `${theme.colors.color1}` : `${theme.colors.color5}`};
`
which gives me the ability to style the parent div
with a custom border color set within my theme.