cwfront/src/components/ChakraBottomNav.js

121 lines
3.0 KiB
JavaScript

import React from "react"
import { Text, Icon, Stack, useColorModeValue } from "@chakra-ui/react"
import { Placeholder } from "./Placeholder"
import { PropTypes } from 'prop-types'
import { useNavigate } from "react-router-dom"
const BottomNavContext = React.createContext([])
const BottomNavProvider = ({ children }) => {
const [active, setActive] = React.useState(0)
return (
<BottomNavContext.Provider value={{
active,
setActive,
}}>
{children}
</BottomNavContext.Provider>
)
}
export const ChakraBottomNavItem = ({ index, icon, text,
bgNormal = null, bgHover = null, bgActive = null, navPath = "", onClick = null, ...rest }) => {
const ctx = React.useContext(BottomNavContext)
const _normal = useColorModeValue('white', 'gray.700')
const _bgNormal = bgNormal || _normal
const _hover = useColorModeValue('blue.100', 'gray.100')
const _bgHover = bgHover || _hover
const _active = useColorModeValue('blue.300', 'gray.300')
const _bgActive = bgActive || _active
const [bg, setBg] = React.useState(_bgNormal)
const navigateTo = useNavigate()
const onClickThis = () => {
setBg(_bgActive)
ctx.setActive(index)
navPath && navigateTo(navPath)
onClick && onClick()
}
const onHover = () => {
setBg(_bgHover)
}
const onLeave = () => {
setBg(_bgNormal)
}
const actived = () => ctx.active === index
return (
<Stack
direction="column"
p="4"
bg={actived() ? _bgActive : bg}
fontFamily="monospace"
fontSize="18"
fontWeight="700"
color={actived() ? 'white' : 'black'}
flex="1"
cursor="pointer"
align="center"
justify="center"
onClick={onClickThis}
onMouseEnter={onHover}
onMouseLeave={onLeave}
{...rest}
>
<Icon as={icon} />
<Text
>
{text}
</Text>
</Stack>
)
}
ChakraBottomNavItem.propTypes = {
// index: PropTypes.string.isRequired,
}
const BottomNavImpl = ({ children, ...rest }) => {
const bg = useColorModeValue('white', 'gray.700')
return (
<Stack
w="full"
position="fixed"
bottom="0"
left="0"
direction="row"
justify="space-around"
align="center"
bg={bg}
borderTop="1px"
borderColor="gray.200"
boxShadow="lg"
{...rest}
>
{children}
</Stack>
)
}
export const ChakraBottomNav = (props) => {
return (
<>
{/* TODO: I didnt use `useDimensions` here, caz it would waste my time to adjust it. */}
<Placeholder h="20" display={props.display || 'relative'} />
<BottomNavProvider>
<BottomNavImpl {...props} />
</BottomNavProvider>
</>
)
}