diff --git a/components/core/UserNav/DropdownMenu.module.css b/components/core/UserNav/DropdownMenu.module.css new file mode 100644 index 000000000..ee30070d2 --- /dev/null +++ b/components/core/UserNav/DropdownMenu.module.css @@ -0,0 +1,29 @@ +.dropdownMenu { + @apply fixed top-0 right-0 z-20 w-full h-full; + + @screen lg { + @apply absolute right-0 w-screen; + max-width: 200px; + } + + & .dropdownMenuContainer { + @apply flex-col py-6 bg-primary h-full justify-around; + + @screen lg { + @apply border border-accents-1 shadow-lg py-2 h-auto; + } + } + + & .link { + @apply flex space-x-2 cursor-pointer px-6 py-3 block space-y-1 hover:bg-accents-1 transition ease-in-out duration-150 text-base leading-6 font-medium text-gray-900 items-center; + text-transform: capitalize; + + & .icons svg { + @apply w-6 h-6; + } + } + + &.off { + @apply hidden; + } +} diff --git a/components/core/UserNav/DropdownMenu.tsx b/components/core/UserNav/DropdownMenu.tsx new file mode 100644 index 000000000..e510bdd29 --- /dev/null +++ b/components/core/UserNav/DropdownMenu.tsx @@ -0,0 +1,75 @@ +import { useTheme } from 'next-themes' +import s from './DropdownMenu.module.css' +import { FC } from 'react' +import { FocusScope } from '@react-aria/focus' +import { + useOverlay, + DismissButton, + usePreventScroll, +} from '@react-aria/overlays' +import Link from 'next/link' +import cn from 'classnames' +import { Moon, Sun } from '@components/icon' +interface DropdownMenuProps { + onClose: () => void + innerRef: React.MutableRefObject +} + +const DropdownMenu: FC = ({ + onClose, + children, + innerRef, + ...props +}) => { + const { theme, setTheme } = useTheme() + + let { overlayProps } = useOverlay( + { + isDismissable: true, + onClose: onClose, + isOpen: true, + }, + innerRef + ) + + usePreventScroll() + return ( + +
+ {/* Needed placeholder for User Interation*/} +
+ +
+ + +
+
+ ) +} + +export default DropdownMenu diff --git a/components/core/UserNav/UserNav.module.css b/components/core/UserNav/UserNav.module.css index 8d5ee16e9..74f1cfa8a 100644 --- a/components/core/UserNav/UserNav.module.css +++ b/components/core/UserNav/UserNav.module.css @@ -12,35 +12,14 @@ .item { @apply mr-6 cursor-pointer relative transition ease-in-out duration-150 text-base flex items-center; &:hover { - @apply text-accents-8; + @apply text-accents-8 transition ease-in-out duration-100 transform scale-110; + } + + &.heart:hover svg { + fill: var(--accents-9); } &:last-child { @apply mr-0; } } - -.dropdownMenu { - @apply bg-primary fixed right-0 z-50 w-full h-full; - - @screen lg { - @apply absolute mt-3 right-0 w-screen; - max-width: 160px; - } - - & .dropdownMenuContainer { - @apply flex-col py-6 bg-primary h-full justify-around; - - @screen lg { - @apply border border-accents-1 shadow-lg py-2 h-auto; - } - } - - & .link { - @apply cursor-pointer px-6 py-3 block space-y-1 hover:bg-accents-1 transition ease-in-out duration-150 text-base leading-6 font-medium text-gray-900; - } - - &.off { - @apply hidden; - } -} diff --git a/components/core/UserNav/UserNav.tsx b/components/core/UserNav/UserNav.tsx index 7ce78c09a..738793cf5 100644 --- a/components/core/UserNav/UserNav.tsx +++ b/components/core/UserNav/UserNav.tsx @@ -1,18 +1,13 @@ -import { FC, useEffect, useState, useRef } from 'react' import Link from 'next/link' import cn from 'classnames' import s from './UserNav.module.css' -import { useTheme } from 'next-themes' +import { FC, useRef } from 'react' + import { Avatar } from '@components/core' import { Heart, Bag } from '@components/icon' import { useUI } from '@components/ui/context' -import { FocusScope } from '@react-aria/focus' +import DropdownMenu from './DropdownMenu' -import { - useOverlay, - DismissButton, - usePreventScroll, -} from '@react-aria/overlays' import useCart from '@lib/bigcommerce/cart/use-cart' interface Props { @@ -25,36 +20,18 @@ const countItems = (count: number, items: any[]) => const UserNav: FC = ({ className, children, ...props }) => { const { data } = useCart() - const { openSidebar, closeSidebar, displaySidebar } = useUI() - const [displayDropdown, setDisplayDropdown] = useState(false) + const { + openSidebar, + closeSidebar, + displaySidebar, + displayDropdown, + openDropdown, + closeDropdown, + } = useUI() + const itemsCount = Object.values(data?.line_items ?? {}).reduce(countItems, 0) let ref = useRef() as React.MutableRefObject - useEffect(() => { - function handleClick(e: any) { - const isInside = e?.target?.closest(`#user-dropdown`) !== null - if (isInside) return - setDisplayDropdown(false) - document.removeEventListener('click', handleClick) - } - function handleKeyPress(e: KeyboardEvent) { - if (e.key === 'Escape') { - setDisplayDropdown(false) - document.removeEventListener('keydown', handleKeyPress) - } - } - - if (displayDropdown) { - document.addEventListener('click', handleClick) - document.addEventListener('keydown', handleKeyPress) - return () => { - document.removeEventListener('click', handleClick) - document.removeEventListener('keydown', handleKeyPress) - } - } - }, [displayDropdown]) - - const toggleDropdown = () => setDisplayDropdown((v) => !v) return ( ) } -interface DropdownMenuProps { - onClose: () => void - innerRef: React.MutableRefObject -} - -const DropdownMenu: FC = ({ - onClose, - children, - innerRef, - ...props -}) => { - const { theme, setTheme } = useTheme() - - let { overlayProps } = useOverlay( - { - onClose: onClose, - isOpen: true, - }, - innerRef - ) - - usePreventScroll() - return ( - - - - ) -} - export default UserNav diff --git a/components/icon/Moon.tsx b/components/icon/Moon.tsx new file mode 100644 index 000000000..db94ac7bd --- /dev/null +++ b/components/icon/Moon.tsx @@ -0,0 +1,19 @@ +const Moon = ({ ...props }) => { + return ( + + + + ) +} + +export default Moon diff --git a/components/icon/Sun.tsx b/components/icon/Sun.tsx new file mode 100644 index 000000000..7457650b0 --- /dev/null +++ b/components/icon/Sun.tsx @@ -0,0 +1,27 @@ +const Sun = ({ ...props }) => { + return ( + + + + + + + + + + + + ) +} + +export default Sun diff --git a/components/icon/index.ts b/components/icon/index.ts index 725587c69..929003d6f 100644 --- a/components/icon/index.ts +++ b/components/icon/index.ts @@ -6,3 +6,5 @@ export { default as ArrowLeft } from './ArrowLeft' export { default as Plus } from './Plus' export { default as Minus } from './Minus' export { default as Check } from './Check' +export { default as Sun } from './Sun' +export { default as Moon } from './Moon' diff --git a/components/product/ProductView/ProductView.module.css b/components/product/ProductView/ProductView.module.css index 615cc7047..c17ad9565 100644 --- a/components/product/ProductView/ProductView.module.css +++ b/components/product/ProductView/ProductView.module.css @@ -34,7 +34,7 @@ } .nameBox { - @apply absolute top-6 left-0 z-30; + @apply absolute top-6 left-0 z-10; & .name { @apply px-6 py-2 bg-primary text-primary font-bold; diff --git a/components/ui/context.tsx b/components/ui/context.tsx index 90fe8de94..e636ecff2 100644 --- a/components/ui/context.tsx +++ b/components/ui/context.tsx @@ -4,10 +4,12 @@ import { SSRProvider, OverlayProvider } from 'react-aria' export interface State { displaySidebar: boolean + displayDropdown: boolean } const initialState = { displaySidebar: false, + displayDropdown: false, } type Action = @@ -17,21 +19,61 @@ type Action = | { type: 'CLOSE_SIDEBAR' } + | { + type: 'OPEN_DROPDOWN' + } + | { + type: 'CLOSE_DROPDOWN' + } export const UIContext = React.createContext(initialState) UIContext.displayName = 'UIContext' +function uiReducer(state: State, action: Action) { + switch (action.type) { + case 'OPEN_SIDEBAR': { + return { + ...state, + displaySidebar: true, + } + } + case 'CLOSE_SIDEBAR': { + return { + ...state, + displaySidebar: false, + } + } + case 'OPEN_DROPDOWN': { + return { + ...state, + displayDropdown: true, + } + } + case 'CLOSE_DROPDOWN': { + return { + ...state, + displayDropdown: false, + } + } + } +} + export const UIProvider: FC = (props) => { const [state, dispatch] = React.useReducer(uiReducer, initialState) const openSidebar = () => dispatch({ type: 'OPEN_SIDEBAR' }) const closeSidebar = () => dispatch({ type: 'CLOSE_SIDEBAR' }) + const openDropdown = () => dispatch({ type: 'OPEN_DROPDOWN' }) + const closeDropdown = () => dispatch({ type: 'CLOSE_DROPDOWN' }) + const value = { ...state, openSidebar, closeSidebar, + openDropdown, + closeDropdown, } return @@ -45,27 +87,6 @@ export const useUI = () => { return context } -function uiReducer(state: State, action: Action) { - switch (action.type) { - case 'OPEN_SIDEBAR': { - return !state.displaySidebar - ? { - ...state, - displaySidebar: true, - } - : state - } - case 'CLOSE_SIDEBAR': { - return state.displaySidebar - ? { - ...state, - displaySidebar: false, - } - : state - } - } -} - export const ManagedUIContext: FC = ({ children }) => (