Skip to content

Commit

Permalink
Nav Redesign: Move search and notifications to footer (#90429)
Browse files Browse the repository at this point in the history
  • Loading branch information
mmtr authored and pull[bot] committed Aug 6, 2024
1 parent 686fc13 commit 7830208
Show file tree
Hide file tree
Showing 11 changed files with 174 additions and 181 deletions.
39 changes: 30 additions & 9 deletions client/layout/global-sidebar/footer.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { recordTracksEvent } from '@automattic/calypso-analytics';
import { useHasEnTranslation } from '@automattic/i18n-utils';
import { LocalizeProps } from 'i18n-calypso';
import { FC } from 'react';
import AsyncLoad from 'calypso/components/async-load';
Expand All @@ -9,34 +10,54 @@ import { UserData } from 'calypso/lib/user/user';
import { useSelector } from 'calypso/state';
import { isSupportSession } from 'calypso/state/support/selectors';
import { GLOBAL_SIDEBAR_EVENTS } from './events';
import SidebarMenuItem from './menu-items/menu-item';
import SidebarNotifications from './menu-items/notifications';
import { SidebarSearch } from './menu-items/search';

export const GlobalSidebarFooter: FC< {
translate: LocalizeProps[ 'translate' ];
user?: UserData;
} > = ( { translate, user } ) => {
const hasEnTranslation = useHasEnTranslation();
const isInSupportSession = Boolean( useSelector( isSupportSession ) );

const isMac = window?.navigator.userAgent && window.navigator.userAgent.indexOf( 'Mac' ) > -1;
const searchShortcut = isMac ? '⌘ + K' : 'Ctrl + K';

return (
<SidebarFooter>
<a
href="/me"
className="sidebar__footer-link sidebar__footer-profile tooltip tooltip-top"
title={ translate( 'Profile' ) }
data-tooltip={ translate( 'Profile' ) }
<SidebarMenuItem
url="/me"
className="sidebar__footer-link sidebar__footer-profile"
tooltip={ translate( 'Profile' ) }
tooltipPlacement="top"
onClick={ () => recordTracksEvent( GLOBAL_SIDEBAR_EVENTS.PROFILE_CLICK ) }
>
<Gravatar user={ user } size={ 20 } />
</a>
icon={ <Gravatar user={ user } size={ 20 } /> }
/>
<AsyncLoad
require="./menu-items/help-center/help-center"
tooltip={ translate( 'Help' ) }
tooltipPlacement="top"
placeholder={
<div className="link-help">
<span className="help"></span>
</div>
}
onClick={ () => recordTracksEvent( GLOBAL_SIDEBAR_EVENTS.HELPCENTER_CLICK ) }
/>
<SidebarSearch
tooltip={
hasEnTranslation( 'Search (%(shortcut)s)' )
? translate( 'Search (%(shortcut)s)', { args: { shortcut: searchShortcut } } )
: translate( 'Jump to…' )
}
onClick={ () => recordTracksEvent( GLOBAL_SIDEBAR_EVENTS.SEARCH_CLICK ) }
/>
<SidebarNotifications
isActive={ true }
className="sidebar__item-notifications"
tooltip={ translate( 'Notifications' ) }
onClick={ () => recordTracksEvent( GLOBAL_SIDEBAR_EVENTS.NOTIFICATION_CLICK ) }
/>
{ isInSupportSession && (
<QuickLanguageSwitcher className="sidebar__footer-language-switcher" shouldRenderAsButton />
) }
Expand Down
37 changes: 8 additions & 29 deletions client/layout/global-sidebar/header.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,14 @@
import { recordTracksEvent } from '@automattic/calypso-analytics';
import { useHasEnTranslation } from '@automattic/i18n-utils';
import { useTranslate } from 'i18n-calypso';
import { useSelector } from 'react-redux';
import { getSectionName } from 'calypso/state/ui/selectors';
import SkipNavigation from '../sidebar/skip-navigation';
import { GLOBAL_SIDEBAR_EVENTS } from './events';
import SidebarNotifications from './menu-items/notifications';
import { SidebarSearch } from './menu-items/search';
import SidebarMenuItem from './menu-items/menu-item';

export const GlobalSidebarHeader = () => {
const hasEnTranslation = useHasEnTranslation();
const translate = useTranslate();

const isMac = window?.navigator.userAgent && window.navigator.userAgent.indexOf( 'Mac' ) > -1;
const searchShortcut = isMac ? '⌘ + K' : 'Ctrl + K';

const sectionName = useSelector( getSectionName );

return (
Expand All @@ -26,30 +20,15 @@ export const GlobalSidebarHeader = () => {
{ sectionName === 'sites-dashboard' ? (
<span className="dotcom"></span>
) : (
<a
href="/sites"
className="link-logo tooltip tooltip-bottom-left"
data-tooltip={ translate( 'View all sites' ) }
<SidebarMenuItem
url="/sites"
className="link-logo"
tooltip={ translate( 'View all sites' ) }
tooltipPlacement="bottom"
onClick={ () => recordTracksEvent( GLOBAL_SIDEBAR_EVENTS.ALLSITES_CLICK ) }
>
<span className="dotcom"></span>
</a>
icon={ <span className="dotcom"></span> }
/>
) }
<span className="gap"></span>
<SidebarSearch
tooltip={
hasEnTranslation( 'Search (%(shortcut)s)' )
? translate( 'Search (%(shortcut)s)', { args: { shortcut: searchShortcut } } )
: translate( 'Jump to…' )
}
onClick={ () => recordTracksEvent( GLOBAL_SIDEBAR_EVENTS.SEARCH_CLICK ) }
/>
<SidebarNotifications
isActive={ true }
className="sidebar__item-notifications"
tooltip={ translate( 'Notifications' ) }
onClick={ () => recordTracksEvent( GLOBAL_SIDEBAR_EVENTS.NOTIFICATION_CLICK ) }
/>
</div>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import SidebarMenuItem from '../menu-item';

const HELP_CENTER_STORE = HelpCenter.register();

const SidebarHelpCenter = ( { tooltip, tooltipPlacement, onClick } ) => {
const SidebarHelpCenter = ( { tooltip, onClick } ) => {
const helpCenterVisible = useDateStoreSelect(
( select ) => select( HELP_CENTER_STORE ).isHelpCenterShown(),
[]
Expand All @@ -29,7 +29,7 @@ const SidebarHelpCenter = ( { tooltip, tooltipPlacement, onClick } ) => {
'is-active': helpCenterVisible,
} ) }
tooltip={ tooltip }
tooltipPlacement={ tooltipPlacement }
tooltipPlacement="top"
icon={ <Icon icon={ help } size={ 28 } /> }
/>
</>
Expand Down
71 changes: 0 additions & 71 deletions client/layout/global-sidebar/menu-items/menu-item.jsx

This file was deleted.

97 changes: 97 additions & 0 deletions client/layout/global-sidebar/menu-items/menu-item.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import classNames from 'classnames';
import React, { useRef, forwardRef, Fragment } from 'react';
import { useSelector } from 'react-redux';
import { useCurrentRoute } from 'calypso/components/route';
import { getShouldShowGlobalSiteSidebar } from 'calypso/state/global-sidebar/selectors';
import { getSelectedSiteId } from 'calypso/state/ui/selectors';
import type { ReactNode, LegacyRef } from 'react';

interface Props {
url?: string;
tipTarget?: string;
onClick: () => void;
tooltip: string;
tooltipPlacement: 'bottom' | 'top' | 'right';
icon?: ReactNode;
className: string;
isActive?: boolean;
preloadSection?: () => void;
hasUnseen?: boolean;
alwaysShowContent?: boolean;
disabled?: boolean;
}

const SidebarMenuItem = forwardRef< HTMLButtonElement | HTMLAnchorElement, Props >(
(
{
url,
tipTarget,
onClick,
tooltip,
tooltipPlacement = 'bottom',
icon,
className,
isActive,
preloadSection,
hasUnseen,
alwaysShowContent,
disabled,
},
ref
) => {
const preloadedRef = useRef( false );

const selectedSiteId = useSelector( getSelectedSiteId );
const { currentSection } = useCurrentRoute() as {
currentSection: false | { group?: string; name?: string };
};
const isSidebarCollapsed = useSelector( ( state ) => {
return getShouldShowGlobalSiteSidebar(
state,
selectedSiteId,
currentSection !== false ? currentSection?.group ?? '' : '',
currentSection !== false ? currentSection?.name ?? '' : ''
);
} );

const preload = () => {
if ( ! preloadedRef.current && preloadSection ) {
preloadedRef.current = true;
preloadSection();
}
};

const renderChildren = () => {
return <Fragment>{ icon && <>{ icon }</> }</Fragment>;
};

const itemClasses = classNames( 'sidebar__item', className, {
'is-active': isActive,
'has-unseen': hasUnseen,
'sidebar__item--always-show-content': alwaysShowContent,
[ `tooltip tooltip-${ isSidebarCollapsed ? 'right' : tooltipPlacement }` ]: tooltip,
} );

const attributes = {
'data-tooltip': tooltip,
'data-tip-target': tipTarget,
onClick: onClick,
className: itemClasses,
onTouchStart: preload,
onMouseEnter: preload,
disabled: disabled,
};

return url ? (
<a { ...attributes } href={ url } ref={ ref as LegacyRef< HTMLAnchorElement > }>
{ renderChildren() }
</a>
) : (
<button { ...attributes } ref={ ref as LegacyRef< HTMLButtonElement > }>
{ renderChildren() }
</button>
);
}
);

export default SidebarMenuItem;
17 changes: 2 additions & 15 deletions client/layout/global-sidebar/menu-items/notifications/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,9 @@ import { withCurrentRoute } from 'calypso/components/route';
import TranslatableString from 'calypso/components/translatable/proptype';
import SidebarMenuItem from 'calypso/layout/global-sidebar/menu-items/menu-item';
import { recordTracksEvent } from 'calypso/state/analytics/actions';
import { getShouldShowGlobalSiteSidebar } from 'calypso/state/global-sidebar/selectors';
import hasUnseenNotifications from 'calypso/state/selectors/has-unseen-notifications';
import isNotificationsOpen from 'calypso/state/selectors/is-notifications-open';
import { toggleNotificationsPanel } from 'calypso/state/ui/actions';
import { getSelectedSiteId } from 'calypso/state/ui/selectors';
import { BellIcon } from './icon';

import './style.scss';
Expand All @@ -28,7 +26,6 @@ class SidebarNotifications extends Component {
isNotificationsOpen: PropTypes.bool,
hasUnseenNotifications: PropTypes.bool,
tooltip: TranslatableString,
shouldShowGlobalSiteSidebar: PropTypes.bool,
};

notificationLink = createRef();
Expand Down Expand Up @@ -146,10 +143,10 @@ class SidebarNotifications extends Component {
onClick={ this.handleClick }
isActive={ this.props.isActive }
tooltip={ this.props.tooltip }
tooltipPlacement="top"
className={ classes }
ref={ this.notificationLink }
key={ this.state.animationState }
tooltipPlacement={ this.props.shouldShowGlobalSiteSidebar ? 'bottom-left' : 'bottom' }
/>
<div className="sidebar-notifications__panel" ref={ this.notificationPanel }>
<AsyncLoad
Expand All @@ -166,20 +163,10 @@ class SidebarNotifications extends Component {
}
}

const mapStateToProps = ( state, { currentSection } ) => {
const sectionGroup = currentSection?.group ?? null;
const sectionName = currentSection?.name ?? null;
const siteId = getSelectedSiteId( state );
const shouldShowGlobalSiteSidebar = getShouldShowGlobalSiteSidebar(
state,
siteId,
sectionGroup,
sectionName
);
const mapStateToProps = ( state ) => {
return {
isNotificationsOpen: isNotificationsOpen( state ),
hasUnseenNotifications: hasUnseenNotifications( state ),
shouldShowGlobalSiteSidebar,
};
};
const mapDispatchToProps = {
Expand Down
Loading

0 comments on commit 7830208

Please sign in to comment.