@elementor/editor-app-bar 0.14.0 → 0.14.2
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/CHANGELOG.md +16 -0
- package/dist/index.d.mts +78 -196
- package/dist/index.d.ts +78 -196
- package/dist/index.js +774 -201
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +734 -162
- package/dist/index.mjs.map +1 -1
- package/package.json +9 -8
- package/src/components/__tests__/app-bar.test.tsx +23 -0
- package/src/components/actions/action.tsx +33 -0
- package/src/components/actions/actions-group.tsx +69 -0
- package/src/components/actions/link.tsx +33 -0
- package/src/components/actions/toggle-action.tsx +35 -0
- package/src/components/app-bar.tsx +42 -0
- package/src/components/locations/__tests__/locations-components.test.tsx +37 -0
- package/src/components/locations/__tests__/menus.test.tsx +158 -0
- package/src/components/locations/integrations-menu-location.tsx +44 -0
- package/src/components/locations/main-menu-location.tsx +57 -0
- package/src/components/locations/page-indication-location.tsx +8 -0
- package/src/components/locations/primary-action-location.tsx +8 -0
- package/src/components/locations/responsive-location.tsx +8 -0
- package/src/components/locations/tools-menu-location.tsx +28 -0
- package/src/components/locations/utilities-menu-location.tsx +35 -0
- package/src/components/ui/popover-menu-item.tsx +47 -0
- package/src/components/ui/popover-menu.tsx +26 -0
- package/src/components/ui/popover-sub-menu.tsx +29 -0
- package/src/components/ui/toolbar-logo.tsx +84 -0
- package/src/components/ui/toolbar-menu-item.tsx +45 -0
- package/src/components/ui/toolbar-menu-more.tsx +29 -0
- package/src/components/ui/toolbar-menu-toggle-item.tsx +34 -0
- package/src/components/ui/toolbar-menu.tsx +15 -0
- package/src/contexts/menu-context.tsx +24 -0
- package/src/extensions/documents-indicator/index.ts +1 -1
- package/src/extensions/documents-preview/index.ts +1 -1
- package/src/extensions/documents-save/components/primary-action-menu.tsx +1 -1
- package/src/extensions/documents-save/hooks/use-document-copy-and-share-props.ts +1 -1
- package/src/extensions/documents-save/hooks/use-document-save-draft-props.ts +1 -1
- package/src/extensions/documents-save/hooks/use-document-save-template-props.ts +1 -1
- package/src/extensions/documents-save/index.ts +1 -1
- package/src/extensions/documents-save/locations.ts +1 -1
- package/src/extensions/elements/index.ts +1 -1
- package/src/extensions/finder/index.ts +1 -1
- package/src/extensions/help/index.ts +1 -1
- package/src/extensions/history/index.ts +1 -1
- package/src/extensions/keyboard-shortcuts/hooks/use-action-props.ts +1 -2
- package/src/extensions/keyboard-shortcuts/index.ts +1 -1
- package/src/extensions/site-settings/hooks/use-action-props.ts +1 -2
- package/src/extensions/site-settings/index.ts +1 -1
- package/src/extensions/structure/hooks/use-action-props.ts +1 -2
- package/src/extensions/structure/index.ts +1 -1
- package/src/extensions/theme-builder/hooks/use-action-props.ts +1 -2
- package/src/extensions/theme-builder/index.ts +1 -1
- package/src/extensions/user-preferences/hooks/use-action-props.ts +1 -2
- package/src/extensions/user-preferences/index.ts +1 -1
- package/src/extensions/wordpress/index.ts +1 -1
- package/src/index.ts +14 -10
- package/src/init.ts +1 -1
- package/src/locations/__tests__/menus.test.tsx +212 -0
- package/src/locations/index.ts +27 -0
- package/src/locations/menus.tsx +172 -0
- package/src/types.ts +4 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { PropsWithChildren } from 'react';
|
|
3
|
+
import { bindMenu, bindTrigger, usePopupState } from '@elementor/ui';
|
|
4
|
+
import ToolbarMenuItem from './toolbar-menu-item';
|
|
5
|
+
import { __ } from '@wordpress/i18n';
|
|
6
|
+
import { DotsVerticalIcon } from '@elementor/icons';
|
|
7
|
+
import PopoverMenu from './popover-menu';
|
|
8
|
+
|
|
9
|
+
export type ToolbarMenuMoreProps = PropsWithChildren<{
|
|
10
|
+
id: string;
|
|
11
|
+
}>
|
|
12
|
+
|
|
13
|
+
export default function ToolbarMenuMore( { children, id }: ToolbarMenuMoreProps ) {
|
|
14
|
+
const popupState = usePopupState( {
|
|
15
|
+
variant: 'popover',
|
|
16
|
+
popupId: id,
|
|
17
|
+
} );
|
|
18
|
+
|
|
19
|
+
return (
|
|
20
|
+
<>
|
|
21
|
+
<ToolbarMenuItem { ...bindTrigger( popupState ) } title={ __( 'More', 'elementor' ) }>
|
|
22
|
+
<DotsVerticalIcon />
|
|
23
|
+
</ToolbarMenuItem>
|
|
24
|
+
<PopoverMenu onClick={ popupState.close } { ...bindMenu( popupState ) }>
|
|
25
|
+
{ children }
|
|
26
|
+
</PopoverMenu>
|
|
27
|
+
</>
|
|
28
|
+
);
|
|
29
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { Box, ToggleButton, ToggleButtonProps, Tooltip } from '@elementor/ui';
|
|
3
|
+
|
|
4
|
+
export type ToolbarMenuToggleItemProps = Omit<ToggleButtonProps, 'onChange'> & {
|
|
5
|
+
title?: string;
|
|
6
|
+
onClick?: () => void;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export default function ToolbarMenuToggleItem( { title, onClick, ...props }: ToolbarMenuToggleItemProps ) {
|
|
10
|
+
return (
|
|
11
|
+
<Tooltip title={ title }>
|
|
12
|
+
{ /* @see https://mui.com/material-ui/react-tooltip/#disabled-elements */ }
|
|
13
|
+
<Box component="span" aria-label={ undefined }>
|
|
14
|
+
<ToggleButton
|
|
15
|
+
{ ...props }
|
|
16
|
+
onChange={ onClick }
|
|
17
|
+
aria-label={ title }
|
|
18
|
+
size="small"
|
|
19
|
+
sx={ {
|
|
20
|
+
border: 0, // Temp fix until the style of the ToggleButton component will be decided.
|
|
21
|
+
'&.Mui-disabled': {
|
|
22
|
+
border: 0, // Temp fix until the style of the ToggleButton component will be decided.
|
|
23
|
+
},
|
|
24
|
+
'& svg': {
|
|
25
|
+
fontSize: '1.25rem',
|
|
26
|
+
height: '1em',
|
|
27
|
+
width: '1em',
|
|
28
|
+
},
|
|
29
|
+
} }
|
|
30
|
+
/>
|
|
31
|
+
</Box>
|
|
32
|
+
</Tooltip>
|
|
33
|
+
);
|
|
34
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { Stack, StackProps } from '@elementor/ui';
|
|
3
|
+
import { MenuContextProvider } from '../../contexts/menu-context';
|
|
4
|
+
|
|
5
|
+
export type ToolbarMenuProps = StackProps;
|
|
6
|
+
|
|
7
|
+
export default function ToolbarMenu( { children, ...props }: ToolbarMenuProps ) {
|
|
8
|
+
return (
|
|
9
|
+
<MenuContextProvider type={ 'toolbar' }>
|
|
10
|
+
<Stack sx={ { px: 1.5 } } spacing={ 1.5 } direction="row" alignItems="center" { ...props }>
|
|
11
|
+
{ children }
|
|
12
|
+
</Stack>
|
|
13
|
+
</MenuContextProvider>
|
|
14
|
+
);
|
|
15
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { createContext, PropsWithChildren, useContext } from 'react';
|
|
3
|
+
import { PopupState } from '@elementor/ui';
|
|
4
|
+
|
|
5
|
+
type MenuContextValue = {
|
|
6
|
+
type: 'toolbar' | 'popover';
|
|
7
|
+
popupState?: PopupState;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const MenuContext = createContext<MenuContextValue>( {
|
|
11
|
+
type: 'toolbar',
|
|
12
|
+
} );
|
|
13
|
+
|
|
14
|
+
export function MenuContextProvider( { type, popupState, children }: PropsWithChildren<MenuContextValue> ) {
|
|
15
|
+
return (
|
|
16
|
+
<MenuContext.Provider value={ { type, popupState } }>
|
|
17
|
+
{ children }
|
|
18
|
+
</MenuContext.Provider>
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function useMenuContext() {
|
|
23
|
+
return useContext( MenuContext );
|
|
24
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { Divider, styled } from '@elementor/ui';
|
|
3
|
-
import {
|
|
3
|
+
import { default as PopoverMenu, PopoverMenuProps } from '../../../components/ui/popover-menu';
|
|
4
4
|
import { documentOptionsMenu } from '../locations';
|
|
5
5
|
|
|
6
6
|
const { useMenuItems } = documentOptionsMenu;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { __ } from '@wordpress/i18n';
|
|
2
|
-
import { ActionProps } from '
|
|
2
|
+
import { ActionProps } from '../../../types';
|
|
3
3
|
import { LinkIcon } from '@elementor/icons';
|
|
4
4
|
import { __useActiveDocument as useActiveDocument, __useActiveDocumentActions as useActiveDocumentActions } from '@elementor/editor-documents';
|
|
5
5
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { __ } from '@wordpress/i18n';
|
|
2
|
-
import { ActionProps } from '
|
|
2
|
+
import { ActionProps } from '../../../types';
|
|
3
3
|
import { FileReportIcon } from '@elementor/icons';
|
|
4
4
|
import { __useActiveDocument as useActiveDocument, __useActiveDocumentActions as useActiveDocumentActions } from '@elementor/editor-documents';
|
|
5
5
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { __ } from '@wordpress/i18n';
|
|
2
|
-
import { ActionProps } from '
|
|
2
|
+
import { ActionProps } from '../../../types';
|
|
3
3
|
import { FolderIcon } from '@elementor/icons';
|
|
4
4
|
import { __useActiveDocumentActions as useActiveDocumentActions } from '@elementor/editor-documents';
|
|
5
5
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { injectIntoPrimaryAction } from '../../locations';
|
|
2
2
|
import useDocumentSaveDraftProps from './hooks/use-document-save-draft-props';
|
|
3
3
|
import useDocumentSaveTemplateProps from './hooks/use-document-save-template-props';
|
|
4
4
|
import useDocumentViewPageProps from './hooks/use-document-view-page-props';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { utilitiesMenu } from '../../locations';
|
|
2
2
|
import { __ } from '@wordpress/i18n';
|
|
3
3
|
import { HelpIcon } from '@elementor/icons';
|
|
4
4
|
import { ExtendedWindow } from '../../types';
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { __ } from '@wordpress/i18n';
|
|
2
|
-
import { ActionProps } from '@elementor/editor-app-bar-ui';
|
|
3
2
|
import { KeyboardIcon } from '@elementor/icons';
|
|
4
3
|
import { __privateRunCommand as runCommand } from '@elementor/editor-v1-adapters';
|
|
5
|
-
import { ExtendedWindow } from '../../../types';
|
|
4
|
+
import { ExtendedWindow, ActionProps } from '../../../types';
|
|
6
5
|
|
|
7
6
|
export default function useActionProps(): ActionProps {
|
|
8
7
|
return {
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { __ } from '@wordpress/i18n';
|
|
2
2
|
import { __privateRunCommand as runCommand, __privateUseRouteStatus as useRouteStatus } from '@elementor/editor-v1-adapters';
|
|
3
|
-
import { ToggleActionProps } from '@elementor/editor-app-bar-ui';
|
|
4
3
|
import { AdjustmentsHorizontalIcon } from '@elementor/icons';
|
|
5
|
-
import { ExtendedWindow } from '../../../types';
|
|
4
|
+
import { ExtendedWindow, ToggleActionProps } from '../../../types';
|
|
6
5
|
|
|
7
6
|
export default function useActionProps(): ToggleActionProps {
|
|
8
7
|
const { isActive, isBlocked } = useRouteStatus( 'panel/global', {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { injectIntoTop } from '@elementor/editor';
|
|
2
2
|
import PortalledPrimaryAction from './components/portalled-primary-action';
|
|
3
|
-
import {
|
|
3
|
+
import { toolsMenu } from '../../locations';
|
|
4
4
|
import useActionProps from './hooks/use-action-props';
|
|
5
5
|
|
|
6
6
|
export function init() {
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { __ } from '@wordpress/i18n';
|
|
2
2
|
import { __privateRunCommand as runCommand, __privateUseRouteStatus as useRouteStatus } from '@elementor/editor-v1-adapters';
|
|
3
3
|
import { StructureIcon } from '@elementor/icons';
|
|
4
|
-
import { ToggleActionProps } from '
|
|
5
|
-
import { ExtendedWindow } from '../../../types';
|
|
4
|
+
import { ExtendedWindow, ToggleActionProps } from '../../../types';
|
|
6
5
|
|
|
7
6
|
export default function useActionProps(): ToggleActionProps {
|
|
8
7
|
const { isActive, isBlocked } = useRouteStatus( 'navigator' );
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { __ } from '@wordpress/i18n';
|
|
2
2
|
import { ThemeBuilderIcon } from '@elementor/icons';
|
|
3
3
|
import { __privateRunCommand as runCommand } from '@elementor/editor-v1-adapters';
|
|
4
|
-
import { ActionProps } from '
|
|
5
|
-
import { ExtendedWindow } from '../../../types';
|
|
4
|
+
import { ExtendedWindow, ActionProps } from '../../../types';
|
|
6
5
|
|
|
7
6
|
export default function useActionProps(): ActionProps {
|
|
8
7
|
return {
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { __ } from '@wordpress/i18n';
|
|
2
|
-
import { ToggleActionProps } from '@elementor/editor-app-bar-ui';
|
|
3
2
|
import { ToggleRightIcon } from '@elementor/icons';
|
|
4
3
|
import { __privateOpenRoute as openRoute, __privateUseRouteStatus as useRouteStatus } from '@elementor/editor-v1-adapters';
|
|
5
|
-
import { ExtendedWindow } from '../../../types';
|
|
4
|
+
import { ExtendedWindow, ToggleActionProps } from '../../../types';
|
|
6
5
|
|
|
7
6
|
export default function useActionProps(): ToggleActionProps {
|
|
8
7
|
const { isActive, isBlocked } = useRouteStatus( 'panel/editor-preferences' );
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { mainMenu } from '../../locations';
|
|
2
2
|
import { __ } from '@wordpress/i18n';
|
|
3
3
|
import { WordpressIcon } from '@elementor/icons';
|
|
4
4
|
import { __useActiveDocument as useActiveDocument } from '@elementor/editor-documents';
|
package/src/index.ts
CHANGED
|
@@ -1,17 +1,21 @@
|
|
|
1
|
-
// Re-exporting the menus & locations from `@elementor/editor-app-bar-ui`
|
|
2
|
-
// to expose the API for other packages to use.
|
|
3
1
|
export {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
} from '
|
|
2
|
+
mainMenu,
|
|
3
|
+
toolsMenu,
|
|
4
|
+
utilitiesMenu,
|
|
5
|
+
integrationsMenu,
|
|
6
|
+
injectIntoPageIndication,
|
|
7
|
+
injectIntoResponsive,
|
|
8
|
+
injectIntoPrimaryAction,
|
|
9
|
+
} from './locations';
|
|
12
10
|
|
|
13
11
|
export { documentOptionsMenu } from './extensions/documents-save/locations';
|
|
14
12
|
|
|
13
|
+
export type {
|
|
14
|
+
ActionProps,
|
|
15
|
+
LinkProps,
|
|
16
|
+
ToggleActionProps,
|
|
17
|
+
} from './types';
|
|
18
|
+
|
|
15
19
|
import init from './init';
|
|
16
20
|
|
|
17
21
|
init();
|
package/src/init.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import AppBar from './components/app-bar';
|
|
2
2
|
import { injectIntoTop } from '@elementor/editor';
|
|
3
3
|
import redirectOldMenus from './sync/redirect-old-menus';
|
|
4
4
|
import { init as initExtensions } from './extensions';
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { createMenu } from '../menus';
|
|
3
|
+
import { fireEvent, render, screen } from '@testing-library/react';
|
|
4
|
+
import { createMockMenuAction, createMockMenuLink, createMockMenuToggleAction } from 'test-utils';
|
|
5
|
+
|
|
6
|
+
describe( 'Menus API', () => {
|
|
7
|
+
it( 'should create a menu with default group when not provided', () => {
|
|
8
|
+
// Act.
|
|
9
|
+
const menu = createMenu();
|
|
10
|
+
|
|
11
|
+
menu.registerAction( createMockMenuAction() );
|
|
12
|
+
|
|
13
|
+
renderMenu( menu );
|
|
14
|
+
|
|
15
|
+
// Assert.
|
|
16
|
+
expect( screen.getByRole( 'button' ) ).toBeInTheDocument();
|
|
17
|
+
} );
|
|
18
|
+
|
|
19
|
+
it( 'should create a menu with groups and append a default group', () => {
|
|
20
|
+
// Act.
|
|
21
|
+
const menu = createMenu( [ 'testGroup' ] );
|
|
22
|
+
|
|
23
|
+
menu.registerAction( {
|
|
24
|
+
...createMockMenuAction(),
|
|
25
|
+
id: 'test',
|
|
26
|
+
} );
|
|
27
|
+
|
|
28
|
+
menu.registerLink( {
|
|
29
|
+
...createMockMenuLink(),
|
|
30
|
+
id: 'test1',
|
|
31
|
+
group: 'testGroup',
|
|
32
|
+
} );
|
|
33
|
+
|
|
34
|
+
renderMenu( menu );
|
|
35
|
+
|
|
36
|
+
// Assert.
|
|
37
|
+
expect( screen.getByRole( 'button' ) ).toBeInTheDocument();
|
|
38
|
+
expect( screen.getByRole( 'link' ) ).toBeInTheDocument();
|
|
39
|
+
} );
|
|
40
|
+
|
|
41
|
+
it( 'should register an action', () => {
|
|
42
|
+
// Arrange.
|
|
43
|
+
const onClick = jest.fn();
|
|
44
|
+
|
|
45
|
+
// Act.
|
|
46
|
+
const menu = createMenu();
|
|
47
|
+
|
|
48
|
+
menu.registerAction( createMockMenuAction( { onClick } ) );
|
|
49
|
+
|
|
50
|
+
renderMenu( menu );
|
|
51
|
+
|
|
52
|
+
// Assert.
|
|
53
|
+
const action = screen.getByRole( 'button' );
|
|
54
|
+
|
|
55
|
+
expect( action ).toBeInTheDocument();
|
|
56
|
+
expect( action ).toHaveAttribute( 'aria-label', 'Test' );
|
|
57
|
+
|
|
58
|
+
// Act.
|
|
59
|
+
fireEvent.click( action );
|
|
60
|
+
|
|
61
|
+
// Assert.
|
|
62
|
+
expect( onClick ).toHaveBeenCalled();
|
|
63
|
+
} );
|
|
64
|
+
|
|
65
|
+
it( 'should register a toggle action', () => {
|
|
66
|
+
// Act.
|
|
67
|
+
const menu = createMenu();
|
|
68
|
+
|
|
69
|
+
menu.registerToggleAction( createMockMenuToggleAction() );
|
|
70
|
+
|
|
71
|
+
renderMenu( menu );
|
|
72
|
+
|
|
73
|
+
// Assert.
|
|
74
|
+
const toggleAction = screen.getByRole( 'button' );
|
|
75
|
+
|
|
76
|
+
expect( toggleAction ).toHaveAttribute( 'aria-pressed', 'false' );
|
|
77
|
+
expect( toggleAction ).toHaveValue( 'test-value' );
|
|
78
|
+
|
|
79
|
+
// Act.
|
|
80
|
+
fireEvent.click( toggleAction );
|
|
81
|
+
|
|
82
|
+
// Assert.
|
|
83
|
+
expect( toggleAction ).toHaveAttribute( 'aria-pressed', 'true' );
|
|
84
|
+
|
|
85
|
+
// Act.
|
|
86
|
+
fireEvent.click( toggleAction );
|
|
87
|
+
|
|
88
|
+
// Assert.
|
|
89
|
+
expect( toggleAction ).toHaveAttribute( 'aria-pressed', 'false' );
|
|
90
|
+
expect( toggleAction ).toBeDisabled();
|
|
91
|
+
} );
|
|
92
|
+
|
|
93
|
+
it( 'should register a link', () => {
|
|
94
|
+
// Act.
|
|
95
|
+
const menu = createMenu();
|
|
96
|
+
|
|
97
|
+
menu.registerLink( createMockMenuLink() );
|
|
98
|
+
|
|
99
|
+
renderMenu( menu );
|
|
100
|
+
|
|
101
|
+
// Assert.
|
|
102
|
+
const link = screen.getByRole( 'link' );
|
|
103
|
+
|
|
104
|
+
expect( link ).toBeInTheDocument();
|
|
105
|
+
expect( link ).toHaveAttribute( 'href', 'https://elementor.com' );
|
|
106
|
+
expect( link ).toHaveAttribute( 'target', '_blank' );
|
|
107
|
+
expect( link ).toHaveAttribute( 'aria-label', 'Test' );
|
|
108
|
+
} );
|
|
109
|
+
|
|
110
|
+
it( 'should not register an action when passing a non-existing group', () => {
|
|
111
|
+
// Act.
|
|
112
|
+
const menu = createMenu();
|
|
113
|
+
|
|
114
|
+
menu.registerLink( {
|
|
115
|
+
...createMockMenuLink(),
|
|
116
|
+
group: 'non-existing-group' as 'default', // Emulate a runtime error.
|
|
117
|
+
} );
|
|
118
|
+
|
|
119
|
+
renderMenu( menu );
|
|
120
|
+
|
|
121
|
+
// Assert.
|
|
122
|
+
expect( screen.queryByRole( 'link' ) ).not.toBeInTheDocument();
|
|
123
|
+
} );
|
|
124
|
+
|
|
125
|
+
it( 'should register an action tooltip', async () => {
|
|
126
|
+
// Arrange.
|
|
127
|
+
const menu = createMenu();
|
|
128
|
+
|
|
129
|
+
// Act.
|
|
130
|
+
menu.registerAction( createMockMenuAction() );
|
|
131
|
+
|
|
132
|
+
// Assert.
|
|
133
|
+
renderMenu( menu );
|
|
134
|
+
|
|
135
|
+
const button = screen.getByLabelText( 'Test' );
|
|
136
|
+
|
|
137
|
+
expect( screen.queryByRole( 'tooltip' ) ).not.toBeInTheDocument();
|
|
138
|
+
|
|
139
|
+
// Act.
|
|
140
|
+
fireEvent.mouseOver(
|
|
141
|
+
button,
|
|
142
|
+
{ bubbles: true },
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
// Assert.
|
|
146
|
+
expect( await screen.findByRole( 'tooltip' ) ).toHaveTextContent( 'Test' );
|
|
147
|
+
} );
|
|
148
|
+
|
|
149
|
+
it( 'should register an action icon', () => {
|
|
150
|
+
// Arrange.
|
|
151
|
+
const menu = createMenu();
|
|
152
|
+
|
|
153
|
+
// Act.
|
|
154
|
+
menu.registerAction( createMockMenuAction() );
|
|
155
|
+
|
|
156
|
+
// Assert.
|
|
157
|
+
renderMenu( menu );
|
|
158
|
+
|
|
159
|
+
const icon = screen.queryByText( 'a' );
|
|
160
|
+
|
|
161
|
+
expect( icon ).toBeInTheDocument();
|
|
162
|
+
expect( icon ).toHaveTextContent( 'a' );
|
|
163
|
+
} );
|
|
164
|
+
|
|
165
|
+
it.each( [
|
|
166
|
+
{
|
|
167
|
+
type: 'action',
|
|
168
|
+
action: 'registerAction',
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
type: 'toggle action',
|
|
172
|
+
action: 'registerToggleAction',
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
type: 'link',
|
|
176
|
+
action: 'registerLink',
|
|
177
|
+
},
|
|
178
|
+
] as const )( 'should register a hidden $type', ( { type, action } ) => {
|
|
179
|
+
// Arrange.
|
|
180
|
+
const menu = createMenu();
|
|
181
|
+
|
|
182
|
+
// Act.
|
|
183
|
+
menu[ action ]( {
|
|
184
|
+
id: 'hidden',
|
|
185
|
+
useProps: () => ( {
|
|
186
|
+
title: `hidden-${ type }`,
|
|
187
|
+
icon: () => <div />,
|
|
188
|
+
visible: false,
|
|
189
|
+
} ),
|
|
190
|
+
} );
|
|
191
|
+
|
|
192
|
+
// Assert.
|
|
193
|
+
renderMenu( menu );
|
|
194
|
+
|
|
195
|
+
expect( screen.queryByLabelText( `hidden-${ type }` ) ).not.toBeInTheDocument();
|
|
196
|
+
} );
|
|
197
|
+
} );
|
|
198
|
+
|
|
199
|
+
function renderMenu<TGroup extends string>( menu: ReturnType<typeof createMenu<TGroup>> ) {
|
|
200
|
+
const MenuComponent = () => {
|
|
201
|
+
const groupedItems = menu.useMenuItems();
|
|
202
|
+
const allItems = Object.values( groupedItems ).flat();
|
|
203
|
+
|
|
204
|
+
return (
|
|
205
|
+
<div>
|
|
206
|
+
{ allItems.map( ( { MenuItem, id } ) => <MenuItem key={ id } /> ) }
|
|
207
|
+
</div>
|
|
208
|
+
);
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
return render( <MenuComponent /> );
|
|
212
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { createMenu } from './menus';
|
|
2
|
+
import { createLocation } from '@elementor/locations';
|
|
3
|
+
|
|
4
|
+
export { createMenu } from './menus';
|
|
5
|
+
|
|
6
|
+
export const {
|
|
7
|
+
inject: injectIntoPageIndication,
|
|
8
|
+
Slot: PageIndicationSlot,
|
|
9
|
+
} = createLocation();
|
|
10
|
+
|
|
11
|
+
export const {
|
|
12
|
+
inject: injectIntoResponsive,
|
|
13
|
+
Slot: ResponsiveSlot,
|
|
14
|
+
} = createLocation();
|
|
15
|
+
|
|
16
|
+
export const {
|
|
17
|
+
inject: injectIntoPrimaryAction,
|
|
18
|
+
Slot: PrimaryActionSlot,
|
|
19
|
+
} = createLocation();
|
|
20
|
+
|
|
21
|
+
export const mainMenu = createMenu( [ 'exits' ] );
|
|
22
|
+
|
|
23
|
+
export const toolsMenu = createMenu();
|
|
24
|
+
|
|
25
|
+
export const utilitiesMenu = createMenu();
|
|
26
|
+
|
|
27
|
+
export const integrationsMenu = createMenu();
|