Skip to content

Commit

Permalink
Trigger onDeselect/onSelect callbacks directly
Browse files Browse the repository at this point in the history
Instead of via an effect hook.
  • Loading branch information
stokesman committed Sep 29, 2024
1 parent 743144b commit df3451b
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 43 deletions.
38 changes: 5 additions & 33 deletions packages/components/src/tools-panel/tools-panel-item/hook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ export function useToolsPanelItem(
registerPanelItem,
deregisterPanelItem,
flagItemCustomization,
isResetting,
shouldRenderPlaceholderItems: shouldRenderPlaceholder,
firstDisplayedItem,
lastDisplayedItem,
Expand Down Expand Up @@ -78,6 +77,8 @@ export function useToolsPanelItem(
isShownByDefault,
label,
panelId,
onDeselect,
onSelect,
} );
}

Expand All @@ -99,6 +100,8 @@ export function useToolsPanelItem(
previousPanelId,
registerPanelItem,
deregisterPanelItem,
onDeselect,
onSelect,
] );

useEffect( () => {
Expand All @@ -121,7 +124,6 @@ export function useToolsPanelItem(
// `ToolsPanel`.
const menuGroup = isShownByDefault ? 'default' : 'optional';
const isMenuItemChecked = menuItems?.[ menuGroup ]?.[ label ];
const wasMenuItemChecked = usePrevious( isMenuItemChecked );
const isRegistered = menuItems?.[ menuGroup ]?.[ label ] !== undefined;

const isValueSet = hasValue();
Expand All @@ -141,40 +143,10 @@ export function useToolsPanelItem(
isShownByDefault,
] );

// Determine if the panel item's corresponding menu is being toggled and
// trigger appropriate callback if it is.
useEffect( () => {
// We check whether this item is currently registered as items rendered
// via fills can persist through the parent panel being remounted.
// See: https://github.com/WordPress/gutenberg/pull/45673
if ( ! isRegistered || isResetting || ! hasMatchingPanel ) {
return;
}

if ( isMenuItemChecked && ! isValueSet && ! wasMenuItemChecked ) {
onSelect?.();
}

if ( ! isMenuItemChecked && isValueSet && wasMenuItemChecked ) {
onDeselect?.();
}
}, [
hasMatchingPanel,
isMenuItemChecked,
isRegistered,
isResetting,
isValueSet,
wasMenuItemChecked,
onSelect,
onDeselect,
] );

// The item is shown if it is a default control regardless of whether it
// has a value. Optional items are shown when they are checked or have
// a value.
const isShown = isShownByDefault
? menuItems?.[ menuGroup ]?.[ label ] !== undefined
: isMenuItemChecked;
const isShown = isShownByDefault ? isRegistered : isMenuItemChecked;

const cx = useCx();
const classes = useMemo( () => {
Expand Down
19 changes: 16 additions & 3 deletions packages/components/src/tools-panel/tools-panel/hook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -357,9 +357,22 @@ export function useToolsPanel(

// Toggle the checked state of a menu item which is then used to determine
// display of the item within the panel.
const toggleItem = useCallback( ( label: string ) => {
panelDispatch( { type: 'TOGGLE_VALUE', label } );
}, [] );
const toggleItem = useCallback(
( label: string ) => {
panelDispatch( { type: 'TOGGLE_VALUE', label } );
const currentItem = panelItems.find(
( item ) => item.label === label
);
if ( currentItem ) {
const { isShownByDefault, onDeselect, onSelect } = currentItem;
const menuGroup = isShownByDefault ? 'default' : 'optional';
const hasValue = menuItems[ menuGroup ][ label ];
const callback = hasValue ? onDeselect : onSelect;
callback?.();
}
},
[ menuItems, panelItems ]
);

// Resets display of children and executes resetAll callback if available.
const resetAllItems = useCallback( () => {
Expand Down
14 changes: 7 additions & 7 deletions packages/components/src/tools-panel/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,13 +133,6 @@ export type ToolsPanelItem = {
* from a shared source.
*/
panelId?: string | null;
};

export type ToolsPanelItemProps = ToolsPanelItem & {
/**
* The child elements.
*/
children?: ReactNode;
/**
* Called when this item is deselected in the `ToolsPanel` menu. This is
* normally used to reset the panel item control's value.
Expand All @@ -150,6 +143,13 @@ export type ToolsPanelItemProps = ToolsPanelItem & {
* menu.
*/
onSelect?: () => void;
};

export type ToolsPanelItemProps = ToolsPanelItem & {
/**
* The child elements.
*/
children?: ReactNode;

/**
* A `ToolsPanel` will collect each item's `resetAllFilter` and pass an
Expand Down

0 comments on commit df3451b

Please sign in to comment.