Skip to content

Commit

Permalink
Merge pull request #14863 from artsy/DIA-726-stabilize-transitions-be…
Browse files Browse the repository at this point in the history
…tween-top-nav-items

fix: stabilize transitions on top nav
  • Loading branch information
dzucconi authored Nov 19, 2024
2 parents 72b2eeb + c41a1ee commit b0af5df
Show file tree
Hide file tree
Showing 4 changed files with 146 additions and 151 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@
"@artsy/icons": "3.22.0",
"@artsy/img": "1.0.3",
"@artsy/multienv": "^1.2.0",
"@artsy/palette": "^39.1.0",
"@artsy/palette-charts": "^38.1.0",
"@artsy/palette": "39.1.2",
"@artsy/palette-charts": "38.1.2",
"@artsy/react-html-parser": "^3.0.2",
"@artsy/xapp": "2.0.0",
"@babel/runtime": "7.13.10",
Expand Down
199 changes: 59 additions & 140 deletions src/Components/NavBar/NavBar.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,10 @@
import {
Box,
Clickable,
Dropdown,
Flex,
Spacer,
Text,
THEME,
} from "@artsy/palette"
import { Box, Clickable, Flex, Spacer, Text, THEME } from "@artsy/palette"
import CloseIcon from "@artsy/icons/CloseIcon"
import PersonIcon from "@artsy/icons/PersonIcon"
import BellStrokeIcon from "@artsy/icons/BellStrokeIcon"
import { useSystemContext } from "System/Hooks/useSystemContext"
import * as React from "react"
import { useEffect, useState } from "react"
import { NavBarSubMenu } from "./Menus"
import {
NavBarMobileMenu,
NavBarMobileMenuIcon,
Expand All @@ -27,18 +18,13 @@ import { ActionType } from "@artsy/cohesion"
import * as DeprecatedAnalyticsSchema from "@artsy/cohesion/dist/DeprecatedSchema"
import { AppContainer } from "Apps/Components/AppContainer"
import { HorizontalPadding } from "Apps/Components/HorizontalPadding"
import { Z } from "Apps/Components/constants"
import { NavBarLoggedOutActions } from "Components/NavBar/NavBarLoggedOutActions"
import { useRouter } from "System/Hooks/useRouter"
import Events from "Utils/Events"
import { __internal__useMatchMedia } from "Utils/Hooks/useMatchMedia"

import { track, useTracking } from "react-tracking"
import {
NavBarItemButton,
NavBarItemLink,
NavBarItemUnfocusableAnchor,
} from "./NavBarItem"
import { NavBarItemButton, NavBarItemLink } from "./NavBarItem"
import { NavBarLoggedInActionsQueryRenderer } from "./NavBarLoggedInActions"
import { NavBarMobileMenuNotificationsIndicatorQueryRenderer } from "./NavBarMobileMenu/NavBarMobileMenuNotificationsIndicator"
import { NavBarPrimaryLogo } from "./NavBarPrimaryLogo"
Expand All @@ -53,6 +39,7 @@ import styled from "styled-components"
import { AppDownloadBanner } from "Components/AppDownloadBanner"
import { Media } from "Utils/Responsive"
import { usePrefetchRoute } from "System/Hooks/usePrefetchRoute"
import { NavBarDropdownPanel } from "./NavBarDropdownPanel"

/**
* NOTE: Fresnel doesn't work correctly here because this is included
Expand Down Expand Up @@ -88,6 +75,10 @@ export const NavBar: React.FC = track(
const isLoggedIn = Boolean(user)
const showNotificationCount = isLoggedIn && mode !== "More"

const [transitionCount, setTransitionCount] = useState(0)

const shouldTransition = transitionCount <= 1

// Close mobile menu if dragging window from small size to desktop
useEffect(() => {
if (!isMobile) {
Expand Down Expand Up @@ -150,6 +141,15 @@ export const NavBar: React.FC = track(
setMode("Idle")
}

const handleMenuEnter = () => {
setTransitionCount(count => count + 1)
}

const handleMenuLeave = () => {
// Reset the counter when leaving the navigation area completely
setTransitionCount(0)
}

if (isEigen) {
return null
}
Expand Down Expand Up @@ -360,130 +360,49 @@ export const NavBar: React.FC = track(
variant="sm"
lineHeight={1}
>
<Flex alignItems="stretch" minWidth={0}>
<Dropdown
zIndex={Z.dropdown}
keepInDOM
placement="bottom"
offset={0}
dropdown={({ setVisible }) => (
<NavBarSubMenu
menu={WHATS_NEW_SUBMENU_DATA.menu}
contextModule={
DeprecatedAnalyticsSchema.ContextModule
.HeaderWhatsNewDropdown
}
onClick={() => setVisible(false)}
/>
)}
>
{({ anchorRef, anchorProps, visible, setVisible }) => (
<NavBarItemButton
ref={anchorRef as any}
px={0}
pr={1}
active={visible}
{...anchorProps}
>
<NavBarItemUnfocusableAnchor
href="/collection/new-this-week"
onMouseOver={() =>
prefetch("/collection/new-this-week")
}
onClick={event => {
handleClick(event)

// Small timeout to avoid transition race condition
setTimeout(() => {
setVisible(false)
}, 100)
}}
data-label={WHATS_NEW_SUBMENU_DATA.text}
/>
{WHATS_NEW_SUBMENU_DATA.text}
</NavBarItemButton>
)}
</Dropdown>

<Dropdown
zIndex={Z.dropdown}
keepInDOM
placement="bottom"
offset={0}
dropdown={({ setVisible }) => (
<NavBarSubMenu
menu={ARTISTS_SUBMENU_DATA.menu}
contextModule={
DeprecatedAnalyticsSchema.ContextModule
.HeaderArtistsDropdown
}
onClick={() => setVisible(false)}
/>
)}
>
{({ anchorRef, anchorProps, visible, setVisible }) => (
<NavBarItemButton
ref={anchorRef as any}
active={visible}
{...anchorProps}
>
<NavBarItemUnfocusableAnchor
href="/artists"
onMouseOver={() => prefetch("/artists")}
onClick={event => {
handleClick(event)

// Small timeout to avoid transition race condition
setTimeout(() => {
setVisible(false)
}, 100)
}}
data-label="Artists"
/>
Artists
</NavBarItemButton>
)}
</Dropdown>

<Dropdown
zIndex={Z.dropdown}
keepInDOM
placement="bottom"
offset={0}
dropdown={({ setVisible }) => (
<NavBarSubMenu
menu={ARTWORKS_SUBMENU_DATA.menu}
contextModule={
DeprecatedAnalyticsSchema.ContextModule
.HeaderArtworksDropdown
}
onClick={() => setVisible(false)}
/>
)}
>
{({ anchorRef, anchorProps, visible, setVisible }) => (
<NavBarItemButton
ref={anchorRef as any}
active={visible}
{...anchorProps}
>
<NavBarItemUnfocusableAnchor
href="/collect"
onMouseOver={() => prefetch("/collect")}
onClick={event => {
handleClick(event)

// Small timeout to avoid transition race condition
setTimeout(() => {
setVisible(false)
}, 100)
}}
data-label="Artworks"
/>
Artworks
</NavBarItemButton>
)}
</Dropdown>
<Flex
alignItems="stretch"
minWidth={0}
onMouseLeave={handleMenuLeave}
>
<NavBarDropdownPanel
href="/collection/new-this-week"
label={WHATS_NEW_SUBMENU_DATA.text}
menu={WHATS_NEW_SUBMENU_DATA.menu}
contextModule={
DeprecatedAnalyticsSchema.ContextModule
.HeaderWhatsNewDropdown
}
onMenuEnter={handleMenuEnter}
handleClick={handleClick}
shouldTransition={shouldTransition}
/>

<NavBarDropdownPanel
href="/artists"
label="Artists"
menu={ARTISTS_SUBMENU_DATA.menu}
contextModule={
DeprecatedAnalyticsSchema.ContextModule
.HeaderArtistsDropdown
}
onMenuEnter={handleMenuEnter}
handleClick={handleClick}
shouldTransition={shouldTransition}
/>

<NavBarDropdownPanel
href="/collect"
label="Artworks"
menu={ARTWORKS_SUBMENU_DATA.menu}
contextModule={
DeprecatedAnalyticsSchema.ContextModule
.HeaderArtworksDropdown
}
onMenuEnter={handleMenuEnter}
handleClick={handleClick}
shouldTransition={shouldTransition}
/>

<NavBarItemLink
href="/auctions"
Expand Down
76 changes: 76 additions & 0 deletions src/Components/NavBar/NavBarDropdownPanel.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { Dropdown } from "@artsy/palette"
import { Z } from "Apps/Components/constants"
import { NavBarSubMenu } from "./Menus"
import { NavBarItemButton, NavBarItemUnfocusableAnchor } from "./NavBarItem"
import { usePrefetchRoute } from "System/Hooks/usePrefetchRoute"
import * as DeprecatedAnalyticsSchema from "@artsy/cohesion/dist/DeprecatedSchema"
import { MenuData } from "Components/NavBar/menuData"

interface NavBarDropdownPanelProps {
href: string
label: string
menu: MenuData
contextModule: string
onMenuEnter: () => void
handleClick: (event: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => void
shouldTransition: boolean
}

export const NavBarDropdownPanel: React.FC<NavBarDropdownPanelProps> = ({
href,
label,
menu,
contextModule,
onMenuEnter,
handleClick,
shouldTransition,
}) => {
const { prefetch } = usePrefetchRoute()

return (
<Dropdown
zIndex={Z.dropdown}
keepInDOM
placement="bottom"
offset={0}
transition={shouldTransition}
// eslint-disable-next-line react/no-unstable-nested-components
dropdown={({ setVisible }) => (
<NavBarSubMenu
menu={menu}
contextModule={
contextModule as DeprecatedAnalyticsSchema.ContextModule
}
onClick={() => setVisible(false)}
/>
)}
>
{({ anchorRef, anchorProps, visible, setVisible }) => {
const { onMouseEnter, ...restAnchorProps } = anchorProps

return (
<NavBarItemButton
ref={anchorRef as any}
active={visible}
onMouseEnter={e => {
onMouseEnter?.(e)
onMenuEnter()
}}
{...restAnchorProps}
>
<NavBarItemUnfocusableAnchor
href={href}
onMouseOver={() => prefetch(href)}
onClick={event => {
handleClick(event)
setTimeout(() => setVisible(false), 100)
}}
data-label={label}
/>
{label}
</NavBarItemButton>
)
}}
</Dropdown>
)
}
18 changes: 9 additions & 9 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,12 @@
dependencies:
dotenv "^10.0.0"

"@artsy/palette-charts@^38.1.0":
version "38.1.0"
resolved "https://registry.yarnpkg.com/@artsy/palette-charts/-/palette-charts-38.1.0.tgz#52fd3758939be218c15935574e69a753ab6c623c"
integrity sha512-G1ZNjgrfz1QfvQEiaDVu5IFt7KjQQhVz0XkWTKAh24kP+pbdb8ef3Cb+BT4vCCaFlCi9IQxLTRhQ2owi0+xgWQ==
"@artsy/palette-charts@38.1.2":
version "38.1.2"
resolved "https://registry.yarnpkg.com/@artsy/palette-charts/-/palette-charts-38.1.2.tgz#d52e7fc0c1a9e1d0b172c4026147d5ec8370a557"
integrity sha512-yS3v9YOPu3cmCxm2ez8RSL8kcJJwwo0LvA4w1mMhiHTkb46cH5Ng/9chsC4CendspcheOOR24YQkeg/hXPGhPw==
dependencies:
"@artsy/palette" "^39.1.0"
"@artsy/palette" "^39.1.2"
"@seznam/compose-react-refs" "^1.0.6"
"@styled-system/theme-get" "^5.1.2"
d3-interpolate "^1.3.2"
Expand All @@ -94,10 +94,10 @@
resolved "https://registry.yarnpkg.com/@artsy/palette-tokens/-/palette-tokens-6.1.0.tgz#f79a1304b59741e982eae98f07d9099d7f1c9347"
integrity sha512-heBh9cuGIECWHdXPLFqmliKKIHob5iSKxi7SlsN36wkLrfIfwhy/NYUhP1OO/u24Khl7ixpTrKzkt6tQEyCSzw==

"@artsy/palette@^39.1.0":
version "39.1.0"
resolved "https://registry.yarnpkg.com/@artsy/palette/-/palette-39.1.0.tgz#2b454f30b17e7b394df776c8aa9f034ee7e04057"
integrity sha512-SJDXzGAnUUAA/43TADk9Sael5lWjrx72zvSDolreeh36EmWmtGFPjuGl4k8OKIoJEVJKJSX4aDeIIcBQZiErJQ==
"@artsy/palette@39.1.2", "@artsy/palette@^39.1.2":
version "39.1.2"
resolved "https://registry.yarnpkg.com/@artsy/palette/-/palette-39.1.2.tgz#8d12b5a1531bfc3a63057a643cbf2c3d79beacb3"
integrity sha512-giuzM56qKsfCBtsiKKjZfVMn7CdnU0xLTb4kD4V8/Ff9qvoMxde3ip9Qy+yR8fyIOxtSmjnbBT9mNcvxYNQWWg==
dependencies:
"@artsy/icons" "^3.2.2"
"@artsy/palette-tokens" "^6.1.0"
Expand Down

0 comments on commit b0af5df

Please sign in to comment.