: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
// Edit visually only works for single block selection.
const clientId = clientIds.length === 1 ? clientIds[0] : undefined;
const canEditVisually = (0,external_wp_data_namespaceObject.useSelect)(select => !!clientId && select(store).getBlockMode(clientId) === 'html', [clientId]);
} = (0,external_wp_data_namespaceObject.useDispatch)(store);
return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToolbarGroup, {
children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToolbarButton, {
toggleBlockMode(clientId);
children: (0,external_wp_i18n_namespaceObject.__)('Edit visually')
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-toolbar/block-name-context.js
const __unstableBlockNameContext = (0,external_wp_element_namespaceObject.createContext)('');
/* harmony default export */ const block_name_context = (__unstableBlockNameContext);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/navigable-toolbar/index.js
function hasOnlyToolbarItem(elements) {
const dataProp = 'toolbarItem';
return !elements.some(element => !(dataProp in element.dataset));
function getAllFocusableToolbarItemsIn(container) {
return Array.from(container.querySelectorAll('[data-toolbar-item]:not([disabled])'));
function hasFocusWithin(container) {
return container.contains(container.ownerDocument.activeElement);
function focusFirstTabbableIn(container) {
const [firstTabbable] = external_wp_dom_namespaceObject.focus.tabbable.find(container);
// When focusing newly mounted toolbars,
// the position of the popover is often not right on the first render
// This prevents the layout shifts when focusing the dialogs.
function useIsAccessibleToolbar(toolbarRef) {
* By default, we'll assume the starting accessible state of the Toolbar
* is true, as it seems to be the most common case.
* Transitioning from an (initial) false to true state causes the
* <Toolbar /> component to mount twice, which is causing undesired
* side-effects. These side-effects appear to only affect certain
* This was initial discovered in this pull-request:
* https://github.com/WordPress/gutenberg/pull/23425
const initialAccessibleToolbarState = true;
// By default, it's gonna render NavigableMenu. If all the tabbable elements
// inside the toolbar are ToolbarItem components (or derived components like
// ToolbarButton), then we can wrap them with the accessible Toolbar
const [isAccessibleToolbar, setIsAccessibleToolbar] = (0,external_wp_element_namespaceObject.useState)(initialAccessibleToolbarState);
const determineIsAccessibleToolbar = (0,external_wp_element_namespaceObject.useCallback)(() => {
const tabbables = external_wp_dom_namespaceObject.focus.tabbable.find(toolbarRef.current);
const onlyToolbarItem = hasOnlyToolbarItem(tabbables);
external_wp_deprecated_default()('Using custom components as toolbar controls', {
alternative: 'ToolbarItem, ToolbarButton or ToolbarDropdownMenu components',
link: 'https://developer.wordpress.org/block-editor/components/toolbar-button/#inside-blockcontrols'
setIsAccessibleToolbar(onlyToolbarItem);
(0,external_wp_element_namespaceObject.useLayoutEffect)(() => {
// Toolbar buttons may be rendered asynchronously, so we use
// MutationObserver to check if the toolbar subtree has been modified.
const observer = new window.MutationObserver(determineIsAccessibleToolbar);
observer.observe(toolbarRef.current, {
return () => observer.disconnect();
}, [determineIsAccessibleToolbar, isAccessibleToolbar, toolbarRef]);
return isAccessibleToolbar;
function useToolbarFocus({
shouldUseKeyboardFocusShortcut,
// Make sure we don't use modified versions of this prop.
const [initialFocusOnMount] = (0,external_wp_element_namespaceObject.useState)(focusOnMount);
const [initialIndex] = (0,external_wp_element_namespaceObject.useState)(defaultIndex);
const focusToolbar = (0,external_wp_element_namespaceObject.useCallback)(() => {
focusFirstTabbableIn(toolbarRef.current);
const focusToolbarViaShortcut = () => {
if (shouldUseKeyboardFocusShortcut) {
// Focus on toolbar when pressing alt+F10 when the toolbar is visible.
(0,external_wp_keyboardShortcuts_namespaceObject.useShortcut)('core/block-editor/focus-toolbar', focusToolbarViaShortcut);
(0,external_wp_element_namespaceObject.useEffect)(() => {
if (initialFocusOnMount) {
}, [isAccessibleToolbar, initialFocusOnMount, focusToolbar]);
(0,external_wp_element_namespaceObject.useEffect)(() => {
// Store ref so we have access on useEffect cleanup: https://legacy.reactjs.org/blog/2020/08/10/react-v17-rc.html#effect-cleanup-timing
const navigableToolbarRef = toolbarRef.current;
// If initialIndex is passed, we focus on that toolbar item when the
// toolbar gets mounted and initial focus is not forced.
// We have to wait for the next browser paint because block controls aren't
// rendered right away when the toolbar gets mounted.
// If the toolbar already had focus before the render, we don't want to move it.
// https://github.com/WordPress/gutenberg/issues/58511
if (!initialFocusOnMount && !hasFocusWithin(navigableToolbarRef)) {
raf = window.requestAnimationFrame(() => {
const items = getAllFocusableToolbarItemsIn(navigableToolbarRef);
const index = initialIndex || 0;
if (items[index] && hasFocusWithin(navigableToolbarRef)) {
// When focusing newly mounted toolbars,
// the position of the popover is often not right on the first render
// This prevents the layout shifts when focusing the dialogs.
window.cancelAnimationFrame(raf);
if (!onIndexChange || !navigableToolbarRef) {
// When the toolbar element is unmounted and onIndexChange is passed, we
// pass the focused toolbar item index so it can be hydrated later.
const items = getAllFocusableToolbarItemsIn(navigableToolbarRef);
const index = items.findIndex(item => item.tabIndex === 0);
}, [initialIndex, initialFocusOnMount, onIndexChange, toolbarRef]);
} = unlock((0,external_wp_data_namespaceObject.useSelect)(store));
* Handles returning focus to the block editor canvas when pressing escape.
(0,external_wp_element_namespaceObject.useEffect)(() => {
const navigableToolbarRef = toolbarRef.current;
if (focusEditorOnEscape) {
const handleKeyDown = event => {
const lastFocus = getLastFocus();
if (event.keyCode === external_wp_keycodes_namespaceObject.ESCAPE && lastFocus?.current) {
// Focus the last focused element when pressing escape.
lastFocus.current.focus();
navigableToolbarRef.addEventListener('keydown', handleKeyDown);
navigableToolbarRef.removeEventListener('keydown', handleKeyDown);
}, [focusEditorOnEscape, getLastFocus, toolbarRef]);
function NavigableToolbar({
focusEditorOnEscape = false,
shouldUseKeyboardFocusShortcut = true,
__experimentalInitialIndex: initialIndex,
__experimentalOnIndexChange: onIndexChange,
const toolbarRef = (0,external_wp_element_namespaceObject.useRef)();
const isAccessibleToolbar = useIsAccessibleToolbar(toolbarRef);
defaultIndex: initialIndex,
shouldUseKeyboardFocusShortcut,
if (isAccessibleToolbar) {
return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.Toolbar, {
label: props['aria-label'],
return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.NavigableMenu, {
orientation: "horizontal",
;// CONCATENATED MODULE: ./node_modules/@wordpress/icons/build-module/library/shuffle.js
const shuffle = /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.SVG, {
xmlns: "http://www.w3.org/2000/SVG",
children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_primitives_namespaceObject.Path, {
d: "M17.192 6.75L15.47 5.03l1.06-1.06 3.537 3.53-3.537 3.53-1.06-1.06 1.723-1.72h-3.19c-.602 0-.993.202-1.28.498-.309.319-.538.792-.695 1.383-.13.488-.222 1.023-.296 1.508-.034.664-.116 1.413-.303 2.117-.193.721-.513 1.467-1.068 2.04-.575.594-1.359.954-2.357.954H4v-1.5h4.003c.601 0 .993-.202 1.28-.498.308-.319.538-.792.695-1.383.149-.557.216-1.093.288-1.662l.039-.31a9.653 9.653 0 0 1 .272-1.653c.193-.722.513-1.467 1.067-2.04.576-.594 1.36-.954 2.358-.954h3.19zM8.004 6.75c.8 0 1.46.23 1.988.628a6.24 6.24 0 0 0-.684 1.396 1.725 1.725 0 0 0-.024-.026c-.287-.296-.679-.498-1.28-.498H4v-1.5h4.003zM12.699 14.726c-.161.459-.38.94-.684 1.396.527.397 1.188.628 1.988.628h3.19l-1.722 1.72 1.06 1.06L20.067 16l-3.537-3.53-1.06 1.06 1.723 1.72h-3.19c-.602 0-.993-.202-1.28-.498a1.96 1.96 0 0 1-.024-.026z"
/* harmony default export */ const library_shuffle = (shuffle);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-toolbar/shuffle.js
const shuffle_EMPTY_ARRAY = [];
function shuffle_Container(props) {
return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToolbarGroup, {
children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(external_wp_components_namespaceObject.ToolbarButton, {
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
__experimentalGetAllowedPatterns
const attributes = getBlockAttributes(clientId);
const _categories = attributes?.metadata?.categories || shuffle_EMPTY_ARRAY;
const _patternName = attributes?.metadata?.patternName;
const rootBlock = getBlockRootClientId(clientId);
const _patterns = __experimentalGetAllowedPatterns(rootBlock);
patternName: _patternName
} = (0,external_wp_data_namespaceObject.useDispatch)(store);
const sameCategoryPatternsWithSingleWrapper = (0,external_wp_element_namespaceObject.useMemo)(() => {
if (!categories || categories.length === 0 || !patterns || patterns.length === 0) {
return shuffle_EMPTY_ARRAY;
return patterns.filter(pattern => {
// Check if the pattern has only one top level block,
// otherwise we may shuffle to pattern that will not allow to continue shuffling.
pattern.blocks.length === 1 && pattern.categories?.some(category => {
return categories.includes(category);
// Check if the pattern is not a synced pattern.
pattern.syncStatus === 'unsynced' || !pattern.id)
}, [categories, patterns]);
if (sameCategoryPatternsWithSingleWrapper.length < 2) {
function getNextPattern() {
const numberOfPatterns = sameCategoryPatternsWithSingleWrapper.length;
const patternIndex = sameCategoryPatternsWithSingleWrapper.findIndex(({
}) => name === patternName);
const nextPatternIndex = patternIndex + 1 < numberOfPatterns ? patternIndex + 1 : 0;
return sameCategoryPatternsWithSingleWrapper[nextPatternIndex];
const ComponentToUse = as;
return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(ComponentToUse, {
label: (0,external_wp_i18n_namespaceObject.__)('Shuffle'),
const nextPattern = getNextPattern();
nextPattern.blocks[0].attributes = {
...nextPattern.blocks[0].attributes,
...nextPattern.blocks[0].attributes.metadata,
replaceBlocks(clientId, nextPattern.blocks);
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-controls/use-has-block-controls.js
function useHasAnyBlockControls() {
let hasAnyBlockControls = false;
for (const group in block_controls_groups) {
// It is safe to violate the rules of hooks here as the `groups` object
// is static and will not change length between renders. Do not return
// early as that will cause the hook to be called a different number of
// times between renders.
// eslint-disable-next-line react-hooks/rules-of-hooks
if (useHasBlockControls(group)) {
hasAnyBlockControls = true;
return hasAnyBlockControls;
function useHasBlockControls(group = 'default') {
const Slot = block_controls_groups[group]?.Slot;
const fills = (0,external_wp_components_namespaceObject.__experimentalUseSlotFills)(Slot?.__unstableName);
true ? external_wp_warning_default()(`Unknown BlockControls group "${group}" provided.`) : 0;
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-toolbar/use-has-block-toolbar.js
* Returns true if the block toolbar should be shown.
* @return {boolean} Whether the block toolbar component will be rendered.
function useHasBlockToolbar() {
} = (0,external_wp_data_namespaceObject.useSelect)(select => {
// we only care about the 1st selected block
// for the toolbar, so we use getBlockSelectionStart
// instead of getSelectedBlockClientIds
const selectedBlockClientId = getBlockSelectionStart();
const blockType = selectedBlockClientId && (0,external_wp_blocks_namespaceObject.getBlockType)(getBlockName(selectedBlockClientId));
isToolbarEnabled: blockType && (0,external_wp_blocks_namespaceObject.hasBlockSupport)(blockType, '__experimentalToolbar', true),
isDefaultEditingMode: getBlockEditingMode(selectedBlockClientId) === 'default'
const hasAnyBlockControls = useHasAnyBlockControls();
if (!isToolbarEnabled || !isDefaultEditingMode && !hasAnyBlockControls) {
;// CONCATENATED MODULE: ./node_modules/@wordpress/block-editor/build-module/components/block-toolbar/index.js
* Renders the block toolbar.
* @see https://github.com/WordPress/gutenberg/blob/HEAD/packages/block-editor/src/components/block-toolbar/README.md
* @param {Object} props Components props.
* @param {boolean} props.hideDragHandle Show or hide the Drag Handle for drag and drop functionality.
* @param {boolean} props.focusOnMount Focus the toolbar when mounted.
* @param {number} props.__experimentalInitialIndex The initial index of the toolbar item to focus.
* @param {Function} props.__experimentalOnIndexChange Callback function to be called when the index of the focused toolbar item changes.
* @param {string} props.variant Style variant of the toolbar, also passed to the Dropdowns rendered from Block Toolbar Buttons.
function PrivateBlockToolbar({
__experimentalInitialIndex,
__experimentalOnIndexChange,
} = (0,external_wp_data_namespaceObject.useSelect)(select => {