121 lines
3.0 KiB
JavaScript
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>
|
|
</>
|
|
)
|
|
} |