@elementor/editor-global-classes 4.2.0-880 → 4.2.0-882

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elementor/editor-global-classes",
3
- "version": "4.2.0-880",
3
+ "version": "4.2.0-882",
4
4
  "private": false,
5
5
  "author": "Elementor Team",
6
6
  "homepage": "https://elementor.com/",
@@ -39,29 +39,29 @@
39
39
  "dev": "tsup --config=../../tsup.dev.ts"
40
40
  },
41
41
  "dependencies": {
42
- "@elementor/editor": "4.2.0-880",
43
- "@elementor/editor-current-user": "4.2.0-880",
44
- "@elementor/editor-documents": "4.2.0-880",
45
- "@elementor/editor-editing-panel": "4.2.0-880",
46
- "@elementor/editor-mcp": "4.2.0-880",
47
- "@elementor/editor-panels": "4.2.0-880",
48
- "@elementor/editor-props": "4.2.0-880",
49
- "@elementor/editor-variables": "4.2.0-880",
50
- "@elementor/editor-styles": "4.2.0-880",
51
- "@elementor/editor-canvas": "4.2.0-880",
52
- "@elementor/editor-styles-repository": "4.2.0-880",
53
- "@elementor/editor-ui": "4.2.0-880",
54
- "@elementor/editor-v1-adapters": "4.2.0-880",
55
- "@elementor/http-client": "4.2.0-880",
42
+ "@elementor/editor": "4.2.0-882",
43
+ "@elementor/editor-current-user": "4.2.0-882",
44
+ "@elementor/editor-documents": "4.2.0-882",
45
+ "@elementor/editor-editing-panel": "4.2.0-882",
46
+ "@elementor/editor-mcp": "4.2.0-882",
47
+ "@elementor/editor-panels": "4.2.0-882",
48
+ "@elementor/editor-props": "4.2.0-882",
49
+ "@elementor/editor-variables": "4.2.0-882",
50
+ "@elementor/editor-styles": "4.2.0-882",
51
+ "@elementor/editor-canvas": "4.2.0-882",
52
+ "@elementor/editor-styles-repository": "4.2.0-882",
53
+ "@elementor/editor-ui": "4.2.0-882",
54
+ "@elementor/editor-v1-adapters": "4.2.0-882",
55
+ "@elementor/http-client": "4.2.0-882",
56
56
  "@elementor/icons": "~1.75.1",
57
- "@elementor/query": "4.2.0-880",
58
- "@elementor/schema": "4.2.0-880",
59
- "@elementor/store": "4.2.0-880",
57
+ "@elementor/query": "4.2.0-882",
58
+ "@elementor/schema": "4.2.0-882",
59
+ "@elementor/store": "4.2.0-882",
60
60
  "@elementor/ui": "1.37.5",
61
- "@elementor/utils": "4.2.0-880",
61
+ "@elementor/utils": "4.2.0-882",
62
62
  "@tanstack/react-virtual": "^3.13.24",
63
63
  "@wordpress/i18n": "^5.13.0",
64
- "@elementor/events": "4.2.0-880"
64
+ "@elementor/events": "4.2.0-882"
65
65
  },
66
66
  "peerDependencies": {
67
67
  "react": "^18.3.1",
@@ -5,14 +5,12 @@ import {
5
5
  } from '@elementor/editor-documents';
6
6
  import { useUserStylesCapability } from '@elementor/editor-styles-repository';
7
7
  import { SaveChangesDialog, useDialog } from '@elementor/editor-ui';
8
- import { isExperimentActive } from '@elementor/editor-v1-adapters';
9
8
  import { IconButton, Tooltip } from '@elementor/ui';
10
9
  import { __ } from '@wordpress/i18n';
11
10
 
12
11
  import { globalClassesStylesProvider } from '../../global-classes-styles-provider';
13
12
  import { usePrefetchCssClassUsage } from '../../hooks/use-prefetch-css-class-usage';
14
13
  import { trackGlobalClasses } from '../../utils/tracking';
15
- import { usePanelActions } from './class-manager-panel';
16
14
  import { FlippedColorSwatchIcon } from './flipped-color-swatch-icon';
17
15
 
18
16
  const trackGlobalClassesButton = () => {
@@ -24,7 +22,6 @@ const trackGlobalClassesButton = () => {
24
22
 
25
23
  export const ClassManagerButton = () => {
26
24
  const document = useActiveDocument();
27
- const { open: openPanel } = usePanelActions();
28
25
  const { save: saveDocument } = useActiveDocumentActions();
29
26
  const { open: openSaveChangesDialog, close: closeSaveChangesDialog, isOpen: isSaveChangesDialogOpen } = useDialog();
30
27
  const { prefetchClassesUsage } = usePrefetchCssClassUsage();
@@ -38,15 +35,11 @@ export const ClassManagerButton = () => {
38
35
  }
39
36
 
40
37
  const toggleClassesManagerPanel = () => {
41
- if ( isExperimentActive( 'e_editor_design_system_panel' ) ) {
42
- window.dispatchEvent(
43
- new CustomEvent( 'elementor/toggle-design-system', {
44
- detail: { tab: 'classes' as const },
45
- } )
46
- );
47
- } else {
48
- openPanel();
49
- }
38
+ window.dispatchEvent(
39
+ new CustomEvent( 'elementor/toggle-design-system', {
40
+ detail: { tab: 'classes' as const },
41
+ } )
42
+ );
50
43
  };
51
44
 
52
45
  const handleOpenPanel = () => {
@@ -1,32 +1,12 @@
1
1
  import * as React from 'react';
2
- import { useCallback, useEffect, useMemo, useState } from 'react';
2
+ import { useCallback, useEffect, useState } from 'react';
3
3
  import { useSuppressedMessage } from '@elementor/editor-current-user';
4
- import { reloadCurrentDocument, setDocumentModifiedStatus } from '@elementor/editor-documents';
5
- import {
6
- __createPanel as createPanel,
7
- Panel,
8
- PanelBody,
9
- PanelFooter,
10
- PanelHeader,
11
- PanelHeaderTitle,
12
- } from '@elementor/editor-panels';
13
- import { ConfirmationDialog, SaveChangesDialog, ThemeProvider, useDialog } from '@elementor/editor-ui';
14
- import { changeEditMode } from '@elementor/editor-v1-adapters';
15
- import { XIcon } from '@elementor/icons';
4
+ import { setDocumentModifiedStatus } from '@elementor/editor-documents';
5
+ import { PanelFooter } from '@elementor/editor-panels';
6
+ import { ConfirmationDialog, SaveChangesDialog, useDialog } from '@elementor/editor-ui';
16
7
  import { useMutation } from '@elementor/query';
17
8
  import { __dispatch as dispatch } from '@elementor/store';
18
- import {
19
- Alert,
20
- Box,
21
- Button,
22
- Chip,
23
- DialogHeader,
24
- Divider,
25
- ErrorBoundary,
26
- IconButton,
27
- type IconButtonProps,
28
- Stack,
29
- } from '@elementor/ui';
9
+ import { Alert, Box, Button, Chip, DialogHeader, Divider, ErrorBoundary, Stack } from '@elementor/ui';
30
10
  import { __ } from '@wordpress/i18n';
31
11
 
32
12
  import { useClassesOrder } from '../../hooks/use-classes-order';
@@ -54,62 +34,22 @@ type StopSyncConfirmationDialogProps = {
54
34
  onConfirm: () => void;
55
35
  };
56
36
 
57
- const id = 'global-classes-manager';
58
-
59
37
  export type ClassManagerPanelEmbeddedProps = {
60
38
  onRequestClose: () => void | Promise< void >;
61
39
  onExposeCloseAttempt?: ( attemptClose: ( () => void ) | null ) => void;
62
40
  };
63
41
 
64
42
  export function ClassManagerPanelEmbedded( { onRequestClose, onExposeCloseAttempt }: ClassManagerPanelEmbeddedProps ) {
65
- return (
66
- <ClassManagerPanelRoot
67
- embedded
68
- onRequestClose={ onRequestClose }
69
- onExposeCloseAttempt={ onExposeCloseAttempt }
70
- />
71
- );
72
- }
73
-
74
- export function ClassManagerPanel() {
75
- return <ClassManagerPanelRoot />;
43
+ return <ClassManagerPanelContent onRequestClose={ onRequestClose } onExposeCloseAttempt={ onExposeCloseAttempt } />;
76
44
  }
77
45
 
78
- export const { panel, usePanelActions } = createPanel( {
79
- id,
80
- component: ClassManagerPanel,
81
- allowedEditModes: [ 'edit', id ],
82
- onOpen: () => {
83
- changeEditMode( id );
84
-
85
- blockPanelInteractions();
86
- },
87
- onClose: async () => {
88
- changeEditMode( 'edit' );
89
- await reloadCurrentDocument();
90
- unblockPanelInteractions();
91
- },
92
- isOpenPreviousElement: true,
93
- } );
94
-
95
- type ClassManagerPanelRootProps = {
96
- embedded?: boolean;
97
- onRequestClose?: () => void | Promise< void >;
46
+ type ClassManagerPanelContentProps = {
47
+ onRequestClose: () => void | Promise< void >;
98
48
  onExposeCloseAttempt?: ( attemptClose: ( () => void ) | null ) => void;
99
49
  };
100
50
 
101
- function ClassManagerPanelRoot( {
102
- embedded = false,
103
- onRequestClose,
104
- onExposeCloseAttempt,
105
- }: ClassManagerPanelRootProps = {} ) {
51
+ function ClassManagerPanelContent( { onRequestClose, onExposeCloseAttempt }: ClassManagerPanelContentProps ) {
106
52
  const isDirty = useDirtyState();
107
- const { close: closeStandalonePanel } = usePanelActions();
108
- const closePanel = useMemo(
109
- () => ( embedded ? onRequestClose ?? ( async () => {} ) : closeStandalonePanel ),
110
- [ embedded, onRequestClose, closeStandalonePanel ]
111
- );
112
-
113
53
  const { open: openSaveChangesDialog, close: closeSaveChangesDialog, isOpen: isSaveChangesDialogOpen } = useDialog();
114
54
  const [ stopSyncConfirmation, setStopSyncConfirmation ] = useState< string | null >( null );
115
55
  const [ startSyncConfirmation, setStartSyncConfirmation ] = useState< string | null >( null );
@@ -129,30 +69,26 @@ function ClassManagerPanelRoot( {
129
69
  return;
130
70
  }
131
71
 
132
- void closePanel();
133
- }, [ isDirty, openSaveChangesDialog, closePanel ] );
72
+ void onRequestClose();
73
+ }, [ isDirty, openSaveChangesDialog, onRequestClose ] );
134
74
 
135
75
  useEffect( () => {
136
- if ( ! embedded || ! onExposeCloseAttempt ) {
76
+ if ( ! onExposeCloseAttempt ) {
137
77
  return;
138
78
  }
139
79
 
140
80
  onExposeCloseAttempt( () => handleClosePanel() );
141
81
 
142
82
  return () => onExposeCloseAttempt( null );
143
- }, [ embedded, onExposeCloseAttempt, handleClosePanel ] );
83
+ }, [ onExposeCloseAttempt, handleClosePanel ] );
144
84
 
145
85
  useEffect( () => {
146
- if ( ! embedded ) {
147
- return;
148
- }
149
-
150
86
  blockPanelInteractions();
151
87
 
152
88
  return () => {
153
89
  unblockPanelInteractions();
154
90
  };
155
- }, [ embedded ] );
91
+ }, [] );
156
92
 
157
93
  const handleStopSync = useCallback( ( classId: string ) => {
158
94
  dispatch(
@@ -193,56 +129,70 @@ function ClassManagerPanelRoot( {
193
129
 
194
130
  usePreventUnload();
195
131
 
196
- const searchFiltersBlock = (
197
- <Box px={ 2 } pb={ 1 }>
198
- <Stack direction="row" alignItems="center" justifyContent="space-between" gap={ 0.5 } sx={ { pb: 0.5 } }>
199
- <Box sx={ embedded ? { flexGrow: 1, minWidth: 0 } : { flexGrow: 1 } }>
200
- <ClassManagerSearch />
201
- </Box>
202
- <CssClassFilter />
203
- { embedded && <TotalCssClassCounter /> }
204
- </Stack>
205
- <ActiveFilters />
206
- </Box>
207
- );
208
-
209
- const listArea = (
210
- <Box
211
- ref={ setScrollElement }
212
- px={ 2 }
213
- sx={ {
214
- flexGrow: 1,
215
- overflowY: 'auto',
216
- ...( embedded ? { minHeight: 0 } : {} ),
217
- } }
218
- >
219
- <GlobalClassesList
220
- disabled={ isPublishing }
221
- scrollElement={ scrollElement }
222
- onStopSyncRequest={ handleStopSyncRequest }
223
- onStartSyncRequest={ ( classId ) => setStartSyncConfirmation( classId ) }
224
- />
225
- </Box>
226
- );
227
-
228
- const saveFooter = (
229
- <PanelFooter>
230
- <Button
231
- fullWidth
232
- size="small"
233
- color="global"
234
- variant="contained"
235
- onClick={ publish }
236
- disabled={ ! isDirty }
237
- loading={ isPublishing }
238
- >
239
- { __( 'Save changes', 'elementor' ) }
240
- </Button>
241
- </PanelFooter>
242
- );
243
-
244
- const dialogs = (
132
+ return (
245
133
  <>
134
+ <ErrorBoundary fallback={ <ErrorBoundaryFallback /> }>
135
+ <SearchAndFilterProvider>
136
+ <Stack
137
+ direction="column"
138
+ sx={ {
139
+ height: '100%',
140
+ width: '100%',
141
+ flex: 1,
142
+ minHeight: 0,
143
+ overflow: 'hidden',
144
+ } }
145
+ >
146
+ <Box px={ 2 } pb={ 1 }>
147
+ <Stack
148
+ direction="row"
149
+ alignItems="center"
150
+ justifyContent="space-between"
151
+ gap={ 0.5 }
152
+ sx={ { pb: 0.5 } }
153
+ >
154
+ <Box sx={ { flexGrow: 1, minWidth: 0 } }>
155
+ <ClassManagerSearch />
156
+ </Box>
157
+ <CssClassFilter />
158
+ <TotalCssClassCounter />
159
+ </Stack>
160
+ <ActiveFilters />
161
+ </Box>
162
+ <Divider />
163
+ <Box
164
+ ref={ setScrollElement }
165
+ px={ 2 }
166
+ sx={ {
167
+ flexGrow: 1,
168
+ overflowY: 'auto',
169
+ minHeight: 0,
170
+ } }
171
+ >
172
+ <GlobalClassesList
173
+ disabled={ isPublishing }
174
+ scrollElement={ scrollElement }
175
+ onStopSyncRequest={ handleStopSyncRequest }
176
+ onStartSyncRequest={ ( classId ) => setStartSyncConfirmation( classId ) }
177
+ />
178
+ </Box>
179
+ <PanelFooter>
180
+ <Button
181
+ fullWidth
182
+ size="small"
183
+ color="global"
184
+ variant="contained"
185
+ onClick={ publish }
186
+ disabled={ ! isDirty }
187
+ loading={ isPublishing }
188
+ >
189
+ { __( 'Save changes', 'elementor' ) }
190
+ </Button>
191
+ </PanelFooter>
192
+ </Stack>
193
+ </SearchAndFilterProvider>
194
+ </ErrorBoundary>
195
+ <ClassManagerIntroduction />
246
196
  { startSyncConfirmation && (
247
197
  <StartSyncToV3Modal
248
198
  externalOpen
@@ -286,7 +236,7 @@ function ClassManagerPanelRoot( {
286
236
  action: async () => {
287
237
  await publish();
288
238
  closeSaveChangesDialog();
289
- void closePanel();
239
+ void onRequestClose();
290
240
  },
291
241
  },
292
242
  } }
@@ -295,88 +245,8 @@ function ClassManagerPanelRoot( {
295
245
  ) }
296
246
  </>
297
247
  );
298
-
299
- const classManagerLayout = embedded ? (
300
- <Stack
301
- direction="column"
302
- sx={ {
303
- height: '100%',
304
- width: '100%',
305
- flex: 1,
306
- minHeight: 0,
307
- overflow: 'hidden',
308
- } }
309
- >
310
- { searchFiltersBlock }
311
- <Divider />
312
- { listArea }
313
- { saveFooter }
314
- </Stack>
315
- ) : (
316
- <Panel>
317
- <PanelHeader>
318
- <Stack p={ 1 } pl={ 2 } width="100%" direction="row" alignItems="center">
319
- <Stack width="100%" direction="row" gap={ 1 }>
320
- <PanelHeaderTitle sx={ { display: 'flex', alignItems: 'center', gap: 0.5 } }>
321
- <FlippedColorSwatchIcon fontSize="inherit" />
322
- { __( 'Class Manager', 'elementor' ) }
323
- </PanelHeaderTitle>
324
- <TotalCssClassCounter />
325
- </Stack>
326
- <ClassPanelCloseButton
327
- disabled={ isPublishing }
328
- onClose={ () => {
329
- if ( isDirty ) {
330
- openSaveChangesDialog();
331
- return;
332
- }
333
-
334
- void closeStandalonePanel();
335
- } }
336
- />
337
- </Stack>
338
- </PanelHeader>
339
- <PanelBody
340
- sx={ {
341
- display: 'flex',
342
- flexDirection: 'column',
343
- height: '100%',
344
- } }
345
- >
346
- { searchFiltersBlock }
347
- <Divider />
348
- { listArea }
349
- </PanelBody>
350
- { saveFooter }
351
- </Panel>
352
- );
353
-
354
- const core = (
355
- <>
356
- <ErrorBoundary fallback={ <ErrorBoundaryFallback /> }>
357
- <SearchAndFilterProvider>{ classManagerLayout }</SearchAndFilterProvider>
358
- </ErrorBoundary>
359
- <ClassManagerIntroduction />
360
- { dialogs }
361
- </>
362
- );
363
-
364
- return embedded ? core : <ThemeProvider>{ core }</ThemeProvider>;
365
248
  }
366
249
 
367
- const ClassPanelCloseButton = ( { onClose, sx, ...props }: IconButtonProps & { onClose: () => void } ) => (
368
- <IconButton
369
- size="small"
370
- color="secondary"
371
- onClick={ onClose }
372
- aria-label="Close"
373
- sx={ { marginLeft: 'auto', ...sx } }
374
- { ...props }
375
- >
376
- <XIcon fontSize="small" />
377
- </IconButton>
378
- );
379
-
380
250
  const ErrorBoundaryFallback = () => (
381
251
  <Box role="alert" sx={ { minHeight: '100%', p: 2 } }>
382
252
  <Alert severity="error" sx={ { mb: 2, maxWidth: 400, textAlign: 'center' } }>
package/src/init.ts CHANGED
@@ -5,17 +5,12 @@ import {
5
5
  registerStyleProviderToColors,
6
6
  } from '@elementor/editor-editing-panel';
7
7
  import { getMCPByDomain } from '@elementor/editor-mcp';
8
- import { __registerPanel as registerPanel } from '@elementor/editor-panels';
9
8
  import { stylesRepository } from '@elementor/editor-styles-repository';
10
- import { isExperimentActive } from '@elementor/editor-v1-adapters';
11
9
  import { __registerSlice as registerSlice } from '@elementor/store';
12
10
 
13
11
  import { ClassManagerButton } from './components/class-manager/class-manager-button';
14
- import { panel } from './components/class-manager/class-manager-panel';
15
12
  import { ConvertLocalClassToGlobalClass } from './components/convert-local-class-to-global-class';
16
13
  import { GlobalStylesImportListener } from './components/global-styles-import-listener';
17
- import { OpenPanelFromEvent } from './components/open-panel-from-event';
18
- import { OpenPanelFromUrl } from './components/open-panel-from-url';
19
14
  import { PopulateStore } from './components/populate-store';
20
15
  import { GLOBAL_CLASSES_PROVIDER_KEY, globalClassesStylesProvider } from './global-classes-styles-provider';
21
16
  import { PrefetchCssClassUsage } from './hooks/use-prefetch-css-class-usage';
@@ -26,10 +21,6 @@ import { SyncWithDocumentSave } from './sync-with-document';
26
21
  export function init() {
27
22
  registerSlice( slice );
28
23
 
29
- if ( ! isExperimentActive( 'e_editor_design_system_panel' ) ) {
30
- registerPanel( panel );
31
- }
32
-
33
24
  stylesRepository.register( globalClassesStylesProvider );
34
25
 
35
26
  injectIntoLogic( {
@@ -52,18 +43,6 @@ export function init() {
52
43
  component: PrefetchCssClassUsage,
53
44
  } );
54
45
 
55
- if ( ! isExperimentActive( 'e_editor_design_system_panel' ) ) {
56
- injectIntoLogic( {
57
- id: 'global-classes-open-panel-from-url',
58
- component: OpenPanelFromUrl,
59
- } );
60
-
61
- injectIntoLogic( {
62
- id: 'global-classes-open-panel-from-event',
63
- component: OpenPanelFromEvent,
64
- } );
65
- }
66
-
67
46
  injectIntoCssClassConvert( {
68
47
  id: 'global-classes-convert-from-local-class',
69
48
  component: ConvertLocalClassToGlobalClass,
@@ -1,26 +1,19 @@
1
1
  import { useEffect } from 'react';
2
- import { __privateListenTo as listenTo, isExperimentActive, v1ReadyEvent } from '@elementor/editor-v1-adapters';
2
+ import { __privateListenTo as listenTo, v1ReadyEvent } from '@elementor/editor-v1-adapters';
3
3
 
4
- import { usePanelActions } from './components/class-manager/class-manager-panel';
5
4
  import { syncWithDocumentSave } from './sync-with-document-save';
6
5
 
7
6
  export function SyncWithDocumentSave() {
8
- const { open: openClassPanel } = usePanelActions();
9
-
10
7
  useEffect( () => {
11
8
  const unsubscribe = listenTo( v1ReadyEvent(), () => {
12
- const open = isExperimentActive( 'e_editor_design_system_panel' )
13
- ? () => {
14
- window.dispatchEvent( new CustomEvent( 'elementor/open-global-classes-manager' ) );
15
- }
16
- : openClassPanel;
9
+ const open = () => {
10
+ window.dispatchEvent( new CustomEvent( 'elementor/open-global-classes-manager' ) );
11
+ };
17
12
 
18
13
  syncWithDocumentSave( { open } );
19
14
  } );
20
15
 
21
16
  return unsubscribe;
22
-
23
- // eslint-disable-next-line react-hooks/exhaustive-deps -- bind once at v1 ready; openClassPanel from createPanel is stable
24
17
  }, [] );
25
18
 
26
19
  return null;
@@ -1,19 +0,0 @@
1
- import { useEffect } from 'react';
2
-
3
- import { usePanelActions } from './class-manager/class-manager-panel';
4
-
5
- const EVENT_OPEN_GLOBAL_CLASSES_MANAGER = 'elementor/open-global-classes-manager';
6
-
7
- export function OpenPanelFromEvent() {
8
- const { open } = usePanelActions();
9
-
10
- useEffect( () => {
11
- const handler = () => open();
12
-
13
- window.addEventListener( EVENT_OPEN_GLOBAL_CLASSES_MANAGER, handler );
14
-
15
- return () => window.removeEventListener( EVENT_OPEN_GLOBAL_CLASSES_MANAGER, handler );
16
- }, [ open ] );
17
-
18
- return null;
19
- }
@@ -1,40 +0,0 @@
1
- import { useEffect, useRef } from 'react';
2
- import { __privateListenTo as listenTo, routeOpenEvent } from '@elementor/editor-v1-adapters';
3
-
4
- import { usePanelActions } from './class-manager/class-manager-panel';
5
-
6
- const ACTIVE_PANEL_PARAM = 'active-panel';
7
- const PANEL_ID = 'global-classes-manager';
8
- const DEFAULT_PANEL_ROUTE = 'panel/elements';
9
-
10
- export function OpenPanelFromUrl() {
11
- const { open } = usePanelActions();
12
- const hasOpened = useRef( false );
13
-
14
- useEffect( () => {
15
- const urlParams = new URLSearchParams( window.location.search );
16
- const activePanel = urlParams.get( ACTIVE_PANEL_PARAM );
17
-
18
- if ( activePanel !== PANEL_ID ) {
19
- return;
20
- }
21
-
22
- // Listen for the default panel route to open - this signals Elementor initialization is complete
23
- const cleanup = listenTo( routeOpenEvent( DEFAULT_PANEL_ROUTE ), () => {
24
- if ( hasOpened.current ) {
25
- return;
26
- }
27
-
28
- hasOpened.current = true;
29
-
30
- // Open panel after default route is established
31
- requestAnimationFrame( () => {
32
- open();
33
- } );
34
- } );
35
-
36
- return cleanup;
37
- }, [ open ] );
38
-
39
- return null;
40
- }