@wordpress/components 23.4.0 → 23.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 (105) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/build/autocomplete/autocompleter-ui.js +41 -17
  3. package/build/autocomplete/autocompleter-ui.js.map +1 -1
  4. package/build/autocomplete/index.js +31 -33
  5. package/build/autocomplete/index.js.map +1 -1
  6. package/build/circular-option-picker/index.js +63 -14
  7. package/build/circular-option-picker/index.js.map +1 -1
  8. package/build/circular-option-picker/types.js +6 -0
  9. package/build/circular-option-picker/types.js.map +1 -0
  10. package/build/dropdown-menu/index.js +6 -2
  11. package/build/dropdown-menu/index.js.map +1 -1
  12. package/build/higher-order/with-constrained-tabbing/index.js +9 -0
  13. package/build/higher-order/with-constrained-tabbing/index.js.map +1 -1
  14. package/build/mobile/global-styles-context/utils.native.js +2 -1
  15. package/build/mobile/global-styles-context/utils.native.js.map +1 -1
  16. package/build/range-control/index.js +1 -0
  17. package/build/range-control/index.js.map +1 -1
  18. package/build/tools-panel/context.js +2 -0
  19. package/build/tools-panel/context.js.map +1 -1
  20. package/build/tools-panel/tools-panel/hook.js +18 -12
  21. package/build/tools-panel/tools-panel/hook.js.map +1 -1
  22. package/build/tools-panel/tools-panel-item/hook.js +14 -2
  23. package/build/tools-panel/tools-panel-item/hook.js.map +1 -1
  24. package/build/ui/context/context-system-provider.js +8 -4
  25. package/build/ui/context/context-system-provider.js.map +1 -1
  26. package/build-module/autocomplete/autocompleter-ui.js +40 -19
  27. package/build-module/autocomplete/autocompleter-ui.js.map +1 -1
  28. package/build-module/autocomplete/index.js +30 -32
  29. package/build-module/autocomplete/index.js.map +1 -1
  30. package/build-module/circular-option-picker/index.js +59 -16
  31. package/build-module/circular-option-picker/index.js.map +1 -1
  32. package/build-module/circular-option-picker/types.js +2 -0
  33. package/build-module/circular-option-picker/types.js.map +1 -0
  34. package/build-module/dropdown-menu/index.js +6 -2
  35. package/build-module/dropdown-menu/index.js.map +1 -1
  36. package/build-module/higher-order/with-constrained-tabbing/index.js +9 -0
  37. package/build-module/higher-order/with-constrained-tabbing/index.js.map +1 -1
  38. package/build-module/mobile/global-styles-context/utils.native.js +2 -1
  39. package/build-module/mobile/global-styles-context/utils.native.js.map +1 -1
  40. package/build-module/range-control/index.js +1 -0
  41. package/build-module/range-control/index.js.map +1 -1
  42. package/build-module/tools-panel/context.js +2 -0
  43. package/build-module/tools-panel/context.js.map +1 -1
  44. package/build-module/tools-panel/tools-panel/hook.js +18 -12
  45. package/build-module/tools-panel/tools-panel/hook.js.map +1 -1
  46. package/build-module/tools-panel/tools-panel-item/hook.js +14 -2
  47. package/build-module/tools-panel/tools-panel-item/hook.js.map +1 -1
  48. package/build-module/ui/context/context-system-provider.js +7 -4
  49. package/build-module/ui/context/context-system-provider.js.map +1 -1
  50. package/build-style/style-rtl.css +1 -0
  51. package/build-style/style.css +1 -0
  52. package/build-types/circular-option-picker/index.d.ts +56 -7
  53. package/build-types/circular-option-picker/index.d.ts.map +1 -1
  54. package/build-types/circular-option-picker/stories/index.d.ts +14 -0
  55. package/build-types/circular-option-picker/stories/index.d.ts.map +1 -0
  56. package/build-types/circular-option-picker/types.d.ts +49 -0
  57. package/build-types/circular-option-picker/types.d.ts.map +1 -0
  58. package/build-types/dropdown-menu/index.d.ts.map +1 -1
  59. package/build-types/h-stack/stories/e2e/index.d.ts +9 -0
  60. package/build-types/h-stack/stories/e2e/index.d.ts.map +1 -0
  61. package/build-types/higher-order/with-constrained-tabbing/index.d.ts +10 -1
  62. package/build-types/higher-order/with-constrained-tabbing/index.d.ts.map +1 -1
  63. package/build-types/range-control/index.d.ts.map +1 -1
  64. package/build-types/tab-panel/stories/index.d.ts +1 -0
  65. package/build-types/tab-panel/stories/index.d.ts.map +1 -1
  66. package/build-types/tools-panel/context.d.ts.map +1 -1
  67. package/build-types/tools-panel/test/index.d.ts +2 -0
  68. package/build-types/tools-panel/test/index.d.ts.map +1 -0
  69. package/build-types/tools-panel/tools-panel/hook.d.ts +3 -1
  70. package/build-types/tools-panel/tools-panel/hook.d.ts.map +1 -1
  71. package/build-types/tools-panel/tools-panel-header/hook.d.ts +1 -1
  72. package/build-types/tools-panel/tools-panel-item/component.d.ts +1 -0
  73. package/build-types/tools-panel/tools-panel-item/component.d.ts.map +1 -1
  74. package/build-types/tools-panel/tools-panel-item/hook.d.ts.map +1 -1
  75. package/build-types/tools-panel/types.d.ts +11 -9
  76. package/build-types/tools-panel/types.d.ts.map +1 -1
  77. package/build-types/ui/context/context-system-provider.d.ts.map +1 -1
  78. package/build-types/v-stack/stories/e2e/index.d.ts +9 -0
  79. package/build-types/v-stack/stories/e2e/index.d.ts.map +1 -0
  80. package/package.json +23 -21
  81. package/src/autocomplete/autocompleter-ui.js +72 -34
  82. package/src/autocomplete/index.js +36 -36
  83. package/src/circular-option-picker/README.md +141 -0
  84. package/src/circular-option-picker/{index.js → index.tsx} +74 -14
  85. package/src/circular-option-picker/stories/index.tsx +134 -0
  86. package/src/circular-option-picker/types.ts +69 -0
  87. package/src/color-palette/test/__snapshots__/index.tsx.snap +1 -1
  88. package/src/dropdown-menu/index.js +6 -3
  89. package/src/h-stack/stories/e2e/index.tsx +36 -0
  90. package/src/higher-order/navigate-regions/style.scss +2 -1
  91. package/src/higher-order/with-constrained-tabbing/index.tsx +30 -0
  92. package/src/mobile/global-styles-context/utils.native.js +1 -0
  93. package/src/range-control/index.tsx +5 -1
  94. package/src/tab-panel/stories/index.tsx +41 -0
  95. package/src/tab-panel/test/index.tsx +794 -262
  96. package/src/tools-panel/context.ts +2 -0
  97. package/src/tools-panel/test/{index.js → index.tsx} +171 -61
  98. package/src/tools-panel/tools-panel/hook.ts +30 -11
  99. package/src/tools-panel/tools-panel-item/hook.ts +18 -2
  100. package/src/tools-panel/types.ts +12 -9
  101. package/src/tree-grid/test/__snapshots__/index.tsx.snap +1 -1
  102. package/src/ui/context/context-system-provider.js +7 -4
  103. package/src/v-stack/stories/e2e/index.tsx +36 -0
  104. package/tsconfig.tsbuildinfo +1 -1
  105. package/src/higher-order/with-constrained-tabbing/index.js +0 -22
@@ -1 +1 @@
1
- {"version":3,"sources":["@wordpress/components/src/tools-panel/tools-panel-item/hook.ts"],"names":["noop","useToolsPanelItem","props","className","hasValue","isShownByDefault","label","panelId","resetAllFilter","onDeselect","onSelect","otherProps","currentPanelId","menuItems","registerPanelItem","deregisterPanelItem","flagItemCustomization","isResetting","shouldRenderPlaceholderItems","shouldRenderPlaceholder","firstDisplayedItem","lastDisplayedItem","__experimentalFirstVisibleItemClass","__experimentalLastVisibleItemClass","hasValueCallback","resetAllFilterCallback","previousPanelId","hasMatchingPanel","menuGroup","isMenuItemChecked","wasMenuItemChecked","isRegistered","undefined","isValueSet","wasValueSet","newValueSet","isShown","cx","classes","placeholderStyle","styles","ToolsPanelItemPlaceholder","firstItemStyle","lastItemStyle","ToolsPanelItem"],"mappings":"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","sourcesContent":["/**\n * WordPress dependencies\n */\nimport { usePrevious } from '@wordpress/compose';\nimport { useCallback, useEffect, useMemo } from '@wordpress/element';\n\n/**\n * Internal dependencies\n */\nimport * as styles from '../styles';\nimport { useToolsPanelContext } from '../context';\nimport { useContextSystem, WordPressComponentProps } from '../../ui/context';\nimport { useCx } from '../../utils/hooks/use-cx';\nimport type { ToolsPanelItemProps } from '../types';\n\nconst noop = () => {};\n\nexport function useToolsPanelItem(\n\tprops: WordPressComponentProps< ToolsPanelItemProps, 'div' >\n) {\n\tconst {\n\t\tclassName,\n\t\thasValue,\n\t\tisShownByDefault = false,\n\t\tlabel,\n\t\tpanelId,\n\t\tresetAllFilter = noop,\n\t\tonDeselect,\n\t\tonSelect,\n\t\t...otherProps\n\t} = useContextSystem( props, 'ToolsPanelItem' );\n\n\tconst {\n\t\tpanelId: currentPanelId,\n\t\tmenuItems,\n\t\tregisterPanelItem,\n\t\tderegisterPanelItem,\n\t\tflagItemCustomization,\n\t\tisResetting,\n\t\tshouldRenderPlaceholderItems: shouldRenderPlaceholder,\n\t\tfirstDisplayedItem,\n\t\tlastDisplayedItem,\n\t\t__experimentalFirstVisibleItemClass,\n\t\t__experimentalLastVisibleItemClass,\n\t} = useToolsPanelContext();\n\n\tconst hasValueCallback = useCallback( hasValue, [ panelId, hasValue ] );\n\tconst resetAllFilterCallback = useCallback( resetAllFilter, [\n\t\tpanelId,\n\t\tresetAllFilter,\n\t] );\n\tconst previousPanelId = usePrevious( currentPanelId );\n\n\tconst hasMatchingPanel =\n\t\tcurrentPanelId === panelId || currentPanelId === null;\n\n\t// Registering the panel item allows the panel to include it in its\n\t// automatically generated menu and determine its initial checked status.\n\tuseEffect( () => {\n\t\tif ( hasMatchingPanel && previousPanelId !== null ) {\n\t\t\tregisterPanelItem( {\n\t\t\t\thasValue: hasValueCallback,\n\t\t\t\tisShownByDefault,\n\t\t\t\tlabel,\n\t\t\t\tresetAllFilter: resetAllFilterCallback,\n\t\t\t\tpanelId,\n\t\t\t} );\n\t\t}\n\n\t\treturn () => {\n\t\t\tif (\n\t\t\t\t( previousPanelId === null && !! currentPanelId ) ||\n\t\t\t\tcurrentPanelId === panelId\n\t\t\t) {\n\t\t\t\tderegisterPanelItem( label );\n\t\t\t}\n\t\t};\n\t}, [\n\t\tcurrentPanelId,\n\t\thasMatchingPanel,\n\t\tisShownByDefault,\n\t\tlabel,\n\t\thasValueCallback,\n\t\tpanelId,\n\t\tpreviousPanelId,\n\t\tresetAllFilterCallback,\n\t\tregisterPanelItem,\n\t\tderegisterPanelItem,\n\t] );\n\n\t// Note: `label` is used as a key when building menu item state in\n\t// `ToolsPanel`.\n\tconst menuGroup = isShownByDefault ? 'default' : 'optional';\n\tconst isMenuItemChecked = menuItems?.[ menuGroup ]?.[ label ];\n\tconst wasMenuItemChecked = usePrevious( isMenuItemChecked );\n\tconst isRegistered = menuItems?.[ menuGroup ]?.[ label ] !== undefined;\n\n\tconst isValueSet = hasValue();\n\tconst wasValueSet = usePrevious( isValueSet );\n\tconst newValueSet = isValueSet && ! wasValueSet;\n\n\t// Notify the panel when an item's value has been set.\n\t//\n\t// 1. For default controls, this is so \"reset\" appears beside its menu item.\n\t// 2. For optional controls, when the panel ID is `null`, it allows the\n\t// panel to ensure the item is toggled on for display in the menu, given the\n\t// value has been set external to the control.\n\tuseEffect( () => {\n\t\tif ( ! newValueSet ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( isShownByDefault || currentPanelId === null ) {\n\t\t\tflagItemCustomization( label, menuGroup );\n\t\t}\n\t}, [\n\t\tcurrentPanelId,\n\t\tnewValueSet,\n\t\tisShownByDefault,\n\t\tmenuGroup,\n\t\tlabel,\n\t\tflagItemCustomization,\n\t] );\n\n\t// Determine if the panel item's corresponding menu is being toggled and\n\t// trigger appropriate callback if it is.\n\tuseEffect( () => {\n\t\t// We check whether this item is currently registered as items rendered\n\t\t// via fills can persist through the parent panel being remounted.\n\t\t// See: https://github.com/WordPress/gutenberg/pull/45673\n\t\tif ( ! isRegistered || isResetting || ! hasMatchingPanel ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( isMenuItemChecked && ! isValueSet && ! wasMenuItemChecked ) {\n\t\t\tonSelect?.();\n\t\t}\n\n\t\tif ( ! isMenuItemChecked && wasMenuItemChecked ) {\n\t\t\tonDeselect?.();\n\t\t}\n\t}, [\n\t\thasMatchingPanel,\n\t\tisMenuItemChecked,\n\t\tisRegistered,\n\t\tisResetting,\n\t\tisValueSet,\n\t\twasMenuItemChecked,\n\t\tonSelect,\n\t\tonDeselect,\n\t] );\n\n\t// The item is shown if it is a default control regardless of whether it\n\t// has a value. Optional items are shown when they are checked or have\n\t// a value.\n\tconst isShown = isShownByDefault\n\t\t? menuItems?.[ menuGroup ]?.[ label ] !== undefined\n\t\t: isMenuItemChecked;\n\n\tconst cx = useCx();\n\tconst classes = useMemo( () => {\n\t\tconst placeholderStyle =\n\t\t\tshouldRenderPlaceholder &&\n\t\t\t! isShown &&\n\t\t\tstyles.ToolsPanelItemPlaceholder;\n\t\tconst firstItemStyle =\n\t\t\tfirstDisplayedItem === label && __experimentalFirstVisibleItemClass;\n\t\tconst lastItemStyle =\n\t\t\tlastDisplayedItem === label && __experimentalLastVisibleItemClass;\n\t\treturn cx(\n\t\t\tstyles.ToolsPanelItem,\n\t\t\tplaceholderStyle,\n\t\t\tclassName,\n\t\t\tfirstItemStyle,\n\t\t\tlastItemStyle\n\t\t);\n\t}, [\n\t\tisShown,\n\t\tshouldRenderPlaceholder,\n\t\tclassName,\n\t\tcx,\n\t\tfirstDisplayedItem,\n\t\tlastDisplayedItem,\n\t\t__experimentalFirstVisibleItemClass,\n\t\t__experimentalLastVisibleItemClass,\n\t\tlabel,\n\t] );\n\n\treturn {\n\t\t...otherProps,\n\t\tisShown,\n\t\tshouldRenderPlaceholder,\n\t\tclassName: classes,\n\t};\n}\n"]}
1
+ {"version":3,"sources":["@wordpress/components/src/tools-panel/tools-panel-item/hook.ts"],"names":["noop","useToolsPanelItem","props","className","hasValue","isShownByDefault","label","panelId","resetAllFilter","onDeselect","onSelect","otherProps","currentPanelId","menuItems","registerResetAllFilter","deregisterResetAllFilter","registerPanelItem","deregisterPanelItem","flagItemCustomization","isResetting","shouldRenderPlaceholderItems","shouldRenderPlaceholder","firstDisplayedItem","lastDisplayedItem","__experimentalFirstVisibleItemClass","__experimentalLastVisibleItemClass","hasValueCallback","resetAllFilterCallback","previousPanelId","hasMatchingPanel","menuGroup","isMenuItemChecked","wasMenuItemChecked","isRegistered","undefined","isValueSet","wasValueSet","newValueSet","isShown","cx","classes","placeholderStyle","styles","ToolsPanelItemPlaceholder","firstItemStyle","lastItemStyle","ToolsPanelItem"],"mappings":"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","sourcesContent":["/**\n * WordPress dependencies\n */\nimport { usePrevious } from '@wordpress/compose';\nimport { useCallback, useEffect, useMemo } from '@wordpress/element';\n\n/**\n * Internal dependencies\n */\nimport * as styles from '../styles';\nimport { useToolsPanelContext } from '../context';\nimport { useContextSystem, WordPressComponentProps } from '../../ui/context';\nimport { useCx } from '../../utils/hooks/use-cx';\nimport type { ToolsPanelItemProps } from '../types';\n\nconst noop = () => {};\n\nexport function useToolsPanelItem(\n\tprops: WordPressComponentProps< ToolsPanelItemProps, 'div' >\n) {\n\tconst {\n\t\tclassName,\n\t\thasValue,\n\t\tisShownByDefault = false,\n\t\tlabel,\n\t\tpanelId,\n\t\tresetAllFilter = noop,\n\t\tonDeselect,\n\t\tonSelect,\n\t\t...otherProps\n\t} = useContextSystem( props, 'ToolsPanelItem' );\n\n\tconst {\n\t\tpanelId: currentPanelId,\n\t\tmenuItems,\n\t\tregisterResetAllFilter,\n\t\tderegisterResetAllFilter,\n\t\tregisterPanelItem,\n\t\tderegisterPanelItem,\n\t\tflagItemCustomization,\n\t\tisResetting,\n\t\tshouldRenderPlaceholderItems: shouldRenderPlaceholder,\n\t\tfirstDisplayedItem,\n\t\tlastDisplayedItem,\n\t\t__experimentalFirstVisibleItemClass,\n\t\t__experimentalLastVisibleItemClass,\n\t} = useToolsPanelContext();\n\n\tconst hasValueCallback = useCallback( hasValue, [ panelId, hasValue ] );\n\tconst resetAllFilterCallback = useCallback( resetAllFilter, [\n\t\tpanelId,\n\t\tresetAllFilter,\n\t] );\n\tconst previousPanelId = usePrevious( currentPanelId );\n\n\tconst hasMatchingPanel =\n\t\tcurrentPanelId === panelId || currentPanelId === null;\n\n\t// Registering the panel item allows the panel to include it in its\n\t// automatically generated menu and determine its initial checked status.\n\tuseEffect( () => {\n\t\tif ( hasMatchingPanel && previousPanelId !== null ) {\n\t\t\tregisterPanelItem( {\n\t\t\t\thasValue: hasValueCallback,\n\t\t\t\tisShownByDefault,\n\t\t\t\tlabel,\n\t\t\t\tpanelId,\n\t\t\t} );\n\t\t}\n\n\t\treturn () => {\n\t\t\tif (\n\t\t\t\t( previousPanelId === null && !! currentPanelId ) ||\n\t\t\t\tcurrentPanelId === panelId\n\t\t\t) {\n\t\t\t\tderegisterPanelItem( label );\n\t\t\t}\n\t\t};\n\t}, [\n\t\tcurrentPanelId,\n\t\thasMatchingPanel,\n\t\tisShownByDefault,\n\t\tlabel,\n\t\thasValueCallback,\n\t\tpanelId,\n\t\tpreviousPanelId,\n\t\tregisterPanelItem,\n\t\tderegisterPanelItem,\n\t] );\n\n\tuseEffect( () => {\n\t\tif ( hasMatchingPanel ) {\n\t\t\tregisterResetAllFilter( resetAllFilterCallback );\n\t\t}\n\t\treturn () => {\n\t\t\tif ( hasMatchingPanel ) {\n\t\t\t\tderegisterResetAllFilter( resetAllFilterCallback );\n\t\t\t}\n\t\t};\n\t}, [\n\t\tregisterResetAllFilter,\n\t\tderegisterResetAllFilter,\n\t\tresetAllFilterCallback,\n\t\thasMatchingPanel,\n\t] );\n\n\t// Note: `label` is used as a key when building menu item state in\n\t// `ToolsPanel`.\n\tconst menuGroup = isShownByDefault ? 'default' : 'optional';\n\tconst isMenuItemChecked = menuItems?.[ menuGroup ]?.[ label ];\n\tconst wasMenuItemChecked = usePrevious( isMenuItemChecked );\n\tconst isRegistered = menuItems?.[ menuGroup ]?.[ label ] !== undefined;\n\n\tconst isValueSet = hasValue();\n\tconst wasValueSet = usePrevious( isValueSet );\n\tconst newValueSet = isValueSet && ! wasValueSet;\n\n\t// Notify the panel when an item's value has been set.\n\t//\n\t// 1. For default controls, this is so \"reset\" appears beside its menu item.\n\t// 2. For optional controls, when the panel ID is `null`, it allows the\n\t// panel to ensure the item is toggled on for display in the menu, given the\n\t// value has been set external to the control.\n\tuseEffect( () => {\n\t\tif ( ! newValueSet ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( isShownByDefault || currentPanelId === null ) {\n\t\t\tflagItemCustomization( label, menuGroup );\n\t\t}\n\t}, [\n\t\tcurrentPanelId,\n\t\tnewValueSet,\n\t\tisShownByDefault,\n\t\tmenuGroup,\n\t\tlabel,\n\t\tflagItemCustomization,\n\t] );\n\n\t// Determine if the panel item's corresponding menu is being toggled and\n\t// trigger appropriate callback if it is.\n\tuseEffect( () => {\n\t\t// We check whether this item is currently registered as items rendered\n\t\t// via fills can persist through the parent panel being remounted.\n\t\t// See: https://github.com/WordPress/gutenberg/pull/45673\n\t\tif ( ! isRegistered || isResetting || ! hasMatchingPanel ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( isMenuItemChecked && ! isValueSet && ! wasMenuItemChecked ) {\n\t\t\tonSelect?.();\n\t\t}\n\n\t\tif ( ! isMenuItemChecked && wasMenuItemChecked ) {\n\t\t\tonDeselect?.();\n\t\t}\n\t}, [\n\t\thasMatchingPanel,\n\t\tisMenuItemChecked,\n\t\tisRegistered,\n\t\tisResetting,\n\t\tisValueSet,\n\t\twasMenuItemChecked,\n\t\tonSelect,\n\t\tonDeselect,\n\t] );\n\n\t// The item is shown if it is a default control regardless of whether it\n\t// has a value. Optional items are shown when they are checked or have\n\t// a value.\n\tconst isShown = isShownByDefault\n\t\t? menuItems?.[ menuGroup ]?.[ label ] !== undefined\n\t\t: isMenuItemChecked;\n\n\tconst cx = useCx();\n\tconst classes = useMemo( () => {\n\t\tconst placeholderStyle =\n\t\t\tshouldRenderPlaceholder &&\n\t\t\t! isShown &&\n\t\t\tstyles.ToolsPanelItemPlaceholder;\n\t\tconst firstItemStyle =\n\t\t\tfirstDisplayedItem === label && __experimentalFirstVisibleItemClass;\n\t\tconst lastItemStyle =\n\t\t\tlastDisplayedItem === label && __experimentalLastVisibleItemClass;\n\t\treturn cx(\n\t\t\tstyles.ToolsPanelItem,\n\t\t\tplaceholderStyle,\n\t\t\tclassName,\n\t\t\tfirstItemStyle,\n\t\t\tlastItemStyle\n\t\t);\n\t}, [\n\t\tisShown,\n\t\tshouldRenderPlaceholder,\n\t\tclassName,\n\t\tcx,\n\t\tfirstDisplayedItem,\n\t\tlastDisplayedItem,\n\t\t__experimentalFirstVisibleItemClass,\n\t\t__experimentalLastVisibleItemClass,\n\t\tlabel,\n\t] );\n\n\treturn {\n\t\t...otherProps,\n\t\tisShown,\n\t\tshouldRenderPlaceholder,\n\t\tclassName: classes,\n\t};\n}\n"]}
@@ -9,9 +9,11 @@ exports.useComponentsContext = exports.ContextSystemProvider = exports.Component
9
9
 
10
10
  var _element = require("@wordpress/element");
11
11
 
12
+ var _deepmerge = _interopRequireDefault(require("deepmerge"));
13
+
12
14
  var _es = _interopRequireDefault(require("fast-deep-equal/es6"));
13
15
 
14
- var _lodash = require("lodash");
16
+ var _isPlainObject = require("is-plain-object");
15
17
 
16
18
  var _warning = _interopRequireDefault(require("@wordpress/warning"));
17
19
 
@@ -62,7 +64,7 @@ function useContextSystemBridge(_ref) {
62
64
  }, [value]); // `parentContext` will always be memoized (i.e., the result of this hook itself)
63
65
  // or the default value from when the `ComponentsContext` was originally
64
66
  // initialized (which will never change, it's a static variable)
65
- // so this memoization will prevent `merge` and `JSON.parse/stringify` from rerunning unless
67
+ // so this memoization will prevent `deepmerge()` from rerunning unless
66
68
  // the references to `value` change OR the `parentContext` has an actual material change
67
69
  // (because again, it's guaranteed to be memoized or a static reference to the empty object
68
70
  // so we know that the only changes for `parentContext` are material ones... i.e., why we
@@ -70,11 +72,13 @@ function useContextSystemBridge(_ref) {
70
72
  // need to bother with the `value`). The `useUpdateEffect` above will ensure that we are
71
73
  // correctly warning when the `value` isn't being properly memoized. All of that to say
72
74
  // that this should be super safe to assume that `useMemo` will only run on actual
73
- // changes to the two dependencies, therefore saving us calls to `merge` and `JSON.parse/stringify`!
75
+ // changes to the two dependencies, therefore saving us calls to `deepmerge()`!
74
76
 
75
77
  const config = (0, _element.useMemo)(() => {
76
78
  // Deep clone `parentContext` to avoid mutating it later.
77
- return (0, _lodash.merge)(JSON.parse(JSON.stringify(parentContext)), value);
79
+ return (0, _deepmerge.default)(parentContext !== null && parentContext !== void 0 ? parentContext : {}, value !== null && value !== void 0 ? value : {}, {
80
+ isMergeableObject: _isPlainObject.isPlainObject
81
+ });
78
82
  }, [parentContext, value]);
79
83
  return config;
80
84
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["@wordpress/components/src/ui/context/context-system-provider.js"],"names":["ComponentsContext","useComponentsContext","useContextSystemBridge","value","parentContext","valueRef","current","JSON","stringify","config","parse","BaseContextSystemProvider","children","contextValue","ContextSystemProvider"],"mappings":";;;;;;;;;AASA;;AANA;;AACA;;AAYA;;AAKA;;AArBA;AACA;AACA;;AAIA;AACA;AACA;;AAUA;AACA;AACA;AAGO,MAAMA,iBAAiB,GAAG;AAChC;AAAqC,EADL,CAA1B;;;AAGA,MAAMC,oBAAoB,GAAG,MAAM,yBAAYD,iBAAZ,CAAnC;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;AACA,SAASE,sBAAT,OAA6C;AAAA,MAAZ;AAAEC,IAAAA;AAAF,GAAY;AAC5C,QAAMC,aAAa,GAAGH,oBAAoB,EAA1C;AAEA,QAAMI,QAAQ,GAAG,qBAAQF,KAAR,CAAjB;AAEA,8BAAiB,MAAM;AACtB,SACC;AACA,qBAAeE,QAAQ,CAACC,OAAxB,EAAiCH,KAAjC,KACA;AACAE,IAAAA,QAAQ,CAACC,OAAT,KAAqBH,KAJtB,EAKE;AACD,qHAAO,gCAAgCI,IAAI,CAACC,SAAL,CAAgBL,KAAhB,CAAyB,EAAhE;AACA;AACD,GATD,EASG,CAAEA,KAAF,CATH,EAL4C,CAgB5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AACA,QAAMM,MAAM,GAAG,sBAAS,MAAM;AAC7B;AACA,WAAO,mBAAOF,IAAI,CAACG,KAAL,CAAYH,IAAI,CAACC,SAAL,CAAgBJ,aAAhB,CAAZ,CAAP,EAAsDD,KAAtD,CAAP;AACA,GAHc,EAGZ,CAAEC,aAAF,EAAiBD,KAAjB,CAHY,CAAf;AAKA,SAAOM,MAAP;AACA;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AACA,MAAME,yBAAyB,GAAG,SAA2B;AAAA,MAAzB;AAAEC,IAAAA,QAAF;AAAYT,IAAAA;AAAZ,GAAyB;AAC5D,QAAMU,YAAY,GAAGX,sBAAsB,CAAE;AAAEC,IAAAA;AAAF,GAAF,CAA3C;AAEA,SACC,4BAAC,iBAAD,CAAmB,QAAnB;AAA4B,IAAA,KAAK,EAAGU;AAApC,KACGD,QADH,CADD;AAKA,CARD;;AAUO,MAAME,qBAAqB,GAAG,mBAAMH,yBAAN,CAA9B","sourcesContent":["/**\n * External dependencies\n */\nimport fastDeepEqual from 'fast-deep-equal/es6';\nimport { merge } from 'lodash';\n\n/**\n * WordPress dependencies\n */\nimport {\n\tcreateContext,\n\tuseContext,\n\tuseRef,\n\tuseMemo,\n\tmemo,\n} from '@wordpress/element';\nimport warn from '@wordpress/warning';\n\n/**\n * Internal dependencies\n */\nimport { useUpdateEffect } from '../../utils';\n\nexport const ComponentsContext = createContext(\n\t/** @type {Record<string, any>} */ ( {} )\n);\nexport const useComponentsContext = () => useContext( ComponentsContext );\n\n/**\n * Consolidates incoming ContextSystem values with a (potential) parent ContextSystem value.\n *\n * Note: This function will warn if it detects an un-memoized `value`\n *\n * @param {Object} props\n * @param {Record<string, any>} props.value\n * @return {Record<string, any>} The consolidated value.\n */\nfunction useContextSystemBridge( { value } ) {\n\tconst parentContext = useComponentsContext();\n\n\tconst valueRef = useRef( value );\n\n\tuseUpdateEffect( () => {\n\t\tif (\n\t\t\t// Objects are equivalent.\n\t\t\tfastDeepEqual( valueRef.current, value ) &&\n\t\t\t// But not the same reference.\n\t\t\tvalueRef.current !== value\n\t\t) {\n\t\t\twarn( `Please memoize your context: ${ JSON.stringify( value ) }` );\n\t\t}\n\t}, [ value ] );\n\n\t// `parentContext` will always be memoized (i.e., the result of this hook itself)\n\t// or the default value from when the `ComponentsContext` was originally\n\t// initialized (which will never change, it's a static variable)\n\t// so this memoization will prevent `merge` and `JSON.parse/stringify` from rerunning unless\n\t// the references to `value` change OR the `parentContext` has an actual material change\n\t// (because again, it's guaranteed to be memoized or a static reference to the empty object\n\t// so we know that the only changes for `parentContext` are material ones... i.e., why we\n\t// don't have to warn in the `useUpdateEffect` hook above for `parentContext` and we only\n\t// need to bother with the `value`). The `useUpdateEffect` above will ensure that we are\n\t// correctly warning when the `value` isn't being properly memoized. All of that to say\n\t// that this should be super safe to assume that `useMemo` will only run on actual\n\t// changes to the two dependencies, therefore saving us calls to `merge` and `JSON.parse/stringify`!\n\tconst config = useMemo( () => {\n\t\t// Deep clone `parentContext` to avoid mutating it later.\n\t\treturn merge( JSON.parse( JSON.stringify( parentContext ) ), value );\n\t}, [ parentContext, value ] );\n\n\treturn config;\n}\n\n/**\n * A Provider component that can modify props for connected components within\n * the Context system.\n *\n * @example\n * ```jsx\n * <ContextSystemProvider value={{ Button: { size: 'small' }}}>\n * <Button>...</Button>\n * </ContextSystemProvider>\n * ```\n *\n * @template {Record<string, any>} T\n * @param {Object} options\n * @param {import('react').ReactNode} options.children Children to render.\n * @param {T} options.value Props to render into connected components.\n * @return {JSX.Element} A Provider wrapped component.\n */\nconst BaseContextSystemProvider = ( { children, value } ) => {\n\tconst contextValue = useContextSystemBridge( { value } );\n\n\treturn (\n\t\t<ComponentsContext.Provider value={ contextValue }>\n\t\t\t{ children }\n\t\t</ComponentsContext.Provider>\n\t);\n};\n\nexport const ContextSystemProvider = memo( BaseContextSystemProvider );\n"]}
1
+ {"version":3,"sources":["@wordpress/components/src/ui/context/context-system-provider.js"],"names":["ComponentsContext","useComponentsContext","useContextSystemBridge","value","parentContext","valueRef","current","JSON","stringify","config","isMergeableObject","isPlainObject","BaseContextSystemProvider","children","contextValue","ContextSystemProvider"],"mappings":";;;;;;;;;AAUA;;AAPA;;AACA;;AACA;;AAYA;;AAKA;;AAtBA;AACA;AACA;;AAKA;AACA;AACA;;AAUA;AACA;AACA;AAGO,MAAMA,iBAAiB,GAAG;AAChC;AAAqC,EADL,CAA1B;;;AAGA,MAAMC,oBAAoB,GAAG,MAAM,yBAAYD,iBAAZ,CAAnC;AAEP;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;AACA,SAASE,sBAAT,OAA6C;AAAA,MAAZ;AAAEC,IAAAA;AAAF,GAAY;AAC5C,QAAMC,aAAa,GAAGH,oBAAoB,EAA1C;AAEA,QAAMI,QAAQ,GAAG,qBAAQF,KAAR,CAAjB;AAEA,8BAAiB,MAAM;AACtB,SACC;AACA,qBAAeE,QAAQ,CAACC,OAAxB,EAAiCH,KAAjC,KACA;AACAE,IAAAA,QAAQ,CAACC,OAAT,KAAqBH,KAJtB,EAKE;AACD,qHAAO,gCAAgCI,IAAI,CAACC,SAAL,CAAgBL,KAAhB,CAAyB,EAAhE;AACA;AACD,GATD,EASG,CAAEA,KAAF,CATH,EAL4C,CAgB5C;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AACA,QAAMM,MAAM,GAAG,sBAAS,MAAM;AAC7B;AACA,WAAO,wBAAWL,aAAX,aAAWA,aAAX,cAAWA,aAAX,GAA4B,EAA5B,EAAgCD,KAAhC,aAAgCA,KAAhC,cAAgCA,KAAhC,GAAyC,EAAzC,EAA6C;AACnDO,MAAAA,iBAAiB,EAAEC;AADgC,KAA7C,CAAP;AAGA,GALc,EAKZ,CAAEP,aAAF,EAAiBD,KAAjB,CALY,CAAf;AAOA,SAAOM,MAAP;AACA;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;AACA,MAAMG,yBAAyB,GAAG,SAA2B;AAAA,MAAzB;AAAEC,IAAAA,QAAF;AAAYV,IAAAA;AAAZ,GAAyB;AAC5D,QAAMW,YAAY,GAAGZ,sBAAsB,CAAE;AAAEC,IAAAA;AAAF,GAAF,CAA3C;AAEA,SACC,4BAAC,iBAAD,CAAmB,QAAnB;AAA4B,IAAA,KAAK,EAAGW;AAApC,KACGD,QADH,CADD;AAKA,CARD;;AAUO,MAAME,qBAAqB,GAAG,mBAAMH,yBAAN,CAA9B","sourcesContent":["/**\n * External dependencies\n */\nimport deepmerge from 'deepmerge';\nimport fastDeepEqual from 'fast-deep-equal/es6';\nimport { isPlainObject } from 'is-plain-object';\n\n/**\n * WordPress dependencies\n */\nimport {\n\tcreateContext,\n\tuseContext,\n\tuseRef,\n\tuseMemo,\n\tmemo,\n} from '@wordpress/element';\nimport warn from '@wordpress/warning';\n\n/**\n * Internal dependencies\n */\nimport { useUpdateEffect } from '../../utils';\n\nexport const ComponentsContext = createContext(\n\t/** @type {Record<string, any>} */ ( {} )\n);\nexport const useComponentsContext = () => useContext( ComponentsContext );\n\n/**\n * Consolidates incoming ContextSystem values with a (potential) parent ContextSystem value.\n *\n * Note: This function will warn if it detects an un-memoized `value`\n *\n * @param {Object} props\n * @param {Record<string, any>} props.value\n * @return {Record<string, any>} The consolidated value.\n */\nfunction useContextSystemBridge( { value } ) {\n\tconst parentContext = useComponentsContext();\n\n\tconst valueRef = useRef( value );\n\n\tuseUpdateEffect( () => {\n\t\tif (\n\t\t\t// Objects are equivalent.\n\t\t\tfastDeepEqual( valueRef.current, value ) &&\n\t\t\t// But not the same reference.\n\t\t\tvalueRef.current !== value\n\t\t) {\n\t\t\twarn( `Please memoize your context: ${ JSON.stringify( value ) }` );\n\t\t}\n\t}, [ value ] );\n\n\t// `parentContext` will always be memoized (i.e., the result of this hook itself)\n\t// or the default value from when the `ComponentsContext` was originally\n\t// initialized (which will never change, it's a static variable)\n\t// so this memoization will prevent `deepmerge()` from rerunning unless\n\t// the references to `value` change OR the `parentContext` has an actual material change\n\t// (because again, it's guaranteed to be memoized or a static reference to the empty object\n\t// so we know that the only changes for `parentContext` are material ones... i.e., why we\n\t// don't have to warn in the `useUpdateEffect` hook above for `parentContext` and we only\n\t// need to bother with the `value`). The `useUpdateEffect` above will ensure that we are\n\t// correctly warning when the `value` isn't being properly memoized. All of that to say\n\t// that this should be super safe to assume that `useMemo` will only run on actual\n\t// changes to the two dependencies, therefore saving us calls to `deepmerge()`!\n\tconst config = useMemo( () => {\n\t\t// Deep clone `parentContext` to avoid mutating it later.\n\t\treturn deepmerge( parentContext ?? {}, value ?? {}, {\n\t\t\tisMergeableObject: isPlainObject,\n\t\t} );\n\t}, [ parentContext, value ] );\n\n\treturn config;\n}\n\n/**\n * A Provider component that can modify props for connected components within\n * the Context system.\n *\n * @example\n * ```jsx\n * <ContextSystemProvider value={{ Button: { size: 'small' }}}>\n * <Button>...</Button>\n * </ContextSystemProvider>\n * ```\n *\n * @template {Record<string, any>} T\n * @param {Object} options\n * @param {import('react').ReactNode} options.children Children to render.\n * @param {T} options.value Props to render into connected components.\n * @return {JSX.Element} A Provider wrapped component.\n */\nconst BaseContextSystemProvider = ( { children, value } ) => {\n\tconst contextValue = useContextSystemBridge( { value } );\n\n\treturn (\n\t\t<ComponentsContext.Provider value={ contextValue }>\n\t\t\t{ children }\n\t\t</ComponentsContext.Provider>\n\t);\n};\n\nexport const ContextSystemProvider = memo( BaseContextSystemProvider );\n"]}
@@ -1,4 +1,4 @@
1
- import { createElement } from "@wordpress/element";
1
+ import { createElement, Fragment } from "@wordpress/element";
2
2
 
3
3
  /**
4
4
  * External dependencies
@@ -8,8 +8,9 @@ import classnames from 'classnames';
8
8
  * WordPress dependencies
9
9
  */
10
10
 
11
- import { useLayoutEffect, useRef, useEffect } from '@wordpress/element';
11
+ import { useLayoutEffect, useRef, useEffect, useState } from '@wordpress/element';
12
12
  import { useAnchor } from '@wordpress/rich-text';
13
+ import { useMergeRefs, useRefEffect } from '@wordpress/compose';
13
14
  /**
14
15
  * Internal dependencies
15
16
  */
@@ -17,6 +18,8 @@ import { useAnchor } from '@wordpress/rich-text';
17
18
  import getDefaultUseItems from './get-default-use-items';
18
19
  import Button from '../button';
19
20
  import Popover from '../popover';
21
+ import { VisuallyHidden } from '../visually-hidden';
22
+ import { createPortal } from 'react-dom';
20
23
  export function getAutoCompleterUI(autocompleter) {
21
24
  const useItems = autocompleter.useItems ? autocompleter.useItems : getDefaultUseItems(autocompleter);
22
25
 
@@ -39,7 +42,16 @@ export function getAutoCompleterUI(autocompleter) {
39
42
  editableContentElement: contentRef.current,
40
43
  value
41
44
  });
45
+ const [needsA11yCompat, setNeedsA11yCompat] = useState(false);
42
46
  const popoverRef = useRef();
47
+ const popoverRefs = useMergeRefs([popoverRef, useRefEffect(node => {
48
+ if (!contentRef.current) return; // If the popover is rendered in a different document than
49
+ // the content, we need to duplicate the options list in the
50
+ // content document so that it's available to the screen
51
+ // readers, which check the DOM ID based aira-* attributes.
52
+
53
+ setNeedsA11yCompat(node.ownerDocument !== contentRef.current.ownerDocument);
54
+ }, [contentRef])]);
43
55
  useOnClickOutside(popoverRef, reset);
44
56
  useLayoutEffect(() => {
45
57
  onChangeOptions(items); // Temporarily disabling exhaustive-deps to avoid introducing unexpected side effecst.
@@ -51,28 +63,37 @@ export function getAutoCompleterUI(autocompleter) {
51
63
  return null;
52
64
  }
53
65
 
54
- return createElement(Popover, {
66
+ const ListBox = _ref2 => {
67
+ let {
68
+ Component = 'div'
69
+ } = _ref2;
70
+ return createElement(Component, {
71
+ id: listBoxId,
72
+ role: "listbox",
73
+ className: "components-autocomplete__results"
74
+ }, items.map((option, index) => createElement(Button, {
75
+ key: option.key,
76
+ id: `components-autocomplete-item-${instanceId}-${option.key}`,
77
+ role: "option",
78
+ "aria-selected": index === selectedIndex,
79
+ disabled: option.isDisabled,
80
+ className: classnames('components-autocomplete__result', className, {
81
+ 'is-selected': index === selectedIndex
82
+ }),
83
+ onClick: () => onSelect(option)
84
+ }, option.label)));
85
+ };
86
+
87
+ return createElement(Fragment, null, createElement(Popover, {
55
88
  focusOnMount: false,
56
89
  onClose: onReset,
57
90
  placement: "top-start",
58
91
  className: "components-autocomplete__popover",
59
92
  anchor: popoverAnchor,
60
- ref: popoverRef
61
- }, createElement("div", {
62
- id: listBoxId,
63
- role: "listbox",
64
- className: "components-autocomplete__results"
65
- }, items.map((option, index) => createElement(Button, {
66
- key: option.key,
67
- id: `components-autocomplete-item-${instanceId}-${option.key}`,
68
- role: "option",
69
- "aria-selected": index === selectedIndex,
70
- disabled: option.isDisabled,
71
- className: classnames('components-autocomplete__result', className, {
72
- 'is-selected': index === selectedIndex
73
- }),
74
- onClick: () => onSelect(option)
75
- }, option.label))));
93
+ ref: popoverRefs
94
+ }, createElement(ListBox, null)), contentRef.current && needsA11yCompat && createPortal(createElement(ListBox, {
95
+ Component: VisuallyHidden
96
+ }), contentRef.current.ownerDocument.body));
76
97
  }
77
98
 
78
99
  return AutocompleterUI;
@@ -1 +1 @@
1
- {"version":3,"sources":["@wordpress/components/src/autocomplete/autocompleter-ui.js"],"names":["classnames","useLayoutEffect","useRef","useEffect","useAnchor","getDefaultUseItems","Button","Popover","getAutoCompleterUI","autocompleter","useItems","AutocompleterUI","filterValue","instanceId","listBoxId","className","selectedIndex","onChangeOptions","onSelect","onReset","reset","value","contentRef","items","popoverAnchor","editableContentElement","current","popoverRef","useOnClickOutside","length","map","option","index","key","isDisabled","label","ref","handler","listener","event","contains","target","document","addEventListener","removeEventListener"],"mappings":"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","sourcesContent":["/**\n * External dependencies\n */\nimport classnames from 'classnames';\n\n/**\n * WordPress dependencies\n */\nimport { useLayoutEffect, useRef, useEffect } from '@wordpress/element';\nimport { useAnchor } from '@wordpress/rich-text';\n\n/**\n * Internal dependencies\n */\nimport getDefaultUseItems from './get-default-use-items';\nimport Button from '../button';\nimport Popover from '../popover';\n\nexport function getAutoCompleterUI( autocompleter ) {\n\tconst useItems = autocompleter.useItems\n\t\t? autocompleter.useItems\n\t\t: getDefaultUseItems( autocompleter );\n\n\tfunction AutocompleterUI( {\n\t\tfilterValue,\n\t\tinstanceId,\n\t\tlistBoxId,\n\t\tclassName,\n\t\tselectedIndex,\n\t\tonChangeOptions,\n\t\tonSelect,\n\t\tonReset,\n\t\treset,\n\t\tvalue,\n\t\tcontentRef,\n\t} ) {\n\t\tconst [ items ] = useItems( filterValue );\n\t\tconst popoverAnchor = useAnchor( {\n\t\t\teditableContentElement: contentRef.current,\n\t\t\tvalue,\n\t\t} );\n\n\t\tconst popoverRef = useRef();\n\n\t\tuseOnClickOutside( popoverRef, reset );\n\n\t\tuseLayoutEffect( () => {\n\t\t\tonChangeOptions( items );\n\t\t\t// Temporarily disabling exhaustive-deps to avoid introducing unexpected side effecst.\n\t\t\t// See https://github.com/WordPress/gutenberg/pull/41820\n\t\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t\t}, [ items ] );\n\n\t\tif ( ! items.length > 0 ) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn (\n\t\t\t<Popover\n\t\t\t\tfocusOnMount={ false }\n\t\t\t\tonClose={ onReset }\n\t\t\t\tplacement=\"top-start\"\n\t\t\t\tclassName=\"components-autocomplete__popover\"\n\t\t\t\tanchor={ popoverAnchor }\n\t\t\t\tref={ popoverRef }\n\t\t\t>\n\t\t\t\t<div\n\t\t\t\t\tid={ listBoxId }\n\t\t\t\t\trole=\"listbox\"\n\t\t\t\t\tclassName=\"components-autocomplete__results\"\n\t\t\t\t>\n\t\t\t\t\t{ items.map( ( option, index ) => (\n\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\tkey={ option.key }\n\t\t\t\t\t\t\tid={ `components-autocomplete-item-${ instanceId }-${ option.key }` }\n\t\t\t\t\t\t\trole=\"option\"\n\t\t\t\t\t\t\taria-selected={ index === selectedIndex }\n\t\t\t\t\t\t\tdisabled={ option.isDisabled }\n\t\t\t\t\t\t\tclassName={ classnames(\n\t\t\t\t\t\t\t\t'components-autocomplete__result',\n\t\t\t\t\t\t\t\tclassName,\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t'is-selected': index === selectedIndex,\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t) }\n\t\t\t\t\t\t\tonClick={ () => onSelect( option ) }\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{ option.label }\n\t\t\t\t\t\t</Button>\n\t\t\t\t\t) ) }\n\t\t\t\t</div>\n\t\t\t</Popover>\n\t\t);\n\t}\n\n\treturn AutocompleterUI;\n}\n\nfunction useOnClickOutside( ref, handler ) {\n\tuseEffect( () => {\n\t\tconst listener = ( event ) => {\n\t\t\t// Do nothing if clicking ref's element or descendent elements, or if the ref is not referencing an element\n\t\t\tif ( ! ref.current || ref.current.contains( event.target ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\thandler( event );\n\t\t};\n\t\tdocument.addEventListener( 'mousedown', listener );\n\t\tdocument.addEventListener( 'touchstart', listener );\n\t\treturn () => {\n\t\t\tdocument.removeEventListener( 'mousedown', listener );\n\t\t\tdocument.removeEventListener( 'touchstart', listener );\n\t\t};\n\t\t// Disable reason: `ref` is a ref object and should not be included in a\n\t\t// hook's dependency list.\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t}, [ handler ] );\n}\n"]}
1
+ {"version":3,"sources":["@wordpress/components/src/autocomplete/autocompleter-ui.js"],"names":["classnames","useLayoutEffect","useRef","useEffect","useState","useAnchor","useMergeRefs","useRefEffect","getDefaultUseItems","Button","Popover","VisuallyHidden","createPortal","getAutoCompleterUI","autocompleter","useItems","AutocompleterUI","filterValue","instanceId","listBoxId","className","selectedIndex","onChangeOptions","onSelect","onReset","reset","value","contentRef","items","popoverAnchor","editableContentElement","current","needsA11yCompat","setNeedsA11yCompat","popoverRef","popoverRefs","node","ownerDocument","useOnClickOutside","length","ListBox","Component","map","option","index","key","isDisabled","label","body","ref","handler","listener","event","contains","target","document","addEventListener","removeEventListener"],"mappings":"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","sourcesContent":["/**\n * External dependencies\n */\nimport classnames from 'classnames';\n\n/**\n * WordPress dependencies\n */\nimport {\n\tuseLayoutEffect,\n\tuseRef,\n\tuseEffect,\n\tuseState,\n} from '@wordpress/element';\nimport { useAnchor } from '@wordpress/rich-text';\nimport { useMergeRefs, useRefEffect } from '@wordpress/compose';\n\n/**\n * Internal dependencies\n */\nimport getDefaultUseItems from './get-default-use-items';\nimport Button from '../button';\nimport Popover from '../popover';\nimport { VisuallyHidden } from '../visually-hidden';\nimport { createPortal } from 'react-dom';\n\nexport function getAutoCompleterUI( autocompleter ) {\n\tconst useItems = autocompleter.useItems\n\t\t? autocompleter.useItems\n\t\t: getDefaultUseItems( autocompleter );\n\n\tfunction AutocompleterUI( {\n\t\tfilterValue,\n\t\tinstanceId,\n\t\tlistBoxId,\n\t\tclassName,\n\t\tselectedIndex,\n\t\tonChangeOptions,\n\t\tonSelect,\n\t\tonReset,\n\t\treset,\n\t\tvalue,\n\t\tcontentRef,\n\t} ) {\n\t\tconst [ items ] = useItems( filterValue );\n\t\tconst popoverAnchor = useAnchor( {\n\t\t\teditableContentElement: contentRef.current,\n\t\t\tvalue,\n\t\t} );\n\n\t\tconst [ needsA11yCompat, setNeedsA11yCompat ] = useState( false );\n\t\tconst popoverRef = useRef();\n\t\tconst popoverRefs = useMergeRefs( [\n\t\t\tpopoverRef,\n\t\t\tuseRefEffect(\n\t\t\t\t( node ) => {\n\t\t\t\t\tif ( ! contentRef.current ) return;\n\n\t\t\t\t\t// If the popover is rendered in a different document than\n\t\t\t\t\t// the content, we need to duplicate the options list in the\n\t\t\t\t\t// content document so that it's available to the screen\n\t\t\t\t\t// readers, which check the DOM ID based aira-* attributes.\n\t\t\t\t\tsetNeedsA11yCompat(\n\t\t\t\t\t\tnode.ownerDocument !== contentRef.current.ownerDocument\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t\t[ contentRef ]\n\t\t\t),\n\t\t] );\n\n\t\tuseOnClickOutside( popoverRef, reset );\n\n\t\tuseLayoutEffect( () => {\n\t\t\tonChangeOptions( items );\n\t\t\t// Temporarily disabling exhaustive-deps to avoid introducing unexpected side effecst.\n\t\t\t// See https://github.com/WordPress/gutenberg/pull/41820\n\t\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t\t}, [ items ] );\n\n\t\tif ( ! items.length > 0 ) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst ListBox = ( { Component = 'div' } ) => (\n\t\t\t<Component\n\t\t\t\tid={ listBoxId }\n\t\t\t\trole=\"listbox\"\n\t\t\t\tclassName=\"components-autocomplete__results\"\n\t\t\t>\n\t\t\t\t{ items.map( ( option, index ) => (\n\t\t\t\t\t<Button\n\t\t\t\t\t\tkey={ option.key }\n\t\t\t\t\t\tid={ `components-autocomplete-item-${ instanceId }-${ option.key }` }\n\t\t\t\t\t\trole=\"option\"\n\t\t\t\t\t\taria-selected={ index === selectedIndex }\n\t\t\t\t\t\tdisabled={ option.isDisabled }\n\t\t\t\t\t\tclassName={ classnames(\n\t\t\t\t\t\t\t'components-autocomplete__result',\n\t\t\t\t\t\t\tclassName,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t'is-selected': index === selectedIndex,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t) }\n\t\t\t\t\t\tonClick={ () => onSelect( option ) }\n\t\t\t\t\t>\n\t\t\t\t\t\t{ option.label }\n\t\t\t\t\t</Button>\n\t\t\t\t) ) }\n\t\t\t</Component>\n\t\t);\n\n\t\treturn (\n\t\t\t<>\n\t\t\t\t<Popover\n\t\t\t\t\tfocusOnMount={ false }\n\t\t\t\t\tonClose={ onReset }\n\t\t\t\t\tplacement=\"top-start\"\n\t\t\t\t\tclassName=\"components-autocomplete__popover\"\n\t\t\t\t\tanchor={ popoverAnchor }\n\t\t\t\t\tref={ popoverRefs }\n\t\t\t\t>\n\t\t\t\t\t<ListBox />\n\t\t\t\t</Popover>\n\t\t\t\t{ contentRef.current &&\n\t\t\t\t\tneedsA11yCompat &&\n\t\t\t\t\tcreatePortal(\n\t\t\t\t\t\t<ListBox Component={ VisuallyHidden } />,\n\t\t\t\t\t\tcontentRef.current.ownerDocument.body\n\t\t\t\t\t) }\n\t\t\t</>\n\t\t);\n\t}\n\n\treturn AutocompleterUI;\n}\n\nfunction useOnClickOutside( ref, handler ) {\n\tuseEffect( () => {\n\t\tconst listener = ( event ) => {\n\t\t\t// Do nothing if clicking ref's element or descendent elements, or if the ref is not referencing an element\n\t\t\tif ( ! ref.current || ref.current.contains( event.target ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\thandler( event );\n\t\t};\n\t\tdocument.addEventListener( 'mousedown', listener );\n\t\tdocument.addEventListener( 'touchstart', listener );\n\t\treturn () => {\n\t\t\tdocument.removeEventListener( 'mousedown', listener );\n\t\t\tdocument.removeEventListener( 'touchstart', listener );\n\t\t};\n\t\t// Disable reason: `ref` is a ref object and should not be included in a\n\t\t// hook's dependency list.\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t}, [ handler ] );\n}\n"]}
@@ -19,6 +19,7 @@ import { speak } from '@wordpress/a11y';
19
19
 
20
20
  import { getAutoCompleterUI } from './autocompleter-ui';
21
21
  import { escapeRegExp } from '../utils/strings';
22
+ const EMPTY_ARRAY = [];
22
23
  /**
23
24
  * A raw completer option.
24
25
  *
@@ -106,7 +107,7 @@ function useAutocomplete(_ref) {
106
107
  const debouncedSpeak = useDebounce(speak, 500);
107
108
  const instanceId = useInstanceId(useAutocomplete);
108
109
  const [selectedIndex, setSelectedIndex] = useState(0);
109
- const [filteredOptions, setFilteredOptions] = useState([]);
110
+ const [filteredOptions, setFilteredOptions] = useState(EMPTY_ARRAY);
110
111
  const [filterValue, setFilterValue] = useState('');
111
112
  const [autocompleter, setAutocompleter] = useState(null);
112
113
  const [AutocompleterUI, setAutocompleterUI] = useState(null);
@@ -157,7 +158,7 @@ function useAutocomplete(_ref) {
157
158
 
158
159
  function reset() {
159
160
  setSelectedIndex(0);
160
- setFilteredOptions([]);
161
+ setFilteredOptions(EMPTY_ARRAY);
161
162
  setFilterValue('');
162
163
  setAutocompleter(null);
163
164
  setAutocompleterUI(null);
@@ -251,24 +252,22 @@ function useAutocomplete(_ref) {
251
252
  }, [record]);
252
253
  useEffect(() => {
253
254
  if (!textContent) {
254
- reset();
255
+ if (autocompleter) reset();
255
256
  return;
256
257
  }
257
258
 
258
- const text = removeAccents(textContent);
259
- const textAfterSelection = getTextContent(slice(record, undefined, getTextContent(record).length));
260
259
  const completer = completers === null || completers === void 0 ? void 0 : completers.find(_ref2 => {
261
260
  let {
262
261
  triggerPrefix,
263
262
  allowContext
264
263
  } = _ref2;
265
- const index = text.lastIndexOf(triggerPrefix);
264
+ const index = textContent.lastIndexOf(triggerPrefix);
266
265
 
267
266
  if (index === -1) {
268
267
  return false;
269
268
  }
270
269
 
271
- const textWithoutTrigger = text.slice(index + triggerPrefix.length);
270
+ const textWithoutTrigger = textContent.slice(index + triggerPrefix.length);
272
271
  const tooDistantFromTrigger = textWithoutTrigger.length > 50; // 50 chars seems to be a good limit.
273
272
  // This is a final barrier to prevent the effect from completing with
274
273
  // an extremely long string, which causes the editor to slow-down
@@ -302,7 +301,9 @@ function useAutocomplete(_ref) {
302
301
  return false;
303
302
  }
304
303
 
305
- if (allowContext && !allowContext(text.slice(0, index), textAfterSelection)) {
304
+ const textAfterSelection = getTextContent(slice(record, undefined, getTextContent(record).length));
305
+
306
+ if (allowContext && !allowContext(textContent.slice(0, index), textAfterSelection)) {
306
307
  return false;
307
308
  }
308
309
 
@@ -314,11 +315,12 @@ function useAutocomplete(_ref) {
314
315
  });
315
316
 
316
317
  if (!completer) {
317
- reset();
318
+ if (autocompleter) reset();
318
319
  return;
319
320
  }
320
321
 
321
322
  const safeTrigger = escapeRegExp(completer.triggerPrefix);
323
+ const text = removeAccents(textContent);
322
324
  const match = text.slice(text.lastIndexOf(completer.triggerPrefix)).match(new RegExp(`${safeTrigger}([\u0000-\uFFFF]*)$`));
323
325
  const query = match && match[1];
324
326
  setAutocompleter(completer);
@@ -356,11 +358,24 @@ function useAutocomplete(_ref) {
356
358
  };
357
359
  }
358
360
 
361
+ function useLastDifferentValue(value) {
362
+ const history = useRef(new Set());
363
+ history.current.add(value); // Keep the history size to 2.
364
+
365
+ if (history.current.size > 2) {
366
+ history.current.delete(Array.from(history.current)[0]);
367
+ }
368
+
369
+ return Array.from(history.current)[0];
370
+ }
371
+
359
372
  export function useAutocompleteProps(options) {
360
- const [isVisible, setIsVisible] = useState(false);
361
373
  const ref = useRef();
362
- const recordAfterInput = useRef();
363
374
  const onKeyDownRef = useRef();
375
+ const {
376
+ record
377
+ } = options;
378
+ const previousRecord = useLastDifferentValue(record);
364
379
  const {
365
380
  popover,
366
381
  listBoxId,
@@ -370,37 +385,20 @@ export function useAutocompleteProps(options) {
370
385
  contentRef: ref
371
386
  });
372
387
  onKeyDownRef.current = onKeyDown;
373
- useEffect(() => {
374
- if (isVisible) {
375
- if (!recordAfterInput.current) {
376
- recordAfterInput.current = options.record;
377
- } else if (recordAfterInput.current.start !== options.record.start || recordAfterInput.current.end !== options.record.end) {
378
- setIsVisible(false);
379
- recordAfterInput.current = null;
380
- }
381
- } // eslint-disable-next-line react-hooks/exhaustive-deps
382
-
383
- }, [options.record]);
384
388
  const mergedRefs = useMergeRefs([ref, useRefEffect(element => {
385
389
  function _onKeyDown(event) {
386
390
  onKeyDownRef.current(event);
387
391
  }
388
392
 
389
- function _onInput() {
390
- // Only show auto complete UI if the user is inputting text.
391
- setIsVisible(true);
392
- recordAfterInput.current = null;
393
- }
394
-
395
393
  element.addEventListener('keydown', _onKeyDown);
396
- element.addEventListener('input', _onInput);
397
394
  return () => {
398
395
  element.removeEventListener('keydown', _onKeyDown);
399
- element.removeEventListener('input', _onInput);
400
396
  };
401
- }, [])]);
397
+ }, [])]); // We only want to show the popover if the user has typed something.
398
+
399
+ const didUserInput = record.text !== (previousRecord === null || previousRecord === void 0 ? void 0 : previousRecord.text);
402
400
 
403
- if (!isVisible) {
401
+ if (!didUserInput) {
404
402
  return {
405
403
  ref: mergedRefs
406
404
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["@wordpress/components/src/autocomplete/index.js"],"names":["removeAccents","renderToString","useEffect","useState","useRef","useMemo","__","_n","sprintf","useInstanceId","useDebounce","useMergeRefs","useRefEffect","create","slice","insert","isCollapsed","getTextContent","speak","getAutoCompleterUI","escapeRegExp","useAutocomplete","record","onChange","onReplace","completers","contentRef","debouncedSpeak","instanceId","selectedIndex","setSelectedIndex","filteredOptions","setFilteredOptions","filterValue","setFilterValue","autocompleter","setAutocompleter","AutocompleterUI","setAutocompleterUI","backspacing","insertCompletion","replacement","end","start","triggerPrefix","length","toInsert","html","select","option","getOptionCompletion","isDisabled","completion","value","action","undefined","reset","announce","options","onChangeOptions","handleKeyDown","event","current","key","defaultPrevented","isComposing","keyCode","preventDefault","textContent","text","textAfterSelection","completer","find","allowContext","index","lastIndexOf","textWithoutTrigger","tooDistantFromTrigger","mismatch","wordsFromTrigger","split","hasOneTriggerWord","matchingWhileBackspacing","test","safeTrigger","match","RegExp","query","selectedKey","className","isExpanded","listBoxId","activeId","hasSelection","onKeyDown","popover","useAutocompleteProps","isVisible","setIsVisible","ref","recordAfterInput","onKeyDownRef","mergedRefs","element","_onKeyDown","_onInput","addEventListener","removeEventListener","children","Autocomplete","isSelected","props"],"mappings":"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","sourcesContent":["/**\n * External dependencies\n */\nimport removeAccents from 'remove-accents';\n\n/**\n * WordPress dependencies\n */\nimport {\n\trenderToString,\n\tuseEffect,\n\tuseState,\n\tuseRef,\n\tuseMemo,\n} from '@wordpress/element';\nimport { __, _n, sprintf } from '@wordpress/i18n';\nimport {\n\tuseInstanceId,\n\tuseDebounce,\n\tuseMergeRefs,\n\tuseRefEffect,\n} from '@wordpress/compose';\nimport {\n\tcreate,\n\tslice,\n\tinsert,\n\tisCollapsed,\n\tgetTextContent,\n} from '@wordpress/rich-text';\nimport { speak } from '@wordpress/a11y';\n\n/**\n * Internal dependencies\n */\nimport { getAutoCompleterUI } from './autocompleter-ui';\nimport { escapeRegExp } from '../utils/strings';\n\n/**\n * A raw completer option.\n *\n * @typedef {*} CompleterOption\n */\n\n/**\n * @callback FnGetOptions\n *\n * @return {(CompleterOption[]|Promise.<CompleterOption[]>)} The completer options or a promise for them.\n */\n\n/**\n * @callback FnGetOptionKeywords\n * @param {CompleterOption} option a completer option.\n *\n * @return {string[]} list of key words to search.\n */\n\n/**\n * @callback FnIsOptionDisabled\n * @param {CompleterOption} option a completer option.\n *\n * @return {string[]} whether or not the given option is disabled.\n */\n\n/**\n * @callback FnGetOptionLabel\n * @param {CompleterOption} option a completer option.\n *\n * @return {(string|Array.<(string|WPElement)>)} list of react components to render.\n */\n\n/**\n * @callback FnAllowContext\n * @param {string} before the string before the auto complete trigger and query.\n * @param {string} after the string after the autocomplete trigger and query.\n *\n * @return {boolean} true if the completer can handle.\n */\n\n/**\n * @typedef {Object} OptionCompletion\n * @property {'insert-at-caret'|'replace'} action the intended placement of the completion.\n * @property {OptionCompletionValue} value the completion value.\n */\n\n/**\n * A completion value.\n *\n * @typedef {(string|WPElement|Object)} OptionCompletionValue\n */\n\n/**\n * @callback FnGetOptionCompletion\n * @param {CompleterOption} value the value of the completer option.\n * @param {string} query the text value of the autocomplete query.\n *\n * @return {(OptionCompletion|OptionCompletionValue)} the completion for the given option. If an\n * \t\t\t\t\t\t\t\t\t\t\t\t\t OptionCompletionValue is returned, the\n * \t\t\t\t\t\t\t\t\t\t\t\t\t completion action defaults to `insert-at-caret`.\n */\n\n/**\n * @typedef {Object} WPCompleter\n * @property {string} name a way to identify a completer, useful for selective overriding.\n * @property {?string} className A class to apply to the popup menu.\n * @property {string} triggerPrefix the prefix that will display the menu.\n * @property {(CompleterOption[]|FnGetOptions)} options the completer options or a function to get them.\n * @property {?FnGetOptionKeywords} getOptionKeywords get the keywords for a given option.\n * @property {?FnIsOptionDisabled} isOptionDisabled get whether or not the given option is disabled.\n * @property {FnGetOptionLabel} getOptionLabel get the label for a given option.\n * @property {?FnAllowContext} allowContext filter the context under which the autocomplete activates.\n * @property {FnGetOptionCompletion} getOptionCompletion get the completion associated with a given option.\n */\n\nfunction useAutocomplete( {\n\trecord,\n\tonChange,\n\tonReplace,\n\tcompleters,\n\tcontentRef,\n} ) {\n\tconst debouncedSpeak = useDebounce( speak, 500 );\n\tconst instanceId = useInstanceId( useAutocomplete );\n\tconst [ selectedIndex, setSelectedIndex ] = useState( 0 );\n\tconst [ filteredOptions, setFilteredOptions ] = useState( [] );\n\tconst [ filterValue, setFilterValue ] = useState( '' );\n\tconst [ autocompleter, setAutocompleter ] = useState( null );\n\tconst [ AutocompleterUI, setAutocompleterUI ] = useState( null );\n\tconst backspacing = useRef( false );\n\n\tfunction insertCompletion( replacement ) {\n\t\tconst end = record.start;\n\t\tconst start =\n\t\t\tend - autocompleter.triggerPrefix.length - filterValue.length;\n\t\tconst toInsert = create( { html: renderToString( replacement ) } );\n\n\t\tonChange( insert( record, toInsert, start, end ) );\n\t}\n\n\tfunction select( option ) {\n\t\tconst { getOptionCompletion } = autocompleter || {};\n\n\t\tif ( option.isDisabled ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( getOptionCompletion ) {\n\t\t\tconst completion = getOptionCompletion( option.value, filterValue );\n\n\t\t\tconst { action, value } =\n\t\t\t\tundefined === completion.action ||\n\t\t\t\tundefined === completion.value\n\t\t\t\t\t? { action: 'insert-at-caret', value: completion }\n\t\t\t\t\t: completion;\n\n\t\t\tif ( 'replace' === action ) {\n\t\t\t\tonReplace( [ value ] );\n\t\t\t\t// When replacing, the component will unmount, so don't reset\n\t\t\t\t// state (below) on an unmounted component.\n\t\t\t\treturn;\n\t\t\t} else if ( 'insert-at-caret' === action ) {\n\t\t\t\tinsertCompletion( value );\n\t\t\t}\n\t\t}\n\n\t\t// Reset autocomplete state after insertion rather than before\n\t\t// so insertion events don't cause the completion menu to redisplay.\n\t\treset();\n\t}\n\n\tfunction reset() {\n\t\tsetSelectedIndex( 0 );\n\t\tsetFilteredOptions( [] );\n\t\tsetFilterValue( '' );\n\t\tsetAutocompleter( null );\n\t\tsetAutocompleterUI( null );\n\t}\n\n\tfunction announce( options ) {\n\t\tif ( ! debouncedSpeak ) {\n\t\t\treturn;\n\t\t}\n\t\tif ( !! options.length ) {\n\t\t\tdebouncedSpeak(\n\t\t\t\tsprintf(\n\t\t\t\t\t/* translators: %d: number of results. */\n\t\t\t\t\t_n(\n\t\t\t\t\t\t'%d result found, use up and down arrow keys to navigate.',\n\t\t\t\t\t\t'%d results found, use up and down arrow keys to navigate.',\n\t\t\t\t\t\toptions.length\n\t\t\t\t\t),\n\t\t\t\t\toptions.length\n\t\t\t\t),\n\t\t\t\t'assertive'\n\t\t\t);\n\t\t} else {\n\t\t\tdebouncedSpeak( __( 'No results.' ), 'assertive' );\n\t\t}\n\t}\n\n\t/**\n\t * Load options for an autocompleter.\n\t *\n\t * @param {Array} options\n\t */\n\tfunction onChangeOptions( options ) {\n\t\tsetSelectedIndex(\n\t\t\toptions.length === filteredOptions.length ? selectedIndex : 0\n\t\t);\n\t\tsetFilteredOptions( options );\n\t\tannounce( options );\n\t}\n\n\tfunction handleKeyDown( event ) {\n\t\tbackspacing.current = event.key === 'Backspace';\n\n\t\tif ( ! autocompleter ) {\n\t\t\treturn;\n\t\t}\n\t\tif ( filteredOptions.length === 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (\n\t\t\tevent.defaultPrevented ||\n\t\t\t// Ignore keydowns from IMEs\n\t\t\tevent.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\treturn;\n\t\t}\n\t\tswitch ( event.key ) {\n\t\t\tcase 'ArrowUp':\n\t\t\t\tsetSelectedIndex(\n\t\t\t\t\t( selectedIndex === 0\n\t\t\t\t\t\t? filteredOptions.length\n\t\t\t\t\t\t: selectedIndex ) - 1\n\t\t\t\t);\n\t\t\t\tbreak;\n\n\t\t\tcase 'ArrowDown':\n\t\t\t\tsetSelectedIndex(\n\t\t\t\t\t( selectedIndex + 1 ) % filteredOptions.length\n\t\t\t\t);\n\t\t\t\tbreak;\n\n\t\t\tcase 'Escape':\n\t\t\t\tsetAutocompleter( null );\n\t\t\t\tsetAutocompleterUI( null );\n\t\t\t\tevent.preventDefault();\n\t\t\t\tbreak;\n\n\t\t\tcase 'Enter':\n\t\t\t\tselect( filteredOptions[ selectedIndex ] );\n\t\t\t\tbreak;\n\n\t\t\tcase 'ArrowLeft':\n\t\t\tcase 'ArrowRight':\n\t\t\t\treset();\n\t\t\t\treturn;\n\n\t\t\tdefault:\n\t\t\t\treturn;\n\t\t}\n\n\t\t// Any handled key should prevent original behavior. This relies on\n\t\t// the early return in the default case.\n\t\tevent.preventDefault();\n\t}\n\n\t// textContent is a primitive (string), memoizing is not strictly necessary\n\t// but this is a preemptive performance improvement, since the autocompleter\n\t// is a potential bottleneck for the editor type metric.\n\tconst textContent = useMemo( () => {\n\t\tif ( isCollapsed( record ) ) {\n\t\t\treturn getTextContent( slice( record, 0 ) );\n\t\t}\n\t}, [ record ] );\n\n\tuseEffect( () => {\n\t\tif ( ! textContent ) {\n\t\t\treset();\n\t\t\treturn;\n\t\t}\n\n\t\tconst text = removeAccents( textContent );\n\t\tconst textAfterSelection = getTextContent(\n\t\t\tslice( record, undefined, getTextContent( record ).length )\n\t\t);\n\t\tconst completer = completers?.find(\n\t\t\t( { triggerPrefix, allowContext } ) => {\n\t\t\t\tconst index = text.lastIndexOf( triggerPrefix );\n\n\t\t\t\tif ( index === -1 ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tconst textWithoutTrigger = text.slice(\n\t\t\t\t\tindex + triggerPrefix.length\n\t\t\t\t);\n\n\t\t\t\tconst tooDistantFromTrigger = textWithoutTrigger.length > 50; // 50 chars seems to be a good limit.\n\t\t\t\t// This is a final barrier to prevent the effect from completing with\n\t\t\t\t// an extremely long string, which causes the editor to slow-down\n\t\t\t\t// significantly. This could happen, for example, if `matchingWhileBackspacing`\n\t\t\t\t// is true and one of the \"words\" end up being too long. If that's the case,\n\t\t\t\t// it will be caught by this guard.\n\t\t\t\tif ( tooDistantFromTrigger ) return false;\n\n\t\t\t\tconst mismatch = filteredOptions.length === 0;\n\t\t\t\tconst wordsFromTrigger = textWithoutTrigger.split( /\\s/ );\n\t\t\t\t// We need to allow the effect to run when not backspacing and if there\n\t\t\t\t// was a mismatch. i.e when typing a trigger + the match string or when\n\t\t\t\t// clicking in an existing trigger word on the page. We do that if we\n\t\t\t\t// detect that we have one word from trigger in the current textual context.\n\t\t\t\t//\n\t\t\t\t// Ex.: \"Some text @a\" <-- \"@a\" will be detected as the trigger word and\n\t\t\t\t// allow the effect to run. It will run until there's a mismatch.\n\t\t\t\tconst hasOneTriggerWord = wordsFromTrigger.length === 1;\n\t\t\t\t// This is used to allow the effect to run when backspacing and if\n\t\t\t\t// \"touching\" a word that \"belongs\" to a trigger. We consider a \"trigger\n\t\t\t\t// word\" any word up to the limit of 3 from the trigger character.\n\t\t\t\t// Anything beyond that is ignored if there's a mismatch. This allows\n\t\t\t\t// us to \"escape\" a mismatch when backspacing, but still imposing some\n\t\t\t\t// sane limits.\n\t\t\t\t//\n\t\t\t\t// Ex: \"Some text @marcelo sekkkk\" <--- \"kkkk\" caused a mismatch, but\n\t\t\t\t// if the user presses backspace here, it will show the completion popup again.\n\t\t\t\tconst matchingWhileBackspacing =\n\t\t\t\t\tbackspacing.current &&\n\t\t\t\t\ttextWithoutTrigger.split( /\\s/ ).length <= 3;\n\n\t\t\t\tif (\n\t\t\t\t\tmismatch &&\n\t\t\t\t\t! ( matchingWhileBackspacing || hasOneTriggerWord )\n\t\t\t\t) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\tallowContext &&\n\t\t\t\t\t! allowContext( text.slice( 0, index ), textAfterSelection )\n\t\t\t\t) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\t/^\\s/.test( textWithoutTrigger ) ||\n\t\t\t\t\t/\\s\\s+$/.test( textWithoutTrigger )\n\t\t\t\t) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\treturn /[\\u0000-\\uFFFF]*$/.test( textWithoutTrigger );\n\t\t\t}\n\t\t);\n\n\t\tif ( ! completer ) {\n\t\t\treset();\n\t\t\treturn;\n\t\t}\n\n\t\tconst safeTrigger = escapeRegExp( completer.triggerPrefix );\n\t\tconst match = text\n\t\t\t.slice( text.lastIndexOf( completer.triggerPrefix ) )\n\t\t\t.match( new RegExp( `${ safeTrigger }([\\u0000-\\uFFFF]*)$` ) );\n\t\tconst query = match && match[ 1 ];\n\n\t\tsetAutocompleter( completer );\n\t\tsetAutocompleterUI( () =>\n\t\t\tcompleter !== autocompleter\n\t\t\t\t? getAutoCompleterUI( completer )\n\t\t\t\t: AutocompleterUI\n\t\t);\n\t\tsetFilterValue( query );\n\t\t// Temporarily disabling exhaustive-deps to avoid introducing unexpected side effecst.\n\t\t// See https://github.com/WordPress/gutenberg/pull/41820\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t}, [ textContent ] );\n\n\tconst { key: selectedKey = '' } = filteredOptions[ selectedIndex ] || {};\n\tconst { className } = autocompleter || {};\n\tconst isExpanded = !! autocompleter && filteredOptions.length > 0;\n\tconst listBoxId = isExpanded\n\t\t? `components-autocomplete-listbox-${ instanceId }`\n\t\t: null;\n\tconst activeId = isExpanded\n\t\t? `components-autocomplete-item-${ instanceId }-${ selectedKey }`\n\t\t: null;\n\tconst hasSelection = record.start !== undefined;\n\n\treturn {\n\t\tlistBoxId,\n\t\tactiveId,\n\t\tonKeyDown: handleKeyDown,\n\t\tpopover: hasSelection && AutocompleterUI && (\n\t\t\t<AutocompleterUI\n\t\t\t\tclassName={ className }\n\t\t\t\tfilterValue={ filterValue }\n\t\t\t\tinstanceId={ instanceId }\n\t\t\t\tlistBoxId={ listBoxId }\n\t\t\t\tselectedIndex={ selectedIndex }\n\t\t\t\tonChangeOptions={ onChangeOptions }\n\t\t\t\tonSelect={ select }\n\t\t\t\tvalue={ record }\n\t\t\t\tcontentRef={ contentRef }\n\t\t\t\treset={ reset }\n\t\t\t/>\n\t\t),\n\t};\n}\n\nexport function useAutocompleteProps( options ) {\n\tconst [ isVisible, setIsVisible ] = useState( false );\n\tconst ref = useRef();\n\tconst recordAfterInput = useRef();\n\tconst onKeyDownRef = useRef();\n\tconst { popover, listBoxId, activeId, onKeyDown } = useAutocomplete( {\n\t\t...options,\n\t\tcontentRef: ref,\n\t} );\n\tonKeyDownRef.current = onKeyDown;\n\n\tuseEffect( () => {\n\t\tif ( isVisible ) {\n\t\t\tif ( ! recordAfterInput.current ) {\n\t\t\t\trecordAfterInput.current = options.record;\n\t\t\t} else if (\n\t\t\t\trecordAfterInput.current.start !== options.record.start ||\n\t\t\t\trecordAfterInput.current.end !== options.record.end\n\t\t\t) {\n\t\t\t\tsetIsVisible( false );\n\t\t\t\trecordAfterInput.current = null;\n\t\t\t}\n\t\t}\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t}, [ options.record ] );\n\n\tconst mergedRefs = useMergeRefs( [\n\t\tref,\n\t\tuseRefEffect( ( element ) => {\n\t\t\tfunction _onKeyDown( event ) {\n\t\t\t\tonKeyDownRef.current( event );\n\t\t\t}\n\t\t\tfunction _onInput() {\n\t\t\t\t// Only show auto complete UI if the user is inputting text.\n\t\t\t\tsetIsVisible( true );\n\t\t\t\trecordAfterInput.current = null;\n\t\t\t}\n\t\t\telement.addEventListener( 'keydown', _onKeyDown );\n\t\t\telement.addEventListener( 'input', _onInput );\n\t\t\treturn () => {\n\t\t\t\telement.removeEventListener( 'keydown', _onKeyDown );\n\t\t\t\telement.removeEventListener( 'input', _onInput );\n\t\t\t};\n\t\t}, [] ),\n\t] );\n\n\tif ( ! isVisible ) {\n\t\treturn { ref: mergedRefs };\n\t}\n\n\treturn {\n\t\tref: mergedRefs,\n\t\tchildren: popover,\n\t\t'aria-autocomplete': listBoxId ? 'list' : undefined,\n\t\t'aria-owns': listBoxId,\n\t\t'aria-activedescendant': activeId,\n\t};\n}\n\nexport default function Autocomplete( { children, isSelected, ...options } ) {\n\tconst { popover, ...props } = useAutocomplete( options );\n\treturn (\n\t\t<>\n\t\t\t{ children( props ) }\n\t\t\t{ isSelected && popover }\n\t\t</>\n\t);\n}\n"]}
1
+ {"version":3,"sources":["@wordpress/components/src/autocomplete/index.js"],"names":["removeAccents","renderToString","useEffect","useState","useRef","useMemo","__","_n","sprintf","useInstanceId","useDebounce","useMergeRefs","useRefEffect","create","slice","insert","isCollapsed","getTextContent","speak","getAutoCompleterUI","escapeRegExp","EMPTY_ARRAY","useAutocomplete","record","onChange","onReplace","completers","contentRef","debouncedSpeak","instanceId","selectedIndex","setSelectedIndex","filteredOptions","setFilteredOptions","filterValue","setFilterValue","autocompleter","setAutocompleter","AutocompleterUI","setAutocompleterUI","backspacing","insertCompletion","replacement","end","start","triggerPrefix","length","toInsert","html","select","option","getOptionCompletion","isDisabled","completion","value","action","undefined","reset","announce","options","onChangeOptions","handleKeyDown","event","current","key","defaultPrevented","isComposing","keyCode","preventDefault","textContent","completer","find","allowContext","index","lastIndexOf","textWithoutTrigger","tooDistantFromTrigger","mismatch","wordsFromTrigger","split","hasOneTriggerWord","matchingWhileBackspacing","textAfterSelection","test","safeTrigger","text","match","RegExp","query","selectedKey","className","isExpanded","listBoxId","activeId","hasSelection","onKeyDown","popover","useLastDifferentValue","history","Set","add","size","delete","Array","from","useAutocompleteProps","ref","onKeyDownRef","previousRecord","mergedRefs","element","_onKeyDown","addEventListener","removeEventListener","didUserInput","children","Autocomplete","isSelected","props"],"mappings":"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","sourcesContent":["/**\n * External dependencies\n */\nimport removeAccents from 'remove-accents';\n\n/**\n * WordPress dependencies\n */\nimport {\n\trenderToString,\n\tuseEffect,\n\tuseState,\n\tuseRef,\n\tuseMemo,\n} from '@wordpress/element';\nimport { __, _n, sprintf } from '@wordpress/i18n';\nimport {\n\tuseInstanceId,\n\tuseDebounce,\n\tuseMergeRefs,\n\tuseRefEffect,\n} from '@wordpress/compose';\nimport {\n\tcreate,\n\tslice,\n\tinsert,\n\tisCollapsed,\n\tgetTextContent,\n} from '@wordpress/rich-text';\nimport { speak } from '@wordpress/a11y';\n\n/**\n * Internal dependencies\n */\nimport { getAutoCompleterUI } from './autocompleter-ui';\nimport { escapeRegExp } from '../utils/strings';\n\nconst EMPTY_ARRAY = [];\n\n/**\n * A raw completer option.\n *\n * @typedef {*} CompleterOption\n */\n\n/**\n * @callback FnGetOptions\n *\n * @return {(CompleterOption[]|Promise.<CompleterOption[]>)} The completer options or a promise for them.\n */\n\n/**\n * @callback FnGetOptionKeywords\n * @param {CompleterOption} option a completer option.\n *\n * @return {string[]} list of key words to search.\n */\n\n/**\n * @callback FnIsOptionDisabled\n * @param {CompleterOption} option a completer option.\n *\n * @return {string[]} whether or not the given option is disabled.\n */\n\n/**\n * @callback FnGetOptionLabel\n * @param {CompleterOption} option a completer option.\n *\n * @return {(string|Array.<(string|WPElement)>)} list of react components to render.\n */\n\n/**\n * @callback FnAllowContext\n * @param {string} before the string before the auto complete trigger and query.\n * @param {string} after the string after the autocomplete trigger and query.\n *\n * @return {boolean} true if the completer can handle.\n */\n\n/**\n * @typedef {Object} OptionCompletion\n * @property {'insert-at-caret'|'replace'} action the intended placement of the completion.\n * @property {OptionCompletionValue} value the completion value.\n */\n\n/**\n * A completion value.\n *\n * @typedef {(string|WPElement|Object)} OptionCompletionValue\n */\n\n/**\n * @callback FnGetOptionCompletion\n * @param {CompleterOption} value the value of the completer option.\n * @param {string} query the text value of the autocomplete query.\n *\n * @return {(OptionCompletion|OptionCompletionValue)} the completion for the given option. If an\n * \t\t\t\t\t\t\t\t\t\t\t\t\t OptionCompletionValue is returned, the\n * \t\t\t\t\t\t\t\t\t\t\t\t\t completion action defaults to `insert-at-caret`.\n */\n\n/**\n * @typedef {Object} WPCompleter\n * @property {string} name a way to identify a completer, useful for selective overriding.\n * @property {?string} className A class to apply to the popup menu.\n * @property {string} triggerPrefix the prefix that will display the menu.\n * @property {(CompleterOption[]|FnGetOptions)} options the completer options or a function to get them.\n * @property {?FnGetOptionKeywords} getOptionKeywords get the keywords for a given option.\n * @property {?FnIsOptionDisabled} isOptionDisabled get whether or not the given option is disabled.\n * @property {FnGetOptionLabel} getOptionLabel get the label for a given option.\n * @property {?FnAllowContext} allowContext filter the context under which the autocomplete activates.\n * @property {FnGetOptionCompletion} getOptionCompletion get the completion associated with a given option.\n */\n\nfunction useAutocomplete( {\n\trecord,\n\tonChange,\n\tonReplace,\n\tcompleters,\n\tcontentRef,\n} ) {\n\tconst debouncedSpeak = useDebounce( speak, 500 );\n\tconst instanceId = useInstanceId( useAutocomplete );\n\tconst [ selectedIndex, setSelectedIndex ] = useState( 0 );\n\tconst [ filteredOptions, setFilteredOptions ] = useState( EMPTY_ARRAY );\n\tconst [ filterValue, setFilterValue ] = useState( '' );\n\tconst [ autocompleter, setAutocompleter ] = useState( null );\n\tconst [ AutocompleterUI, setAutocompleterUI ] = useState( null );\n\tconst backspacing = useRef( false );\n\n\tfunction insertCompletion( replacement ) {\n\t\tconst end = record.start;\n\t\tconst start =\n\t\t\tend - autocompleter.triggerPrefix.length - filterValue.length;\n\t\tconst toInsert = create( { html: renderToString( replacement ) } );\n\n\t\tonChange( insert( record, toInsert, start, end ) );\n\t}\n\n\tfunction select( option ) {\n\t\tconst { getOptionCompletion } = autocompleter || {};\n\n\t\tif ( option.isDisabled ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( getOptionCompletion ) {\n\t\t\tconst completion = getOptionCompletion( option.value, filterValue );\n\n\t\t\tconst { action, value } =\n\t\t\t\tundefined === completion.action ||\n\t\t\t\tundefined === completion.value\n\t\t\t\t\t? { action: 'insert-at-caret', value: completion }\n\t\t\t\t\t: completion;\n\n\t\t\tif ( 'replace' === action ) {\n\t\t\t\tonReplace( [ value ] );\n\t\t\t\t// When replacing, the component will unmount, so don't reset\n\t\t\t\t// state (below) on an unmounted component.\n\t\t\t\treturn;\n\t\t\t} else if ( 'insert-at-caret' === action ) {\n\t\t\t\tinsertCompletion( value );\n\t\t\t}\n\t\t}\n\n\t\t// Reset autocomplete state after insertion rather than before\n\t\t// so insertion events don't cause the completion menu to redisplay.\n\t\treset();\n\t}\n\n\tfunction reset() {\n\t\tsetSelectedIndex( 0 );\n\t\tsetFilteredOptions( EMPTY_ARRAY );\n\t\tsetFilterValue( '' );\n\t\tsetAutocompleter( null );\n\t\tsetAutocompleterUI( null );\n\t}\n\n\tfunction announce( options ) {\n\t\tif ( ! debouncedSpeak ) {\n\t\t\treturn;\n\t\t}\n\t\tif ( !! options.length ) {\n\t\t\tdebouncedSpeak(\n\t\t\t\tsprintf(\n\t\t\t\t\t/* translators: %d: number of results. */\n\t\t\t\t\t_n(\n\t\t\t\t\t\t'%d result found, use up and down arrow keys to navigate.',\n\t\t\t\t\t\t'%d results found, use up and down arrow keys to navigate.',\n\t\t\t\t\t\toptions.length\n\t\t\t\t\t),\n\t\t\t\t\toptions.length\n\t\t\t\t),\n\t\t\t\t'assertive'\n\t\t\t);\n\t\t} else {\n\t\t\tdebouncedSpeak( __( 'No results.' ), 'assertive' );\n\t\t}\n\t}\n\n\t/**\n\t * Load options for an autocompleter.\n\t *\n\t * @param {Array} options\n\t */\n\tfunction onChangeOptions( options ) {\n\t\tsetSelectedIndex(\n\t\t\toptions.length === filteredOptions.length ? selectedIndex : 0\n\t\t);\n\t\tsetFilteredOptions( options );\n\t\tannounce( options );\n\t}\n\n\tfunction handleKeyDown( event ) {\n\t\tbackspacing.current = event.key === 'Backspace';\n\n\t\tif ( ! autocompleter ) {\n\t\t\treturn;\n\t\t}\n\t\tif ( filteredOptions.length === 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (\n\t\t\tevent.defaultPrevented ||\n\t\t\t// Ignore keydowns from IMEs\n\t\t\tevent.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\treturn;\n\t\t}\n\t\tswitch ( event.key ) {\n\t\t\tcase 'ArrowUp':\n\t\t\t\tsetSelectedIndex(\n\t\t\t\t\t( selectedIndex === 0\n\t\t\t\t\t\t? filteredOptions.length\n\t\t\t\t\t\t: selectedIndex ) - 1\n\t\t\t\t);\n\t\t\t\tbreak;\n\n\t\t\tcase 'ArrowDown':\n\t\t\t\tsetSelectedIndex(\n\t\t\t\t\t( selectedIndex + 1 ) % filteredOptions.length\n\t\t\t\t);\n\t\t\t\tbreak;\n\n\t\t\tcase 'Escape':\n\t\t\t\tsetAutocompleter( null );\n\t\t\t\tsetAutocompleterUI( null );\n\t\t\t\tevent.preventDefault();\n\t\t\t\tbreak;\n\n\t\t\tcase 'Enter':\n\t\t\t\tselect( filteredOptions[ selectedIndex ] );\n\t\t\t\tbreak;\n\n\t\t\tcase 'ArrowLeft':\n\t\t\tcase 'ArrowRight':\n\t\t\t\treset();\n\t\t\t\treturn;\n\n\t\t\tdefault:\n\t\t\t\treturn;\n\t\t}\n\n\t\t// Any handled key should prevent original behavior. This relies on\n\t\t// the early return in the default case.\n\t\tevent.preventDefault();\n\t}\n\n\t// textContent is a primitive (string), memoizing is not strictly necessary\n\t// but this is a preemptive performance improvement, since the autocompleter\n\t// is a potential bottleneck for the editor type metric.\n\tconst textContent = useMemo( () => {\n\t\tif ( isCollapsed( record ) ) {\n\t\t\treturn getTextContent( slice( record, 0 ) );\n\t\t}\n\t}, [ record ] );\n\n\tuseEffect( () => {\n\t\tif ( ! textContent ) {\n\t\t\tif ( autocompleter ) reset();\n\t\t\treturn;\n\t\t}\n\n\t\tconst completer = completers?.find(\n\t\t\t( { triggerPrefix, allowContext } ) => {\n\t\t\t\tconst index = textContent.lastIndexOf( triggerPrefix );\n\n\t\t\t\tif ( index === -1 ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tconst textWithoutTrigger = textContent.slice(\n\t\t\t\t\tindex + triggerPrefix.length\n\t\t\t\t);\n\n\t\t\t\tconst tooDistantFromTrigger = textWithoutTrigger.length > 50; // 50 chars seems to be a good limit.\n\t\t\t\t// This is a final barrier to prevent the effect from completing with\n\t\t\t\t// an extremely long string, which causes the editor to slow-down\n\t\t\t\t// significantly. This could happen, for example, if `matchingWhileBackspacing`\n\t\t\t\t// is true and one of the \"words\" end up being too long. If that's the case,\n\t\t\t\t// it will be caught by this guard.\n\t\t\t\tif ( tooDistantFromTrigger ) return false;\n\n\t\t\t\tconst mismatch = filteredOptions.length === 0;\n\t\t\t\tconst wordsFromTrigger = textWithoutTrigger.split( /\\s/ );\n\t\t\t\t// We need to allow the effect to run when not backspacing and if there\n\t\t\t\t// was a mismatch. i.e when typing a trigger + the match string or when\n\t\t\t\t// clicking in an existing trigger word on the page. We do that if we\n\t\t\t\t// detect that we have one word from trigger in the current textual context.\n\t\t\t\t//\n\t\t\t\t// Ex.: \"Some text @a\" <-- \"@a\" will be detected as the trigger word and\n\t\t\t\t// allow the effect to run. It will run until there's a mismatch.\n\t\t\t\tconst hasOneTriggerWord = wordsFromTrigger.length === 1;\n\t\t\t\t// This is used to allow the effect to run when backspacing and if\n\t\t\t\t// \"touching\" a word that \"belongs\" to a trigger. We consider a \"trigger\n\t\t\t\t// word\" any word up to the limit of 3 from the trigger character.\n\t\t\t\t// Anything beyond that is ignored if there's a mismatch. This allows\n\t\t\t\t// us to \"escape\" a mismatch when backspacing, but still imposing some\n\t\t\t\t// sane limits.\n\t\t\t\t//\n\t\t\t\t// Ex: \"Some text @marcelo sekkkk\" <--- \"kkkk\" caused a mismatch, but\n\t\t\t\t// if the user presses backspace here, it will show the completion popup again.\n\t\t\t\tconst matchingWhileBackspacing =\n\t\t\t\t\tbackspacing.current &&\n\t\t\t\t\ttextWithoutTrigger.split( /\\s/ ).length <= 3;\n\n\t\t\t\tif (\n\t\t\t\t\tmismatch &&\n\t\t\t\t\t! ( matchingWhileBackspacing || hasOneTriggerWord )\n\t\t\t\t) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tconst textAfterSelection = getTextContent(\n\t\t\t\t\tslice( record, undefined, getTextContent( record ).length )\n\t\t\t\t);\n\n\t\t\t\tif (\n\t\t\t\t\tallowContext &&\n\t\t\t\t\t! allowContext(\n\t\t\t\t\t\ttextContent.slice( 0, index ),\n\t\t\t\t\t\ttextAfterSelection\n\t\t\t\t\t)\n\t\t\t\t) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tif (\n\t\t\t\t\t/^\\s/.test( textWithoutTrigger ) ||\n\t\t\t\t\t/\\s\\s+$/.test( textWithoutTrigger )\n\t\t\t\t) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\treturn /[\\u0000-\\uFFFF]*$/.test( textWithoutTrigger );\n\t\t\t}\n\t\t);\n\n\t\tif ( ! completer ) {\n\t\t\tif ( autocompleter ) reset();\n\t\t\treturn;\n\t\t}\n\n\t\tconst safeTrigger = escapeRegExp( completer.triggerPrefix );\n\t\tconst text = removeAccents( textContent );\n\t\tconst match = text\n\t\t\t.slice( text.lastIndexOf( completer.triggerPrefix ) )\n\t\t\t.match( new RegExp( `${ safeTrigger }([\\u0000-\\uFFFF]*)$` ) );\n\t\tconst query = match && match[ 1 ];\n\n\t\tsetAutocompleter( completer );\n\t\tsetAutocompleterUI( () =>\n\t\t\tcompleter !== autocompleter\n\t\t\t\t? getAutoCompleterUI( completer )\n\t\t\t\t: AutocompleterUI\n\t\t);\n\t\tsetFilterValue( query );\n\t\t// Temporarily disabling exhaustive-deps to avoid introducing unexpected side effecst.\n\t\t// See https://github.com/WordPress/gutenberg/pull/41820\n\t\t// eslint-disable-next-line react-hooks/exhaustive-deps\n\t}, [ textContent ] );\n\n\tconst { key: selectedKey = '' } = filteredOptions[ selectedIndex ] || {};\n\tconst { className } = autocompleter || {};\n\tconst isExpanded = !! autocompleter && filteredOptions.length > 0;\n\tconst listBoxId = isExpanded\n\t\t? `components-autocomplete-listbox-${ instanceId }`\n\t\t: null;\n\tconst activeId = isExpanded\n\t\t? `components-autocomplete-item-${ instanceId }-${ selectedKey }`\n\t\t: null;\n\tconst hasSelection = record.start !== undefined;\n\n\treturn {\n\t\tlistBoxId,\n\t\tactiveId,\n\t\tonKeyDown: handleKeyDown,\n\t\tpopover: hasSelection && AutocompleterUI && (\n\t\t\t<AutocompleterUI\n\t\t\t\tclassName={ className }\n\t\t\t\tfilterValue={ filterValue }\n\t\t\t\tinstanceId={ instanceId }\n\t\t\t\tlistBoxId={ listBoxId }\n\t\t\t\tselectedIndex={ selectedIndex }\n\t\t\t\tonChangeOptions={ onChangeOptions }\n\t\t\t\tonSelect={ select }\n\t\t\t\tvalue={ record }\n\t\t\t\tcontentRef={ contentRef }\n\t\t\t\treset={ reset }\n\t\t\t/>\n\t\t),\n\t};\n}\n\nfunction useLastDifferentValue( value ) {\n\tconst history = useRef( new Set() );\n\n\thistory.current.add( value );\n\n\t// Keep the history size to 2.\n\tif ( history.current.size > 2 ) {\n\t\thistory.current.delete( Array.from( history.current )[ 0 ] );\n\t}\n\n\treturn Array.from( history.current )[ 0 ];\n}\n\nexport function useAutocompleteProps( options ) {\n\tconst ref = useRef();\n\tconst onKeyDownRef = useRef();\n\tconst { record } = options;\n\tconst previousRecord = useLastDifferentValue( record );\n\tconst { popover, listBoxId, activeId, onKeyDown } = useAutocomplete( {\n\t\t...options,\n\t\tcontentRef: ref,\n\t} );\n\tonKeyDownRef.current = onKeyDown;\n\n\tconst mergedRefs = useMergeRefs( [\n\t\tref,\n\t\tuseRefEffect( ( element ) => {\n\t\t\tfunction _onKeyDown( event ) {\n\t\t\t\tonKeyDownRef.current( event );\n\t\t\t}\n\t\t\telement.addEventListener( 'keydown', _onKeyDown );\n\t\t\treturn () => {\n\t\t\t\telement.removeEventListener( 'keydown', _onKeyDown );\n\t\t\t};\n\t\t}, [] ),\n\t] );\n\n\t// We only want to show the popover if the user has typed something.\n\tconst didUserInput = record.text !== previousRecord?.text;\n\n\tif ( ! didUserInput ) {\n\t\treturn { ref: mergedRefs };\n\t}\n\n\treturn {\n\t\tref: mergedRefs,\n\t\tchildren: popover,\n\t\t'aria-autocomplete': listBoxId ? 'list' : undefined,\n\t\t'aria-owns': listBoxId,\n\t\t'aria-activedescendant': activeId,\n\t};\n}\n\nexport default function Autocomplete( { children, isSelected, ...options } ) {\n\tconst { popover, ...props } = useAutocomplete( options );\n\treturn (\n\t\t<>\n\t\t\t{ children( props ) }\n\t\t\t{ isSelected && popover }\n\t\t</>\n\t);\n}\n"]}