diff --git a/packages/block-editor/src/components/inspector-controls-tabs/index.js b/packages/block-editor/src/components/inspector-controls-tabs/index.js index de192050d05cb..4784e654994be 100644 --- a/packages/block-editor/src/components/inspector-controls-tabs/index.js +++ b/packages/block-editor/src/components/inspector-controls-tabs/index.js @@ -11,6 +11,7 @@ import SettingsTab from './settings-tab'; import StylesTab from './styles-tab'; import InspectorControls from '../inspector-controls'; import useIsListViewTabDisabled from './use-is-list-view-tab-disabled'; +import useLastSelectedInspectorControlTab from './use-last-selected-inspector-control-tab'; export default function InspectorControlsTabs( { blockName, @@ -18,19 +19,25 @@ export default function InspectorControlsTabs( { hasBlockStyles, tabs, } ) { + const [ lastSelectedTab, setLastSelectedTab ] = + useLastSelectedInspectorControlTab( tabs ); + // The tabs panel will mount before fills are rendered to the list view // slot. This means the list view tab isn't initially included in the // available tabs so the panel defaults selection to the settings tab // which at the time is the first tab. This check allows blocks known to // include the list view tab to set it as the tab selected by default. - const initialTabName = ! useIsListViewTabDisabled( blockName ) - ? TAB_LIST_VIEW.name - : undefined; + const hasListTab = ! useIsListViewTabDisabled( blockName ); + + const initialTabName = + lastSelectedTab ?? ( hasListTab ? TAB_LIST_VIEW.name : undefined ); + return ( { ( tab ) => { diff --git a/packages/block-editor/src/components/inspector-controls-tabs/use-last-selected-inspector-control-tab.js b/packages/block-editor/src/components/inspector-controls-tabs/use-last-selected-inspector-control-tab.js new file mode 100644 index 0000000000000..6733c00d2d090 --- /dev/null +++ b/packages/block-editor/src/components/inspector-controls-tabs/use-last-selected-inspector-control-tab.js @@ -0,0 +1,40 @@ +/** + * WordPress dependencies + */ +import { useDispatch, useSelect } from '@wordpress/data'; +import { useCallback } from '@wordpress/element'; + +/** + * Internal dependencies + */ +import { store as blockEditorStore } from '../../store'; +import { TAB_LIST_VIEW } from './utils'; + +const SETTINGS_KEY = 'lastSelectedInspectorControlTab'; + +export default function useLastSelectedInspectorControlTab( tabs ) { + const lastTab = useSelect( ( select ) => { + const settings = select( blockEditorStore ).getSettings(); + return settings[ SETTINGS_KEY ]; + } ); + + const { updateSettings } = useDispatch( blockEditorStore ); + + const setLastSelectedTab = useCallback( + ( tabName ) => { + if ( TAB_LIST_VIEW.name === tabName ) { + return; + } + updateSettings( { + [ SETTINGS_KEY ]: tabName, + } ); + }, + [ updateSettings ] + ); + + const selectedBlockHasTab = !! tabs?.find( + ( { name } ) => lastTab === name + ); + + return [ selectedBlockHasTab ? lastTab : undefined, setLastSelectedTab ]; +}