Added new menu animations

This commit is contained in:
Max Kotlan 2021-12-11 09:59:32 -05:00 committed by Thomas Zarebczan
parent bc514b1d5c
commit 7418e27994
5 changed files with 166 additions and 101 deletions

View file

@ -122,6 +122,13 @@ function Page(props: Props) {
>
{getSideNavElem()}
<div
className={classnames({
'sidebar--pusher': fullWidthPage,
'sidebar--pusher--open': sidebarOpen && fullWidthPage,
'sidebar--pusher--filepage': !fullWidthPage,
})}
>
<main
id={'main-content'}
className={classnames(MAIN_CLASS, className, {
@ -138,10 +145,6 @@ function Page(props: Props) {
{!isMobile && rightSide && <div className="main__right-side">{rightSide}</div>}
</main>
{/* @if TARGET='app' */}
<StatusBar />
{/* @endif */}
</div>
{/* @if TARGET='web' */}
{!noFooter && (
<React.Suspense fallback={null}>
@ -149,6 +152,11 @@ function Page(props: Props) {
</React.Suspense>
)}
{/* @endif */}
</div>
{/* @if TARGET='app' */}
<StatusBar />
{/* @endif */}
</div>
</Fragment>
);
}

View file

@ -10,7 +10,7 @@ import Icon from 'component/common/icon';
import NotificationBubble from 'component/notificationBubble';
import I18nMessage from 'component/i18nMessage';
import ChannelThumbnail from 'component/channelThumbnail';
import { useIsLargeScreen } from 'effects/use-screensize';
import { useIsMobile, useIsLargeScreen } from 'effects/use-screensize';
import { GetLinksData } from 'util/buildHomepage';
import { DOMAIN, ENABLE_UI_NOTIFICATIONS, ENABLE_NO_SOURCE_CLAIMS, CHANNEL_STAKED_LEVEL_LIVESTREAM } from 'config';
@ -219,9 +219,33 @@ function SideNavigation(props: Props) {
const isPersonalized = !IS_WEB || isAuthenticated;
const isAbsolute = isOnFilePage || isMediumScreen;
const microNavigation = !sidebarOpen || isMediumScreen;
const isMobile = useIsMobile();
const showSubscriptionSection = sidebarOpen && isPersonalized && subscriptions && subscriptions.length > 0;
const menuCanCloseCompletey = livestreamEnabled || isOnFilePage || isMobile;
const hideMenuFromView = menuCanCloseCompletey && !sidebarOpen;
const [canDisposeMenu, setCanDisposeMenu] = React.useState(false);
React.useEffect(() => {
if (hideMenuFromView) {
const handler = setTimeout(() => {
setCanDisposeMenu(true);
}, 250);
return () => {
clearTimeout(handler);
};
} else {
setCanDisposeMenu(false);
}
}, [hideMenuFromView]);
const shouldRenderLargeMenuPushorAbsolute = menuCanCloseCompletey || sidebarOpen;
const showMicroMenu = !sidebarOpen && !menuCanCloseCompletey;
const showPushMenu = sidebarOpen && !menuCanCloseCompletey;
const showSubscriptionSection =
shouldRenderLargeMenuPushorAbsolute && isPersonalized && subscriptions && subscriptions.length > 0;
const showTagSection = sidebarOpen && isPersonalized && followedTags && followedTags.length;
let displayedSubscriptions = subscriptions;
@ -388,59 +412,42 @@ function SideNavigation(props: Props) {
return (
<div
className={classnames('navigation__wrapper', {
'navigation__wrapper--micro': microNavigation && !isOnFilePage,
'navigation__wrapper--micro': showMicroMenu,
'navigation__wrapper--absolute': isAbsolute,
})}
>
{!isOnFilePage && (
<nav
aria-label={'Sidebar'}
className={classnames('navigation', {
'navigation--micro': microNavigation,
'navigation--micro': showMicroMenu,
'navigation--push': showPushMenu,
'navigation-file-page-and-mobile': hideMenuFromView,
})}
>
<div>
<ul className={classnames('navigation-links', { 'navigation-links--micro': !sidebarOpen })}>
{getLink(HOME)}
{getLink(RECENT_FROM_FOLLOWING)}
{getLink(PLAYLISTS)}
</ul>
<ul className={classnames('navigation-links', { 'navigation-links--micro': !sidebarOpen })}>
{EXTRA_SIDEBAR_LINKS && (
<>
{/* $FlowFixMe -- GetLinksData should fix it's data type */}
{EXTRA_SIDEBAR_LINKS.map((linkProps) => getLink(linkProps))}
{getLink(WILD_WEST)}
</>
)}
</ul>
{getSubscriptionSection()}
{getFollowedTagsSection()}
{!isAuthenticated && sidebarOpen && unAuthNudge}
</div>
{sidebarOpen && helpLinks}
</nav>
)}
{(isOnFilePage || isMediumScreen) && sidebarOpen && (
<>
<nav className="navigation--absolute">
<div>
{(!canDisposeMenu || sidebarOpen) && (
<div className="navigation-inner-container">
<ul className="navigation-links--absolute mobile-only">
{notificationsEnabled && getLink(NOTIFICATIONS)}
{email && livestreamEnabled && getLink(GO_LIVE)}
</ul>
<ul className="navigation-links--absolute">
<ul
className={classnames('navigation-links', {
'navigation-links--micro': showMicroMenu,
'navigation-links--absolute': shouldRenderLargeMenuPushorAbsolute,
})}
>
{getLink(HOME)}
{getLink(RECENT_FROM_FOLLOWING)}
{getLink(PLAYLISTS)}
</ul>
<ul className="navigation-links--absolute">
<ul
className={classnames('navigation-links', {
'navigation-links--micro': showMicroMenu,
'navigation-links--absolute': shouldRenderLargeMenuPushorAbsolute,
})}
>
{EXTRA_SIDEBAR_LINKS && (
<>
{/* $FlowFixMe -- GetLinksData should fix it's data type */}
@ -457,13 +464,17 @@ function SideNavigation(props: Props) {
{getSubscriptionSection()}
{getFollowedTagsSection()}
{!isAuthenticated && unAuthNudge}
{helpLinks}
{!isAuthenticated && sidebarOpen && unAuthNudge}
</div>
</nav>
<div className="navigation__overlay" onClick={() => setSidebarOpen(false)} />
</>
)}
{(!canDisposeMenu || sidebarOpen) && shouldRenderLargeMenuPushorAbsolute && helpLinks}
</nav>
<div
className={classnames('navigation__overlay', {
'navigation__overlay--active': isAbsolute && sidebarOpen,
})}
onClick={() => setSidebarOpen(false)}
/>
</div>
);
}

View file

@ -47,19 +47,43 @@
padding: 0;
}
.sidebar--pusher {
animation-timing-function: var(--resizing-animation-function);
transition: transform var(--resizing-animation-timing);
transform-origin: left;
position: absolute;
@media (max-width: $breakpoint-small) {
transform: translateX(0);
width: calc(100% - var(--spacing-m));
}
@media (min-width: $breakpoint-small) {
transform: translateX(var(--side-nav-width--micro));
width: calc(100% - ((var(--side-nav-width--micro))));
}
}
.sidebar--pusher--filepage {
width: 100%;
}
.sidebar--pusher--open {
@media (min-width: $breakpoint-medium) {
transform: translateX(var(--side-nav-width));
width: calc(100% - var(--side-nav-width));
}
}
.main {
position: relative;
width: calc(100% - var(--side-nav-width) - var(--spacing-l));
width: calc(100% - 2 * var(--spacing-l));
max-width: var(--page-max-width);
z-index: 0;
margin-right: auto;
margin-left: auto;
@media (max-width: $breakpoint-medium) and (min-width: $breakpoint-small) {
margin: 0 var(--spacing-l);
}
@media (max-width: $breakpoint-medium) {
@media (max-width: $breakpoint-small) {
width: 100%;
}
}
@ -254,12 +278,7 @@
.main--full-width {
@extend .main;
@media (min-width: $breakpoint-large) {
max-width: none;
width: 100%;
margin: 0 var(--spacing-l);
}
}
.main--auth-page {

View file

@ -21,6 +21,7 @@
position: fixed;
left: 0;
overflow-y: auto;
overflow-x: hidden;
top: var(--header-height);
width: var(--side-nav-width);
height: calc(100vh - var(--header-height));
@ -30,6 +31,13 @@
display: flex;
flex-direction: column;
animation-timing-function: var(--resizing-animation-function);
transition: transform var(--resizing-animation-timing);
z-index: 4;
background-color: var(--color-card-background);
transform: translateX(0);
transform-origin: left;
@media (min-width: $breakpoint-small) {
overflow-y: hidden;
justify-content: space-between;
@ -45,25 +53,25 @@
}
}
.navigation--push-back {
transform: translateX(calc(-1 * (var(--side-nav-width) - var(--side-nav-width--micro))));
}
.navigation--push {
transform: translateX(0);
}
.navigation--mac {
top: calc(var(--header-height) + var(--mac-titlebar-height));
}
.navigation--absolute {
@extend .navigation;
z-index: 4;
width: var(--side-nav-width);
background-color: var(--color-card-background);
box-shadow: var(--card-box-shadow);
.navigation-link {
padding-left: var(--spacing-m);
}
.navigation-file-page-and-mobile {
transform: translateX(calc(-1 * var(--side-nav-width)));
}
.navigation--micro {
@extend .navigation;
width: var(--side-nav-width--micro);
transform: translateX(calc(-1 * (var(--side-nav-width) - var(--side-nav-width--micro))));
@media (max-width: $breakpoint-small) {
display: none;
@ -101,6 +109,7 @@
}
.button__content {
margin-left: auto;
padding: var(--spacing-s);
justify-content: flex-start;
flex-direction: column;
@ -188,6 +197,10 @@
list-style: none;
}
.navigation-inner-container {
width: var(--side-nav-width);
}
.navigation-links--micro {
.icon {
height: 1.5rem;
@ -271,12 +284,22 @@
z-index: 3;
left: 0;
top: var(--header-height);
visibility: hidden;
opacity: 0;
animation-timing-function: var(--resizing-animation-function);
transition: visibility var(--resizing-animation-timing), opacity var(--resizing-animation-timing);
&.navigation__overlay--mac {
top: calc(var(--header-height) + var(--mac-titlebar-height));
}
}
.navigation__overlay--active {
opacity: 1;
visibility: visible;
animation: fadeIn var(--resizing-animation-timing) var(--resizing-animation-function);
}
.navigation__auth-nudge {
@extend .card;
margin: var(--spacing-s);

View file

@ -100,6 +100,10 @@ $breakpoint-large: 1600px;
--tag-height: 1.5rem;
--livestream-comments-width: 30rem;
// Animations
--resizing-animation-function: ease-in;
--resizing-animation-timing: 180ms;
}
@media (max-width: $breakpoint-small) {