1- import React , { useEffect , useMemo , useState } from 'react' ;
1+ import React , { useEffect , useMemo } from 'react' ;
22import classNames from 'classnames' ;
33import { get , isNumber , isString } from 'lodash-es' ;
44
55import useConfig from '../../hooks/useConfig' ;
66import useDomRefCallback from '../../hooks/useDomRefCallback' ;
77import useRipple from '../../hooks/useRipple' ;
8+ import { isAllSelected } from '../util/checkAll' ;
89import { getKeyMapping } from '../util/helper' ;
910
1011import type { StyledProps } from '../../common' ;
@@ -34,6 +35,9 @@ export interface SelectOptionProps
3435 optionLength ?: number ;
3536 isVirtual ?: boolean ;
3637 onRowMounted ?: ( rowData : { ref : HTMLElement ; data : SelectOption } ) => void ;
38+ isHovered ?: boolean ;
39+ currentOptions ?: SelectOption [ ] ;
40+ valueType ?: TdSelectProps [ 'valueType' ] ;
3741}
3842
3943const componentType = 'select' ;
@@ -57,29 +61,26 @@ const Option: React.FC<SelectOptionProps> = (props) => {
5761 style,
5862 className,
5963 isVirtual,
64+ isHovered,
65+ currentOptions,
66+ valueType,
6067 } = props ;
6168
6269 const label = propLabel || value ;
6370 const disabled = propDisabled || ( multiple && Array . isArray ( selectedValue ) && max && selectedValue . length >= max ) ;
64- const initCheckedStatus = ! ( Array . isArray ( selectedValue ) && selectedValue . length === props . optionLength ) ;
6571
6672 let selected : boolean ;
6773 let indeterminate : boolean ;
68- // 处理存在禁用项时,全选状态无法来回切换的问题
69- const [ allSelectableChecked , setAllSelectableChecked ] = useState ( initCheckedStatus ) ;
7074
7175 const titleContent = useMemo ( ( ) => {
72- // 外部设置 props,说明希望受控
7376 const controlledTitle = Reflect . has ( props , 'title' ) ;
7477 if ( controlledTitle ) return propTitle ;
7578 if ( typeof label === 'string' ) return label ;
7679 return null ;
77- // eslint-disable-next-line react-hooks/exhaustive-deps
78- } , [ propTitle , label ] ) ;
80+ } , [ propTitle , label , props ] ) ;
7981
8082 const { classPrefix } = useConfig ( ) ;
8183
82- // 使用斜八角动画
8384 const [ optionRef , setRefCurrent ] = useDomRefCallback ( ) ;
8485 useRipple ( optionRef ) ;
8586
@@ -106,7 +107,6 @@ const Option: React.FC<SelectOptionProps> = (props) => {
106107 if ( multiple && Array . isArray ( selectedValue ) ) {
107108 selected = selectedValue . some ( ( item ) => {
108109 if ( isNumber ( item ) || isString ( item ) ) {
109- // 如果非 object 类型
110110 return item === value ;
111111 }
112112 return get ( item , valueKey ) === value ;
@@ -121,9 +121,10 @@ const Option: React.FC<SelectOptionProps> = (props) => {
121121 if ( ! disabled && ! checkAll ) {
122122 onSelect ( value , { label : String ( label ) , selected, event, restData } ) ;
123123 }
124- if ( checkAll ) {
125- props . onCheckAllChange ?.( allSelectableChecked , event ) ;
126- setAllSelectableChecked ( ! allSelectableChecked ) ;
124+ if ( checkAll && currentOptions ) {
125+ // 使用工具函数计算当前是否全选
126+ const allSelected = isAllSelected ( currentOptions , selectedValue , keys , valueType ) ;
127+ props . onCheckAllChange ?.( ! allSelected , event ) ;
127128 }
128129 } ;
129130
@@ -161,7 +162,7 @@ const Option: React.FC<SelectOptionProps> = (props) => {
161162 < li
162163 className = { classNames ( className , `${ classPrefix } -${ componentType } -option` , {
163164 [ `${ classPrefix } -is-disabled` ] : disabled ,
164- [ `${ classPrefix } -is-selected` ] : selected ,
165+ [ `${ classPrefix } -is-selected` ] : selected && ! isHovered ,
165166 [ `${ classPrefix } -size-s` ] : size === 'small' ,
166167 [ `${ classPrefix } -size-l` ] : size === 'large' ,
167168 } ) }
0 commit comments