: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
(0,external_wp_a11y_namespaceObject.speak)((0,external_wp_i18n_namespaceObject.sprintf)(
// translators: %s: The name of the control being reset e.g. "Padding".
(0,external_wp_i18n_namespaceObject.__)('%s hidden and reset to default'), label), 'assertive');
(0,external_wp_a11y_namespaceObject.speak)((0,external_wp_i18n_namespaceObject.sprintf)(
// translators: %s: The name of the control being reset e.g. "Padding".
(0,external_wp_i18n_namespaceObject.__)('%s is now visible'), label), 'assertive');
role: "menuitemcheckbox",
const component_ToolsPanelHeader = (props, forwardedRef) => {
areAllOptionalControlsHidden,
defaultControlsItemClassName,
} = useToolsPanelHeader(props);
const defaultItems = Object.entries(menuItems?.default || {});
const optionalItems = Object.entries(menuItems?.optional || {});
const dropDownMenuIcon = areAllOptionalControlsHidden ? library_plus : more_vertical;
const dropDownMenuLabelText = (0,external_wp_i18n_namespaceObject.sprintf)(
// translators: %s: The name of the tool e.g. "Color" or "Typography".
(0,external_wp_i18n_namespaceObject._x)('%s options', 'Button label to reveal tool panel options'), labelText);
const dropdownMenuDescriptionText = areAllOptionalControlsHidden ? (0,external_wp_i18n_namespaceObject.__)('All options are currently hidden') : undefined;
const canResetAll = [...defaultItems, ...optionalItems].some(([, isSelected]) => isSelected);
return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(h_stack_component, {
children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(heading_component, {
className: headingClassName,
}), hasMenuItems && /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(dropdown_menu, {
label: dropDownMenuLabelText,
className: dropdownMenuClassName
describedBy: dropdownMenuDescriptionText
children: () => /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(external_ReactJSXRuntime_namespaceObject.Fragment, {
children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(menu_group, {
children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(DefaultControlsGroup, {
itemClassName: defaultControlsItemClassName
}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(OptionalControlsGroup, {
}), /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(menu_group, {
children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(menu_item, {
"aria-disabled": !canResetAll
// @ts-expect-error - TODO: If this "tertiary" style is something we really want to allow on MenuItem,
// we should rename it and explicitly allow it as an official API. All the other Button variants
// don't make sense in a MenuItem context, and should be disallowed.
(0,external_wp_a11y_namespaceObject.speak)((0,external_wp_i18n_namespaceObject.__)('All options reset'), 'assertive');
children: (0,external_wp_i18n_namespaceObject.__)('Reset all')
const ConnectedToolsPanelHeader = contextConnect(component_ToolsPanelHeader, 'ToolsPanelHeader');
/* harmony default export */ const tools_panel_header_component = (ConnectedToolsPanelHeader);
;// CONCATENATED MODULE: ./node_modules/@wordpress/components/build-module/tools-panel/tools-panel/hook.js
const DEFAULT_COLUMNS = 2;
const generateMenuItems = ({
const group = isShownByDefault ? 'default' : 'optional';
// If a menu item for this label has already been flagged as customized
// (for default controls), or toggled on (for optional controls), do not
// overwrite its value as those controls would lose that state.
const existingItemValue = currentMenuItems?.[group]?.[label];
const value = existingItemValue ? existingItemValue : hasValue();
newMenuItems[group][label] = shouldReset ? false : value;
// Loop the known, previously registered items first to maintain menu order.
menuItemOrder.forEach(key => {
if (newMenuItems.default.hasOwnProperty(key)) {
menuItems.default[key] = newMenuItems.default[key];
if (newMenuItems.optional.hasOwnProperty(key)) {
menuItems.optional[key] = newMenuItems.optional[key];
// Loop newMenuItems object adding any that aren't in the known items order.
Object.keys(newMenuItems.default).forEach(key => {
if (!menuItems.default.hasOwnProperty(key)) {
menuItems.default[key] = newMenuItems.default[key];
Object.keys(newMenuItems.optional).forEach(key => {
if (!menuItems.optional.hasOwnProperty(key)) {
menuItems.optional[key] = newMenuItems.optional[key];
const isMenuItemTypeEmpty = obj => obj && Object.keys(obj).length === 0;
function useToolsPanel(props) {
shouldRenderPlaceholderItems = false,
__experimentalFirstVisibleItemClass,
__experimentalLastVisibleItemClass,
} = useContextSystem(props, 'ToolsPanel');
const isResetting = (0,external_wp_element_namespaceObject.useRef)(false);
const wasResetting = isResetting.current;
// `isResetting` is cleared via this hook to effectively batch together
// the resetAll task. Without this, the flag is cleared after the first
// control updates and forces a rerender with subsequent controls then
// believing they need to reset, unfortunately using stale data.
(0,external_wp_element_namespaceObject.useEffect)(() => {
isResetting.current = false;
// Allow panel items to register themselves.
const [panelItems, setPanelItems] = (0,external_wp_element_namespaceObject.useState)([]);
const [menuItemOrder, setMenuItemOrder] = (0,external_wp_element_namespaceObject.useState)([]);
const [resetAllFilters, setResetAllFilters] = (0,external_wp_element_namespaceObject.useState)([]);
const registerPanelItem = (0,external_wp_element_namespaceObject.useCallback)(item => {
// Add item to panel items.
const newItems = [...items];
// If an item with this label has already been registered, remove it
// first. This can happen when an item is moved between the default
const existingIndex = newItems.findIndex(oldItem => oldItem.label === item.label);
if (existingIndex !== -1) {
newItems.splice(existingIndex, 1);
return [...newItems, item];
// Track the initial order of item registration. This is used for
// maintaining menu item order later.
setMenuItemOrder(items => {
if (items.includes(item.label)) {
return [...items, item.label];
}, [setPanelItems, setMenuItemOrder]);
// Panels need to deregister on unmount to avoid orphans in menu state.
// This is an issue when panel items are being injected via SlotFills.
const deregisterPanelItem = (0,external_wp_element_namespaceObject.useCallback)(label => {
// When switching selections between components injecting matching
// controls, e.g. both panels have a "padding" control, the
// deregistration of the first panel doesn't occur until after the
// registration of the next.
const newItems = [...items];
const index = newItems.findIndex(item => item.label === label);
newItems.splice(index, 1);
const registerResetAllFilter = (0,external_wp_element_namespaceObject.useCallback)(newFilter => {
setResetAllFilters(filters => {
return [...filters, newFilter];
}, [setResetAllFilters]);
const deregisterResetAllFilter = (0,external_wp_element_namespaceObject.useCallback)(filterToRemove => {
setResetAllFilters(filters => {
return filters.filter(filter => filter !== filterToRemove);
}, [setResetAllFilters]);
// Manage and share display state of menu items representing child controls.
const [menuItems, setMenuItems] = (0,external_wp_element_namespaceObject.useState)({
// Setup menuItems state as panel items register themselves.
(0,external_wp_element_namespaceObject.useEffect)(() => {
setMenuItems(prevState => {
const items = generateMenuItems({
currentMenuItems: prevState,
}, [panelItems, setMenuItems, menuItemOrder]);
// Updates the status of the panel’s menu items. For default items the
// value represents whether it differs from the default and for optional
// items whether the item is shown.
const flagItemCustomization = (0,external_wp_element_namespaceObject.useCallback)((value, label, group = 'default') => {
// Whether all optional menu items are hidden or not must be tracked
// in order to later determine if the panel display is empty and handle
// conditional display of a plus icon to indicate the presence of further
const [areAllOptionalControlsHidden, setAreAllOptionalControlsHidden] = (0,external_wp_element_namespaceObject.useState)(false);
(0,external_wp_element_namespaceObject.useEffect)(() => {
if (isMenuItemTypeEmpty(menuItems?.default) && !isMenuItemTypeEmpty(menuItems?.optional)) {
const allControlsHidden = !Object.entries(menuItems.optional).some(([, isSelected]) => isSelected);
setAreAllOptionalControlsHidden(allControlsHidden);
}, [menuItems, setAreAllOptionalControlsHidden]);
const classes = (0,external_wp_element_namespaceObject.useMemo)(() => {
const wrapperStyle = hasInnerWrapper && ToolsPanelWithInnerWrapper(DEFAULT_COLUMNS);
const emptyStyle = isMenuItemTypeEmpty(menuItems?.default) && areAllOptionalControlsHidden && ToolsPanelHiddenInnerWrapper;
return cx(ToolsPanel(DEFAULT_COLUMNS), wrapperStyle, emptyStyle, className);
}, [areAllOptionalControlsHidden, className, cx, hasInnerWrapper, menuItems]);
// Toggle the checked state of a menu item which is then used to determine
// display of the item within the panel.
const toggleItem = (0,external_wp_element_namespaceObject.useCallback)(label => {
const currentItem = panelItems.find(item => item.label === label);
const menuGroup = currentItem.isShownByDefault ? 'default' : 'optional';
[label]: !menuItems[menuGroup][label]
setMenuItems(newMenuItems);
}, [menuItems, panelItems, setMenuItems]);
// Resets display of children and executes resetAll callback if available.
const resetAllItems = (0,external_wp_element_namespaceObject.useCallback)(() => {
if (typeof resetAll === 'function') {
isResetting.current = true;
resetAll(resetAllFilters);
// Turn off display of all non-default items.
const resetMenuItems = generateMenuItems({
setMenuItems(resetMenuItems);
}, [panelItems, resetAllFilters, resetAll, setMenuItems, menuItemOrder]);
// Assist ItemGroup styling when there are potentially hidden placeholder
// items by identifying first & last items that are toggled on for display.
const getFirstVisibleItemLabel = items => {
const optionalItems = menuItems.optional || {};
const firstItem = items.find(item => item.isShownByDefault || !!optionalItems[item.label]);
const firstDisplayedItem = getFirstVisibleItemLabel(panelItems);
const lastDisplayedItem = getFirstVisibleItemLabel([...panelItems].reverse());
const panelContext = (0,external_wp_element_namespaceObject.useMemo)(() => ({
areAllOptionalControlsHidden,
deregisterResetAllFilter,
hasMenuItems: !!panelItems.length,
isResetting: isResetting.current,
shouldRenderPlaceholderItems,
__experimentalFirstVisibleItemClass,
__experimentalLastVisibleItemClass
}), [areAllOptionalControlsHidden, deregisterPanelItem, deregisterResetAllFilter, firstDisplayedItem, flagItemCustomization, lastDisplayedItem, menuItems, panelId, panelItems, registerResetAllFilter, registerPanelItem, shouldRenderPlaceholderItems, __experimentalFirstVisibleItemClass, __experimentalLastVisibleItemClass]);
;// CONCATENATED MODULE: ./node_modules/@wordpress/components/build-module/tools-panel/tools-panel/component.js
const UnconnectedToolsPanel = (props, forwardedRef) => {
} = useToolsPanel(props);
return /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(grid_component, {
children: /*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsxs)(ToolsPanelContext.Provider, {
children: [/*#__PURE__*/(0,external_ReactJSXRuntime_namespaceObject.jsx)(tools_panel_header_component, {
headingLevel: headingLevel,
dropdownMenuProps: dropdownMenuProps
* The `ToolsPanel` is a container component that displays its children preceded
* by a header. The header includes a dropdown menu which is automatically
* generated from the panel's inner `ToolsPanelItems`.
* import { __ } from '@wordpress/i18n';
* __experimentalToolsPanel as ToolsPanel,
* __experimentalToolsPanelItem as ToolsPanelItem,
* __experimentalUnitControl as UnitControl
* } from '@wordpress/components';
* const [ height, setHeight ] = useState();
* const [ width, setWidth ] = useState();
* const resetAll = () => {
* <ToolsPanel label={ __( 'Dimensions' ) } resetAll={ resetAll }>
* hasValue={ () => !! height }
* label={ __( 'Height' ) }
* onDeselect={ () => setHeight() }
* label={ __( 'Height' ) }
* hasValue={ () => !! width }
* label={ __( 'Width' ) }
* onDeselect={ () => setWidth() }
* label={ __( 'Width' ) }
const component_ToolsPanel = contextConnect(UnconnectedToolsPanel, 'ToolsPanel');
/* harmony default export */ const tools_panel_component = (component_ToolsPanel);
;// CONCATENATED MODULE: ./node_modules/@wordpress/components/build-module/tools-panel/tools-panel-item/hook.js
const hook_noop = () => {};
function useToolsPanelItem(props) {
isShownByDefault = false,
resetAllFilter = hook_noop,
} = useContextSystem(props, 'ToolsPanelItem');
deregisterResetAllFilter,
shouldRenderPlaceholderItems: shouldRenderPlaceholder,