@elementor/editor-app-bar 0.6.9 → 0.7.1

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.
@@ -3,24 +3,20 @@ import { usePopupState, bindMenu, bindTrigger, Stack, Divider } from '@elementor
3
3
  import { mainMenu } from '../../locations';
4
4
  import PopoverMenu from '../ui/popover-menu';
5
5
  import ToolbarLogo from '../ui/toolbar-logo';
6
+ import IntegrationsMenuLocation from './integrations-menu-location';
6
7
 
7
8
  const { useMenuItems } = mainMenu;
8
9
 
9
10
  export default function MainMenuLocation() {
10
11
  const menuItems = useMenuItems();
11
12
 
12
- const orderedGroups = [
13
- menuItems.default,
14
- menuItems.exits,
15
- ];
16
-
17
13
  const popupState = usePopupState( {
18
14
  variant: 'popover',
19
15
  popupId: 'elementor-v2-app-bar-main-menu',
20
16
  } );
21
17
 
22
18
  return (
23
- <Stack sx={ { paddingInlineStart: 4 } } direction="row" alignItems="center">
19
+ <Stack sx={ { paddingInlineStart: 3 } } direction="row" alignItems="center">
24
20
  <ToolbarLogo
25
21
  { ...bindTrigger( popupState ) }
26
22
  selected={ popupState.isOpen }
@@ -28,22 +24,14 @@ export default function MainMenuLocation() {
28
24
  <PopoverMenu
29
25
  onClick={ popupState.close }
30
26
  { ...bindMenu( popupState ) }
31
- PaperProps={ {
32
- sx: { mt: 4, marginInlineStart: -2 },
33
- } }
27
+ marginThreshold={ 8 }
34
28
  >
35
- {
36
- orderedGroups
37
- .filter( ( group ) => group.length )
38
- .map( ( group, index ) => {
39
- return [
40
- index > 0 ? <Divider key={ index } orientation="horizontal" /> : null,
41
- ...group.map(
42
- ( { MenuItem, id } ) => <MenuItem key={ id } />
43
- ),
44
- ];
45
- } )
46
- }
29
+ { menuItems.default.map( ( { MenuItem, id } ) => <MenuItem key={ id } /> ) }
30
+
31
+ <IntegrationsMenuLocation key="integrations-location" parentPopupState={ popupState } />
32
+
33
+ { menuItems.exits.length > 0 && <Divider /> }
34
+ { menuItems.exits.map( ( { MenuItem, id } ) => <MenuItem key={ id } /> ) }
47
35
  </PopoverMenu>
48
36
  </Stack>
49
37
  );
@@ -0,0 +1,29 @@
1
+ import * as React from 'react';
2
+ import PopoverMenu, { PopoverMenuProps } from './popover-menu';
3
+ import { useTheme } from '@elementor/ui';
4
+
5
+ export default function PopoverSubMenu( { children, ...props }: PopoverMenuProps ) {
6
+ const theme = useTheme();
7
+ const isRTL = theme.direction === 'rtl';
8
+
9
+ return (
10
+ <PopoverMenu
11
+ sx={ { pointerEvents: 'none' } }
12
+ PaperProps={ {
13
+ sx: {
14
+ // This is a workaround to support RTL in PopoverMenu, since it doesn't support it yet.
15
+ ...( isRTL
16
+ ? { marginInlineEnd: -2 }
17
+ : { marginInlineStart: 2 }
18
+ ),
19
+ pointerEvents: 'auto',
20
+ },
21
+ } }
22
+ anchorOrigin={ { vertical: 'center', horizontal: isRTL ? 'left' : 'right' } }
23
+ transformOrigin={ { vertical: 'center', horizontal: isRTL ? 'right' : 'left' } }
24
+ { ...props }
25
+ >
26
+ { children }
27
+ </PopoverMenu>
28
+ );
29
+ }
@@ -23,8 +23,8 @@ const ElementorLogo = ( props: SvgIconProps ) => {
23
23
  );
24
24
  };
25
25
 
26
- const StyledToggleButton = styled( ToggleButton )( () => ( {
27
- padding: 0,
26
+ const StyledToggleButton = styled( ToggleButton )( ( { theme } ) => ( {
27
+ paddingInline: theme.spacing( 1 ),
28
28
  '&.MuiToggleButton-root:hover': {
29
29
  backgroundColor: 'initial',
30
30
  },
@@ -1,7 +1,7 @@
1
1
  import * as React from 'react';
2
2
  import SettingsButton from '../settings-button';
3
3
  import { openRoute, useRouteStatus } from '@elementor/editor-v1-adapters';
4
- import { fireEvent, render } from '@testing-library/react';
4
+ import { fireEvent, render, screen } from '@testing-library/react';
5
5
 
6
6
  jest.mock( '@elementor/editor-v1-adapters', () => ( {
7
7
  openRoute: jest.fn(),
@@ -18,10 +18,10 @@ jest.mock( '@elementor/editor-documents', () => ( {
18
18
  describe( '@elementor/editor-app-bar - App bar document settings button', () => {
19
19
  it( 'should open the document settings panel on click', () => {
20
20
  // Arrange.
21
- const { getByRole } = render( <SettingsButton /> );
21
+ render( <SettingsButton /> );
22
22
 
23
23
  // Act.
24
- fireEvent.click( getByRole( 'button' ) );
24
+ fireEvent.click( screen.getByRole( 'button' ) );
25
25
 
26
26
  // Assert.
27
27
  expect( openRoute ).toHaveBeenCalledTimes( 1 );
@@ -33,12 +33,12 @@ describe( '@elementor/editor-app-bar - App bar document settings button', () =>
33
33
  jest.mocked( useRouteStatus ).mockReturnValue( { isActive: true, isBlocked: true } );
34
34
 
35
35
  // Act.
36
- const { getByRole } = render( <SettingsButton /> );
36
+ render( <SettingsButton /> );
37
37
 
38
38
  // Assert.
39
- const button = getByRole( 'button' );
39
+ const button = screen.getByRole( 'button' );
40
40
 
41
- expect( button ).toHaveAttribute( 'disabled' );
41
+ expect( button ).toBeDisabled();
42
42
  expect( button ).toHaveAttribute( 'aria-pressed', 'true' );
43
43
  expect( useRouteStatus ).toHaveBeenCalledTimes( 1 );
44
44
  expect( useRouteStatus ).toHaveBeenCalledWith( 'panel/page-settings' );
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import { render } from '@testing-library/react';
2
+ import { render, screen } from '@testing-library/react';
3
3
  import PrimaryActionMenu from '../primary-action-menu';
4
4
  import { documentOptionsMenu } from '../../../../locations';
5
5
 
@@ -29,10 +29,10 @@ describe( '@elementor/editor-app-bar - Primary action menu', () => {
29
29
  } );
30
30
 
31
31
  // Act.
32
- const { getAllByRole } = render( <PrimaryActionMenu open={ true } anchorEl={ document.body } /> );
32
+ render( <PrimaryActionMenu open={ true } anchorEl={ document.body } /> );
33
33
 
34
34
  // Assert.
35
- const menuItems = getAllByRole( 'menuitem' );
35
+ const menuItems = screen.getAllByRole( 'menuitem' );
36
36
 
37
37
  expect( menuItems ).toHaveLength( 2 );
38
38
  expect( menuItems[ 0 ] ).toHaveTextContent( 'First action' );
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import PrimaryAction from '../primary-action';
3
- import { fireEvent, render } from '@testing-library/react';
3
+ import { fireEvent, render, screen } from '@testing-library/react';
4
4
  import { createMockDocument } from 'test-utils';
5
5
  import { useActiveDocument, useActiveDocumentActions } from '@elementor/editor-documents';
6
6
 
@@ -40,10 +40,10 @@ describe( '@elementor/editor-app-bar - Top Bar Primary Action', () => {
40
40
  jest.mocked( useActiveDocument ).mockReturnValue( mockDocument );
41
41
 
42
42
  // Act.
43
- const { getAllByRole } = render( <PrimaryAction /> );
43
+ render( <PrimaryAction /> );
44
44
 
45
45
  // Assert.
46
- expect( getAllByRole( 'button' )[ 0 ] ).toHaveTextContent( 'Submit' );
46
+ expect( screen.getAllByRole( 'button' )[ 0 ] ).toHaveTextContent( 'Submit' );
47
47
  } );
48
48
 
49
49
  it( 'should have "Publish" text when the user can publish the document', () => {
@@ -57,10 +57,10 @@ describe( '@elementor/editor-app-bar - Top Bar Primary Action', () => {
57
57
  jest.mocked( useActiveDocument ).mockReturnValue( mockDocument );
58
58
 
59
59
  // Act.
60
- const { getAllByRole } = render( <PrimaryAction /> );
60
+ render( <PrimaryAction /> );
61
61
 
62
62
  // Assert.
63
- expect( getAllByRole( 'button' )[ 0 ] ).toHaveTextContent( 'Publish' );
63
+ expect( screen.getAllByRole( 'button' )[ 0 ] ).toHaveTextContent( 'Publish' );
64
64
  } );
65
65
 
66
66
  it( 'should disable main and the menu buttons when the document is a Kit', () => {
@@ -76,11 +76,11 @@ describe( '@elementor/editor-app-bar - Top Bar Primary Action', () => {
76
76
  jest.mocked( useActiveDocument ).mockReturnValue( mockDocument );
77
77
 
78
78
  // Act.
79
- const { getByText, getByLabelText } = render( <PrimaryAction /> );
79
+ render( <PrimaryAction /> );
80
80
 
81
81
  // Assert.
82
- const mainButton = getByText( 'Publish' );
83
- const menuButton = getByLabelText( 'Save Options' );
82
+ const mainButton = screen.getByText( 'Publish' );
83
+ const menuButton = screen.getByLabelText( 'Save Options' );
84
84
 
85
85
  expect( mainButton ).toBeDisabled();
86
86
  expect( menuButton ).toBeDisabled();
@@ -93,11 +93,11 @@ describe( '@elementor/editor-app-bar - Top Bar Primary Action', () => {
93
93
  jest.mocked( useActiveDocument ).mockReturnValue( mockDocument );
94
94
 
95
95
  // Act.
96
- const { getByText, getByLabelText } = render( <PrimaryAction /> );
96
+ render( <PrimaryAction /> );
97
97
 
98
98
  // Assert.
99
- const mainButton = getByText( 'Publish' );
100
- const menuButton = getByLabelText( 'Save Options' );
99
+ const mainButton = screen.getByText( 'Publish' );
100
+ const menuButton = screen.getByLabelText( 'Save Options' );
101
101
 
102
102
  expect( mainButton ).toBeDisabled();
103
103
  expect( menuButton ).toBeEnabled();
@@ -116,11 +116,11 @@ describe( '@elementor/editor-app-bar - Top Bar Primary Action', () => {
116
116
  jest.mocked( useActiveDocument ).mockReturnValue( mockDocument );
117
117
 
118
118
  // Act.
119
- const { getByText, getByLabelText } = render( <PrimaryAction /> );
119
+ render( <PrimaryAction /> );
120
120
 
121
121
  // Assert.
122
- const mainButton = getByText( 'Publish' );
123
- const menuButton = getByLabelText( 'Save Options' );
122
+ const mainButton = screen.getByText( 'Publish' );
123
+ const menuButton = screen.getByLabelText( 'Save Options' );
124
124
 
125
125
  expect( mainButton ).toBeEnabled();
126
126
  expect( menuButton ).toBeEnabled();
@@ -133,9 +133,9 @@ describe( '@elementor/editor-app-bar - Top Bar Primary Action', () => {
133
133
  jest.mocked( useActiveDocument ).mockReturnValue( mockDocument );
134
134
 
135
135
  // Act.
136
- const { getAllByRole } = render( <PrimaryAction /> );
136
+ render( <PrimaryAction /> );
137
137
 
138
- fireEvent.click( getAllByRole( 'button' )[ 0 ] );
138
+ fireEvent.click( screen.getAllByRole( 'button' )[ 0 ] );
139
139
 
140
140
  // Assert.
141
141
  expect( actionsMock.save ).toHaveBeenCalledTimes( 1 );
@@ -151,17 +151,17 @@ describe( '@elementor/editor-app-bar - Top Bar Primary Action', () => {
151
151
  jest.mocked( useActiveDocument ).mockReturnValue( mockDocument );
152
152
 
153
153
  // Act.
154
- const { getAllByRole } = render( <PrimaryAction /> );
154
+ render( <PrimaryAction /> );
155
155
 
156
- const button = getAllByRole( 'button' )[ 0 ];
157
- const loader = getAllByRole( 'progressbar' )[ 0 ];
156
+ const button = screen.getAllByRole( 'button' )[ 0 ];
157
+ const loader = screen.getAllByRole( 'progressbar' )[ 0 ];
158
158
 
159
159
  fireEvent.click( button );
160
160
 
161
161
  // Assert.
162
162
  expect( actionsMock.save ).not.toHaveBeenCalled();
163
163
  expect( loader ).toBeInTheDocument();
164
- expect( button.textContent ).toBe( '' );
164
+ expect( button ).toHaveTextContent( '' );
165
165
  } );
166
166
 
167
167
  it( 'should not show a loader when the button is disabled', () => {
@@ -177,12 +177,12 @@ describe( '@elementor/editor-app-bar - Top Bar Primary Action', () => {
177
177
  jest.mocked( useActiveDocument ).mockReturnValue( mockDocument );
178
178
 
179
179
  // Act.
180
- const { getAllByRole, queryByRole } = render( <PrimaryAction /> );
181
- const button = getAllByRole( 'button' )[ 0 ];
182
- const loader = queryByRole( 'progressbar' );
180
+ render( <PrimaryAction /> );
181
+ const button = screen.getAllByRole( 'button' )[ 0 ];
182
+ const loader = screen.queryByRole( 'progressbar' );
183
183
 
184
184
  // Assert.
185
185
  expect( loader ).not.toBeInTheDocument();
186
- expect( button.textContent ).not.toBe( '' );
186
+ expect( button ).not.toHaveTextContent( '' );
187
187
  } );
188
188
  } );
@@ -31,8 +31,9 @@ export default function PrimaryActionMenu( props: PopoverMenuProps ) {
31
31
  vertical: 'top',
32
32
  horizontal: 'right',
33
33
  } }
34
+ marginThreshold={ 8 }
34
35
  PaperProps={ {
35
- sx: { mt: 2, ml: 3 },
36
+ sx: { mt: 2 },
36
37
  } }
37
38
  >
38
39
  { saveActions.map( ( { MenuItem, id }, index ) => ( [
@@ -41,7 +41,7 @@ describe( '@elementor/editor-app-bar - Portalled primary action', () => {
41
41
  navigateTo( 'panel/global/menu' );
42
42
 
43
43
  // Assert.
44
- expect( screen.queryByRole( 'button' ) ).toBeInTheDocument();
44
+ expect( screen.getByRole( 'button' ) ).toBeInTheDocument();
45
45
  } );
46
46
 
47
47
  it( 'should not render the button when opening another panel', () => {
@@ -90,9 +90,9 @@ describe( '@elementor/editor-app-bar - Primary action', () => {
90
90
  } ) );
91
91
 
92
92
  // Act.
93
- const { getByRole } = render( <PrimaryAction /> );
93
+ render( <PrimaryAction /> );
94
94
 
95
- const loader = getByRole( 'progressbar' );
95
+ const loader = screen.getByRole( 'progressbar' );
96
96
 
97
97
  // Assert.
98
98
  expect( loader ).toBeInTheDocument();
package/src/index.ts CHANGED
@@ -3,6 +3,7 @@ export {
3
3
  toolsMenu,
4
4
  utilitiesMenu,
5
5
  documentOptionsMenu,
6
+ integrationsMenu,
6
7
  injectIntoPageIndication,
7
8
  injectIntoResponsive,
8
9
  injectIntoPrimaryAction,
@@ -1,6 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { createMenu } from '../menus';
3
- import { act, fireEvent, render } from '@testing-library/react';
3
+ import { fireEvent, render, screen } from '@testing-library/react';
4
4
  import { createMockMenuAction, createMockMenuLink, createMockMenuToggleAction } from 'test-utils';
5
5
 
6
6
  describe( '@elementor/editor-app-bar - Menus API', () => {
@@ -10,10 +10,10 @@ describe( '@elementor/editor-app-bar - Menus API', () => {
10
10
 
11
11
  menu.registerAction( createMockMenuAction() );
12
12
 
13
- const { getByRole } = renderMenu( menu );
13
+ renderMenu( menu );
14
14
 
15
15
  // Assert.
16
- expect( getByRole( 'button' ) ).toBeInTheDocument();
16
+ expect( screen.getByRole( 'button' ) ).toBeInTheDocument();
17
17
  } );
18
18
 
19
19
  it( 'should create a menu with groups and append a default group', () => {
@@ -31,11 +31,11 @@ describe( '@elementor/editor-app-bar - Menus API', () => {
31
31
  group: 'testGroup',
32
32
  } );
33
33
 
34
- const { getByRole } = renderMenu( menu );
34
+ renderMenu( menu );
35
35
 
36
36
  // Assert.
37
- expect( getByRole( 'button' ) ).toBeInTheDocument();
38
- expect( getByRole( 'link' ) ).toBeInTheDocument();
37
+ expect( screen.getByRole( 'button' ) ).toBeInTheDocument();
38
+ expect( screen.getByRole( 'link' ) ).toBeInTheDocument();
39
39
  } );
40
40
 
41
41
  it( 'should register an action', () => {
@@ -47,10 +47,10 @@ describe( '@elementor/editor-app-bar - Menus API', () => {
47
47
 
48
48
  menu.registerAction( createMockMenuAction( { onClick } ) );
49
49
 
50
- const { getByRole } = renderMenu( menu );
50
+ renderMenu( menu );
51
51
 
52
52
  // Assert.
53
- const action = getByRole( 'button' );
53
+ const action = screen.getByRole( 'button' );
54
54
 
55
55
  expect( action ).toBeInTheDocument();
56
56
  expect( action ).toHaveAttribute( 'aria-label', 'Test' );
@@ -68,13 +68,13 @@ describe( '@elementor/editor-app-bar - Menus API', () => {
68
68
 
69
69
  menu.registerToggleAction( createMockMenuToggleAction() );
70
70
 
71
- const { getByRole } = renderMenu( menu );
71
+ renderMenu( menu );
72
72
 
73
73
  // Assert.
74
- const toggleAction = getByRole( 'button' );
74
+ const toggleAction = screen.getByRole( 'button' );
75
75
 
76
76
  expect( toggleAction ).toHaveAttribute( 'aria-pressed', 'false' );
77
- expect( toggleAction ).toHaveAttribute( 'value', 'test-value' );
77
+ expect( toggleAction ).toHaveValue( 'test-value' );
78
78
 
79
79
  // Act.
80
80
  fireEvent.click( toggleAction );
@@ -87,7 +87,7 @@ describe( '@elementor/editor-app-bar - Menus API', () => {
87
87
 
88
88
  // Assert.
89
89
  expect( toggleAction ).toHaveAttribute( 'aria-pressed', 'false' );
90
- expect( toggleAction ).toHaveAttribute( 'disabled' );
90
+ expect( toggleAction ).toBeDisabled();
91
91
  } );
92
92
 
93
93
  it( 'should register a link', () => {
@@ -96,10 +96,10 @@ describe( '@elementor/editor-app-bar - Menus API', () => {
96
96
 
97
97
  menu.registerLink( createMockMenuLink() );
98
98
 
99
- const { getByRole } = renderMenu( menu );
99
+ renderMenu( menu );
100
100
 
101
101
  // Assert.
102
- const link = getByRole( 'link' );
102
+ const link = screen.getByRole( 'link' );
103
103
 
104
104
  expect( link ).toBeInTheDocument();
105
105
  expect( link ).toHaveAttribute( 'href', 'https://elementor.com' );
@@ -116,10 +116,10 @@ describe( '@elementor/editor-app-bar - Menus API', () => {
116
116
  group: 'non-existing-group' as 'default', // Emulate a runtime error.
117
117
  } );
118
118
 
119
- const { queryByRole } = renderMenu( menu );
119
+ renderMenu( menu );
120
120
 
121
121
  // Assert.
122
- expect( queryByRole( 'link' ) ).not.toBeInTheDocument();
122
+ expect( screen.queryByRole( 'link' ) ).not.toBeInTheDocument();
123
123
  } );
124
124
 
125
125
  it( 'should register an action tooltip', async () => {
@@ -130,22 +130,20 @@ describe( '@elementor/editor-app-bar - Menus API', () => {
130
130
  menu.registerAction( createMockMenuAction() );
131
131
 
132
132
  // Assert.
133
- const { getByLabelText, queryByRole, findByRole } = renderMenu( menu );
133
+ renderMenu( menu );
134
134
 
135
- const button = getByLabelText( 'Test' );
135
+ const button = screen.getByLabelText( 'Test' );
136
136
 
137
- expect( queryByRole( 'tooltip' ) ).not.toBeInTheDocument();
137
+ expect( screen.queryByRole( 'tooltip' ) ).not.toBeInTheDocument();
138
138
 
139
139
  // Act.
140
- act( () => {
141
- fireEvent(
142
- button,
143
- new MouseEvent( 'mouseover', { bubbles: true } ),
144
- );
145
- } );
140
+ fireEvent.mouseOver(
141
+ button,
142
+ { bubbles: true },
143
+ );
146
144
 
147
145
  // Assert.
148
- expect( await findByRole( 'tooltip' ) ).toHaveTextContent( 'Test' );
146
+ expect( await screen.findByRole( 'tooltip' ) ).toHaveTextContent( 'Test' );
149
147
  } );
150
148
 
151
149
  it( 'should register an action icon', () => {
@@ -156,9 +154,9 @@ describe( '@elementor/editor-app-bar - Menus API', () => {
156
154
  menu.registerAction( createMockMenuAction() );
157
155
 
158
156
  // Assert.
159
- const { queryByText } = renderMenu( menu );
157
+ renderMenu( menu );
160
158
 
161
- const icon = queryByText( 'a' );
159
+ const icon = screen.queryByText( 'a' );
162
160
 
163
161
  expect( icon ).toBeInTheDocument();
164
162
  expect( icon ).toHaveTextContent( 'a' );
@@ -192,9 +190,9 @@ describe( '@elementor/editor-app-bar - Menus API', () => {
192
190
  } );
193
191
 
194
192
  // Assert.
195
- const { queryByLabelText } = renderMenu( menu );
193
+ renderMenu( menu );
196
194
 
197
- expect( queryByLabelText( `hidden-${ type }` ) ).not.toBeInTheDocument();
195
+ expect( screen.queryByLabelText( `hidden-${ type }` ) ).not.toBeInTheDocument();
198
196
  } );
199
197
  } );
200
198
 
@@ -24,4 +24,6 @@ export const toolsMenu = createMenu();
24
24
 
25
25
  export const utilitiesMenu = createMenu();
26
26
 
27
+ export const integrationsMenu = createMenu();
28
+
27
29
  export const documentOptionsMenu = createMenu( [ 'save' ] );