@@ -2,7 +2,7 @@ import { useI18n } from '@affine/i18n';
22import { ArrowLeftSmallIcon } from '@blocksuite/icons/rc' ;
33import { Slot } from '@radix-ui/react-slot' ;
44import clsx from 'clsx' ;
5- import { useCallback , useContext , useEffect , useRef , useState } from 'react' ;
5+ import { useCallback , useContext , useMemo , useState } from 'react' ;
66
77import { observeResize } from '../../../utils' ;
88import { Button } from '../../button' ;
@@ -33,9 +33,29 @@ export const MobileMenu = ({
3333 const [ sliderHeight , setSliderHeight ] = useState ( 0 ) ;
3434 const { setOpen : pSetOpen } = useContext ( MobileMenuContext ) ;
3535 const finalOpen = rootOptions ?. open ?? open ;
36- const sliderRef = useRef < HTMLDivElement > ( null ) ;
3736 const activeIndex = subMenus . length ;
3837
38+ // dynamic height for slider
39+ const onSliderRef = useMemo ( ( ) => {
40+ let unsub : ( ( ) => void ) | null = null ;
41+
42+ return ( sliderDiv : HTMLDivElement | null ) => {
43+ unsub ?.( ) ;
44+
45+ if ( ! sliderDiv || ! finalOpen ) return ;
46+
47+ const active = sliderDiv . querySelector (
48+ `.${ styles . menuContent } [data-index="${ activeIndex } "]`
49+ ) ;
50+ if ( ! active ) return ;
51+
52+ // for the situation that content is loaded asynchronously
53+ unsub = observeResize ( active , entry => {
54+ setSliderHeight ( entry . borderBoxSize [ 0 ] . blockSize ) ;
55+ } ) ;
56+ } ;
57+ } , [ activeIndex , finalOpen ] ) ;
58+
3959 const onOpenChange = useCallback (
4060 ( open : boolean ) => {
4161 if ( ! open ) {
@@ -57,31 +77,6 @@ export const MobileMenu = ({
5777 [ onOpenChange , open ]
5878 ) ;
5979
60- // dynamic height for slider
61- useEffect ( ( ) => {
62- if ( ! finalOpen ) return ;
63- let observer : ( ) => void ;
64- const t = setTimeout ( ( ) => {
65- const slider = sliderRef . current ;
66- if ( ! slider ) return ;
67-
68- const active = slider . querySelector (
69- `.${ styles . menuContent } [data-index="${ activeIndex } "]`
70- ) ;
71- if ( ! active ) return ;
72-
73- // for the situation that content is loaded asynchronously
74- observer = observeResize ( active , entry => {
75- setSliderHeight ( entry . borderBoxSize [ 0 ] . blockSize ) ;
76- } ) ;
77- } , 0 ) ;
78-
79- return ( ) => {
80- clearTimeout ( t ) ;
81- observer ?.( ) ;
82- } ;
83- } , [ activeIndex , finalOpen ] ) ;
84-
8580 const t = useI18n ( ) ;
8681
8782 /**
@@ -122,7 +117,7 @@ export const MobileMenu = ({
122117 } }
123118 >
124119 < div
125- ref = { sliderRef }
120+ ref = { onSliderRef }
126121 className = { styles . slider }
127122 style = { {
128123 transform : `translateX(-${ 100 * activeIndex } %)` ,
0 commit comments