88 lines
2.5 KiB
TypeScript
88 lines
2.5 KiB
TypeScript
import { View, Text } from '@tarojs/components'
|
|
import { useCallback, useEffect, useMemo, useRef, useState, memo } from 'react'
|
|
import styles from './index.module.scss'
|
|
import classnames from 'classnames'
|
|
import Iconfont, { IconNames } from '../iconfont/iconfont'
|
|
import Popup from '../popup'
|
|
import FilterButton from '../filterButton'
|
|
// 弹窗选择向上弹窗还是向下弹窗
|
|
type Direction = 'up' | 'down'
|
|
// 配置 菜单可选项
|
|
export type DropDownOptions = {
|
|
text: string
|
|
value: number
|
|
}
|
|
|
|
interface DropDownEvent {
|
|
change?: (value: DropDownOptions['value']) => void // value 变化时触发
|
|
}
|
|
|
|
interface PropsType extends DropDownEvent{
|
|
direction?: Direction
|
|
title: string // 已选中的菜单标题
|
|
options?: DropDownOptions[]
|
|
value?: number | string // 当前选中的值
|
|
children?: React.ReactNode
|
|
activeColor?: string
|
|
}
|
|
|
|
export default (props: PropsType) => {
|
|
const { children, direction = 'down', title, value, options, change, activeColor } = props
|
|
|
|
const [showPopup, setShowPopup] = useState(false)
|
|
|
|
const handleClickOption = (value: DropDownOptions['value']) => {
|
|
|
|
change?.(value)
|
|
}
|
|
|
|
const defaultOptions = useMemo(() => {
|
|
const currentValue = value
|
|
return options?.map(({text, value})=>{
|
|
return (
|
|
<FilterButton isActive={currentValue === value} onClick={() => handleClickOption(value)}>
|
|
{text}
|
|
</FilterButton>
|
|
)
|
|
|
|
})
|
|
}, [value])
|
|
|
|
const getIconName = () => {
|
|
if(direction === 'up'){
|
|
return showPopup ? 'icon-zhankai1' : 'icon-shouqi1'
|
|
}
|
|
// down
|
|
return showPopup ? 'icon-shouqi1' : 'icon-zhankai1'
|
|
}
|
|
|
|
const handleClickTitle = () => {
|
|
setShowPopup(true)
|
|
}
|
|
|
|
const handleClosePopup = () => {
|
|
setShowPopup(false)
|
|
}
|
|
|
|
return (
|
|
<View className={styles.dropDownItem}>
|
|
<View className={styles['dropDownItem--title']} onClick={handleClickTitle}>
|
|
<Text className={styles['dropDownItem--title--text']} style={{ color: activeColor }}>
|
|
{title}
|
|
</Text>
|
|
<Iconfont name={getIconName()} size={20} color={value !== options![0].value ? activeColor : '#333'}></Iconfont>
|
|
</View>
|
|
<Popup
|
|
onClose={handleClosePopup}
|
|
show={showPopup}
|
|
showTitle={false}
|
|
safeAreaInsetBottom={false}
|
|
customStyle={{ position: 'absolute', top: 'unset' }}
|
|
overlayStyle={{ position: 'absolute', top: 'unset' }}
|
|
position={direction === 'down' ? 'top' : 'bottom'}>
|
|
{children ? children : defaultOptions}
|
|
</Popup>
|
|
</View>
|
|
)
|
|
}
|