@wordpress/commands 0.9.0 → 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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,8 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ ## 0.10.0 (2023-08-10)
6
+
5
7
  ## 0.9.0 (2023-07-20)
6
8
 
7
9
  ## 0.8.0 (2023-07-05)
@@ -65,7 +65,8 @@ function CommandMenuLoader({
65
65
  value: (_command$searchLabel = command.searchLabel) !== null && _command$searchLabel !== void 0 ? _command$searchLabel : command.label,
66
66
  onSelect: () => command.callback({
67
67
  close
68
- })
68
+ }),
69
+ id: command.name
69
70
  }, (0, _element.createElement)(_components.__experimentalHStack, {
70
71
  alignment: "left",
71
72
  className: "commands-command-menu__item"
@@ -138,7 +139,8 @@ function CommandMenuGroup({
138
139
  value: (_command$searchLabel2 = command.searchLabel) !== null && _command$searchLabel2 !== void 0 ? _command$searchLabel2 : command.label,
139
140
  onSelect: () => command.callback({
140
141
  close
141
- })
142
+ }),
143
+ id: command.name
142
144
  }, (0, _element.createElement)(_components.__experimentalHStack, {
143
145
  alignment: "left",
144
146
  className: "commands-command-menu__item"
@@ -157,6 +159,34 @@ function CommandMenuGroup({
157
159
  })));
158
160
  }
159
161
 
162
+ function CommandInput({
163
+ isOpen,
164
+ search,
165
+ setSearch
166
+ }) {
167
+ const commandMenuInput = (0, _element.useRef)();
168
+
169
+ const _value = (0, _cmdk.useCommandState)(state => state.value);
170
+
171
+ const selectedItemId = (0, _element.useMemo)(() => {
172
+ const item = document.querySelector(`[cmdk-item=""][data-value="${_value}"]`);
173
+ return item?.getAttribute('id');
174
+ }, [_value]);
175
+ (0, _element.useEffect)(() => {
176
+ // Focus the command palette input when mounting the modal.
177
+ if (isOpen) {
178
+ commandMenuInput.current.focus();
179
+ }
180
+ }, [isOpen]);
181
+ return (0, _element.createElement)(_cmdk.Command.Input, {
182
+ ref: commandMenuInput,
183
+ value: search,
184
+ onValueChange: setSearch,
185
+ placeholder: (0, _i18n.__)('Type a command or search'),
186
+ "aria-activedescendant": selectedItemId
187
+ });
188
+ }
189
+
160
190
  function CommandMenu() {
161
191
  const {
162
192
  registerShortcut
@@ -168,7 +198,6 @@ function CommandMenu() {
168
198
  close
169
199
  } = (0, _data.useDispatch)(_store.store);
170
200
  const [loaders, setLoaders] = (0, _element.useState)({});
171
- const commandMenuInput = (0, _element.useRef)();
172
201
  (0, _element.useEffect)(() => {
173
202
  registerShortcut({
174
203
  name: 'core/commands',
@@ -180,7 +209,11 @@ function CommandMenu() {
180
209
  }
181
210
  });
182
211
  }, [registerShortcut]);
183
- (0, _keyboardShortcuts.useShortcut)('core/commands', event => {
212
+ (0, _keyboardShortcuts.useShortcut)('core/commands',
213
+ /** @type {import('react').KeyboardEventHandler} */
214
+ event => {
215
+ // Bails to avoid obscuring the effect of the preceding handler(s).
216
+ if (event.defaultPrevented) return;
184
217
  event.preventDefault();
185
218
 
186
219
  if (isOpen) {
@@ -200,17 +233,20 @@ function CommandMenu() {
200
233
  close();
201
234
  };
202
235
 
203
- (0, _element.useEffect)(() => {
204
- // Focus the command palette input when mounting the modal.
205
- if (isOpen) {
206
- commandMenuInput.current.focus();
207
- }
208
- }, [isOpen]);
209
-
210
236
  if (!isOpen) {
211
237
  return false;
212
238
  }
213
239
 
240
+ const onKeyDown = event => {
241
+ if ( // Ignore keydowns from IMEs
242
+ event.nativeEvent.isComposing || // Workaround for Mac Safari where the final Enter/Backspace of an IME composition
243
+ // is `isComposing=false`, even though it's technically still part of the composition.
244
+ // These can only be detected by keyCode.
245
+ event.keyCode === 229) {
246
+ event.preventDefault();
247
+ }
248
+ };
249
+
214
250
  const isLoading = Object.values(loaders).some(Boolean);
215
251
  return (0, _element.createElement)(_components.Modal, {
216
252
  className: "commands-command-menu",
@@ -220,14 +256,14 @@ function CommandMenu() {
220
256
  }, (0, _element.createElement)("div", {
221
257
  className: "commands-command-menu__container"
222
258
  }, (0, _element.createElement)(_cmdk.Command, {
223
- label: (0, _i18n.__)('Command palette')
259
+ label: (0, _i18n.__)('Command palette'),
260
+ onKeyDown: onKeyDown
224
261
  }, (0, _element.createElement)("div", {
225
262
  className: "commands-command-menu__header"
226
- }, (0, _element.createElement)(_cmdk.Command.Input, {
227
- ref: commandMenuInput,
228
- value: search,
229
- onValueChange: setSearch,
230
- placeholder: (0, _i18n.__)('Type a command or search')
263
+ }, (0, _element.createElement)(CommandInput, {
264
+ search: search,
265
+ setSearch: setSearch,
266
+ isOpen: isOpen
231
267
  })), (0, _element.createElement)(_cmdk.Command.List, null, search && !isLoading && (0, _element.createElement)(_cmdk.Command.Empty, null, (0, _i18n.__)('No results found.')), (0, _element.createElement)(CommandMenuGroup, {
232
268
  search: search,
233
269
  setLoader: setLoader,
@@ -1 +1 @@
1
- {"version":3,"sources":["@wordpress/commands/src/components/command-menu.js"],"names":["CommandMenuLoader","name","search","hook","setLoader","close","isLoading","commands","length","map","command","searchLabel","label","callback","icon","CommandMenuLoaderWrapper","currentLoader","key","setKey","current","prevKey","CommandMenuGroup","isContextual","loaders","select","getCommands","getCommandLoaders","commandsStore","loader","CommandMenu","registerShortcut","keyboardShortcutsStore","setSearch","isOpen","open","setLoaders","commandMenuInput","category","description","keyCombination","modifier","character","event","preventDefault","bindGlobal","value","closeAndReset","focus","Object","values","some","Boolean"],"mappings":"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","sourcesContent":["/**\n * External dependencies\n */\nimport { Command } from 'cmdk';\n\n/**\n * WordPress dependencies\n */\nimport { useSelect, useDispatch } from '@wordpress/data';\nimport { useState, useEffect, useRef, useCallback } from '@wordpress/element';\nimport { __ } from '@wordpress/i18n';\nimport {\n\tModal,\n\tTextHighlight,\n\t__experimentalHStack as HStack,\n} from '@wordpress/components';\nimport {\n\tstore as keyboardShortcutsStore,\n\tuseShortcut,\n} from '@wordpress/keyboard-shortcuts';\nimport { Icon } from '@wordpress/icons';\n\n/**\n * Internal dependencies\n */\nimport { store as commandsStore } from '../store';\n\nfunction CommandMenuLoader( { name, search, hook, setLoader, close } ) {\n\tconst { isLoading, commands = [] } = hook( { search } ) ?? {};\n\tuseEffect( () => {\n\t\tsetLoader( name, isLoading );\n\t}, [ setLoader, name, isLoading ] );\n\n\tif ( ! commands.length ) {\n\t\treturn null;\n\t}\n\n\treturn (\n\t\t<>\n\t\t\t<Command.List>\n\t\t\t\t{ commands.map( ( command ) => (\n\t\t\t\t\t<Command.Item\n\t\t\t\t\t\tkey={ command.name }\n\t\t\t\t\t\tvalue={ command.searchLabel ?? command.label }\n\t\t\t\t\t\tonSelect={ () => command.callback( { close } ) }\n\t\t\t\t\t>\n\t\t\t\t\t\t<HStack\n\t\t\t\t\t\t\talignment=\"left\"\n\t\t\t\t\t\t\tclassName=\"commands-command-menu__item\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Icon icon={ command.icon } />\n\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t<TextHighlight\n\t\t\t\t\t\t\t\t\ttext={ command.label }\n\t\t\t\t\t\t\t\t\thighlight={ search }\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</HStack>\n\t\t\t\t\t</Command.Item>\n\t\t\t\t) ) }\n\t\t\t</Command.List>\n\t\t</>\n\t);\n}\n\nexport function CommandMenuLoaderWrapper( { hook, search, setLoader, close } ) {\n\t// The \"hook\" prop is actually a custom React hook\n\t// so to avoid breaking the rules of hooks\n\t// the CommandMenuLoaderWrapper component need to be\n\t// remounted on each hook prop change\n\t// We use the key state to make sure we do that properly.\n\tconst currentLoader = useRef( hook );\n\tconst [ key, setKey ] = useState( 0 );\n\tuseEffect( () => {\n\t\tif ( currentLoader.current !== hook ) {\n\t\t\tcurrentLoader.current = hook;\n\t\t\tsetKey( ( prevKey ) => prevKey + 1 );\n\t\t}\n\t}, [ hook ] );\n\n\treturn (\n\t\t<CommandMenuLoader\n\t\t\tkey={ key }\n\t\t\thook={ currentLoader.current }\n\t\t\tsearch={ search }\n\t\t\tsetLoader={ setLoader }\n\t\t\tclose={ close }\n\t\t/>\n\t);\n}\n\nexport function CommandMenuGroup( { isContextual, search, setLoader, close } ) {\n\tconst { commands, loaders } = useSelect(\n\t\t( select ) => {\n\t\t\tconst { getCommands, getCommandLoaders } = select( commandsStore );\n\t\t\treturn {\n\t\t\t\tcommands: getCommands( isContextual ),\n\t\t\t\tloaders: getCommandLoaders( isContextual ),\n\t\t\t};\n\t\t},\n\t\t[ isContextual ]\n\t);\n\n\tif ( ! commands.length && ! loaders.length ) {\n\t\treturn null;\n\t}\n\n\treturn (\n\t\t<Command.Group>\n\t\t\t{ commands.map( ( command ) => (\n\t\t\t\t<Command.Item\n\t\t\t\t\tkey={ command.name }\n\t\t\t\t\tvalue={ command.searchLabel ?? command.label }\n\t\t\t\t\tonSelect={ () => command.callback( { close } ) }\n\t\t\t\t>\n\t\t\t\t\t<HStack\n\t\t\t\t\t\talignment=\"left\"\n\t\t\t\t\t\tclassName=\"commands-command-menu__item\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<Icon icon={ command.icon } />\n\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t<TextHighlight\n\t\t\t\t\t\t\t\ttext={ command.label }\n\t\t\t\t\t\t\t\thighlight={ search }\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</HStack>\n\t\t\t\t</Command.Item>\n\t\t\t) ) }\n\t\t\t{ loaders.map( ( loader ) => (\n\t\t\t\t<CommandMenuLoaderWrapper\n\t\t\t\t\tkey={ loader.name }\n\t\t\t\t\thook={ loader.hook }\n\t\t\t\t\tsearch={ search }\n\t\t\t\t\tsetLoader={ setLoader }\n\t\t\t\t\tclose={ close }\n\t\t\t\t/>\n\t\t\t) ) }\n\t\t</Command.Group>\n\t);\n}\n\nexport function CommandMenu() {\n\tconst { registerShortcut } = useDispatch( keyboardShortcutsStore );\n\tconst [ search, setSearch ] = useState( '' );\n\tconst isOpen = useSelect(\n\t\t( select ) => select( commandsStore ).isOpen(),\n\t\t[]\n\t);\n\tconst { open, close } = useDispatch( commandsStore );\n\tconst [ loaders, setLoaders ] = useState( {} );\n\tconst commandMenuInput = useRef();\n\n\tuseEffect( () => {\n\t\tregisterShortcut( {\n\t\t\tname: 'core/commands',\n\t\t\tcategory: 'global',\n\t\t\tdescription: __( 'Open the command palette' ),\n\t\t\tkeyCombination: {\n\t\t\t\tmodifier: 'primary',\n\t\t\t\tcharacter: 'k',\n\t\t\t},\n\t\t} );\n\t}, [ registerShortcut ] );\n\n\tuseShortcut(\n\t\t'core/commands',\n\t\t( event ) => {\n\t\t\tevent.preventDefault();\n\t\t\tif ( isOpen ) {\n\t\t\t\tclose();\n\t\t\t} else {\n\t\t\t\topen();\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tbindGlobal: true,\n\t\t}\n\t);\n\n\tconst setLoader = useCallback(\n\t\t( name, value ) =>\n\t\t\tsetLoaders( ( current ) => ( {\n\t\t\t\t...current,\n\t\t\t\t[ name ]: value,\n\t\t\t} ) ),\n\t\t[]\n\t);\n\tconst closeAndReset = () => {\n\t\tsetSearch( '' );\n\t\tclose();\n\t};\n\n\tuseEffect( () => {\n\t\t// Focus the command palette input when mounting the modal.\n\t\tif ( isOpen ) {\n\t\t\tcommandMenuInput.current.focus();\n\t\t}\n\t}, [ isOpen ] );\n\n\tif ( ! isOpen ) {\n\t\treturn false;\n\t}\n\tconst isLoading = Object.values( loaders ).some( Boolean );\n\n\treturn (\n\t\t<Modal\n\t\t\tclassName=\"commands-command-menu\"\n\t\t\toverlayClassName=\"commands-command-menu__overlay\"\n\t\t\tonRequestClose={ closeAndReset }\n\t\t\t__experimentalHideHeader\n\t\t>\n\t\t\t<div className=\"commands-command-menu__container\">\n\t\t\t\t<Command label={ __( 'Command palette' ) }>\n\t\t\t\t\t<div className=\"commands-command-menu__header\">\n\t\t\t\t\t\t<Command.Input\n\t\t\t\t\t\t\tref={ commandMenuInput }\n\t\t\t\t\t\t\tvalue={ search }\n\t\t\t\t\t\t\tonValueChange={ setSearch }\n\t\t\t\t\t\t\tplaceholder={ __( 'Type a command or search' ) }\n\t\t\t\t\t\t/>\n\t\t\t\t\t</div>\n\t\t\t\t\t<Command.List>\n\t\t\t\t\t\t{ search && ! isLoading && (\n\t\t\t\t\t\t\t<Command.Empty>\n\t\t\t\t\t\t\t\t{ __( 'No results found.' ) }\n\t\t\t\t\t\t\t</Command.Empty>\n\t\t\t\t\t\t) }\n\t\t\t\t\t\t<CommandMenuGroup\n\t\t\t\t\t\t\tsearch={ search }\n\t\t\t\t\t\t\tsetLoader={ setLoader }\n\t\t\t\t\t\t\tclose={ closeAndReset }\n\t\t\t\t\t\t\tisContextual\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t{ search && (\n\t\t\t\t\t\t\t<CommandMenuGroup\n\t\t\t\t\t\t\t\tsearch={ search }\n\t\t\t\t\t\t\t\tsetLoader={ setLoader }\n\t\t\t\t\t\t\t\tclose={ closeAndReset }\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t) }\n\t\t\t\t\t</Command.List>\n\t\t\t\t</Command>\n\t\t\t</div>\n\t\t</Modal>\n\t);\n}\n"]}
1
+ {"version":3,"sources":["@wordpress/commands/src/components/command-menu.js"],"names":["CommandMenuLoader","name","search","hook","setLoader","close","isLoading","commands","length","map","command","searchLabel","label","callback","icon","CommandMenuLoaderWrapper","currentLoader","key","setKey","current","prevKey","CommandMenuGroup","isContextual","loaders","select","getCommands","getCommandLoaders","commandsStore","loader","CommandInput","isOpen","setSearch","commandMenuInput","_value","state","value","selectedItemId","item","document","querySelector","getAttribute","focus","CommandMenu","registerShortcut","keyboardShortcutsStore","open","setLoaders","category","description","keyCombination","modifier","character","event","defaultPrevented","preventDefault","bindGlobal","closeAndReset","onKeyDown","nativeEvent","isComposing","keyCode","Object","values","some","Boolean"],"mappings":"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","sourcesContent":["/**\n * External dependencies\n */\nimport { Command, useCommandState } from 'cmdk';\n\n/**\n * WordPress dependencies\n */\nimport { useSelect, useDispatch } from '@wordpress/data';\nimport {\n\tuseState,\n\tuseEffect,\n\tuseRef,\n\tuseCallback,\n\tuseMemo,\n} from '@wordpress/element';\nimport { __ } from '@wordpress/i18n';\nimport {\n\tModal,\n\tTextHighlight,\n\t__experimentalHStack as HStack,\n} from '@wordpress/components';\nimport {\n\tstore as keyboardShortcutsStore,\n\tuseShortcut,\n} from '@wordpress/keyboard-shortcuts';\nimport { Icon } from '@wordpress/icons';\n\n/**\n * Internal dependencies\n */\nimport { store as commandsStore } from '../store';\n\nfunction CommandMenuLoader( { name, search, hook, setLoader, close } ) {\n\tconst { isLoading, commands = [] } = hook( { search } ) ?? {};\n\tuseEffect( () => {\n\t\tsetLoader( name, isLoading );\n\t}, [ setLoader, name, isLoading ] );\n\n\tif ( ! commands.length ) {\n\t\treturn null;\n\t}\n\n\treturn (\n\t\t<>\n\t\t\t<Command.List>\n\t\t\t\t{ commands.map( ( command ) => (\n\t\t\t\t\t<Command.Item\n\t\t\t\t\t\tkey={ command.name }\n\t\t\t\t\t\tvalue={ command.searchLabel ?? command.label }\n\t\t\t\t\t\tonSelect={ () => command.callback( { close } ) }\n\t\t\t\t\t\tid={ command.name }\n\t\t\t\t\t>\n\t\t\t\t\t\t<HStack\n\t\t\t\t\t\t\talignment=\"left\"\n\t\t\t\t\t\t\tclassName=\"commands-command-menu__item\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Icon icon={ command.icon } />\n\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t<TextHighlight\n\t\t\t\t\t\t\t\t\ttext={ command.label }\n\t\t\t\t\t\t\t\t\thighlight={ search }\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</HStack>\n\t\t\t\t\t</Command.Item>\n\t\t\t\t) ) }\n\t\t\t</Command.List>\n\t\t</>\n\t);\n}\n\nexport function CommandMenuLoaderWrapper( { hook, search, setLoader, close } ) {\n\t// The \"hook\" prop is actually a custom React hook\n\t// so to avoid breaking the rules of hooks\n\t// the CommandMenuLoaderWrapper component need to be\n\t// remounted on each hook prop change\n\t// We use the key state to make sure we do that properly.\n\tconst currentLoader = useRef( hook );\n\tconst [ key, setKey ] = useState( 0 );\n\tuseEffect( () => {\n\t\tif ( currentLoader.current !== hook ) {\n\t\t\tcurrentLoader.current = hook;\n\t\t\tsetKey( ( prevKey ) => prevKey + 1 );\n\t\t}\n\t}, [ hook ] );\n\n\treturn (\n\t\t<CommandMenuLoader\n\t\t\tkey={ key }\n\t\t\thook={ currentLoader.current }\n\t\t\tsearch={ search }\n\t\t\tsetLoader={ setLoader }\n\t\t\tclose={ close }\n\t\t/>\n\t);\n}\n\nexport function CommandMenuGroup( { isContextual, search, setLoader, close } ) {\n\tconst { commands, loaders } = useSelect(\n\t\t( select ) => {\n\t\t\tconst { getCommands, getCommandLoaders } = select( commandsStore );\n\t\t\treturn {\n\t\t\t\tcommands: getCommands( isContextual ),\n\t\t\t\tloaders: getCommandLoaders( isContextual ),\n\t\t\t};\n\t\t},\n\t\t[ isContextual ]\n\t);\n\n\tif ( ! commands.length && ! loaders.length ) {\n\t\treturn null;\n\t}\n\n\treturn (\n\t\t<Command.Group>\n\t\t\t{ commands.map( ( command ) => (\n\t\t\t\t<Command.Item\n\t\t\t\t\tkey={ command.name }\n\t\t\t\t\tvalue={ command.searchLabel ?? command.label }\n\t\t\t\t\tonSelect={ () => command.callback( { close } ) }\n\t\t\t\t\tid={ command.name }\n\t\t\t\t>\n\t\t\t\t\t<HStack\n\t\t\t\t\t\talignment=\"left\"\n\t\t\t\t\t\tclassName=\"commands-command-menu__item\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<Icon icon={ command.icon } />\n\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t<TextHighlight\n\t\t\t\t\t\t\t\ttext={ command.label }\n\t\t\t\t\t\t\t\thighlight={ search }\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</HStack>\n\t\t\t\t</Command.Item>\n\t\t\t) ) }\n\t\t\t{ loaders.map( ( loader ) => (\n\t\t\t\t<CommandMenuLoaderWrapper\n\t\t\t\t\tkey={ loader.name }\n\t\t\t\t\thook={ loader.hook }\n\t\t\t\t\tsearch={ search }\n\t\t\t\t\tsetLoader={ setLoader }\n\t\t\t\t\tclose={ close }\n\t\t\t\t/>\n\t\t\t) ) }\n\t\t</Command.Group>\n\t);\n}\n\nfunction CommandInput( { isOpen, search, setSearch } ) {\n\tconst commandMenuInput = useRef();\n\tconst _value = useCommandState( ( state ) => state.value );\n\tconst selectedItemId = useMemo( () => {\n\t\tconst item = document.querySelector(\n\t\t\t`[cmdk-item=\"\"][data-value=\"${ _value }\"]`\n\t\t);\n\t\treturn item?.getAttribute( 'id' );\n\t}, [ _value ] );\n\tuseEffect( () => {\n\t\t// Focus the command palette input when mounting the modal.\n\t\tif ( isOpen ) {\n\t\t\tcommandMenuInput.current.focus();\n\t\t}\n\t}, [ isOpen ] );\n\treturn (\n\t\t<Command.Input\n\t\t\tref={ commandMenuInput }\n\t\t\tvalue={ search }\n\t\t\tonValueChange={ setSearch }\n\t\t\tplaceholder={ __( 'Type a command or search' ) }\n\t\t\taria-activedescendant={ selectedItemId }\n\t\t/>\n\t);\n}\n\nexport function CommandMenu() {\n\tconst { registerShortcut } = useDispatch( keyboardShortcutsStore );\n\tconst [ search, setSearch ] = useState( '' );\n\tconst isOpen = useSelect(\n\t\t( select ) => select( commandsStore ).isOpen(),\n\t\t[]\n\t);\n\tconst { open, close } = useDispatch( commandsStore );\n\tconst [ loaders, setLoaders ] = useState( {} );\n\n\tuseEffect( () => {\n\t\tregisterShortcut( {\n\t\t\tname: 'core/commands',\n\t\t\tcategory: 'global',\n\t\t\tdescription: __( 'Open the command palette' ),\n\t\t\tkeyCombination: {\n\t\t\t\tmodifier: 'primary',\n\t\t\t\tcharacter: 'k',\n\t\t\t},\n\t\t} );\n\t}, [ registerShortcut ] );\n\n\tuseShortcut(\n\t\t'core/commands',\n\t\t/** @type {import('react').KeyboardEventHandler} */\n\t\t( event ) => {\n\t\t\t// Bails to avoid obscuring the effect of the preceding handler(s).\n\t\t\tif ( event.defaultPrevented ) return;\n\n\t\t\tevent.preventDefault();\n\t\t\tif ( isOpen ) {\n\t\t\t\tclose();\n\t\t\t} else {\n\t\t\t\topen();\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tbindGlobal: true,\n\t\t}\n\t);\n\n\tconst setLoader = useCallback(\n\t\t( name, value ) =>\n\t\t\tsetLoaders( ( current ) => ( {\n\t\t\t\t...current,\n\t\t\t\t[ name ]: value,\n\t\t\t} ) ),\n\t\t[]\n\t);\n\tconst closeAndReset = () => {\n\t\tsetSearch( '' );\n\t\tclose();\n\t};\n\n\tif ( ! isOpen ) {\n\t\treturn false;\n\t}\n\n\tconst onKeyDown = ( event ) => {\n\t\tif (\n\t\t\t// Ignore keydowns from IMEs\n\t\t\tevent.nativeEvent.isComposing ||\n\t\t\t// Workaround for Mac Safari where the final Enter/Backspace of an IME composition\n\t\t\t// is `isComposing=false`, even though it's technically still part of the composition.\n\t\t\t// These can only be detected by keyCode.\n\t\t\tevent.keyCode === 229\n\t\t) {\n\t\t\tevent.preventDefault();\n\t\t}\n\t};\n\n\tconst isLoading = Object.values( loaders ).some( Boolean );\n\n\treturn (\n\t\t<Modal\n\t\t\tclassName=\"commands-command-menu\"\n\t\t\toverlayClassName=\"commands-command-menu__overlay\"\n\t\t\tonRequestClose={ closeAndReset }\n\t\t\t__experimentalHideHeader\n\t\t>\n\t\t\t<div className=\"commands-command-menu__container\">\n\t\t\t\t<Command\n\t\t\t\t\tlabel={ __( 'Command palette' ) }\n\t\t\t\t\tonKeyDown={ onKeyDown }\n\t\t\t\t>\n\t\t\t\t\t<div className=\"commands-command-menu__header\">\n\t\t\t\t\t\t<CommandInput\n\t\t\t\t\t\t\tsearch={ search }\n\t\t\t\t\t\t\tsetSearch={ setSearch }\n\t\t\t\t\t\t\tisOpen={ isOpen }\n\t\t\t\t\t\t/>\n\t\t\t\t\t</div>\n\t\t\t\t\t<Command.List>\n\t\t\t\t\t\t{ search && ! isLoading && (\n\t\t\t\t\t\t\t<Command.Empty>\n\t\t\t\t\t\t\t\t{ __( 'No results found.' ) }\n\t\t\t\t\t\t\t</Command.Empty>\n\t\t\t\t\t\t) }\n\t\t\t\t\t\t<CommandMenuGroup\n\t\t\t\t\t\t\tsearch={ search }\n\t\t\t\t\t\t\tsetLoader={ setLoader }\n\t\t\t\t\t\t\tclose={ closeAndReset }\n\t\t\t\t\t\t\tisContextual\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t{ search && (\n\t\t\t\t\t\t\t<CommandMenuGroup\n\t\t\t\t\t\t\t\tsearch={ search }\n\t\t\t\t\t\t\t\tsetLoader={ setLoader }\n\t\t\t\t\t\t\t\tclose={ closeAndReset }\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t) }\n\t\t\t\t\t</Command.List>\n\t\t\t\t</Command>\n\t\t\t</div>\n\t\t</Modal>\n\t);\n}\n"]}
@@ -3,13 +3,13 @@ import { createElement, Fragment } from "@wordpress/element";
3
3
  /**
4
4
  * External dependencies
5
5
  */
6
- import { Command } from 'cmdk';
6
+ import { Command, useCommandState } from 'cmdk';
7
7
  /**
8
8
  * WordPress dependencies
9
9
  */
10
10
 
11
11
  import { useSelect, useDispatch } from '@wordpress/data';
12
- import { useState, useEffect, useRef, useCallback } from '@wordpress/element';
12
+ import { useState, useEffect, useRef, useCallback, useMemo } from '@wordpress/element';
13
13
  import { __ } from '@wordpress/i18n';
14
14
  import { Modal, TextHighlight, __experimentalHStack as HStack } from '@wordpress/components';
15
15
  import { store as keyboardShortcutsStore, useShortcut } from '@wordpress/keyboard-shortcuts';
@@ -51,7 +51,8 @@ function CommandMenuLoader({
51
51
  value: (_command$searchLabel = command.searchLabel) !== null && _command$searchLabel !== void 0 ? _command$searchLabel : command.label,
52
52
  onSelect: () => command.callback({
53
53
  close
54
- })
54
+ }),
55
+ id: command.name
55
56
  }, createElement(HStack, {
56
57
  alignment: "left",
57
58
  className: "commands-command-menu__item"
@@ -123,7 +124,8 @@ export function CommandMenuGroup({
123
124
  value: (_command$searchLabel2 = command.searchLabel) !== null && _command$searchLabel2 !== void 0 ? _command$searchLabel2 : command.label,
124
125
  onSelect: () => command.callback({
125
126
  close
126
- })
127
+ }),
128
+ id: command.name
127
129
  }, createElement(HStack, {
128
130
  alignment: "left",
129
131
  className: "commands-command-menu__item"
@@ -141,6 +143,35 @@ export function CommandMenuGroup({
141
143
  close: close
142
144
  })));
143
145
  }
146
+
147
+ function CommandInput({
148
+ isOpen,
149
+ search,
150
+ setSearch
151
+ }) {
152
+ const commandMenuInput = useRef();
153
+
154
+ const _value = useCommandState(state => state.value);
155
+
156
+ const selectedItemId = useMemo(() => {
157
+ const item = document.querySelector(`[cmdk-item=""][data-value="${_value}"]`);
158
+ return item?.getAttribute('id');
159
+ }, [_value]);
160
+ useEffect(() => {
161
+ // Focus the command palette input when mounting the modal.
162
+ if (isOpen) {
163
+ commandMenuInput.current.focus();
164
+ }
165
+ }, [isOpen]);
166
+ return createElement(Command.Input, {
167
+ ref: commandMenuInput,
168
+ value: search,
169
+ onValueChange: setSearch,
170
+ placeholder: __('Type a command or search'),
171
+ "aria-activedescendant": selectedItemId
172
+ });
173
+ }
174
+
144
175
  export function CommandMenu() {
145
176
  const {
146
177
  registerShortcut
@@ -152,7 +183,6 @@ export function CommandMenu() {
152
183
  close
153
184
  } = useDispatch(commandsStore);
154
185
  const [loaders, setLoaders] = useState({});
155
- const commandMenuInput = useRef();
156
186
  useEffect(() => {
157
187
  registerShortcut({
158
188
  name: 'core/commands',
@@ -164,7 +194,11 @@ export function CommandMenu() {
164
194
  }
165
195
  });
166
196
  }, [registerShortcut]);
167
- useShortcut('core/commands', event => {
197
+ useShortcut('core/commands',
198
+ /** @type {import('react').KeyboardEventHandler} */
199
+ event => {
200
+ // Bails to avoid obscuring the effect of the preceding handler(s).
201
+ if (event.defaultPrevented) return;
168
202
  event.preventDefault();
169
203
 
170
204
  if (isOpen) {
@@ -184,17 +218,20 @@ export function CommandMenu() {
184
218
  close();
185
219
  };
186
220
 
187
- useEffect(() => {
188
- // Focus the command palette input when mounting the modal.
189
- if (isOpen) {
190
- commandMenuInput.current.focus();
191
- }
192
- }, [isOpen]);
193
-
194
221
  if (!isOpen) {
195
222
  return false;
196
223
  }
197
224
 
225
+ const onKeyDown = event => {
226
+ if ( // Ignore keydowns from IMEs
227
+ event.nativeEvent.isComposing || // Workaround for Mac Safari where the final Enter/Backspace of an IME composition
228
+ // is `isComposing=false`, even though it's technically still part of the composition.
229
+ // These can only be detected by keyCode.
230
+ event.keyCode === 229) {
231
+ event.preventDefault();
232
+ }
233
+ };
234
+
198
235
  const isLoading = Object.values(loaders).some(Boolean);
199
236
  return createElement(Modal, {
200
237
  className: "commands-command-menu",
@@ -204,14 +241,14 @@ export function CommandMenu() {
204
241
  }, createElement("div", {
205
242
  className: "commands-command-menu__container"
206
243
  }, createElement(Command, {
207
- label: __('Command palette')
244
+ label: __('Command palette'),
245
+ onKeyDown: onKeyDown
208
246
  }, createElement("div", {
209
247
  className: "commands-command-menu__header"
210
- }, createElement(Command.Input, {
211
- ref: commandMenuInput,
212
- value: search,
213
- onValueChange: setSearch,
214
- placeholder: __('Type a command or search')
248
+ }, createElement(CommandInput, {
249
+ search: search,
250
+ setSearch: setSearch,
251
+ isOpen: isOpen
215
252
  })), createElement(Command.List, null, search && !isLoading && createElement(Command.Empty, null, __('No results found.')), createElement(CommandMenuGroup, {
216
253
  search: search,
217
254
  setLoader: setLoader,
@@ -1 +1 @@
1
- {"version":3,"sources":["@wordpress/commands/src/components/command-menu.js"],"names":["Command","useSelect","useDispatch","useState","useEffect","useRef","useCallback","__","Modal","TextHighlight","__experimentalHStack","HStack","store","keyboardShortcutsStore","useShortcut","Icon","commandsStore","CommandMenuLoader","name","search","hook","setLoader","close","isLoading","commands","length","map","command","searchLabel","label","callback","icon","CommandMenuLoaderWrapper","currentLoader","key","setKey","current","prevKey","CommandMenuGroup","isContextual","loaders","select","getCommands","getCommandLoaders","loader","CommandMenu","registerShortcut","setSearch","isOpen","open","setLoaders","commandMenuInput","category","description","keyCombination","modifier","character","event","preventDefault","bindGlobal","value","closeAndReset","focus","Object","values","some","Boolean"],"mappings":";;AAAA;AACA;AACA;AACA,SAASA,OAAT,QAAwB,MAAxB;AAEA;AACA;AACA;;AACA,SAASC,SAAT,EAAoBC,WAApB,QAAuC,iBAAvC;AACA,SAASC,QAAT,EAAmBC,SAAnB,EAA8BC,MAA9B,EAAsCC,WAAtC,QAAyD,oBAAzD;AACA,SAASC,EAAT,QAAmB,iBAAnB;AACA,SACCC,KADD,EAECC,aAFD,EAGCC,oBAAoB,IAAIC,MAHzB,QAIO,uBAJP;AAKA,SACCC,KAAK,IAAIC,sBADV,EAECC,WAFD,QAGO,+BAHP;AAIA,SAASC,IAAT,QAAqB,kBAArB;AAEA;AACA;AACA;;AACA,SAASH,KAAK,IAAII,aAAlB,QAAuC,UAAvC;;AAEA,SAASC,iBAAT,CAA4B;AAAEC,EAAAA,IAAF;AAAQC,EAAAA,MAAR;AAAgBC,EAAAA,IAAhB;AAAsBC,EAAAA,SAAtB;AAAiCC,EAAAA;AAAjC,CAA5B,EAAuE;AAAA;;AACtE,QAAM;AAAEC,IAAAA,SAAF;AAAaC,IAAAA,QAAQ,GAAG;AAAxB,eAA+BJ,IAAI,CAAE;AAAED,IAAAA;AAAF,GAAF,CAAnC,yCAAqD,EAA3D;AACAf,EAAAA,SAAS,CAAE,MAAM;AAChBiB,IAAAA,SAAS,CAAEH,IAAF,EAAQK,SAAR,CAAT;AACA,GAFQ,EAEN,CAAEF,SAAF,EAAaH,IAAb,EAAmBK,SAAnB,CAFM,CAAT;;AAIA,MAAK,CAAEC,QAAQ,CAACC,MAAhB,EAAyB;AACxB,WAAO,IAAP;AACA;;AAED,SACC,8BACC,cAAC,OAAD,CAAS,IAAT,QACGD,QAAQ,CAACE,GAAT,CAAgBC,OAAF;AAAA;;AAAA,WACf,cAAC,OAAD,CAAS,IAAT;AACC,MAAA,GAAG,EAAGA,OAAO,CAACT,IADf;AAEC,MAAA,KAAK,0BAAGS,OAAO,CAACC,WAAX,uEAA0BD,OAAO,CAACE,KAFxC;AAGC,MAAA,QAAQ,EAAG,MAAMF,OAAO,CAACG,QAAR,CAAkB;AAAER,QAAAA;AAAF,OAAlB;AAHlB,OAKC,cAAC,MAAD;AACC,MAAA,SAAS,EAAC,MADX;AAEC,MAAA,SAAS,EAAC;AAFX,OAIC,cAAC,IAAD;AAAM,MAAA,IAAI,EAAGK,OAAO,CAACI;AAArB,MAJD,EAKC,4BACC,cAAC,aAAD;AACC,MAAA,IAAI,EAAGJ,OAAO,CAACE,KADhB;AAEC,MAAA,SAAS,EAAGV;AAFb,MADD,CALD,CALD,CADe;AAAA,GAAd,CADH,CADD,CADD;AA0BA;;AAED,OAAO,SAASa,wBAAT,CAAmC;AAAEZ,EAAAA,IAAF;AAAQD,EAAAA,MAAR;AAAgBE,EAAAA,SAAhB;AAA2BC,EAAAA;AAA3B,CAAnC,EAAwE;AAC9E;AACA;AACA;AACA;AACA;AACA,QAAMW,aAAa,GAAG5B,MAAM,CAAEe,IAAF,CAA5B;AACA,QAAM,CAAEc,GAAF,EAAOC,MAAP,IAAkBhC,QAAQ,CAAE,CAAF,CAAhC;AACAC,EAAAA,SAAS,CAAE,MAAM;AAChB,QAAK6B,aAAa,CAACG,OAAd,KAA0BhB,IAA/B,EAAsC;AACrCa,MAAAA,aAAa,CAACG,OAAd,GAAwBhB,IAAxB;AACAe,MAAAA,MAAM,CAAIE,OAAF,IAAeA,OAAO,GAAG,CAA3B,CAAN;AACA;AACD,GALQ,EAKN,CAAEjB,IAAF,CALM,CAAT;AAOA,SACC,cAAC,iBAAD;AACC,IAAA,GAAG,EAAGc,GADP;AAEC,IAAA,IAAI,EAAGD,aAAa,CAACG,OAFtB;AAGC,IAAA,MAAM,EAAGjB,MAHV;AAIC,IAAA,SAAS,EAAGE,SAJb;AAKC,IAAA,KAAK,EAAGC;AALT,IADD;AASA;AAED,OAAO,SAASgB,gBAAT,CAA2B;AAAEC,EAAAA,YAAF;AAAgBpB,EAAAA,MAAhB;AAAwBE,EAAAA,SAAxB;AAAmCC,EAAAA;AAAnC,CAA3B,EAAwE;AAC9E,QAAM;AAAEE,IAAAA,QAAF;AAAYgB,IAAAA;AAAZ,MAAwBvC,SAAS,CACpCwC,MAAF,IAAc;AACb,UAAM;AAAEC,MAAAA,WAAF;AAAeC,MAAAA;AAAf,QAAqCF,MAAM,CAAEzB,aAAF,CAAjD;AACA,WAAO;AACNQ,MAAAA,QAAQ,EAAEkB,WAAW,CAAEH,YAAF,CADf;AAENC,MAAAA,OAAO,EAAEG,iBAAiB,CAAEJ,YAAF;AAFpB,KAAP;AAIA,GAPqC,EAQtC,CAAEA,YAAF,CARsC,CAAvC;;AAWA,MAAK,CAAEf,QAAQ,CAACC,MAAX,IAAqB,CAAEe,OAAO,CAACf,MAApC,EAA6C;AAC5C,WAAO,IAAP;AACA;;AAED,SACC,cAAC,OAAD,CAAS,KAAT,QACGD,QAAQ,CAACE,GAAT,CAAgBC,OAAF;AAAA;;AAAA,WACf,cAAC,OAAD,CAAS,IAAT;AACC,MAAA,GAAG,EAAGA,OAAO,CAACT,IADf;AAEC,MAAA,KAAK,2BAAGS,OAAO,CAACC,WAAX,yEAA0BD,OAAO,CAACE,KAFxC;AAGC,MAAA,QAAQ,EAAG,MAAMF,OAAO,CAACG,QAAR,CAAkB;AAAER,QAAAA;AAAF,OAAlB;AAHlB,OAKC,cAAC,MAAD;AACC,MAAA,SAAS,EAAC,MADX;AAEC,MAAA,SAAS,EAAC;AAFX,OAIC,cAAC,IAAD;AAAM,MAAA,IAAI,EAAGK,OAAO,CAACI;AAArB,MAJD,EAKC,4BACC,cAAC,aAAD;AACC,MAAA,IAAI,EAAGJ,OAAO,CAACE,KADhB;AAEC,MAAA,SAAS,EAAGV;AAFb,MADD,CALD,CALD,CADe;AAAA,GAAd,CADH,EAqBGqB,OAAO,CAACd,GAAR,CAAekB,MAAF,IACd,cAAC,wBAAD;AACC,IAAA,GAAG,EAAGA,MAAM,CAAC1B,IADd;AAEC,IAAA,IAAI,EAAG0B,MAAM,CAACxB,IAFf;AAGC,IAAA,MAAM,EAAGD,MAHV;AAIC,IAAA,SAAS,EAAGE,SAJb;AAKC,IAAA,KAAK,EAAGC;AALT,IADC,CArBH,CADD;AAiCA;AAED,OAAO,SAASuB,WAAT,GAAuB;AAC7B,QAAM;AAAEC,IAAAA;AAAF,MAAuB5C,WAAW,CAAEW,sBAAF,CAAxC;AACA,QAAM,CAAEM,MAAF,EAAU4B,SAAV,IAAwB5C,QAAQ,CAAE,EAAF,CAAtC;AACA,QAAM6C,MAAM,GAAG/C,SAAS,CACrBwC,MAAF,IAAcA,MAAM,CAAEzB,aAAF,CAAN,CAAwBgC,MAAxB,EADS,EAEvB,EAFuB,CAAxB;AAIA,QAAM;AAAEC,IAAAA,IAAF;AAAQ3B,IAAAA;AAAR,MAAkBpB,WAAW,CAAEc,aAAF,CAAnC;AACA,QAAM,CAAEwB,OAAF,EAAWU,UAAX,IAA0B/C,QAAQ,CAAE,EAAF,CAAxC;AACA,QAAMgD,gBAAgB,GAAG9C,MAAM,EAA/B;AAEAD,EAAAA,SAAS,CAAE,MAAM;AAChB0C,IAAAA,gBAAgB,CAAE;AACjB5B,MAAAA,IAAI,EAAE,eADW;AAEjBkC,MAAAA,QAAQ,EAAE,QAFO;AAGjBC,MAAAA,WAAW,EAAE9C,EAAE,CAAE,0BAAF,CAHE;AAIjB+C,MAAAA,cAAc,EAAE;AACfC,QAAAA,QAAQ,EAAE,SADK;AAEfC,QAAAA,SAAS,EAAE;AAFI;AAJC,KAAF,CAAhB;AASA,GAVQ,EAUN,CAAEV,gBAAF,CAVM,CAAT;AAYAhC,EAAAA,WAAW,CACV,eADU,EAER2C,KAAF,IAAa;AACZA,IAAAA,KAAK,CAACC,cAAN;;AACA,QAAKV,MAAL,EAAc;AACb1B,MAAAA,KAAK;AACL,KAFD,MAEO;AACN2B,MAAAA,IAAI;AACJ;AACD,GATS,EAUV;AACCU,IAAAA,UAAU,EAAE;AADb,GAVU,CAAX;AAeA,QAAMtC,SAAS,GAAGf,WAAW,CAC5B,CAAEY,IAAF,EAAQ0C,KAAR,KACCV,UAAU,CAAId,OAAF,KAAiB,EAC5B,GAAGA,OADyB;AAE5B,KAAElB,IAAF,GAAU0C;AAFkB,GAAjB,CAAF,CAFiB,EAM5B,EAN4B,CAA7B;;AAQA,QAAMC,aAAa,GAAG,MAAM;AAC3Bd,IAAAA,SAAS,CAAE,EAAF,CAAT;AACAzB,IAAAA,KAAK;AACL,GAHD;;AAKAlB,EAAAA,SAAS,CAAE,MAAM;AAChB;AACA,QAAK4C,MAAL,EAAc;AACbG,MAAAA,gBAAgB,CAACf,OAAjB,CAAyB0B,KAAzB;AACA;AACD,GALQ,EAKN,CAAEd,MAAF,CALM,CAAT;;AAOA,MAAK,CAAEA,MAAP,EAAgB;AACf,WAAO,KAAP;AACA;;AACD,QAAMzB,SAAS,GAAGwC,MAAM,CAACC,MAAP,CAAexB,OAAf,EAAyByB,IAAzB,CAA+BC,OAA/B,CAAlB;AAEA,SACC,cAAC,KAAD;AACC,IAAA,SAAS,EAAC,uBADX;AAEC,IAAA,gBAAgB,EAAC,gCAFlB;AAGC,IAAA,cAAc,EAAGL,aAHlB;AAIC,IAAA,wBAAwB;AAJzB,KAMC;AAAK,IAAA,SAAS,EAAC;AAAf,KACC,cAAC,OAAD;AAAS,IAAA,KAAK,EAAGtD,EAAE,CAAE,iBAAF;AAAnB,KACC;AAAK,IAAA,SAAS,EAAC;AAAf,KACC,cAAC,OAAD,CAAS,KAAT;AACC,IAAA,GAAG,EAAG4C,gBADP;AAEC,IAAA,KAAK,EAAGhC,MAFT;AAGC,IAAA,aAAa,EAAG4B,SAHjB;AAIC,IAAA,WAAW,EAAGxC,EAAE,CAAE,0BAAF;AAJjB,IADD,CADD,EASC,cAAC,OAAD,CAAS,IAAT,QACGY,MAAM,IAAI,CAAEI,SAAZ,IACD,cAAC,OAAD,CAAS,KAAT,QACGhB,EAAE,CAAE,mBAAF,CADL,CAFF,EAMC,cAAC,gBAAD;AACC,IAAA,MAAM,EAAGY,MADV;AAEC,IAAA,SAAS,EAAGE,SAFb;AAGC,IAAA,KAAK,EAAGwC,aAHT;AAIC,IAAA,YAAY;AAJb,IAND,EAYG1C,MAAM,IACP,cAAC,gBAAD;AACC,IAAA,MAAM,EAAGA,MADV;AAEC,IAAA,SAAS,EAAGE,SAFb;AAGC,IAAA,KAAK,EAAGwC;AAHT,IAbF,CATD,CADD,CAND,CADD;AAyCA","sourcesContent":["/**\n * External dependencies\n */\nimport { Command } from 'cmdk';\n\n/**\n * WordPress dependencies\n */\nimport { useSelect, useDispatch } from '@wordpress/data';\nimport { useState, useEffect, useRef, useCallback } from '@wordpress/element';\nimport { __ } from '@wordpress/i18n';\nimport {\n\tModal,\n\tTextHighlight,\n\t__experimentalHStack as HStack,\n} from '@wordpress/components';\nimport {\n\tstore as keyboardShortcutsStore,\n\tuseShortcut,\n} from '@wordpress/keyboard-shortcuts';\nimport { Icon } from '@wordpress/icons';\n\n/**\n * Internal dependencies\n */\nimport { store as commandsStore } from '../store';\n\nfunction CommandMenuLoader( { name, search, hook, setLoader, close } ) {\n\tconst { isLoading, commands = [] } = hook( { search } ) ?? {};\n\tuseEffect( () => {\n\t\tsetLoader( name, isLoading );\n\t}, [ setLoader, name, isLoading ] );\n\n\tif ( ! commands.length ) {\n\t\treturn null;\n\t}\n\n\treturn (\n\t\t<>\n\t\t\t<Command.List>\n\t\t\t\t{ commands.map( ( command ) => (\n\t\t\t\t\t<Command.Item\n\t\t\t\t\t\tkey={ command.name }\n\t\t\t\t\t\tvalue={ command.searchLabel ?? command.label }\n\t\t\t\t\t\tonSelect={ () => command.callback( { close } ) }\n\t\t\t\t\t>\n\t\t\t\t\t\t<HStack\n\t\t\t\t\t\t\talignment=\"left\"\n\t\t\t\t\t\t\tclassName=\"commands-command-menu__item\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Icon icon={ command.icon } />\n\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t<TextHighlight\n\t\t\t\t\t\t\t\t\ttext={ command.label }\n\t\t\t\t\t\t\t\t\thighlight={ search }\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</HStack>\n\t\t\t\t\t</Command.Item>\n\t\t\t\t) ) }\n\t\t\t</Command.List>\n\t\t</>\n\t);\n}\n\nexport function CommandMenuLoaderWrapper( { hook, search, setLoader, close } ) {\n\t// The \"hook\" prop is actually a custom React hook\n\t// so to avoid breaking the rules of hooks\n\t// the CommandMenuLoaderWrapper component need to be\n\t// remounted on each hook prop change\n\t// We use the key state to make sure we do that properly.\n\tconst currentLoader = useRef( hook );\n\tconst [ key, setKey ] = useState( 0 );\n\tuseEffect( () => {\n\t\tif ( currentLoader.current !== hook ) {\n\t\t\tcurrentLoader.current = hook;\n\t\t\tsetKey( ( prevKey ) => prevKey + 1 );\n\t\t}\n\t}, [ hook ] );\n\n\treturn (\n\t\t<CommandMenuLoader\n\t\t\tkey={ key }\n\t\t\thook={ currentLoader.current }\n\t\t\tsearch={ search }\n\t\t\tsetLoader={ setLoader }\n\t\t\tclose={ close }\n\t\t/>\n\t);\n}\n\nexport function CommandMenuGroup( { isContextual, search, setLoader, close } ) {\n\tconst { commands, loaders } = useSelect(\n\t\t( select ) => {\n\t\t\tconst { getCommands, getCommandLoaders } = select( commandsStore );\n\t\t\treturn {\n\t\t\t\tcommands: getCommands( isContextual ),\n\t\t\t\tloaders: getCommandLoaders( isContextual ),\n\t\t\t};\n\t\t},\n\t\t[ isContextual ]\n\t);\n\n\tif ( ! commands.length && ! loaders.length ) {\n\t\treturn null;\n\t}\n\n\treturn (\n\t\t<Command.Group>\n\t\t\t{ commands.map( ( command ) => (\n\t\t\t\t<Command.Item\n\t\t\t\t\tkey={ command.name }\n\t\t\t\t\tvalue={ command.searchLabel ?? command.label }\n\t\t\t\t\tonSelect={ () => command.callback( { close } ) }\n\t\t\t\t>\n\t\t\t\t\t<HStack\n\t\t\t\t\t\talignment=\"left\"\n\t\t\t\t\t\tclassName=\"commands-command-menu__item\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<Icon icon={ command.icon } />\n\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t<TextHighlight\n\t\t\t\t\t\t\t\ttext={ command.label }\n\t\t\t\t\t\t\t\thighlight={ search }\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</HStack>\n\t\t\t\t</Command.Item>\n\t\t\t) ) }\n\t\t\t{ loaders.map( ( loader ) => (\n\t\t\t\t<CommandMenuLoaderWrapper\n\t\t\t\t\tkey={ loader.name }\n\t\t\t\t\thook={ loader.hook }\n\t\t\t\t\tsearch={ search }\n\t\t\t\t\tsetLoader={ setLoader }\n\t\t\t\t\tclose={ close }\n\t\t\t\t/>\n\t\t\t) ) }\n\t\t</Command.Group>\n\t);\n}\n\nexport function CommandMenu() {\n\tconst { registerShortcut } = useDispatch( keyboardShortcutsStore );\n\tconst [ search, setSearch ] = useState( '' );\n\tconst isOpen = useSelect(\n\t\t( select ) => select( commandsStore ).isOpen(),\n\t\t[]\n\t);\n\tconst { open, close } = useDispatch( commandsStore );\n\tconst [ loaders, setLoaders ] = useState( {} );\n\tconst commandMenuInput = useRef();\n\n\tuseEffect( () => {\n\t\tregisterShortcut( {\n\t\t\tname: 'core/commands',\n\t\t\tcategory: 'global',\n\t\t\tdescription: __( 'Open the command palette' ),\n\t\t\tkeyCombination: {\n\t\t\t\tmodifier: 'primary',\n\t\t\t\tcharacter: 'k',\n\t\t\t},\n\t\t} );\n\t}, [ registerShortcut ] );\n\n\tuseShortcut(\n\t\t'core/commands',\n\t\t( event ) => {\n\t\t\tevent.preventDefault();\n\t\t\tif ( isOpen ) {\n\t\t\t\tclose();\n\t\t\t} else {\n\t\t\t\topen();\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tbindGlobal: true,\n\t\t}\n\t);\n\n\tconst setLoader = useCallback(\n\t\t( name, value ) =>\n\t\t\tsetLoaders( ( current ) => ( {\n\t\t\t\t...current,\n\t\t\t\t[ name ]: value,\n\t\t\t} ) ),\n\t\t[]\n\t);\n\tconst closeAndReset = () => {\n\t\tsetSearch( '' );\n\t\tclose();\n\t};\n\n\tuseEffect( () => {\n\t\t// Focus the command palette input when mounting the modal.\n\t\tif ( isOpen ) {\n\t\t\tcommandMenuInput.current.focus();\n\t\t}\n\t}, [ isOpen ] );\n\n\tif ( ! isOpen ) {\n\t\treturn false;\n\t}\n\tconst isLoading = Object.values( loaders ).some( Boolean );\n\n\treturn (\n\t\t<Modal\n\t\t\tclassName=\"commands-command-menu\"\n\t\t\toverlayClassName=\"commands-command-menu__overlay\"\n\t\t\tonRequestClose={ closeAndReset }\n\t\t\t__experimentalHideHeader\n\t\t>\n\t\t\t<div className=\"commands-command-menu__container\">\n\t\t\t\t<Command label={ __( 'Command palette' ) }>\n\t\t\t\t\t<div className=\"commands-command-menu__header\">\n\t\t\t\t\t\t<Command.Input\n\t\t\t\t\t\t\tref={ commandMenuInput }\n\t\t\t\t\t\t\tvalue={ search }\n\t\t\t\t\t\t\tonValueChange={ setSearch }\n\t\t\t\t\t\t\tplaceholder={ __( 'Type a command or search' ) }\n\t\t\t\t\t\t/>\n\t\t\t\t\t</div>\n\t\t\t\t\t<Command.List>\n\t\t\t\t\t\t{ search && ! isLoading && (\n\t\t\t\t\t\t\t<Command.Empty>\n\t\t\t\t\t\t\t\t{ __( 'No results found.' ) }\n\t\t\t\t\t\t\t</Command.Empty>\n\t\t\t\t\t\t) }\n\t\t\t\t\t\t<CommandMenuGroup\n\t\t\t\t\t\t\tsearch={ search }\n\t\t\t\t\t\t\tsetLoader={ setLoader }\n\t\t\t\t\t\t\tclose={ closeAndReset }\n\t\t\t\t\t\t\tisContextual\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t{ search && (\n\t\t\t\t\t\t\t<CommandMenuGroup\n\t\t\t\t\t\t\t\tsearch={ search }\n\t\t\t\t\t\t\t\tsetLoader={ setLoader }\n\t\t\t\t\t\t\t\tclose={ closeAndReset }\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t) }\n\t\t\t\t\t</Command.List>\n\t\t\t\t</Command>\n\t\t\t</div>\n\t\t</Modal>\n\t);\n}\n"]}
1
+ {"version":3,"sources":["@wordpress/commands/src/components/command-menu.js"],"names":["Command","useCommandState","useSelect","useDispatch","useState","useEffect","useRef","useCallback","useMemo","__","Modal","TextHighlight","__experimentalHStack","HStack","store","keyboardShortcutsStore","useShortcut","Icon","commandsStore","CommandMenuLoader","name","search","hook","setLoader","close","isLoading","commands","length","map","command","searchLabel","label","callback","icon","CommandMenuLoaderWrapper","currentLoader","key","setKey","current","prevKey","CommandMenuGroup","isContextual","loaders","select","getCommands","getCommandLoaders","loader","CommandInput","isOpen","setSearch","commandMenuInput","_value","state","value","selectedItemId","item","document","querySelector","getAttribute","focus","CommandMenu","registerShortcut","open","setLoaders","category","description","keyCombination","modifier","character","event","defaultPrevented","preventDefault","bindGlobal","closeAndReset","onKeyDown","nativeEvent","isComposing","keyCode","Object","values","some","Boolean"],"mappings":";;AAAA;AACA;AACA;AACA,SAASA,OAAT,EAAkBC,eAAlB,QAAyC,MAAzC;AAEA;AACA;AACA;;AACA,SAASC,SAAT,EAAoBC,WAApB,QAAuC,iBAAvC;AACA,SACCC,QADD,EAECC,SAFD,EAGCC,MAHD,EAICC,WAJD,EAKCC,OALD,QAMO,oBANP;AAOA,SAASC,EAAT,QAAmB,iBAAnB;AACA,SACCC,KADD,EAECC,aAFD,EAGCC,oBAAoB,IAAIC,MAHzB,QAIO,uBAJP;AAKA,SACCC,KAAK,IAAIC,sBADV,EAECC,WAFD,QAGO,+BAHP;AAIA,SAASC,IAAT,QAAqB,kBAArB;AAEA;AACA;AACA;;AACA,SAASH,KAAK,IAAII,aAAlB,QAAuC,UAAvC;;AAEA,SAASC,iBAAT,CAA4B;AAAEC,EAAAA,IAAF;AAAQC,EAAAA,MAAR;AAAgBC,EAAAA,IAAhB;AAAsBC,EAAAA,SAAtB;AAAiCC,EAAAA;AAAjC,CAA5B,EAAuE;AAAA;;AACtE,QAAM;AAAEC,IAAAA,SAAF;AAAaC,IAAAA,QAAQ,GAAG;AAAxB,eAA+BJ,IAAI,CAAE;AAAED,IAAAA;AAAF,GAAF,CAAnC,yCAAqD,EAA3D;AACAhB,EAAAA,SAAS,CAAE,MAAM;AAChBkB,IAAAA,SAAS,CAAEH,IAAF,EAAQK,SAAR,CAAT;AACA,GAFQ,EAEN,CAAEF,SAAF,EAAaH,IAAb,EAAmBK,SAAnB,CAFM,CAAT;;AAIA,MAAK,CAAEC,QAAQ,CAACC,MAAhB,EAAyB;AACxB,WAAO,IAAP;AACA;;AAED,SACC,8BACC,cAAC,OAAD,CAAS,IAAT,QACGD,QAAQ,CAACE,GAAT,CAAgBC,OAAF;AAAA;;AAAA,WACf,cAAC,OAAD,CAAS,IAAT;AACC,MAAA,GAAG,EAAGA,OAAO,CAACT,IADf;AAEC,MAAA,KAAK,0BAAGS,OAAO,CAACC,WAAX,uEAA0BD,OAAO,CAACE,KAFxC;AAGC,MAAA,QAAQ,EAAG,MAAMF,OAAO,CAACG,QAAR,CAAkB;AAAER,QAAAA;AAAF,OAAlB,CAHlB;AAIC,MAAA,EAAE,EAAGK,OAAO,CAACT;AAJd,OAMC,cAAC,MAAD;AACC,MAAA,SAAS,EAAC,MADX;AAEC,MAAA,SAAS,EAAC;AAFX,OAIC,cAAC,IAAD;AAAM,MAAA,IAAI,EAAGS,OAAO,CAACI;AAArB,MAJD,EAKC,4BACC,cAAC,aAAD;AACC,MAAA,IAAI,EAAGJ,OAAO,CAACE,KADhB;AAEC,MAAA,SAAS,EAAGV;AAFb,MADD,CALD,CAND,CADe;AAAA,GAAd,CADH,CADD,CADD;AA2BA;;AAED,OAAO,SAASa,wBAAT,CAAmC;AAAEZ,EAAAA,IAAF;AAAQD,EAAAA,MAAR;AAAgBE,EAAAA,SAAhB;AAA2BC,EAAAA;AAA3B,CAAnC,EAAwE;AAC9E;AACA;AACA;AACA;AACA;AACA,QAAMW,aAAa,GAAG7B,MAAM,CAAEgB,IAAF,CAA5B;AACA,QAAM,CAAEc,GAAF,EAAOC,MAAP,IAAkBjC,QAAQ,CAAE,CAAF,CAAhC;AACAC,EAAAA,SAAS,CAAE,MAAM;AAChB,QAAK8B,aAAa,CAACG,OAAd,KAA0BhB,IAA/B,EAAsC;AACrCa,MAAAA,aAAa,CAACG,OAAd,GAAwBhB,IAAxB;AACAe,MAAAA,MAAM,CAAIE,OAAF,IAAeA,OAAO,GAAG,CAA3B,CAAN;AACA;AACD,GALQ,EAKN,CAAEjB,IAAF,CALM,CAAT;AAOA,SACC,cAAC,iBAAD;AACC,IAAA,GAAG,EAAGc,GADP;AAEC,IAAA,IAAI,EAAGD,aAAa,CAACG,OAFtB;AAGC,IAAA,MAAM,EAAGjB,MAHV;AAIC,IAAA,SAAS,EAAGE,SAJb;AAKC,IAAA,KAAK,EAAGC;AALT,IADD;AASA;AAED,OAAO,SAASgB,gBAAT,CAA2B;AAAEC,EAAAA,YAAF;AAAgBpB,EAAAA,MAAhB;AAAwBE,EAAAA,SAAxB;AAAmCC,EAAAA;AAAnC,CAA3B,EAAwE;AAC9E,QAAM;AAAEE,IAAAA,QAAF;AAAYgB,IAAAA;AAAZ,MAAwBxC,SAAS,CACpCyC,MAAF,IAAc;AACb,UAAM;AAAEC,MAAAA,WAAF;AAAeC,MAAAA;AAAf,QAAqCF,MAAM,CAAEzB,aAAF,CAAjD;AACA,WAAO;AACNQ,MAAAA,QAAQ,EAAEkB,WAAW,CAAEH,YAAF,CADf;AAENC,MAAAA,OAAO,EAAEG,iBAAiB,CAAEJ,YAAF;AAFpB,KAAP;AAIA,GAPqC,EAQtC,CAAEA,YAAF,CARsC,CAAvC;;AAWA,MAAK,CAAEf,QAAQ,CAACC,MAAX,IAAqB,CAAEe,OAAO,CAACf,MAApC,EAA6C;AAC5C,WAAO,IAAP;AACA;;AAED,SACC,cAAC,OAAD,CAAS,KAAT,QACGD,QAAQ,CAACE,GAAT,CAAgBC,OAAF;AAAA;;AAAA,WACf,cAAC,OAAD,CAAS,IAAT;AACC,MAAA,GAAG,EAAGA,OAAO,CAACT,IADf;AAEC,MAAA,KAAK,2BAAGS,OAAO,CAACC,WAAX,yEAA0BD,OAAO,CAACE,KAFxC;AAGC,MAAA,QAAQ,EAAG,MAAMF,OAAO,CAACG,QAAR,CAAkB;AAAER,QAAAA;AAAF,OAAlB,CAHlB;AAIC,MAAA,EAAE,EAAGK,OAAO,CAACT;AAJd,OAMC,cAAC,MAAD;AACC,MAAA,SAAS,EAAC,MADX;AAEC,MAAA,SAAS,EAAC;AAFX,OAIC,cAAC,IAAD;AAAM,MAAA,IAAI,EAAGS,OAAO,CAACI;AAArB,MAJD,EAKC,4BACC,cAAC,aAAD;AACC,MAAA,IAAI,EAAGJ,OAAO,CAACE,KADhB;AAEC,MAAA,SAAS,EAAGV;AAFb,MADD,CALD,CAND,CADe;AAAA,GAAd,CADH,EAsBGqB,OAAO,CAACd,GAAR,CAAekB,MAAF,IACd,cAAC,wBAAD;AACC,IAAA,GAAG,EAAGA,MAAM,CAAC1B,IADd;AAEC,IAAA,IAAI,EAAG0B,MAAM,CAACxB,IAFf;AAGC,IAAA,MAAM,EAAGD,MAHV;AAIC,IAAA,SAAS,EAAGE,SAJb;AAKC,IAAA,KAAK,EAAGC;AALT,IADC,CAtBH,CADD;AAkCA;;AAED,SAASuB,YAAT,CAAuB;AAAEC,EAAAA,MAAF;AAAU3B,EAAAA,MAAV;AAAkB4B,EAAAA;AAAlB,CAAvB,EAAuD;AACtD,QAAMC,gBAAgB,GAAG5C,MAAM,EAA/B;;AACA,QAAM6C,MAAM,GAAGlD,eAAe,CAAImD,KAAF,IAAaA,KAAK,CAACC,KAArB,CAA9B;;AACA,QAAMC,cAAc,GAAG9C,OAAO,CAAE,MAAM;AACrC,UAAM+C,IAAI,GAAGC,QAAQ,CAACC,aAAT,CACX,8BAA8BN,MAAQ,IAD3B,CAAb;AAGA,WAAOI,IAAI,EAAEG,YAAN,CAAoB,IAApB,CAAP;AACA,GAL6B,EAK3B,CAAEP,MAAF,CAL2B,CAA9B;AAMA9C,EAAAA,SAAS,CAAE,MAAM;AAChB;AACA,QAAK2C,MAAL,EAAc;AACbE,MAAAA,gBAAgB,CAACZ,OAAjB,CAAyBqB,KAAzB;AACA;AACD,GALQ,EAKN,CAAEX,MAAF,CALM,CAAT;AAMA,SACC,cAAC,OAAD,CAAS,KAAT;AACC,IAAA,GAAG,EAAGE,gBADP;AAEC,IAAA,KAAK,EAAG7B,MAFT;AAGC,IAAA,aAAa,EAAG4B,SAHjB;AAIC,IAAA,WAAW,EAAGxC,EAAE,CAAE,0BAAF,CAJjB;AAKC,6BAAwB6C;AALzB,IADD;AASA;;AAED,OAAO,SAASM,WAAT,GAAuB;AAC7B,QAAM;AAAEC,IAAAA;AAAF,MAAuB1D,WAAW,CAAEY,sBAAF,CAAxC;AACA,QAAM,CAAEM,MAAF,EAAU4B,SAAV,IAAwB7C,QAAQ,CAAE,EAAF,CAAtC;AACA,QAAM4C,MAAM,GAAG9C,SAAS,CACrByC,MAAF,IAAcA,MAAM,CAAEzB,aAAF,CAAN,CAAwB8B,MAAxB,EADS,EAEvB,EAFuB,CAAxB;AAIA,QAAM;AAAEc,IAAAA,IAAF;AAAQtC,IAAAA;AAAR,MAAkBrB,WAAW,CAAEe,aAAF,CAAnC;AACA,QAAM,CAAEwB,OAAF,EAAWqB,UAAX,IAA0B3D,QAAQ,CAAE,EAAF,CAAxC;AAEAC,EAAAA,SAAS,CAAE,MAAM;AAChBwD,IAAAA,gBAAgB,CAAE;AACjBzC,MAAAA,IAAI,EAAE,eADW;AAEjB4C,MAAAA,QAAQ,EAAE,QAFO;AAGjBC,MAAAA,WAAW,EAAExD,EAAE,CAAE,0BAAF,CAHE;AAIjByD,MAAAA,cAAc,EAAE;AACfC,QAAAA,QAAQ,EAAE,SADK;AAEfC,QAAAA,SAAS,EAAE;AAFI;AAJC,KAAF,CAAhB;AASA,GAVQ,EAUN,CAAEP,gBAAF,CAVM,CAAT;AAYA7C,EAAAA,WAAW,CACV,eADU;AAEV;AACEqD,EAAAA,KAAF,IAAa;AACZ;AACA,QAAKA,KAAK,CAACC,gBAAX,EAA8B;AAE9BD,IAAAA,KAAK,CAACE,cAAN;;AACA,QAAKvB,MAAL,EAAc;AACbxB,MAAAA,KAAK;AACL,KAFD,MAEO;AACNsC,MAAAA,IAAI;AACJ;AACD,GAbS,EAcV;AACCU,IAAAA,UAAU,EAAE;AADb,GAdU,CAAX;AAmBA,QAAMjD,SAAS,GAAGhB,WAAW,CAC5B,CAAEa,IAAF,EAAQiC,KAAR,KACCU,UAAU,CAAIzB,OAAF,KAAiB,EAC5B,GAAGA,OADyB;AAE5B,KAAElB,IAAF,GAAUiC;AAFkB,GAAjB,CAAF,CAFiB,EAM5B,EAN4B,CAA7B;;AAQA,QAAMoB,aAAa,GAAG,MAAM;AAC3BxB,IAAAA,SAAS,CAAE,EAAF,CAAT;AACAzB,IAAAA,KAAK;AACL,GAHD;;AAKA,MAAK,CAAEwB,MAAP,EAAgB;AACf,WAAO,KAAP;AACA;;AAED,QAAM0B,SAAS,GAAKL,KAAF,IAAa;AAC9B,SACC;AACAA,IAAAA,KAAK,CAACM,WAAN,CAAkBC,WAAlB,IACA;AACA;AACA;AACAP,IAAAA,KAAK,CAACQ,OAAN,KAAkB,GANnB,EAOE;AACDR,MAAAA,KAAK,CAACE,cAAN;AACA;AACD,GAXD;;AAaA,QAAM9C,SAAS,GAAGqD,MAAM,CAACC,MAAP,CAAerC,OAAf,EAAyBsC,IAAzB,CAA+BC,OAA/B,CAAlB;AAEA,SACC,cAAC,KAAD;AACC,IAAA,SAAS,EAAC,uBADX;AAEC,IAAA,gBAAgB,EAAC,gCAFlB;AAGC,IAAA,cAAc,EAAGR,aAHlB;AAIC,IAAA,wBAAwB;AAJzB,KAMC;AAAK,IAAA,SAAS,EAAC;AAAf,KACC,cAAC,OAAD;AACC,IAAA,KAAK,EAAGhE,EAAE,CAAE,iBAAF,CADX;AAEC,IAAA,SAAS,EAAGiE;AAFb,KAIC;AAAK,IAAA,SAAS,EAAC;AAAf,KACC,cAAC,YAAD;AACC,IAAA,MAAM,EAAGrD,MADV;AAEC,IAAA,SAAS,EAAG4B,SAFb;AAGC,IAAA,MAAM,EAAGD;AAHV,IADD,CAJD,EAWC,cAAC,OAAD,CAAS,IAAT,QACG3B,MAAM,IAAI,CAAEI,SAAZ,IACD,cAAC,OAAD,CAAS,KAAT,QACGhB,EAAE,CAAE,mBAAF,CADL,CAFF,EAMC,cAAC,gBAAD;AACC,IAAA,MAAM,EAAGY,MADV;AAEC,IAAA,SAAS,EAAGE,SAFb;AAGC,IAAA,KAAK,EAAGkD,aAHT;AAIC,IAAA,YAAY;AAJb,IAND,EAYGpD,MAAM,IACP,cAAC,gBAAD;AACC,IAAA,MAAM,EAAGA,MADV;AAEC,IAAA,SAAS,EAAGE,SAFb;AAGC,IAAA,KAAK,EAAGkD;AAHT,IAbF,CAXD,CADD,CAND,CADD;AA2CA","sourcesContent":["/**\n * External dependencies\n */\nimport { Command, useCommandState } from 'cmdk';\n\n/**\n * WordPress dependencies\n */\nimport { useSelect, useDispatch } from '@wordpress/data';\nimport {\n\tuseState,\n\tuseEffect,\n\tuseRef,\n\tuseCallback,\n\tuseMemo,\n} from '@wordpress/element';\nimport { __ } from '@wordpress/i18n';\nimport {\n\tModal,\n\tTextHighlight,\n\t__experimentalHStack as HStack,\n} from '@wordpress/components';\nimport {\n\tstore as keyboardShortcutsStore,\n\tuseShortcut,\n} from '@wordpress/keyboard-shortcuts';\nimport { Icon } from '@wordpress/icons';\n\n/**\n * Internal dependencies\n */\nimport { store as commandsStore } from '../store';\n\nfunction CommandMenuLoader( { name, search, hook, setLoader, close } ) {\n\tconst { isLoading, commands = [] } = hook( { search } ) ?? {};\n\tuseEffect( () => {\n\t\tsetLoader( name, isLoading );\n\t}, [ setLoader, name, isLoading ] );\n\n\tif ( ! commands.length ) {\n\t\treturn null;\n\t}\n\n\treturn (\n\t\t<>\n\t\t\t<Command.List>\n\t\t\t\t{ commands.map( ( command ) => (\n\t\t\t\t\t<Command.Item\n\t\t\t\t\t\tkey={ command.name }\n\t\t\t\t\t\tvalue={ command.searchLabel ?? command.label }\n\t\t\t\t\t\tonSelect={ () => command.callback( { close } ) }\n\t\t\t\t\t\tid={ command.name }\n\t\t\t\t\t>\n\t\t\t\t\t\t<HStack\n\t\t\t\t\t\t\talignment=\"left\"\n\t\t\t\t\t\t\tclassName=\"commands-command-menu__item\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Icon icon={ command.icon } />\n\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t<TextHighlight\n\t\t\t\t\t\t\t\t\ttext={ command.label }\n\t\t\t\t\t\t\t\t\thighlight={ search }\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</HStack>\n\t\t\t\t\t</Command.Item>\n\t\t\t\t) ) }\n\t\t\t</Command.List>\n\t\t</>\n\t);\n}\n\nexport function CommandMenuLoaderWrapper( { hook, search, setLoader, close } ) {\n\t// The \"hook\" prop is actually a custom React hook\n\t// so to avoid breaking the rules of hooks\n\t// the CommandMenuLoaderWrapper component need to be\n\t// remounted on each hook prop change\n\t// We use the key state to make sure we do that properly.\n\tconst currentLoader = useRef( hook );\n\tconst [ key, setKey ] = useState( 0 );\n\tuseEffect( () => {\n\t\tif ( currentLoader.current !== hook ) {\n\t\t\tcurrentLoader.current = hook;\n\t\t\tsetKey( ( prevKey ) => prevKey + 1 );\n\t\t}\n\t}, [ hook ] );\n\n\treturn (\n\t\t<CommandMenuLoader\n\t\t\tkey={ key }\n\t\t\thook={ currentLoader.current }\n\t\t\tsearch={ search }\n\t\t\tsetLoader={ setLoader }\n\t\t\tclose={ close }\n\t\t/>\n\t);\n}\n\nexport function CommandMenuGroup( { isContextual, search, setLoader, close } ) {\n\tconst { commands, loaders } = useSelect(\n\t\t( select ) => {\n\t\t\tconst { getCommands, getCommandLoaders } = select( commandsStore );\n\t\t\treturn {\n\t\t\t\tcommands: getCommands( isContextual ),\n\t\t\t\tloaders: getCommandLoaders( isContextual ),\n\t\t\t};\n\t\t},\n\t\t[ isContextual ]\n\t);\n\n\tif ( ! commands.length && ! loaders.length ) {\n\t\treturn null;\n\t}\n\n\treturn (\n\t\t<Command.Group>\n\t\t\t{ commands.map( ( command ) => (\n\t\t\t\t<Command.Item\n\t\t\t\t\tkey={ command.name }\n\t\t\t\t\tvalue={ command.searchLabel ?? command.label }\n\t\t\t\t\tonSelect={ () => command.callback( { close } ) }\n\t\t\t\t\tid={ command.name }\n\t\t\t\t>\n\t\t\t\t\t<HStack\n\t\t\t\t\t\talignment=\"left\"\n\t\t\t\t\t\tclassName=\"commands-command-menu__item\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<Icon icon={ command.icon } />\n\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t<TextHighlight\n\t\t\t\t\t\t\t\ttext={ command.label }\n\t\t\t\t\t\t\t\thighlight={ search }\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</HStack>\n\t\t\t\t</Command.Item>\n\t\t\t) ) }\n\t\t\t{ loaders.map( ( loader ) => (\n\t\t\t\t<CommandMenuLoaderWrapper\n\t\t\t\t\tkey={ loader.name }\n\t\t\t\t\thook={ loader.hook }\n\t\t\t\t\tsearch={ search }\n\t\t\t\t\tsetLoader={ setLoader }\n\t\t\t\t\tclose={ close }\n\t\t\t\t/>\n\t\t\t) ) }\n\t\t</Command.Group>\n\t);\n}\n\nfunction CommandInput( { isOpen, search, setSearch } ) {\n\tconst commandMenuInput = useRef();\n\tconst _value = useCommandState( ( state ) => state.value );\n\tconst selectedItemId = useMemo( () => {\n\t\tconst item = document.querySelector(\n\t\t\t`[cmdk-item=\"\"][data-value=\"${ _value }\"]`\n\t\t);\n\t\treturn item?.getAttribute( 'id' );\n\t}, [ _value ] );\n\tuseEffect( () => {\n\t\t// Focus the command palette input when mounting the modal.\n\t\tif ( isOpen ) {\n\t\t\tcommandMenuInput.current.focus();\n\t\t}\n\t}, [ isOpen ] );\n\treturn (\n\t\t<Command.Input\n\t\t\tref={ commandMenuInput }\n\t\t\tvalue={ search }\n\t\t\tonValueChange={ setSearch }\n\t\t\tplaceholder={ __( 'Type a command or search' ) }\n\t\t\taria-activedescendant={ selectedItemId }\n\t\t/>\n\t);\n}\n\nexport function CommandMenu() {\n\tconst { registerShortcut } = useDispatch( keyboardShortcutsStore );\n\tconst [ search, setSearch ] = useState( '' );\n\tconst isOpen = useSelect(\n\t\t( select ) => select( commandsStore ).isOpen(),\n\t\t[]\n\t);\n\tconst { open, close } = useDispatch( commandsStore );\n\tconst [ loaders, setLoaders ] = useState( {} );\n\n\tuseEffect( () => {\n\t\tregisterShortcut( {\n\t\t\tname: 'core/commands',\n\t\t\tcategory: 'global',\n\t\t\tdescription: __( 'Open the command palette' ),\n\t\t\tkeyCombination: {\n\t\t\t\tmodifier: 'primary',\n\t\t\t\tcharacter: 'k',\n\t\t\t},\n\t\t} );\n\t}, [ registerShortcut ] );\n\n\tuseShortcut(\n\t\t'core/commands',\n\t\t/** @type {import('react').KeyboardEventHandler} */\n\t\t( event ) => {\n\t\t\t// Bails to avoid obscuring the effect of the preceding handler(s).\n\t\t\tif ( event.defaultPrevented ) return;\n\n\t\t\tevent.preventDefault();\n\t\t\tif ( isOpen ) {\n\t\t\t\tclose();\n\t\t\t} else {\n\t\t\t\topen();\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\tbindGlobal: true,\n\t\t}\n\t);\n\n\tconst setLoader = useCallback(\n\t\t( name, value ) =>\n\t\t\tsetLoaders( ( current ) => ( {\n\t\t\t\t...current,\n\t\t\t\t[ name ]: value,\n\t\t\t} ) ),\n\t\t[]\n\t);\n\tconst closeAndReset = () => {\n\t\tsetSearch( '' );\n\t\tclose();\n\t};\n\n\tif ( ! isOpen ) {\n\t\treturn false;\n\t}\n\n\tconst onKeyDown = ( event ) => {\n\t\tif (\n\t\t\t// Ignore keydowns from IMEs\n\t\t\tevent.nativeEvent.isComposing ||\n\t\t\t// Workaround for Mac Safari where the final Enter/Backspace of an IME composition\n\t\t\t// is `isComposing=false`, even though it's technically still part of the composition.\n\t\t\t// These can only be detected by keyCode.\n\t\t\tevent.keyCode === 229\n\t\t) {\n\t\t\tevent.preventDefault();\n\t\t}\n\t};\n\n\tconst isLoading = Object.values( loaders ).some( Boolean );\n\n\treturn (\n\t\t<Modal\n\t\t\tclassName=\"commands-command-menu\"\n\t\t\toverlayClassName=\"commands-command-menu__overlay\"\n\t\t\tonRequestClose={ closeAndReset }\n\t\t\t__experimentalHideHeader\n\t\t>\n\t\t\t<div className=\"commands-command-menu__container\">\n\t\t\t\t<Command\n\t\t\t\t\tlabel={ __( 'Command palette' ) }\n\t\t\t\t\tonKeyDown={ onKeyDown }\n\t\t\t\t>\n\t\t\t\t\t<div className=\"commands-command-menu__header\">\n\t\t\t\t\t\t<CommandInput\n\t\t\t\t\t\t\tsearch={ search }\n\t\t\t\t\t\t\tsetSearch={ setSearch }\n\t\t\t\t\t\t\tisOpen={ isOpen }\n\t\t\t\t\t\t/>\n\t\t\t\t\t</div>\n\t\t\t\t\t<Command.List>\n\t\t\t\t\t\t{ search && ! isLoading && (\n\t\t\t\t\t\t\t<Command.Empty>\n\t\t\t\t\t\t\t\t{ __( 'No results found.' ) }\n\t\t\t\t\t\t\t</Command.Empty>\n\t\t\t\t\t\t) }\n\t\t\t\t\t\t<CommandMenuGroup\n\t\t\t\t\t\t\tsearch={ search }\n\t\t\t\t\t\t\tsetLoader={ setLoader }\n\t\t\t\t\t\t\tclose={ closeAndReset }\n\t\t\t\t\t\t\tisContextual\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t{ search && (\n\t\t\t\t\t\t\t<CommandMenuGroup\n\t\t\t\t\t\t\t\tsearch={ search }\n\t\t\t\t\t\t\t\tsetLoader={ setLoader }\n\t\t\t\t\t\t\t\tclose={ closeAndReset }\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t) }\n\t\t\t\t\t</Command.List>\n\t\t\t\t</Command>\n\t\t\t</div>\n\t\t</Modal>\n\t);\n}\n"]}
@@ -202,7 +202,7 @@
202
202
  .commands-command-menu__container [cmdk-list-sizer] {
203
203
  position: relative;
204
204
  }
205
- .commands-command-menu__container [cmdk-group]:has([cmdk-group-items]:not(:empty)) + [cmdk-group]:has([cmdk-group-items]:not(:empty)) {
205
+ .commands-command-menu__container [cmdk-group]:has([cmdk-group-items]:not(:empty)):not([hidden]) + [cmdk-group]:has([cmdk-group-items]:not(:empty)) {
206
206
  border-top: 1px solid #e0e0e0;
207
207
  }
208
208
 
@@ -202,7 +202,7 @@
202
202
  .commands-command-menu__container [cmdk-list-sizer] {
203
203
  position: relative;
204
204
  }
205
- .commands-command-menu__container [cmdk-group]:has([cmdk-group-items]:not(:empty)) + [cmdk-group]:has([cmdk-group-items]:not(:empty)) {
205
+ .commands-command-menu__container [cmdk-group]:has([cmdk-group-items]:not(:empty)):not([hidden]) + [cmdk-group]:has([cmdk-group-items]:not(:empty)) {
206
206
  border-top: 1px solid #e0e0e0;
207
207
  }
208
208
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/commands",
3
- "version": "0.9.0",
3
+ "version": "0.10.0",
4
4
  "description": "Handles the commands menu.",
5
5
  "author": "The WordPress Contributors",
6
6
  "license": "GPL-2.0-or-later",
@@ -27,13 +27,13 @@
27
27
  "react-native": "src/index",
28
28
  "dependencies": {
29
29
  "@babel/runtime": "^7.16.0",
30
- "@wordpress/components": "^25.4.0",
31
- "@wordpress/data": "^9.8.0",
32
- "@wordpress/element": "^5.15.0",
33
- "@wordpress/i18n": "^4.38.0",
34
- "@wordpress/icons": "^9.29.0",
35
- "@wordpress/keyboard-shortcuts": "^4.15.0",
36
- "@wordpress/private-apis": "^0.20.0",
30
+ "@wordpress/components": "^25.5.0",
31
+ "@wordpress/data": "^9.9.0",
32
+ "@wordpress/element": "^5.16.0",
33
+ "@wordpress/i18n": "^4.39.0",
34
+ "@wordpress/icons": "^9.30.0",
35
+ "@wordpress/keyboard-shortcuts": "^4.16.0",
36
+ "@wordpress/private-apis": "^0.21.0",
37
37
  "cmdk": "^0.2.0",
38
38
  "rememo": "^4.0.2"
39
39
  },
@@ -43,5 +43,5 @@
43
43
  "publishConfig": {
44
44
  "access": "public"
45
45
  },
46
- "gitHead": "6f14d11ed4cb59df110a28ebaa23ecba95eb673a"
46
+ "gitHead": "b898cf1dc8e70841d1647ea0994ac6278acc18a7"
47
47
  }
@@ -1,13 +1,19 @@
1
1
  /**
2
2
  * External dependencies
3
3
  */
4
- import { Command } from 'cmdk';
4
+ import { Command, useCommandState } from 'cmdk';
5
5
 
6
6
  /**
7
7
  * WordPress dependencies
8
8
  */
9
9
  import { useSelect, useDispatch } from '@wordpress/data';
10
- import { useState, useEffect, useRef, useCallback } from '@wordpress/element';
10
+ import {
11
+ useState,
12
+ useEffect,
13
+ useRef,
14
+ useCallback,
15
+ useMemo,
16
+ } from '@wordpress/element';
11
17
  import { __ } from '@wordpress/i18n';
12
18
  import {
13
19
  Modal,
@@ -43,6 +49,7 @@ function CommandMenuLoader( { name, search, hook, setLoader, close } ) {
43
49
  key={ command.name }
44
50
  value={ command.searchLabel ?? command.label }
45
51
  onSelect={ () => command.callback( { close } ) }
52
+ id={ command.name }
46
53
  >
47
54
  <HStack
48
55
  alignment="left"
@@ -112,6 +119,7 @@ export function CommandMenuGroup( { isContextual, search, setLoader, close } ) {
112
119
  key={ command.name }
113
120
  value={ command.searchLabel ?? command.label }
114
121
  onSelect={ () => command.callback( { close } ) }
122
+ id={ command.name }
115
123
  >
116
124
  <HStack
117
125
  alignment="left"
@@ -140,6 +148,32 @@ export function CommandMenuGroup( { isContextual, search, setLoader, close } ) {
140
148
  );
141
149
  }
142
150
 
151
+ function CommandInput( { isOpen, search, setSearch } ) {
152
+ const commandMenuInput = useRef();
153
+ const _value = useCommandState( ( state ) => state.value );
154
+ const selectedItemId = useMemo( () => {
155
+ const item = document.querySelector(
156
+ `[cmdk-item=""][data-value="${ _value }"]`
157
+ );
158
+ return item?.getAttribute( 'id' );
159
+ }, [ _value ] );
160
+ useEffect( () => {
161
+ // Focus the command palette input when mounting the modal.
162
+ if ( isOpen ) {
163
+ commandMenuInput.current.focus();
164
+ }
165
+ }, [ isOpen ] );
166
+ return (
167
+ <Command.Input
168
+ ref={ commandMenuInput }
169
+ value={ search }
170
+ onValueChange={ setSearch }
171
+ placeholder={ __( 'Type a command or search' ) }
172
+ aria-activedescendant={ selectedItemId }
173
+ />
174
+ );
175
+ }
176
+
143
177
  export function CommandMenu() {
144
178
  const { registerShortcut } = useDispatch( keyboardShortcutsStore );
145
179
  const [ search, setSearch ] = useState( '' );
@@ -149,7 +183,6 @@ export function CommandMenu() {
149
183
  );
150
184
  const { open, close } = useDispatch( commandsStore );
151
185
  const [ loaders, setLoaders ] = useState( {} );
152
- const commandMenuInput = useRef();
153
186
 
154
187
  useEffect( () => {
155
188
  registerShortcut( {
@@ -165,7 +198,11 @@ export function CommandMenu() {
165
198
 
166
199
  useShortcut(
167
200
  'core/commands',
201
+ /** @type {import('react').KeyboardEventHandler} */
168
202
  ( event ) => {
203
+ // Bails to avoid obscuring the effect of the preceding handler(s).
204
+ if ( event.defaultPrevented ) return;
205
+
169
206
  event.preventDefault();
170
207
  if ( isOpen ) {
171
208
  close();
@@ -191,16 +228,23 @@ export function CommandMenu() {
191
228
  close();
192
229
  };
193
230
 
194
- useEffect( () => {
195
- // Focus the command palette input when mounting the modal.
196
- if ( isOpen ) {
197
- commandMenuInput.current.focus();
198
- }
199
- }, [ isOpen ] );
200
-
201
231
  if ( ! isOpen ) {
202
232
  return false;
203
233
  }
234
+
235
+ const onKeyDown = ( event ) => {
236
+ if (
237
+ // Ignore keydowns from IMEs
238
+ event.nativeEvent.isComposing ||
239
+ // Workaround for Mac Safari where the final Enter/Backspace of an IME composition
240
+ // is `isComposing=false`, even though it's technically still part of the composition.
241
+ // These can only be detected by keyCode.
242
+ event.keyCode === 229
243
+ ) {
244
+ event.preventDefault();
245
+ }
246
+ };
247
+
204
248
  const isLoading = Object.values( loaders ).some( Boolean );
205
249
 
206
250
  return (
@@ -211,13 +255,15 @@ export function CommandMenu() {
211
255
  __experimentalHideHeader
212
256
  >
213
257
  <div className="commands-command-menu__container">
214
- <Command label={ __( 'Command palette' ) }>
258
+ <Command
259
+ label={ __( 'Command palette' ) }
260
+ onKeyDown={ onKeyDown }
261
+ >
215
262
  <div className="commands-command-menu__header">
216
- <Command.Input
217
- ref={ commandMenuInput }
218
- value={ search }
219
- onValueChange={ setSearch }
220
- placeholder={ __( 'Type a command or search' ) }
263
+ <CommandInput
264
+ search={ search }
265
+ setSearch={ setSearch }
266
+ isOpen={ isOpen }
221
267
  />
222
268
  </div>
223
269
  <Command.List>
@@ -116,8 +116,8 @@
116
116
  position: relative;
117
117
  }
118
118
 
119
- [cmdk-group]:has([cmdk-group-items]:not(:empty)) + [cmdk-group]:has([cmdk-group-items]:not(:empty)) {
120
- border-top: 1px solid $gray-200;
119
+ [cmdk-group]:has([cmdk-group-items]:not(:empty)):not([hidden]) + [cmdk-group]:has([cmdk-group-items]:not(:empty)) {
120
+ border-top: $border-width solid $gray-200;
121
121
  }
122
122
  }
123
123