How can I make the active NavLink
look similar to this? I tried following the React-Router-Dom docs but it didn't give this desired look. Is it possible to pass the isActive
prop from the NavLink
component to the Flex
component? I created a minimum representation of the sidebar down below. I'd appreciate any help.
Here's a minimal recreation of the sidebar made using Chakra UI: https://codesandbox.io/s/sidebar-ckm26m?file=/src/index.js
//imports
const App = () => {
return (
<Stack spacing={4}>
<NavLink to="/overview">
<Flex align="center" p="2" mx="2" ...>
<Box p="4px" border="1px" ...>
<AiOutlineDashboard size={16} />
</Box>
<Box ml={2} fontSize="sm">
Overview
</Box>
</Flex>
</NavLink>
<NavLink to="/app">
<Flex align="center" p="2" mx="2" ...>
<Box p="4px" border="1px" ...>
<IoApps size={16} />
</Box>
<Box ml={2} fontSize="sm">
Apps
</Box>
</Flex>
</NavLink>
</Stack>
)
}
export default App
Is it possible to pass the
isActive
prop from theNavLink
component to theFlex
component?
Yes, it is entirely possible. The NavLink
component understands and knows how to match the active route, there's no need to reinvent the wheel by using the useLocation
hook and manually checking the current pathname
.
The NavLink
component's children
prop can take a render function that is passed the isActive
prop.
Example Implementation:
const App = () => {
return (
<Box
bg="white"
borderRight="1px"
w="200px"
pos="fixed"
overflow="auto"
h="full"
>
<Stack spacing={4}>
<NavLink to="/overview">
{({ isActive }) => ( // <-- children render function
<LinkContainer
icon={<IoApps size={16} />}
isActive={isActive} // <-- pass isActive through as prop
label="Overview"
/>
)}
</NavLink>
<NavLink to="/app">
{({ isActive }) => (
<LinkContainer
icon={<AiOutlineDashboard size={16} />}
isActive={isActive}
label="Apps"
/>
)}
</NavLink>
</Stack>
</Box>
);
};
const LinkContainer = ({ icon, isActive, label }) => (
<Flex
align="center"
p="2"
mx="2"
borderRadius="lg"
role="group"
fontSize="14px"
cursor="pointer"
{...(isActive // <-- conditionally apply active props/styling/etc
? {
bg: "#002c8a",
color: "#fff",
borderColor: "#002c8a"
}
: {})}
_hover={{
bg: "#f5f5f5",
color: "#002c8a",
borderColor: "#002c8a"
}}
>
<Box
p="4px"
border="1px"
borderRadius="full"
borderColor="gray.200"
fontSize="26"
>
{icon}
</Box>
<Box ml={2} fontSize="sm">
{label}
</Box>
</Flex>
);