Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Replace tabs
  • Loading branch information
talldan committed Aug 24, 2021
commit 67f70cbba58ca1fdc6c36c31fa215a921c2eeae5
92 changes: 7 additions & 85 deletions packages/edit-post/src/components/preferences-modal/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,10 @@ import { get } from 'lodash';
/**
* WordPress dependencies
*/
import {
__experimentalNavigation as Navigation,
__experimentalNavigationMenu as NavigationMenu,
__experimentalNavigationItem as NavigationItem,
TabPanel,
} from '@wordpress/components';
import { __ } from '@wordpress/i18n';
import { useViewportMatch } from '@wordpress/compose';
import { useSelect, useDispatch } from '@wordpress/data';
import { useMemo, useCallback, useState } from '@wordpress/element';
import { useMemo } from '@wordpress/element';
import {
PostTaxonomies,
PostExcerptCheck,
Expand All @@ -27,6 +21,7 @@ import {
import { store as coreStore } from '@wordpress/core-data';
import {
PreferencesModal,
PreferencesModalTabs,
PreferencesModalSection,
PreferencesModalFeatureToggle,
} from '@wordpress/interface';
Expand All @@ -44,7 +39,6 @@ import { store as editPostStore } from '../../store';
import BlockManager from '../block-manager';

const MODAL_NAME = 'edit-post/preferences';
const PREFERENCES_MENU = 'preferences-menu';

export default function PostEditorPreferencesModal() {
const isLargeViewport = useViewportMatch( 'medium' );
Expand Down Expand Up @@ -74,11 +68,11 @@ export default function PostEditorPreferencesModal() {
},
[ isLargeViewport ]
);
const sections = useMemo(
const tabs = useMemo(
() => [
{
name: 'general',
label: __( 'General' ),
title: __( 'General' ),
content: (
<>
{ isLargeViewport && (
Expand Down Expand Up @@ -151,7 +145,7 @@ export default function PostEditorPreferencesModal() {
},
{
name: 'blocks',
label: __( 'Blocks' ),
title: __( 'Blocks' ),
content: (
<>
<PreferencesModalSection
Expand Down Expand Up @@ -192,7 +186,7 @@ export default function PostEditorPreferencesModal() {
},
{
name: 'panels',
label: __( 'Panels' ),
title: __( 'Panels' ),
content: (
<>
<PreferencesModalSection
Expand Down Expand Up @@ -267,85 +261,13 @@ export default function PostEditorPreferencesModal() {
[ isViewable, isLargeViewport, showBlockBreadcrumbsOption ]
);

// This is also used to sync the two different rendered components
// between small and large viewports.
const [ activeMenu, setActiveMenu ] = useState( PREFERENCES_MENU );
/**
* Create helper objects from `sections` for easier data handling.
* `tabs` is used for creating the `TabPanel` and `sectionsContentMap`
* is used for easier access to active tab's content.
*/
const { tabs, sectionsContentMap } = useMemo(
() =>
sections.reduce(
( accumulator, { name, tabLabel: title, content } ) => {
accumulator.tabs.push( { name, title } );
accumulator.sectionsContentMap[ name ] = content;
return accumulator;
},
{ tabs: [], sectionsContentMap: {} }
),
[ sections ]
);
const getCurrentTab = useCallback(
( tab ) => sectionsContentMap[ tab.name ] || null,
[ sectionsContentMap ]
);
if ( ! isModalActive ) {
return null;
}
let modalContent;
// We render different components based on the viewport size.
if ( isLargeViewport ) {
modalContent = (
<TabPanel
className="edit-post-preferences__tabs"
tabs={ tabs }
initialTabName={
activeMenu !== PREFERENCES_MENU ? activeMenu : undefined
}
onSelect={ setActiveMenu }
orientation="vertical"
>
{ getCurrentTab }
</TabPanel>
);
} else {
modalContent = (
<Navigation
activeMenu={ activeMenu }
onActivateMenu={ setActiveMenu }
>
<NavigationMenu menu={ PREFERENCES_MENU }>
{ tabs.map( ( tab ) => {
return (
<NavigationItem
key={ tab.name }
title={ tab.title }
navigateToMenu={ tab.name }
/>
);
} ) }
</NavigationMenu>
{ sections.map( ( section ) => {
return (
<NavigationMenu
key={ `${ section.name }-menu` }
menu={ section.name }
title={ section.tabLabel }
parentMenu={ PREFERENCES_MENU }
>
<NavigationItem>{ section.content }</NavigationItem>
</NavigationMenu>
);
} ) }
</Navigation>
);
}

return (
<PreferencesModal onRequestClose={ closeModal }>
{ modalContent }
<PreferencesModalTabs tabs={ tabs } />
</PreferencesModal>
);
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

.edit-post-preferences-modal {
.components-navigation__menu {
.edit-post-preferences-modal__custom-fields-confirmation-button {
Expand Down
10 changes: 6 additions & 4 deletions packages/interface/src/components/preferences-modal/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ $vertical-tabs-width: 160px;
}
}

.interface-preferences-modal__navigation {
// Needs specificity, so double up the class name.
.interface-preferences-modal__navigation.components-navigation {
background-color: $white;
padding: 0;
max-height: 100%;
Expand All @@ -77,7 +78,8 @@ $vertical-tabs-width: 160px;
}
}

.interface-preferences-modal__navigation-menu {
// Needs specificity, so double up the class name.
.interface-preferences-modal__navigation-menu.components-navigation__menu {
margin: 0;
color: $gray-900;

Expand All @@ -97,8 +99,8 @@ $vertical-tabs-width: 160px;
}
}

.interface-preferences-modal__navigation-item {
// The inheritance of some items is quite strong, so we have to duplicate this one.
// Needs specificity, so double up the class name.
.interface-preferences-modal__navigation-item.components-navigation__item {
color: $gray-900;

& > button {
Expand Down
28 changes: 19 additions & 9 deletions packages/interface/src/components/preferences-modal/tabs.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,23 @@ import {
TabPanel,
} from '@wordpress/components';
import { useViewportMatch } from '@wordpress/compose';
import { useMemo, useState } from '@wordpress/element';
import { useCallback, useState } from '@wordpress/element';

const TOP_LEVEL_MENU_NAME = 'interface/preferences-modal-top-level-menu';

export default function PreferencesModalTabs( { tabs } ) {
const isTabbedLayout = useViewportMatch( 'medium' );

const [ activeTabName, setActiveTabName ] = useState();
const currentTabContent = useMemo(
() => tabs.find( ( tab ) => tab.name === activeTabName )?.content,

// Tab panel requires a callback child, so make one.
const getCurrentTabContent = useCallback(
() =>
tabs.find( ( tab ) => tab.name === activeTabName )?.content ||
tabs[ 0 ].content,
[ tabs, activeTabName ]
);

// On big screens, do a tabbed layout.
if ( isTabbedLayout ) {
return (
<TabPanel
Expand All @@ -30,31 +34,37 @@ export default function PreferencesModalTabs( { tabs } ) {
onSelect={ setActiveTabName }
orientation="vertical"
>
{ currentTabContent || tabs[ 0 ].content }
{ getCurrentTabContent }
</TabPanel>
);
}

// One little screens, do a navigation layout.
return (
<Navigation
className="interface-preferences-modal__navigation"
activeMenu={ activeTabName }
activeMenu={ activeTabName || TOP_LEVEL_MENU_NAME }
onActivateMenu={ setActiveTabName }
>
<NavigationMenu menu={ TOP_LEVEL_MENU_NAME }>
<NavigationMenu
className="interface-preferences-modal__navigation-menu"
menu={ TOP_LEVEL_MENU_NAME }
>
{ tabs.map( ( tab ) => (
<NavigationItem
className="interface-preferences-modal__navigation-item"
key={ tab.name }
title={ tab.label }
title={ tab.title }
navigateToMenu={ tab.name }
/>
) ) }
</NavigationMenu>
{ tabs.map( ( tab ) => (
<NavigationMenu
key={ `${ tab.name }-menu` }
className="interface-preferences-modal__navigation-menu"
menu={ tab.name }
title={ tab.label }
title={ tab.title }
parentMenu={ TOP_LEVEL_MENU_NAME }
>
<NavigationItem className="interface-preferences-modal__navigation-item">
Expand Down