1
1
'use client' ;
2
- import React , { useEffect , useMemo } from 'react' ;
2
+ import React , { useCallback , useEffect , useMemo } from 'react' ;
3
3
import Collapse from './collapse' ;
4
4
import useCurrentState from '../utils/use-current-state' ;
5
5
import { setChildrenIndex } from '../utils/collections' ;
6
6
import { CollapseContext , CollapseConfig } from './collapse-context' ;
7
7
import useScale , { withScale } from '../use-scale' ;
8
8
import useClasses from '../use-classes' ;
9
+ import { isArray } from 'lodash' ;
9
10
10
11
interface Props {
11
12
multiple ?: boolean ;
12
13
className ?: string ;
13
- value ?: number [ ] ;
14
- onChange ?: ( openIndices : number [ ] ) => void ;
14
+ value ?: Array < number | string > ;
15
+ onChange ?: ( openIndices : Array < number | string > ) => void ;
15
16
}
16
17
17
18
type NativeAttrs = Omit < React . HTMLAttributes < HTMLDivElement > , keyof Props > ;
@@ -27,8 +28,9 @@ const CollapseGroupComponent: React.FC<React.PropsWithChildren<CollapseGroupProp
27
28
} : React . PropsWithChildren < CollapseGroupProps > ) => {
28
29
const { SCALE , UNIT , CLASS_NAMES } = useScale ( ) ;
29
30
30
- const [ state , setState , stateRef ] = useCurrentState < Array < number > > ( value ) ;
31
+ const [ state , setState , stateRef ] = useCurrentState < Array < number | string > > ( value ) ;
31
32
const classes = useClasses ( 'collapse-group' , className , CLASS_NAMES ) ;
33
+ const hasIndexChildren = useMemo ( ( ) => setChildrenIndex ( children , [ Collapse ] ) , [ children ] ) ;
32
34
33
35
useEffect ( ( ) => {
34
36
setState ( value ) ;
@@ -37,32 +39,41 @@ const CollapseGroupComponent: React.FC<React.PropsWithChildren<CollapseGroupProp
37
39
useEffect ( ( ) => {
38
40
if ( onChange ) {
39
41
const openIndices = stateRef . current . filter ( index => {
40
- if ( ! Array . isArray ( hasIndexChildren ) ) {
41
- return true ;
42
- }
43
- const isDisabled = hasIndexChildren . find ( ( child : React . ReactElement ) => child . props . index === index ) ?. props . disabled ;
44
- return ! isDisabled ;
42
+ if ( ! Array . isArray ( hasIndexChildren ) ) return true ;
43
+ const child = hasIndexChildren . find ( ( child : React . ReactElement ) => child . props . index === index ) ;
44
+ return child && ! child . props . disabled ;
45
45
} ) ;
46
46
onChange ( openIndices ) ;
47
47
}
48
- } , [ state ] ) ;
48
+ } , [ state , hasIndexChildren ] ) ;
49
49
50
- const updateValues = ( currentIndex : number , nextState : boolean ) => {
51
- if ( ! multiple ) {
52
- if ( nextState ) {
53
- setState ( [ currentIndex ] ) ;
50
+ const updateValues = useCallback (
51
+ ( currentIndex : number | string , nextState : boolean ) => {
52
+ if ( ! multiple ) {
53
+ if ( nextState ) {
54
+ const isDisabled =
55
+ isArray ( hasIndexChildren ) && hasIndexChildren . find ( ( child : React . ReactElement ) => child . props . index === currentIndex ) ?. props . disabled ;
56
+ if ( ! isDisabled ) {
57
+ setState ( [ currentIndex ] ) ;
58
+ } else {
59
+ setState ( [ ] ) ;
60
+ }
61
+ } else {
62
+ setState ( [ ] ) ;
63
+ }
54
64
} else {
55
- setState ( [ ] ) ;
56
- }
57
- } else {
58
- const currentIndexExists = stateRef . current . includes ( currentIndex ) ;
59
- if ( nextState && ! currentIndexExists ) {
60
- setState ( [ ... stateRef . current , currentIndex ] ) ;
61
- } else if ( ! nextState && currentIndexExists ) {
62
- setState ( stateRef . current . filter ( item => item !== currentIndex ) ) ;
65
+ const currentIndexExists = stateRef . current . includes ( currentIndex ) ;
66
+ const isDisabled =
67
+ isArray ( hasIndexChildren ) && hasIndexChildren . find ( ( child : React . ReactElement ) => child . props . index === currentIndex ) ?. props . disabled ;
68
+ if ( nextState && ! currentIndexExists && ! isDisabled ) {
69
+ setState ( [ ... stateRef . current , currentIndex ] ) ;
70
+ } else if ( ! nextState && currentIndexExists ) {
71
+ setState ( stateRef . current . filter ( item => item !== currentIndex ) ) ;
72
+ }
63
73
}
64
- }
65
- } ;
74
+ } ,
75
+ [ hasIndexChildren , multiple ] ,
76
+ ) ;
66
77
67
78
const initialValue = useMemo < CollapseConfig > (
68
79
( ) => ( {
@@ -71,7 +82,6 @@ const CollapseGroupComponent: React.FC<React.PropsWithChildren<CollapseGroupProp
71
82
} ) ,
72
83
[ state . join ( ',' ) ] ,
73
84
) ;
74
- const hasIndexChildren = useMemo ( ( ) => setChildrenIndex ( children , [ Collapse ] ) , [ children ] ) ;
75
85
76
86
return (
77
87
< CollapseContext . Provider value = { initialValue } >
0 commit comments