120 lines
3.5 KiB
TypeScript
120 lines
3.5 KiB
TypeScript
import { View } from '@tarojs/components'
|
|
import classnames from 'classnames'
|
|
import React, { SetStateAction, forwardRef, useCallback, useEffect, useImperativeHandle, useRef, useState } from 'react'
|
|
import IconFont from '../iconfont/iconfont'
|
|
import styles from './index.module.scss'
|
|
import { usePropsValue } from '@/use/useCommon'
|
|
|
|
type CheckboxSize = 'normal' | 'small'
|
|
|
|
interface params {
|
|
onSelect?: () => void // 选择触发
|
|
onClose?: () => void // 取消触发
|
|
status?: boolean // 是否选中
|
|
hiddenCheckboxIcon?: boolean // 隐藏多选框
|
|
disabled?: boolean // 是否禁用
|
|
triggerLabel?: boolean // 点击label是否触发选中
|
|
circle?: boolean
|
|
round?: boolean
|
|
size?: CheckboxSize
|
|
children?: React.ReactNode
|
|
customStyles?: React.CSSProperties
|
|
customClassName?: string
|
|
customTextClass?: string
|
|
}
|
|
export default forwardRef((props: params, ref) => {
|
|
const {
|
|
onSelect,
|
|
onClose,
|
|
status = false,
|
|
disabled = false,
|
|
circle = false,
|
|
round = true,
|
|
triggerLabel = true,
|
|
size = 'normal',
|
|
children,
|
|
customStyles = {},
|
|
customClassName = '',
|
|
customTextClass = '',
|
|
hiddenCheckboxIcon = false,
|
|
} = props
|
|
const [selected, setSelected] = usePropsValue({
|
|
value: status,
|
|
defaultValue: false,
|
|
})
|
|
// const selectedRef = useRef(status)
|
|
// if (status !== undefined){
|
|
// selectedRef.current = status
|
|
// }
|
|
// const [, setForceUpdate] = useState({})
|
|
// const setSelected = useCallback((v: SetStateAction<boolean>) => {
|
|
// const nextValue = typeof v === 'function' ? (v as (prevValue: boolean) => boolean)(selectedRef.current) : v
|
|
// console.log('对比',nextValue, selectedRef.current)
|
|
// if (nextValue === selectedRef.current) return
|
|
// selectedRef.current = nextValue
|
|
// console.log('强制刷新', nextValue, selectedRef.current)
|
|
// setForceUpdate({})
|
|
// }, [])
|
|
|
|
const onSelectEven = () => {
|
|
if (disabled) { return false }
|
|
const res = !selected
|
|
if (res) {
|
|
onSelect?.()
|
|
}
|
|
else {
|
|
onClose?.()
|
|
}
|
|
console.log('res', res)
|
|
setSelected(res)
|
|
}
|
|
|
|
const handleClickChildren = (event) => {
|
|
if (!triggerLabel) {
|
|
return event.stopPropagation()
|
|
}
|
|
}
|
|
|
|
const getMainClassName = () => {
|
|
const classObject = {
|
|
[styles['checkbox_main--selected']]: selected,
|
|
[styles[`checkbox_main--${size}`]]: size,
|
|
[styles['checkbox_main--round']]: round,
|
|
[styles['checkbox_main--circle']]: circle,
|
|
}
|
|
return classObject
|
|
}
|
|
|
|
const getClassName = () => {
|
|
const classObject = {
|
|
[styles.no_checkbox_item]: disabled,
|
|
[styles.checkbox_item_select]: selected,
|
|
}
|
|
return classObject
|
|
}
|
|
|
|
useImperativeHandle(ref, () => ({
|
|
onSelectEven,
|
|
}))
|
|
// useEffect(() => {
|
|
// setSelected(status)
|
|
// }, [status])
|
|
return (
|
|
<View className={classnames(customClassName, styles.checkbox)} style={customStyles} onClick={onSelectEven}>
|
|
{!hiddenCheckboxIcon && (
|
|
<View className={classnames(styles.checkbox_main, getMainClassName())}>
|
|
<View className={classnames(styles.checkbox_item, getClassName())}>
|
|
{selected && <IconFont name="icon-a-jizhumima" size={22} color="#fff"></IconFont>}
|
|
</View>
|
|
</View>
|
|
)}
|
|
|
|
{children && (
|
|
<View className={classnames(styles['checkbox--text'], customTextClass)} onClick={handleClickChildren}>
|
|
{children}
|
|
</View>
|
|
)}
|
|
</View>
|
|
)
|
|
})
|