@wordpress/commands 0.4.0 → 0.5.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 (51) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/README.md +16 -0
  3. package/build/components/command-menu.js +60 -51
  4. package/build/components/command-menu.js.map +1 -1
  5. package/build/hooks/use-command-context.js +45 -0
  6. package/build/hooks/use-command-context.js.map +1 -0
  7. package/build/hooks/use-command-loader.js +6 -11
  8. package/build/hooks/use-command-loader.js.map +1 -1
  9. package/build/hooks/use-command.js +4 -3
  10. package/build/hooks/use-command.js.map +1 -1
  11. package/build/index.js +18 -0
  12. package/build/index.js.map +1 -1
  13. package/build/private-apis.js +2 -5
  14. package/build/private-apis.js.map +1 -1
  15. package/build/store/actions.js +35 -40
  16. package/build/store/actions.js.map +1 -1
  17. package/build/store/reducer.js +38 -22
  18. package/build/store/reducer.js.map +1 -1
  19. package/build/store/selectors.js +20 -17
  20. package/build/store/selectors.js.map +1 -1
  21. package/build-module/components/command-menu.js +60 -51
  22. package/build-module/components/command-menu.js.map +1 -1
  23. package/build-module/hooks/use-command-context.js +35 -0
  24. package/build-module/hooks/use-command-context.js.map +1 -0
  25. package/build-module/hooks/use-command-loader.js +6 -11
  26. package/build-module/hooks/use-command-loader.js.map +1 -1
  27. package/build-module/hooks/use-command.js +4 -3
  28. package/build-module/hooks/use-command.js.map +1 -1
  29. package/build-module/index.js +2 -0
  30. package/build-module/index.js.map +1 -1
  31. package/build-module/private-apis.js +2 -4
  32. package/build-module/private-apis.js.map +1 -1
  33. package/build-module/store/actions.js +33 -40
  34. package/build-module/store/actions.js.map +1 -1
  35. package/build-module/store/reducer.js +38 -22
  36. package/build-module/store/reducer.js.map +1 -1
  37. package/build-module/store/selectors.js +17 -16
  38. package/build-module/store/selectors.js.map +1 -1
  39. package/build-style/style-rtl.css +6 -1
  40. package/build-style/style.css +6 -1
  41. package/package.json +9 -9
  42. package/src/components/command-menu.js +38 -35
  43. package/src/components/style.scss +8 -1
  44. package/src/hooks/use-command-context.js +32 -0
  45. package/src/hooks/use-command-loader.js +12 -6
  46. package/src/hooks/use-command.js +5 -3
  47. package/src/index.js +2 -0
  48. package/src/private-apis.js +2 -4
  49. package/src/store/actions.js +31 -26
  50. package/src/store/reducer.js +33 -27
  51. package/src/store/selectors.js +18 -20
@@ -24,19 +24,21 @@ export default function useCommand( command ) {
24
24
  useEffect( () => {
25
25
  registerCommand( {
26
26
  name: command.name,
27
- group: command.group,
27
+ context: command.context,
28
28
  label: command.label,
29
+ searchLabel: command.searchLabel,
29
30
  icon: command.icon,
30
31
  callback: currentCallback.current,
31
32
  } );
32
33
  return () => {
33
- unregisterCommand( command.name, command.group );
34
+ unregisterCommand( command.name );
34
35
  };
35
36
  }, [
36
37
  command.name,
37
38
  command.label,
38
- command.group,
39
+ command.searchLabel,
39
40
  command.icon,
41
+ command.context,
40
42
  registerCommand,
41
43
  unregisterCommand,
42
44
  ] );
package/src/index.js CHANGED
@@ -1,2 +1,4 @@
1
1
  export { CommandMenu } from './components/command-menu';
2
2
  export { privateApis } from './private-apis';
3
+ export { default as useCommand } from './hooks/use-command';
4
+ export { default as useCommandLoader } from './hooks/use-command-loader';
@@ -6,8 +6,7 @@ import { __dangerousOptInToUnstableAPIsOnlyForCoreModules } from '@wordpress/pri
6
6
  /**
7
7
  * Internal dependencies
8
8
  */
9
- import { default as useCommand } from './hooks/use-command';
10
- import { default as useCommandLoader } from './hooks/use-command-loader';
9
+ import { default as useCommandContext } from './hooks/use-command-context';
11
10
  import { store } from './store';
12
11
 
13
12
  export const { lock, unlock } =
@@ -18,7 +17,6 @@ export const { lock, unlock } =
18
17
 
19
18
  export const privateApis = {};
20
19
  lock( privateApis, {
21
- useCommand,
22
- useCommandLoader,
20
+ useCommandContext,
23
21
  store,
24
22
  } );
@@ -5,11 +5,12 @@
5
5
  *
6
6
  * @typedef {Object} WPCommandConfig
7
7
  *
8
- * @property {string} name Command name.
9
- * @property {string} label Command label.
10
- * @property {string=} group Command group.
11
- * @property {JSX.Element} icon Command icon.
12
- * @property {Function} callback Command callback.
8
+ * @property {string} name Command name.
9
+ * @property {string} label Command label.
10
+ * @property {string=} searchLabel Command search label.
11
+ * @property {string=} context Command context.
12
+ * @property {JSX.Element} icon Command icon.
13
+ * @property {Function} callback Command callback.
13
14
  */
14
15
 
15
16
  /**
@@ -21,9 +22,9 @@
21
22
  *
22
23
  * @typedef {Object} WPCommandLoaderConfig
23
24
  *
24
- * @property {string} name Command loader name.
25
- * @property {string=} group Command loader group.
26
- * @property {WPCommandLoaderHook} hook Command loader hook.
25
+ * @property {string} name Command loader name.
26
+ * @property {string=} context Command loader context.
27
+ * @property {WPCommandLoaderHook} hook Command loader hook.
27
28
  */
28
29
 
29
30
  /**
@@ -33,30 +34,24 @@
33
34
  *
34
35
  * @return {Object} action.
35
36
  */
36
- export function registerCommand( { name, label, icon, callback, group = '' } ) {
37
+ export function registerCommand( config ) {
37
38
  return {
38
39
  type: 'REGISTER_COMMAND',
39
- name,
40
- label,
41
- icon,
42
- callback,
43
- group,
40
+ ...config,
44
41
  };
45
42
  }
46
43
 
47
44
  /**
48
45
  * Returns an action object used to unregister a command.
49
46
  *
50
- * @param {string} name Command name.
51
- * @param {string} group Command group.
47
+ * @param {string} name Command name.
52
48
  *
53
49
  * @return {Object} action.
54
50
  */
55
- export function unregisterCommand( name, group ) {
51
+ export function unregisterCommand( name ) {
56
52
  return {
57
53
  type: 'UNREGISTER_COMMAND',
58
54
  name,
59
- group,
60
55
  };
61
56
  }
62
57
 
@@ -67,28 +62,24 @@ export function unregisterCommand( name, group ) {
67
62
  *
68
63
  * @return {Object} action.
69
64
  */
70
- export function registerCommandLoader( { name, group = '', hook } ) {
65
+ export function registerCommandLoader( config ) {
71
66
  return {
72
67
  type: 'REGISTER_COMMAND_LOADER',
73
- name,
74
- group,
75
- hook,
68
+ ...config,
76
69
  };
77
70
  }
78
71
 
79
72
  /**
80
73
  * Unregister command loader hook.
81
74
  *
82
- * @param {string} name Command loader name.
83
- * @param {string} group Command loader group.
75
+ * @param {string} name Command loader name.
84
76
  *
85
77
  * @return {Object} action.
86
78
  */
87
- export function unregisterCommandLoader( name, group ) {
79
+ export function unregisterCommandLoader( name ) {
88
80
  return {
89
81
  type: 'UNREGISTER_COMMAND_LOADER',
90
82
  name,
91
- group,
92
83
  };
93
84
  }
94
85
 
@@ -113,3 +104,17 @@ export function close() {
113
104
  type: 'CLOSE',
114
105
  };
115
106
  }
107
+
108
+ /**
109
+ * Sets the active context.
110
+ *
111
+ * @param {string} context Context.
112
+ *
113
+ * @return {Object} action.
114
+ */
115
+ export function setContext( context ) {
116
+ return {
117
+ type: 'SET_CONTEXT',
118
+ context,
119
+ };
120
+ }
@@ -16,24 +16,18 @@ function commands( state = {}, action ) {
16
16
  case 'REGISTER_COMMAND':
17
17
  return {
18
18
  ...state,
19
- [ action.group ]: {
20
- ...state[ action.group ],
21
- [ action.name ]: {
22
- name: action.name,
23
- label: action.label,
24
- group: action.group,
25
- callback: action.callback,
26
- icon: action.icon,
27
- },
19
+ [ action.name ]: {
20
+ name: action.name,
21
+ label: action.label,
22
+ searchLabel: action.searchLabel,
23
+ context: action.context,
24
+ callback: action.callback,
25
+ icon: action.icon,
28
26
  },
29
27
  };
30
28
  case 'UNREGISTER_COMMAND': {
31
- const { [ action.name ]: _, ...remainingState } =
32
- state?.[ action.group ];
33
- return {
34
- ...state,
35
- [ action.group ]: remainingState,
36
- };
29
+ const { [ action.name ]: _, ...remainingState } = state;
30
+ return remainingState;
37
31
  }
38
32
  }
39
33
 
@@ -53,21 +47,15 @@ function commandLoaders( state = {}, action ) {
53
47
  case 'REGISTER_COMMAND_LOADER':
54
48
  return {
55
49
  ...state,
56
- [ action.group ]: {
57
- ...state[ action.group ],
58
- [ action.name ]: {
59
- name: action.name,
60
- hook: action.hook,
61
- },
50
+ [ action.name ]: {
51
+ name: action.name,
52
+ context: action.context,
53
+ hook: action.hook,
62
54
  },
63
55
  };
64
56
  case 'UNREGISTER_COMMAND_LOADER': {
65
- const { [ action.name ]: _, ...remainingState } =
66
- state?.[ action.group ];
67
- return {
68
- ...state,
69
- [ action.group ]: remainingState,
70
- };
57
+ const { [ action.name ]: _, ...remainingState } = state;
58
+ return remainingState;
71
59
  }
72
60
  }
73
61
 
@@ -93,10 +81,28 @@ function isOpen( state = false, action ) {
93
81
  return state;
94
82
  }
95
83
 
84
+ /**
85
+ * Reducer returning the command center's active context.
86
+ *
87
+ * @param {Object} state Current state.
88
+ * @param {Object} action Dispatched action.
89
+ *
90
+ * @return {boolean} Updated state.
91
+ */
92
+ function context( state = 'root', action ) {
93
+ switch ( action.type ) {
94
+ case 'SET_CONTEXT':
95
+ return action.context;
96
+ }
97
+
98
+ return state;
99
+ }
100
+
96
101
  const reducer = combineReducers( {
97
102
  commands,
98
103
  commandLoaders,
99
104
  isOpen,
105
+ context,
100
106
  } );
101
107
 
102
108
  export default reducer;
@@ -3,32 +3,30 @@
3
3
  */
4
4
  import createSelector from 'rememo';
5
5
 
6
- function unique( array ) {
7
- return array.filter(
8
- ( value, index, current ) => current.indexOf( value ) === index
9
- );
10
- }
11
-
12
- export const getGroups = createSelector(
13
- ( state ) =>
14
- unique(
15
- Object.keys( state.commands ).concat(
16
- Object.keys( state.commandLoaders )
17
- )
18
- ),
19
- ( state ) => [ state.commands, state.commandLoaders ]
20
- );
21
-
22
6
  export const getCommands = createSelector(
23
- ( state, group ) => Object.values( state.commands[ group ] ?? {} ),
24
- ( state, group ) => [ state.commands[ group ] ]
7
+ ( state, contextual = false ) =>
8
+ Object.values( state.commands ).filter( ( command ) => {
9
+ const isContextual =
10
+ command.context && command.context === state.context;
11
+ return contextual ? isContextual : ! isContextual;
12
+ } ),
13
+ ( state ) => [ state.commands, state.context ]
25
14
  );
26
15
 
27
16
  export const getCommandLoaders = createSelector(
28
- ( state, group ) => Object.values( state.commandLoaders[ group ] ?? {} ),
29
- ( state, group ) => [ state.commandLoaders[ group ] ]
17
+ ( state, contextual = false ) =>
18
+ Object.values( state.commandLoaders ).filter( ( loader ) => {
19
+ const isContextual =
20
+ loader.context && loader.context === state.context;
21
+ return contextual ? isContextual : ! isContextual;
22
+ } ),
23
+ ( state ) => [ state.commandLoaders, state.context ]
30
24
  );
31
25
 
32
26
  export function isOpen( state ) {
33
27
  return state.isOpen;
34
28
  }
29
+
30
+ export function getContext( state ) {
31
+ return state.context;
32
+ }