@@ -88,6 +88,7 @@ interface DrawerContextValue {
8888 onOpenChange : ( open : boolean ) => void ;
8989 headerVisible : boolean ;
9090 overlayVisible : boolean ;
91+ wasFirstOpen : boolean ;
9192}
9293
9394const [ DrawerProvider , useDrawer ] = createContext < DrawerContextValue | null > ( 'Drawer' , null ) ;
@@ -127,6 +128,13 @@ const Root = React.forwardRef<HTMLDivElement, RootProps>(
127128 [ setOpen , onOpenChange ] ,
128129 ) ;
129130
131+ // Used to skip the animation on component mount when the drawer is closed but the header is visible.
132+ const [ wasFirstOpen , setWasFirstOpen ] = React . useState ( false ) ;
133+
134+ React . useEffect ( ( ) => {
135+ if ( open ) setWasFirstOpen ( true ) ;
136+ } , [ open ] ) ;
137+
130138 const dialogOpen = headerVisible ? true : open ?? false ;
131139 const isOpen = open ?? false ;
132140 const modal = ! ! ( isOpen && overlayVisible ) ;
@@ -138,6 +146,7 @@ const Root = React.forwardRef<HTMLDivElement, RootProps>(
138146 onOpenChange = { handleOpenChange }
139147 headerVisible = { headerVisible }
140148 overlayVisible = { overlayVisible }
149+ wasFirstOpen = { wasFirstOpen }
141150 >
142151 < Dialog . Root { ...props } open = { dialogOpen } onOpenChange = { handleOpenChange } modal = { modal } >
143152 { children }
@@ -564,7 +573,7 @@ const Body = React.forwardRef<BodyElement, BodyProps>(({ children, ...restProps
564573 if ( ! expandable ) return content ;
565574
566575 return (
567- < ExpandableSection $ open= { open } $ flex>
576+ < ExpandableSection open = { open } flex >
568577 { content }
569578 </ ExpandableSection >
570579 ) ;
@@ -620,30 +629,56 @@ const Footer = React.forwardRef<FooterElement, FooterProps>((props, forwardedRef
620629
621630 if ( ! expandable ) return content ;
622631
623- return (
624- < ExpandableSection $open = { open } $flex = { false } >
625- { content }
626- </ ExpandableSection >
627- ) ;
632+ return < ExpandableSection open = { open } > { content } </ ExpandableSection > ;
628633} ) ;
629634
630635const Foot = styled < FlexComponent < 'footer' > > ( Flex ) `
631636 border-top: solid 1px ${ ( props ) => props . theme . colors . neutral150 } ;
632637 flex-shrink: 0;
633638` ;
634639
635- const ExpandableSection = styled . div < { $open : boolean ; $flex ?: boolean } > `
640+ const ExpandableSection = ( {
641+ open,
642+ flex = false ,
643+ children,
644+ } : {
645+ open : boolean ;
646+ flex ?: boolean ;
647+ children : React . ReactNode ;
648+ } ) => {
649+ const drawer = useDrawer ( 'Drawer.ExpandableSection' ) ;
650+ const wasFirstOpen = drawer ?. wasFirstOpen ?? false ;
651+
652+ // Before the first opening, the animation should be skipped to prevent it from happening on component mount.
653+ const skipAnimation = ! wasFirstOpen && ! open ;
654+
655+ return (
656+ < ExpandableSectionImpl $open = { open } $flex = { flex } $skipAnimation = { skipAnimation } >
657+ { children }
658+ </ ExpandableSectionImpl >
659+ ) ;
660+ } ;
661+
662+ const ExpandableSectionImpl = styled . div < {
663+ $open : boolean ;
664+ $flex ?: boolean ;
665+ $skipAnimation ?: boolean ;
666+ } > `
636667 overflow: hidden;
637668 display: flex;
638669 flex-direction: column;
639670 ${ ( props ) => ( props . $flex ? 'flex: 1; min-height: 0;' : 'flex-shrink: 0;' ) }
640671 max-height: ${ ( props ) => ( props . $open ? '100vh' : '0' ) } ;
672+ opacity: ${ ( props ) => ( props . $open ? 1 : 0 ) } ;
641673
642674 @media (prefers-reduced-motion: no-preference) {
643- animation: ${ ( { $open } ) => ( $open ? OPEN_DRAWER_ANIMATION : CLOSE_DRAWER_ANIMATION ) }
644- ${ ( { $open, theme } ) =>
645- $open ? theme . motion . timings [ CLOSING_ANIMATION_DURATION ] : theme . motion . timings [ OPENING_ANIMATION_DURATION ] }
646- ${ ( p ) => p . theme . motion . easings . authenticMotion } ;
675+ ${ ( { $skipAnimation, $open, theme } ) =>
676+ ! $skipAnimation &&
677+ css `
678+ animation : ${ $open ? OPEN_DRAWER_ANIMATION : CLOSE_DRAWER_ANIMATION }
679+ ${ $open ? theme . motion . timings [ OPENING_ANIMATION_DURATION ] : theme . motion . timings [ CLOSING_ANIMATION_DURATION ] }
680+ ${ theme . motion . easings . authenticMotion } ;
681+ ` }
647682 }
648683` ;
649684
0 commit comments