In this article I will share the code to create navbar in chakra-ui. We will use React Js for this. You may use any framework of your choice. Primary components used in it are –
- Box
- Flex
- Text
- IconButton
- Button
- Stack
- Collapse
- Icon
- Link
- Popover
- useColorModeValue
- …more
Code Example
import { Box, Flex, Text, IconButton, Button, Stack, Collapse, Icon, Link, Popover, PopoverTrigger, PopoverContent, useColorModeValue, useBreakpointValue, useDisclosure, } from '@chakra-ui/react'; import { HamburgerIcon, CloseIcon, ChevronDownIcon, ChevronRightIcon, } from '@chakra-ui/icons'; export default function WithSubnavigation() { const { isOpen, onToggle } = useDisclosure(); return ( <Box> <Flex bg={useColorModeValue('white', 'gray.800')} color={useColorModeValue('gray.600', 'white')} minH={'60px'} py={{ base: 2 }} px={{ base: 4 }} borderBottom={1} borderStyle={'solid'} borderColor={useColorModeValue('gray.200', 'gray.900')} align={'center'}> <Flex flex={{ base: 1, md: 'auto' }} ml={{ base: -2 }} display={{ base: 'flex', md: 'none' }}> <IconButton onClick={onToggle} icon={ isOpen ? <CloseIcon w={3} h={3} /> : <HamburgerIcon w={5} h={5} /> } variant={'ghost'} aria-label={'Toggle Navigation'} /> </Flex> <Flex flex={{ base: 1 }} justify={{ base: 'center', md: 'start' }}> <Text textAlign={useBreakpointValue({ base: 'center', md: 'left' })} fontFamily={'heading'} color={useColorModeValue('gray.800', 'white')}> Logo </Text> <Flex display={{ base: 'none', md: 'flex' }} ml={10}> <DesktopNav /> </Flex> </Flex> <Stack flex={{ base: 1, md: 0 }} justify={'flex-end'} direction={'row'} spacing={6}> <Button as={'a'} fontSize={'sm'} fontWeight={400} variant={'link'} href={'#'}> Sign In </Button> <Button display={{ base: 'none', md: 'inline-flex' }} fontSize={'sm'} fontWeight={600} color={'white'} bg={'pink.400'} href={'#'} _hover={{ bg: 'pink.300', }}> Sign Up </Button> </Stack> </Flex> <Collapse in={isOpen} animateOpacity> <MobileNav /> </Collapse> </Box> ); } const DesktopNav = () => { const linkColor = useColorModeValue('gray.600', 'gray.200'); const linkHoverColor = useColorModeValue('gray.800', 'white'); const popoverContentBgColor = useColorModeValue('white', 'gray.800'); return ( <Stack direction={'row'} spacing={4}> {NAV_ITEMS.map((navItem) => ( <Box key={navItem.label}> <Popover trigger={'hover'} placement={'bottom-start'}> <PopoverTrigger> <Link p={2} href={navItem.href ?? '#'} fontSize={'sm'} fontWeight={500} color={linkColor} _hover={{ textDecoration: 'none', color: linkHoverColor, }}> {navItem.label} </Link> </PopoverTrigger> {navItem.children && ( <PopoverContent border={0} boxShadow={'xl'} bg={popoverContentBgColor} p={4} rounded={'xl'} minW={'sm'}> <Stack> {navItem.children.map((child) => ( <DesktopSubNav key={child.label} {...child} /> ))} </Stack> </PopoverContent> )} </Popover> </Box> ))} </Stack> ); }; const DesktopSubNav = ({ label, href, subLabel }: NavItem) => { return ( <Link href={href} role={'group'} display={'block'} p={2} rounded={'md'} _hover={{ bg: useColorModeValue('pink.50', 'gray.900') }}> <Stack direction={'row'} align={'center'}> <Box> <Text transition={'all .3s ease'} _groupHover={{ color: 'pink.400' }} fontWeight={500}> {label} </Text> <Text fontSize={'sm'}>{subLabel}</Text> </Box> <Flex transition={'all .3s ease'} transform={'translateX(-10px)'} opacity={0} _groupHover={{ opacity: '100%', transform: 'translateX(0)' }} justify={'flex-end'} align={'center'} flex={1}> <Icon color={'pink.400'} w={5} h={5} as={ChevronRightIcon} /> </Flex> </Stack> </Link> ); }; const MobileNav = () => { return ( <Stack bg={useColorModeValue('white', 'gray.800')} p={4} display={{ md: 'none' }}> {NAV_ITEMS.map((navItem) => ( <MobileNavItem key={navItem.label} {...navItem} /> ))} </Stack> ); }; const MobileNavItem = ({ label, children, href }: NavItem) => { const { isOpen, onToggle } = useDisclosure(); return ( <Stack spacing={4} onClick={children && onToggle}> <Flex py={2} as={Link} href={href ?? '#'} justify={'space-between'} align={'center'} _hover={{ textDecoration: 'none', }}> <Text fontWeight={600} color={useColorModeValue('gray.600', 'gray.200')}> {label} </Text> {children && ( <Icon as={ChevronDownIcon} transition={'all .25s ease-in-out'} transform={isOpen ? 'rotate(180deg)' : ''} w={6} h={6} /> )} </Flex> <Collapse in={isOpen} animateOpacity style={{ marginTop: '0!important' }}> <Stack mt={2} pl={4} borderLeft={1} borderStyle={'solid'} borderColor={useColorModeValue('gray.200', 'gray.700')} align={'start'}> {children && children.map((child) => ( <Link key={child.label} py={2} href={child.href}> {child.label} </Link> ))} </Stack> </Collapse> </Stack> ); }; interface NavItem { label: string; subLabel?: string; children?: Array<NavItem>; href?: string; } const NAV_ITEMS: Array<NavItem> = [ { label: 'Superheroes', children: [ { label: 'Explore Superheroes', subLabel: 'Summary of all superheroes', href: '#', }, { label: 'New Additions', subLabel: 'Training to be superhero', href: '#', }, ], }, { label: 'Weapons', children: [ { label: 'External Weapons', subLabel: 'Not due to mutation', href: '#', }, { label: 'Superpowers', subLabel: 'Powers due to mutation', href: '#', }, ], }, { label: 'Marvel', href: '#', }, { label: 'DC', href: '#', }, ];
The output will look like this –