@@ -42,6 +42,8 @@ export class AccordionCollapseEvent extends ComposedEvent {
4242 }
4343}
4444
45+ const CSS_TIMING_UNITS_RE = / (?< value > [ 0 - 9 . ] + ) (?< unit > [ a - z A - Z ] + ) / g;
46+
4547/**
4648 * Accordions toggle the visibility of sections of content.
4749 * They feature panels that consist of a section text label and a caret icon that collapses or expands to reveal more information.
@@ -214,6 +216,10 @@ export class PfeAccordion extends LitElement {
214216
215217 private logger = new Logger ( this ) ;
216218
219+ private styles = getComputedStyle ( this ) ;
220+
221+ private transitionDuration = this . getAnimationDuration ( ) ;
222+
217223 connectedCallback ( ) {
218224 super . connectedCallback ( ) ;
219225 this . addEventListener ( 'change' , this . _changeHandler as EventListener ) ;
@@ -286,6 +292,7 @@ export class PfeAccordion extends LitElement {
286292 }
287293
288294 panel . expanded = true ;
295+ panel . hidden = false ;
289296
290297 await panel . updateComplete ;
291298
@@ -318,29 +325,49 @@ export class PfeAccordion extends LitElement {
318325 const rect = panel . getBoundingClientRect ( ) ;
319326
320327 panel . expanded = false ;
328+ panel . hidden = true ;
321329
322330 this . _animate ( panel , rect . height , 0 ) ;
323331 }
324332
333+ private getAnimationDuration ( ) {
334+ if ( 'computedStyleMap' in this ) {
335+ // @ts -expect-error: https://caniuse.com/?search=computedStyleMap
336+ return this . computedStyleMap ( ) . get ( 'transition-duration' ) ?. to ( 'ms' ) . value ;
337+ } else {
338+ const { transitionDuration } = this . styles ;
339+ const groups = CSS_TIMING_UNITS_RE . exec ( transitionDuration ) ?. groups ;
340+ if ( ! groups ) {
341+ return null ;
342+ }
343+ const factor = groups . unit === 's' ? 1000 : 1 ;
344+ return parseFloat ( groups . value ) * factor ;
345+ }
346+ }
347+
325348 private async _animate ( panel : PfeAccordionPanel , start : number , end : number ) {
326349 if ( panel ) {
327350 const header = panel . previousElementSibling ;
328- if ( header ) {
329- header . classList . add ( 'animating' ) ;
351+
352+ const transitionDuration = this . getAnimationDuration ( ) ;
353+ if ( transitionDuration ) {
354+ this . transitionDuration = transitionDuration ;
330355 }
331356
357+ const duration = this . transitionDuration ;
358+
359+ header ?. classList . add ( 'animating' ) ;
332360 panel . classList . add ( 'animating' ) ;
333- panel . style . height = `${ start } px` ;
334361
335- // panel.animate({ height: [`${start}px`, `${end}px`] }).play();
362+ const animation = panel . animate ( { height : [ `${ start } px` , `${ end } px` ] } , { duration } ) ;
363+ animation . play ( ) ;
364+ await animation . finished ;
365+
366+ header ?. classList . remove ( 'animating' ) ;
367+ panel . classList . remove ( 'animating' ) ;
336368
337- // TODO: use Element#animate
338- requestAnimationFrame ( ( ) => {
339- requestAnimationFrame ( ( ) => {
340- panel . style . height = `${ end } px` ;
341- panel . addEventListener ( 'transitionend' , this . _transitionEndHandler , { once : true } ) ;
342- } ) ;
343- } ) ;
369+ panel . style . removeProperty ( 'height' ) ;
370+ panel . hidden = ! panel . expanded ;
344371 }
345372 }
346373
@@ -380,16 +407,6 @@ export class PfeAccordion extends LitElement {
380407 newHeader ?. focus ?.( ) ;
381408 }
382409
383- @bound private _transitionEndHandler ( evt : TransitionEvent ) {
384- const panel = evt . target as PfeAccordionPanel ;
385- const header = panel . previousElementSibling ;
386- if ( header ) {
387- header . classList . remove ( 'animating' ) ;
388- }
389- panel . style . removeProperty ( 'height' ) ;
390- panel . classList . remove ( 'animating' ) ;
391- }
392-
393410 private _allHeaders ( ) : PfeAccordionHeader [ ] {
394411 return Array . from ( this . children ) . filter ( PfeAccordion . isHeader ) ;
395412 }
@@ -532,6 +549,7 @@ export class PfeAccordion extends LitElement {
532549 if ( panel ) {
533550 header . setAttribute ( 'aria-controls' , panel . id ) ;
534551 panel . setAttribute ( 'aria-labelledby' , header . id ) ;
552+ panel . hidden = ! panel . expanded ;
535553 }
536554 } ) ;
537555
0 commit comments