@elementor/editor-app-bar 0.3.0 → 0.4.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 (31) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/index.d.ts +27 -42
  3. package/dist/index.js +73 -88
  4. package/dist/index.js.map +1 -1
  5. package/dist/index.mjs +75 -90
  6. package/dist/index.mjs.map +1 -1
  7. package/package.json +5 -5
  8. package/src/components/locations/__tests__/locations-components.test.tsx +1 -1
  9. package/src/components/locations/__tests__/menus.test.tsx +4 -4
  10. package/src/components/locations/page-indication-location.tsx +2 -3
  11. package/src/components/locations/primary-action-location.tsx +2 -3
  12. package/src/components/locations/responsive-location.tsx +2 -3
  13. package/src/extensions/documents-indicator/index.ts +1 -1
  14. package/src/extensions/documents-preview/index.ts +1 -1
  15. package/src/extensions/documents-save/components/__tests__/primary-action-menu.test.tsx +2 -2
  16. package/src/extensions/documents-save/index.ts +3 -3
  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/index.ts +1 -1
  22. package/src/extensions/site-settings/index.ts +2 -2
  23. package/src/extensions/structure/index.ts +1 -1
  24. package/src/extensions/theme-builder/index.ts +1 -1
  25. package/src/extensions/user-preferences/index.ts +1 -1
  26. package/src/extensions/wordpress/index.ts +1 -1
  27. package/src/init.ts +1 -1
  28. package/src/locations/__tests__/menus.test.tsx +15 -30
  29. package/src/locations/index.ts +19 -21
  30. package/src/locations/menus.tsx +57 -69
  31. package/src/locations/consts.ts +0 -4
@@ -3,7 +3,7 @@ import useThemeBuilderActionProps from './hooks/use-action-props';
3
3
 
4
4
  export function init() {
5
5
  mainMenu.registerAction( {
6
- name: 'open-theme-builder',
6
+ id: 'open-theme-builder',
7
7
  useProps: useThemeBuilderActionProps,
8
8
  } );
9
9
  }
@@ -3,7 +3,7 @@ import useActionProps from './hooks/use-action-props';
3
3
 
4
4
  export function init() {
5
5
  mainMenu.registerToggleAction( {
6
- name: 'open-user-preferences',
6
+ id: 'open-user-preferences',
7
7
  priority: 30, // After history.
8
8
  useProps: useActionProps,
9
9
  } );
@@ -5,7 +5,7 @@ import { useActiveDocument } from '@elementor/editor-documents';
5
5
 
6
6
  export function init() {
7
7
  mainMenu.registerLink( {
8
- name: 'exit-to-wordpress',
8
+ id: 'exit-to-wordpress',
9
9
  group: 'exits',
10
10
  useProps: () => {
11
11
  const document = useActiveDocument();
package/src/init.ts CHANGED
@@ -9,7 +9,7 @@ export default function init() {
9
9
  initExtensions();
10
10
 
11
11
  injectIntoTop( {
12
- name: 'app-bar',
12
+ id: 'app-bar',
13
13
  filler: AppBar,
14
14
  } );
15
15
  }
@@ -6,9 +6,7 @@ import { createMockMenuAction, createMockMenuLink, createMockMenuToggleAction }
6
6
  describe( '@elementor/editor-app-bar - Menus API', () => {
7
7
  it( 'should create a menu with default group when not provided', () => {
8
8
  // Act.
9
- const menu = createMenu( {
10
- name: 'test',
11
- } );
9
+ const menu = createMenu();
12
10
 
13
11
  menu.registerAction( createMockMenuAction() );
14
12
 
@@ -20,15 +18,16 @@ describe( '@elementor/editor-app-bar - Menus API', () => {
20
18
 
21
19
  it( 'should create a menu with groups and append a default group', () => {
22
20
  // Act.
23
- const menu = createMenu( {
24
- name: 'test',
25
- groups: [ 'testGroup' ],
26
- } );
21
+ const menu = createMenu( [ 'testGroup' ] );
27
22
 
28
- menu.registerAction( createMockMenuAction() );
23
+ menu.registerAction( {
24
+ ...createMockMenuAction(),
25
+ id: 'test',
26
+ } );
29
27
 
30
28
  menu.registerLink( {
31
29
  ...createMockMenuLink(),
30
+ id: 'test1',
32
31
  group: 'testGroup',
33
32
  } );
34
33
 
@@ -44,9 +43,7 @@ describe( '@elementor/editor-app-bar - Menus API', () => {
44
43
  const onClick = jest.fn();
45
44
 
46
45
  // Act.
47
- const menu = createMenu( {
48
- name: 'test',
49
- } );
46
+ const menu = createMenu();
50
47
 
51
48
  menu.registerAction( createMockMenuAction( { onClick } ) );
52
49
 
@@ -67,9 +64,7 @@ describe( '@elementor/editor-app-bar - Menus API', () => {
67
64
 
68
65
  it( 'should register a toggle action', () => {
69
66
  // Act.
70
- const menu = createMenu( {
71
- name: 'test',
72
- } );
67
+ const menu = createMenu();
73
68
 
74
69
  menu.registerToggleAction( createMockMenuToggleAction() );
75
70
 
@@ -97,9 +92,7 @@ describe( '@elementor/editor-app-bar - Menus API', () => {
97
92
 
98
93
  it( 'should register a link', () => {
99
94
  // Act.
100
- const menu = createMenu( {
101
- name: 'test',
102
- } );
95
+ const menu = createMenu();
103
96
 
104
97
  menu.registerLink( createMockMenuLink() );
105
98
 
@@ -116,9 +109,7 @@ describe( '@elementor/editor-app-bar - Menus API', () => {
116
109
 
117
110
  it( 'should not register an action when passing a non-existing group', () => {
118
111
  // Act.
119
- const menu = createMenu( {
120
- name: 'test',
121
- } );
112
+ const menu = createMenu();
122
113
 
123
114
  menu.registerLink( {
124
115
  ...createMockMenuLink(),
@@ -133,9 +124,7 @@ describe( '@elementor/editor-app-bar - Menus API', () => {
133
124
 
134
125
  it( 'should register an action tooltip', async () => {
135
126
  // Arrange.
136
- const menu = createMenu( {
137
- name: 'test',
138
- } );
127
+ const menu = createMenu();
139
128
 
140
129
  // Act.
141
130
  menu.registerAction( createMockMenuAction() );
@@ -161,9 +150,7 @@ describe( '@elementor/editor-app-bar - Menus API', () => {
161
150
 
162
151
  it( 'should register an action icon', () => {
163
152
  // Arrange.
164
- const menu = createMenu( {
165
- name: 'test',
166
- } );
153
+ const menu = createMenu();
167
154
 
168
155
  // Act.
169
156
  menu.registerAction( createMockMenuAction() );
@@ -192,13 +179,11 @@ describe( '@elementor/editor-app-bar - Menus API', () => {
192
179
  },
193
180
  ] as const )( 'should register a hidden $type', ( { type, action } ) => {
194
181
  // Arrange.
195
- const menu = createMenu( {
196
- name: 'test',
197
- } );
182
+ const menu = createMenu();
198
183
 
199
184
  // Act.
200
185
  menu[ action ]( {
201
- name: 'hidden',
186
+ id: 'hidden',
202
187
  useProps: () => ( {
203
188
  title: `hidden-${ type }`,
204
189
  icon: () => <div />,
@@ -1,29 +1,27 @@
1
1
  import { createMenu } from './menus';
2
- import { createInjectorFor } from '@elementor/locations';
3
- import { LOCATION_PAGE_INDICATION, LOCATION_PRIMARY_ACTION, LOCATION_RESPONSIVE } from './consts';
4
-
5
- export * from './consts';
2
+ import { createLocation } from '@elementor/locations';
6
3
 
7
4
  export { createMenu } from './menus';
8
5
 
9
- export const injectIntoPageIndication = createInjectorFor( LOCATION_PAGE_INDICATION );
10
- export const injectIntoResponsive = createInjectorFor( LOCATION_RESPONSIVE );
11
- export const injectIntoPrimaryAction = createInjectorFor( LOCATION_PRIMARY_ACTION );
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();
12
20
 
13
- export const mainMenu = createMenu( {
14
- name: 'main',
15
- groups: [ 'exits' ],
16
- } );
21
+ export const mainMenu = createMenu( [ 'exits' ] );
17
22
 
18
- export const toolsMenu = createMenu( {
19
- name: 'tools',
20
- } );
23
+ export const toolsMenu = createMenu();
21
24
 
22
- export const utilitiesMenu = createMenu( {
23
- name: 'utilities',
24
- } );
25
+ export const utilitiesMenu = createMenu();
25
26
 
26
- export const documentOptionsMenu = createMenu( {
27
- name: 'document-options',
28
- groups: [ 'save' ],
29
- } );
27
+ export const documentOptionsMenu = createMenu( [ 'save' ] );
@@ -1,29 +1,23 @@
1
1
  import * as React from 'react';
2
2
  import { ComponentPropsWithoutRef, ElementType, useMemo } from 'react';
3
- import { inject, useInjectionsOf } from '@elementor/locations';
3
+ import { createLocation, Location } from '@elementor/locations';
4
4
  import Action from '../components/actions/action';
5
5
  import ToggleAction from '../components/actions/toggle-action';
6
6
  import Link from '../components/actions/link';
7
7
 
8
- type MenuName = string;
9
8
  type GroupName = string;
10
9
 
11
- type Menu<TGroup extends GroupName = 'default'> = {
12
- name: MenuName,
13
- groups: TGroup[],
14
- };
15
-
16
- type MenuWithOptionalGroups<TGroup extends GroupName> = Omit<Menu<TGroup>, 'groups'> & { groups?: TGroup[] };
17
-
18
10
  type MenuGroup<TGroup extends GroupName> = TGroup | 'default';
19
11
 
20
12
  type GroupedItems<TGroup extends GroupName> = Record<MenuGroup<TGroup>, Array<{ id: string, MenuItem: ElementType }>>;
21
13
 
14
+ type GroupLocationMap<TGroup extends GroupName> = Record<MenuGroup<TGroup>, Location>;
15
+
22
16
  type MenuItem<
23
17
  TGroup extends GroupName,
24
18
  TComponent extends ElementType,
25
19
  > = {
26
- name: string,
20
+ id: string,
27
21
  group?: TGroup,
28
22
  priority?: number,
29
23
  overwrite?: boolean,
@@ -32,34 +26,42 @@ type MenuItem<
32
26
  { useProps: () => ComponentPropsWithoutRef<TComponent>, props?: never }
33
27
  )
34
28
 
35
- export function createMenu<TGroup extends GroupName = 'default'>( { name: menuName, groups = [] }: MenuWithOptionalGroups<TGroup> ) {
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>> {
36
39
  const menuGroups: MenuGroup<TGroup>[] = [
37
40
  ...groups,
38
41
  'default' as const,
39
42
  ];
40
43
 
41
- const registerAction = createRegisterMenuItem( {
42
- menuName,
43
- menuGroups,
44
- component: Action,
45
- } );
46
-
47
- const registerToggleAction = createRegisterMenuItem( {
48
- menuName,
49
- menuGroups,
50
- component: ToggleAction,
51
- } );
52
-
53
- const registerLink = createRegisterMenuItem( {
54
- menuName,
55
- menuGroups,
56
- component: Link,
57
- } );
58
-
59
- const useMenuItems = createUseMenuItems( {
60
- menuName,
61
- menuGroups,
62
- } );
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 );
63
65
 
64
66
  return {
65
67
  registerAction,
@@ -70,15 +72,14 @@ export function createMenu<TGroup extends GroupName = 'default'>( { name: menuNa
70
72
  }
71
73
 
72
74
  function createRegisterMenuItem<
73
- TMenuName extends MenuName,
74
75
  TGroup extends GroupName,
75
76
  TComponent extends ElementType,
76
- >( { menuName, menuGroups, component }: {
77
- menuName: TMenuName,
77
+ >( { locations, menuGroups, component }: {
78
+ locations: GroupLocationMap<TGroup>
78
79
  menuGroups: MenuGroup<TGroup>[],
79
80
  component: TComponent,
80
81
  } ) {
81
- return ( { group = 'default', name, overwrite, priority, ...args }: MenuItem<MenuGroup<TGroup>, TComponent> ) => {
82
+ return ( { group = 'default', id, overwrite, priority, ...args }: MenuItem<MenuGroup<TGroup>, TComponent> ) => {
82
83
  if ( ! menuGroups.includes( group ) ) {
83
84
  return;
84
85
  }
@@ -93,11 +94,8 @@ function createRegisterMenuItem<
93
94
  return <Component { ...props } { ...componentProps } />;
94
95
  };
95
96
 
96
- const location = getMenuLocationId( menuName, group );
97
-
98
- inject( {
99
- location,
100
- name,
97
+ locations[ group ].inject( {
98
+ id,
101
99
  filler: Filler,
102
100
  options: {
103
101
  priority,
@@ -107,35 +105,25 @@ function createRegisterMenuItem<
107
105
  };
108
106
  }
109
107
 
110
- function createUseMenuItems<
111
- TMenuName extends MenuName,
112
- TGroup extends GroupName,
113
- >( { menuName, menuGroups }: {
114
- menuName: TMenuName,
115
- menuGroups: MenuGroup<TGroup>[],
116
- } ) {
117
- const locations = menuGroups.map( ( group ) => getMenuLocationId( menuName, group ) );
118
-
108
+ function createUseMenuItems<TGroup extends GroupName>( locations : GroupLocationMap<TGroup> ) {
119
109
  return () => {
120
- const injectionsGroups = useInjectionsOf( locations );
121
-
122
110
  // Normalize the injections groups to an object with the groups as keys.
123
111
  return useMemo( () => {
124
- return injectionsGroups.reduce<GroupedItems<TGroup>>( ( acc, injections, index ) => {
125
- const groupName = menuGroups[ index ];
126
-
127
- return {
128
- ...acc,
129
- [ groupName ]: injections.map( ( injection ) => ( {
130
- id: injection.id,
131
- MenuItem: injection.filler,
132
- } ) ),
133
- };
134
- }, {} as GroupedItems<TGroup> );
135
- }, [ injectionsGroups ] );
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.filler,
118
+ } ) );
119
+
120
+ return {
121
+ ...carry,
122
+ [ groupName ]: items,
123
+ };
124
+ },
125
+ {} as GroupedItems<TGroup>
126
+ );
127
+ }, [] );
136
128
  };
137
129
  }
138
-
139
- function getMenuLocationId( menu: MenuName, group: GroupName ) {
140
- return `editor/app-bar/${ menu }/${ group }` as const;
141
- }
@@ -1,4 +0,0 @@
1
- // Locations
2
- export const LOCATION_PAGE_INDICATION = 'editor/app-bar/page-indication' as const;
3
- export const LOCATION_RESPONSIVE = 'editor/app-bar/responsive' as const;
4
- export const LOCATION_PRIMARY_ACTION = 'editor/app-bar/primary-action' as const;