@@ -12,7 +12,8 @@ import { ColorPalette, DragHandle, Emphasis, IconButton, IconButtonProps, Theme
12
12
import { Comp , GenericProps , HasTheme , isComponent } from '@lumx/react/utils/type' ;
13
13
import { getRootClassName , handleBasicClasses } from '@lumx/react/utils/className' ;
14
14
import { partitionMulti } from '@lumx/react/utils/partitionMulti' ;
15
- import { WINDOW } from '@lumx/react/constants' ;
15
+ import { useTransitionVisibility } from '@lumx/react/hooks/useTransitionVisibility' ;
16
+ import { EXPANSION_PANEL_TRANSITION_DURATION } from '@lumx/core/js/constants' ;
16
17
17
18
/**
18
19
* Defines the props of the component.
@@ -81,7 +82,6 @@ export const ExpansionPanel: Comp<ExpansionPanelProps, HTMLDivElement> = forward
81
82
...forwardedProps
82
83
} = props ;
83
84
84
- const [ isChildrenVisible , setIsChildrenVisible ] = useState ( isOpen ) ;
85
85
const children : ReactNode [ ] = Children . toArray ( anyChildren ) ;
86
86
87
87
// Partition children by types.
@@ -96,34 +96,16 @@ export const ExpansionPanel: Comp<ExpansionPanelProps, HTMLDivElement> = forward
96
96
) ;
97
97
98
98
const toggleOpen = ( event : React . MouseEvent ) => {
99
- const hasReducedMotionEnabled = WINDOW ?. matchMedia ?.( '(prefers-reduced-motion: reduce)' ) ?. matches ;
100
99
const shouldOpen = ! isOpen ;
101
100
102
101
if ( isFunction ( onOpen ) && shouldOpen ) {
103
102
onOpen ( event ) ;
104
- // On open, we immediately show children
105
- setIsChildrenVisible ( true ) ;
106
103
}
107
104
if ( isFunction ( onClose ) && ! shouldOpen ) {
108
105
onClose ( event ) ;
109
- /**
110
- * On close, we only show children immediately if reduced motion is enabled
111
- * When disabled, the children will be hidden via the `onTransitionEnd` prop.
112
- */
113
- if ( hasReducedMotionEnabled ) {
114
- setIsChildrenVisible ( false ) ;
115
- }
116
106
}
117
107
if ( isFunction ( onToggleOpen ) ) {
118
108
onToggleOpen ( shouldOpen , event ) ;
119
- /**
120
- * On toggle, we forward the show state if
121
- * * the toggle will open the expansion panel
122
- * * reduced motion is enabled. When disabled, the children will be hidden via the `onTransitionEnd` prop.
123
- * */
124
- if ( shouldOpen || hasReducedMotionEnabled ) {
125
- setIsChildrenVisible ( shouldOpen ) ;
126
- }
127
109
}
128
110
} ;
129
111
@@ -145,6 +127,9 @@ export const ExpansionPanel: Comp<ExpansionPanelProps, HTMLDivElement> = forward
145
127
146
128
const wrapperRef = useRef < HTMLDivElement > ( null ) ;
147
129
130
+ /** Hide the children at the end of the transition */
131
+ const isChildrenVisible = useTransitionVisibility ( wrapperRef , ! ! isOpen , EXPANSION_PANEL_TRANSITION_DURATION ) ;
132
+
148
133
// Switch max height on/off to activate the CSS transition (updates when children changes).
149
134
const [ maxHeight , setMaxHeight ] = useState ( '0' ) ;
150
135
useEffect ( ( ) => {
@@ -174,16 +159,7 @@ export const ExpansionPanel: Comp<ExpansionPanelProps, HTMLDivElement> = forward
174
159
</ header >
175
160
176
161
{ ( isOpen || isChildrenVisible ) && (
177
- < div
178
- className = { `${ CLASSNAME } __wrapper` }
179
- style = { { maxHeight } }
180
- // At the end of the closing transition, remove the children from the DOM
181
- onTransitionEnd = { ( ) => {
182
- if ( ! isOpen ) {
183
- setIsChildrenVisible ( false ) ;
184
- }
185
- } }
186
- >
162
+ < div className = { `${ CLASSNAME } __wrapper` } style = { { maxHeight } } >
187
163
< div className = { `${ CLASSNAME } __container` } ref = { wrapperRef } >
188
164
< div className = { `${ CLASSNAME } __content` } > { content } </ div >
189
165
0 commit comments