@elementor/editor-app-bar 0.9.7 → 0.10.0

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.
Files changed (60) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/index.d.mts +9 -218
  3. package/dist/index.d.ts +9 -218
  4. package/dist/index.js +169 -641
  5. package/dist/index.js.map +1 -1
  6. package/dist/index.mjs +142 -619
  7. package/dist/index.mjs.map +1 -1
  8. package/package.json +4 -7
  9. package/src/extensions/documents-indicator/index.ts +1 -1
  10. package/src/extensions/documents-preview/index.ts +1 -1
  11. package/src/extensions/documents-save/components/__tests__/primary-action-menu.test.tsx +1 -1
  12. package/src/extensions/documents-save/components/primary-action-menu.tsx +2 -2
  13. package/src/extensions/documents-save/hooks/use-document-save-draft-props.ts +1 -1
  14. package/src/extensions/documents-save/hooks/use-document-save-template-props.ts +1 -1
  15. package/src/extensions/documents-save/index.ts +2 -1
  16. package/src/extensions/documents-save/locations.ts +3 -0
  17. package/src/extensions/elements/index.ts +1 -1
  18. package/src/extensions/finder/index.ts +1 -1
  19. package/src/extensions/help/index.ts +1 -1
  20. package/src/extensions/history/index.ts +1 -1
  21. package/src/extensions/keyboard-shortcuts/hooks/use-action-props.ts +1 -1
  22. package/src/extensions/keyboard-shortcuts/index.ts +1 -1
  23. package/src/extensions/site-settings/hooks/use-action-props.ts +1 -1
  24. package/src/extensions/site-settings/index.ts +1 -1
  25. package/src/extensions/structure/hooks/use-action-props.ts +1 -1
  26. package/src/extensions/structure/index.ts +1 -1
  27. package/src/extensions/theme-builder/hooks/use-action-props.ts +1 -1
  28. package/src/extensions/theme-builder/index.ts +1 -1
  29. package/src/extensions/user-preferences/hooks/use-action-props.ts +1 -1
  30. package/src/extensions/user-preferences/index.ts +1 -1
  31. package/src/extensions/wordpress/index.ts +1 -1
  32. package/src/index.ts +12 -9
  33. package/src/init.ts +1 -1
  34. package/src/components/__tests__/top-bar.test.tsx +0 -15
  35. package/src/components/actions/action.tsx +0 -33
  36. package/src/components/actions/link.tsx +0 -33
  37. package/src/components/actions/toggle-action.tsx +0 -35
  38. package/src/components/app-bar.tsx +0 -37
  39. package/src/components/locations/__tests__/locations-components.test.tsx +0 -37
  40. package/src/components/locations/__tests__/menus.test.tsx +0 -120
  41. package/src/components/locations/integrations-menu-location.tsx +0 -59
  42. package/src/components/locations/main-menu-location.tsx +0 -38
  43. package/src/components/locations/page-indication-location.tsx +0 -8
  44. package/src/components/locations/primary-action-location.tsx +0 -8
  45. package/src/components/locations/responsive-location.tsx +0 -8
  46. package/src/components/locations/tools-menu-location.tsx +0 -26
  47. package/src/components/locations/utilities-menu-location.tsx +0 -35
  48. package/src/components/ui/popover-menu-item.tsx +0 -44
  49. package/src/components/ui/popover-menu.tsx +0 -24
  50. package/src/components/ui/popover-sub-menu.tsx +0 -29
  51. package/src/components/ui/toolbar-logo.tsx +0 -84
  52. package/src/components/ui/toolbar-menu-item.tsx +0 -45
  53. package/src/components/ui/toolbar-menu-more.tsx +0 -29
  54. package/src/components/ui/toolbar-menu-toggle-item.tsx +0 -34
  55. package/src/components/ui/toolbar-menu.tsx +0 -15
  56. package/src/contexts/menu-context.tsx +0 -20
  57. package/src/locations/__tests__/menus.test.tsx +0 -212
  58. package/src/locations/index.ts +0 -29
  59. package/src/locations/menus.tsx +0 -129
  60. package/src/types.ts +0 -3
@@ -1,45 +0,0 @@
1
- import * as React from 'react';
2
- import { Box, IconButton, IconButtonProps, Tooltip as BaseTooltip, TooltipProps } from '@elementor/ui';
3
-
4
- export type ToolbarMenuItemProps = IconButtonProps & {
5
- title?: string;
6
- selected?: boolean;
7
- }
8
-
9
- export default function ToolbarMenuItem( { title, ...props }: ToolbarMenuItemProps ) {
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
- <IconButton
15
- { ...props }
16
- aria-label={ title }
17
- size="medium"
18
- sx={ {
19
- '& svg': {
20
- fontSize: '1.25rem',
21
- height: '1em',
22
- width: '1em',
23
- },
24
- '&:hover': {
25
- color: 'text.primary',
26
- },
27
- } }
28
- />
29
- </Box>
30
- </Tooltip>
31
- );
32
- }
33
-
34
- function Tooltip( props: TooltipProps ) {
35
- return <BaseTooltip
36
- PopperProps={ {
37
- sx: {
38
- '&.MuiTooltip-popper .MuiTooltip-tooltip.MuiTooltip-tooltipPlacementBottom': {
39
- mt: 2,
40
- },
41
- },
42
- } }
43
- { ...props }
44
- />;
45
- }
@@ -1,29 +0,0 @@
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
- }
@@ -1,34 +0,0 @@
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
- }
@@ -1,15 +0,0 @@
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
- }
@@ -1,20 +0,0 @@
1
- import * as React from 'react';
2
- import { createContext, PropsWithChildren, useContext } from 'react';
3
-
4
- type MenuContextValue = {
5
- type: 'toolbar' | 'popover';
6
- }
7
-
8
- const MenuContext = createContext<MenuContextValue>( { type: 'toolbar' } );
9
-
10
- export function MenuContextProvider( { type, children }: PropsWithChildren<MenuContextValue> ) {
11
- return (
12
- <MenuContext.Provider value={ { type } }>
13
- { children }
14
- </MenuContext.Provider>
15
- );
16
- }
17
-
18
- export function useMenuContext() {
19
- return useContext( MenuContext );
20
- }
@@ -1,212 +0,0 @@
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( '@elementor/editor-app-bar - 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
- }
@@ -1,29 +0,0 @@
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();
28
-
29
- export const documentOptionsMenu = createMenu( [ 'save' ] );
@@ -1,129 +0,0 @@
1
- import * as React from 'react';
2
- import { ComponentPropsWithoutRef, ElementType, useMemo } from 'react';
3
- import { createLocation, Location } from '@elementor/locations';
4
- import Action from '../components/actions/action';
5
- import ToggleAction from '../components/actions/toggle-action';
6
- import Link from '../components/actions/link';
7
-
8
- type GroupName = string;
9
-
10
- type MenuGroup<TGroup extends GroupName> = TGroup | 'default';
11
-
12
- type GroupedItems<TGroup extends GroupName> = Record<MenuGroup<TGroup>, Array<{ id: string, MenuItem: ElementType }>>;
13
-
14
- type GroupLocationMap<TGroup extends GroupName> = Record<MenuGroup<TGroup>, Location>;
15
-
16
- type MenuItem<
17
- TGroup extends GroupName,
18
- TComponent extends ElementType,
19
- > = {
20
- id: string,
21
- group?: TGroup,
22
- priority?: number,
23
- overwrite?: boolean,
24
- } & (
25
- { props: ComponentPropsWithoutRef<TComponent>, useProps?: never } |
26
- { useProps: () => ComponentPropsWithoutRef<TComponent>, props?: never }
27
- )
28
-
29
- type MenuActions<TGroup extends GroupName> = {
30
- registerAction: ( args: MenuItem<TGroup, typeof Action> ) => void,
31
- registerToggleAction: ( args: MenuItem<TGroup, typeof ToggleAction> ) => void,
32
- registerLink: ( args: MenuItem<TGroup, typeof Link> ) => void,
33
- useMenuItems: () => GroupedItems<TGroup>,
34
- }
35
-
36
- export function createMenu<
37
- TGroup extends GroupName = 'default'
38
- >( groups: TGroup[] = [] ): MenuActions<MenuGroup<TGroup>> {
39
- const menuGroups: MenuGroup<TGroup>[] = [
40
- ...groups,
41
- 'default' as const,
42
- ];
43
-
44
- const locations = menuGroups.reduce(
45
- ( carry, group ) => ( {
46
- ...carry,
47
- [ group ]: createLocation(),
48
- } ),
49
- {} as GroupLocationMap<TGroup>
50
- );
51
-
52
- const [
53
- registerAction,
54
- registerToggleAction,
55
- registerLink,
56
- ] = [ Action, ToggleAction, Link ].map(
57
- ( Component ) => createRegisterMenuItem( {
58
- locations,
59
- menuGroups,
60
- component: Component,
61
- } )
62
- );
63
-
64
- const useMenuItems = createUseMenuItems( locations );
65
-
66
- return {
67
- registerAction,
68
- registerToggleAction,
69
- registerLink,
70
- useMenuItems,
71
- };
72
- }
73
-
74
- function createRegisterMenuItem<
75
- TGroup extends GroupName,
76
- TComponent extends ElementType,
77
- >( { locations, menuGroups, component }: {
78
- locations: GroupLocationMap<TGroup>
79
- menuGroups: MenuGroup<TGroup>[],
80
- component: TComponent,
81
- } ) {
82
- return ( { group = 'default', id, overwrite, priority, ...args }: MenuItem<MenuGroup<TGroup>, TComponent> ) => {
83
- if ( ! menuGroups.includes( group ) ) {
84
- return;
85
- }
86
-
87
- const useProps = 'props' in args ? () => args.props : args.useProps;
88
-
89
- const Component = component as ElementType;
90
-
91
- const InjectedComponent = ( props: object ) => {
92
- const componentProps = useProps();
93
-
94
- return <Component { ...props } { ...componentProps } />;
95
- };
96
-
97
- locations[ group ].inject( {
98
- id,
99
- component: InjectedComponent,
100
- options: {
101
- priority,
102
- overwrite,
103
- },
104
- } );
105
- };
106
- }
107
-
108
- function createUseMenuItems<TGroup extends GroupName>( locations : GroupLocationMap<TGroup> ) {
109
- return () => {
110
- // Normalize the injections groups to an object with the groups as keys.
111
- return useMemo( () => {
112
- return Object.entries( locations ).reduce<GroupedItems<TGroup>>(
113
- ( carry, [ groupName, location ] ) => {
114
- const items = location.getInjections()
115
- .map( ( injection ) => ( {
116
- id: injection.id,
117
- MenuItem: injection.component,
118
- } ) );
119
-
120
- return {
121
- ...carry,
122
- [ groupName ]: items,
123
- };
124
- },
125
- {} as GroupedItems<TGroup>
126
- );
127
- }, [] );
128
- };
129
- }
package/src/types.ts DELETED
@@ -1,3 +0,0 @@
1
- export type { Props as ActionProps } from './components/actions/action';
2
- export type { Props as ToggleActionProps } from './components/actions/toggle-action';
3
- export type { Props as LinkProps } from './components/actions/link';