4
0
forked from crowetic/commerce

Removing HeadlessUI and React-Aria

This commit is contained in:
Belen Curcio 2020-11-26 13:13:30 -03:00
parent 9dbd606eef
commit b5fd6bd38e
20 changed files with 417 additions and 2587 deletions

View File

@ -1,11 +1,9 @@
import { FC } from 'react'
import cn from 'classnames' import cn from 'classnames'
import { useRouter } from 'next/router'
import Link from 'next/link' import Link from 'next/link'
import { Menu } from '@headlessui/react' import { FC, useState } from 'react'
import { DoubleChevron } from '@components/icons' import { useRouter } from 'next/router'
import s from './I18nWidget.module.css' import s from './I18nWidget.module.css'
import { Cross } from '@components/icons'
interface LOCALE_DATA { interface LOCALE_DATA {
name: string name: string
img: { img: {
@ -32,6 +30,7 @@ const LOCALES_MAP: Record<string, LOCALE_DATA> = {
} }
const I18nWidget: FC = () => { const I18nWidget: FC = () => {
const [display, setDisplay] = useState(false)
const { const {
locale, locale,
locales, locales,
@ -39,42 +38,61 @@ const I18nWidget: FC = () => {
asPath: currentPath, asPath: currentPath,
} = useRouter() } = useRouter()
const options = locales?.filter((val) => val !== locale) const options = locales?.filter((val) => val !== locale)
const currentLocale = locale || defaultLocale const currentLocale = locale || defaultLocale
return ( return (
<nav className={s.root}> <nav className={s.root}>
<Menu> <div className="flex items-center relative">
<Menu.Button className={s.button} aria-label="Language selector"> <button className={s.button} aria-label="Language selector" />
<img <img
className="block mr-2 w-5" className="block mr-2 w-5"
src={`/${LOCALES_MAP[currentLocale].img.filename}`} src={`/${LOCALES_MAP[currentLocale].img.filename}`}
alt={LOCALES_MAP[currentLocale].img.alt} alt={LOCALES_MAP[currentLocale].img.alt}
/> />
<span className="mr-2">{LOCALES_MAP[currentLocale].name}</span>
{options && ( {options && (
<span> <span className="cursor-pointer" onClick={() => setDisplay(!display)}>
<DoubleChevron /> <svg
viewBox="0 0 24 24"
width="24"
height="24"
stroke="currentColor"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
fill="none"
shapeRendering="geometricPrecision"
>
<path d="M6 9l6 6 6-6" />
</svg>
</span> </span>
)} )}
</Menu.Button> </div>
<div className="absolute top-0 right-0">
{options?.length ? ( {options?.length && display ? (
<Menu.Items className={s.dropdownMenu}> <div className={s.dropdownMenu}>
<div className="flex flex-row justify-end px-6">
<button
onClick={() => setDisplay(false)}
aria-label="Close panel"
className={s.closeButton}
>
<Cross className="h-6 w-6" />
</button>
</div>
<ul>
{options.map((locale) => ( {options.map((locale) => (
<Menu.Item key={locale}> <li key={locale}>
{({ active }) => (
<Link href={currentPath} locale={locale}> <Link href={currentPath} locale={locale}>
<a className={cn(s.item, { [s.active]: active })}> <a className={cn(s.item)} onClick={() => setDisplay(false)}>
{LOCALES_MAP[locale].name} {LOCALES_MAP[locale].name}
</a> </a>
</Link> </Link>
)} </li>
</Menu.Item>
))} ))}
</Menu.Items> </ul>
</div>
) : null} ) : null}
</Menu> </div>
</nav> </nav>
) )
} }

View File

@ -5,7 +5,6 @@ import { useRouter } from 'next/router'
import React, { FC } from 'react' import React, { FC } from 'react'
import { useUI } from '@components/ui/context' import { useUI } from '@components/ui/context'
import { Navbar, Footer } from '@components/common' import { Navbar, Footer } from '@components/common'
import { usePreventScroll } from '@react-aria/overlays'
import { useAcceptCookies } from '@lib/hooks/useAcceptCookies' import { useAcceptCookies } from '@lib/hooks/useAcceptCookies'
import { CommerceProvider } from '@bigcommerce/storefront-data-hooks' import { CommerceProvider } from '@bigcommerce/storefront-data-hooks'
import { Sidebar, Button, Modal, LoadingDots } from '@components/ui' import { Sidebar, Button, Modal, LoadingDots } from '@components/ui'
@ -56,10 +55,6 @@ const Layout: FC<Props> = ({ children, pageProps }) => {
const { acceptedCookies, onAcceptCookies } = useAcceptCookies() const { acceptedCookies, onAcceptCookies } = useAcceptCookies()
const { locale = 'en-US' } = useRouter() const { locale = 'en-US' } = useRouter()
usePreventScroll({
isDisabled: !(displaySidebar || displayModal),
})
return ( return (
<CommerceProvider locale={locale}> <CommerceProvider locale={locale}>
<div className={cn(s.root)}> <div className={cn(s.root)}>

View File

@ -1,2 +0,0 @@
.root {
}

View File

@ -1,55 +0,0 @@
import React, { FC } from 'react'
import { Switch } from '@headlessui/react'
import { Moon, Sun } from '@components/icons'
interface Props {
className?: string
checked: boolean
onChange: any
}
const Toggle: FC<Props> = ({ className, checked, onChange }) => {
return (
<Switch
checked={checked}
onChange={onChange}
className="focus:outline-none"
>
<span
role="checkbox"
aria-checked="false"
tabIndex={0}
className={`${
checked ? 'bg-gray-800' : 'bg-gray-200'
} relative inline-flex flex-shrink-0 h-6 w-11 border-2 border-transparent rounded-full cursor-pointer transition-colors ease-in-out duration-150 focus:outline-none focus:shadow-outline`}
>
<span
aria-hidden="true"
className={`${
checked ? 'translate-x-5' : 'translate-x-0'
} translate-x-0 relative inline-block h-5 w-5 rounded-full bg-white shadow transform transition ease-in-out duration-150`}
>
<span
className={`${
checked
? 'opacity-0 ease-out duration-150'
: 'opacity-100 ease-in duration-150'
} absolute inset-0 h-full w-full flex items-center justify-center transition-opacity`}
>
<Sun className="h-3 w-3 text-accent-3" />
</span>
<span
className={`${
checked
? 'opacity-100 ease-in duration-150'
: 'opacity-0 ease-out duration-150'
} opacity-0 ease-out duration-150 absolute inset-0 h-full w-full flex items-center justify-center transition-opacity`}
>
<Moon className="h-3 w-3 text-yellow-400" />
</span>
</span>
</span>
</Switch>
)
}
export default Toggle

View File

@ -1 +0,0 @@
export { default } from './Toggle'

View File

@ -1,16 +1,16 @@
import { FC } from 'react'
import Link from 'next/link'
import { useTheme } from 'next-themes'
import cn from 'classnames' import cn from 'classnames'
import Link from 'next/link'
import { FC, useState } from 'react'
import { useTheme } from 'next-themes'
import { useRouter } from 'next/router'
import s from './DropdownMenu.module.css' import s from './DropdownMenu.module.css'
import { Avatar } from '@components/common'
import { Moon, Sun } from '@components/icons' import { Moon, Sun } from '@components/icons'
import { useUI } from '@components/ui/context' import { useUI } from '@components/ui/context'
import { Menu, Transition } from '@headlessui/react'
import useLogout from '@bigcommerce/storefront-data-hooks/use-logout'
import { useRouter } from 'next/router'
import useLogout from '@bigcommerce/storefront-data-hooks/use-logout'
interface DropdownMenuProps { interface DropdownMenuProps {
open: boolean open?: boolean
} }
const LINKS = [ const LINKS = [
@ -29,25 +29,26 @@ const LINKS = [
] ]
const DropdownMenu: FC<DropdownMenuProps> = ({ open = false }) => { const DropdownMenu: FC<DropdownMenuProps> = ({ open = false }) => {
const { theme, setTheme } = useTheme()
const logout = useLogout() const logout = useLogout()
const { pathname } = useRouter() const { pathname } = useRouter()
const { theme, setTheme } = useTheme()
const [display, setDisplay] = useState(false)
const { closeSidebarIfPresent } = useUI() const { closeSidebarIfPresent } = useUI()
return ( return (
<Transition <div>
show={open} <button
enter="transition ease-out duration-150 z-20" className={s.avatarButton}
enterFrom="transform opacity-0 scale-95" onClick={() => setDisplay(!display)}
enterTo="transform opacity-100 scale-100" aria-label="Menu"
leave="transition ease-in duration-75"
leaveFrom="transform opacity-100 scale-100"
leaveTo="transform opacity-0 scale-95"
> >
<Menu.Items className={s.dropdownMenu}> <Avatar />
</button>
{display && (
<ul className={s.dropdownMenu}>
{LINKS.map(({ name, href }) => ( {LINKS.map(({ name, href }) => (
<Menu.Item key={href}> <li key={href}>
<div> <div>
<Link href={href}> <Link href={href}>
<a <a
@ -60,9 +61,9 @@ const DropdownMenu: FC<DropdownMenuProps> = ({ open = false }) => {
</a> </a>
</Link> </Link>
</div> </div>
</Menu.Item> </li>
))} ))}
<Menu.Item> <li>
<a <a
className={cn(s.link, 'justify-between')} className={cn(s.link, 'justify-between')}
onClick={() => onClick={() =>
@ -80,17 +81,18 @@ const DropdownMenu: FC<DropdownMenuProps> = ({ open = false }) => {
)} )}
</div> </div>
</a> </a>
</Menu.Item> </li>
<Menu.Item> <li>
<a <a
className={cn(s.link, 'border-t border-accents-2 mt-4')} className={cn(s.link, 'border-t border-accents-2 mt-4')}
onClick={() => logout()} onClick={() => logout()}
> >
Logout Logout
</a> </a>
</Menu.Item> </li>
</Menu.Items> </ul>
</Transition> )}
</div>
) )
} }

View File

@ -3,12 +3,11 @@ import Link from 'next/link'
import cn from 'classnames' import cn from 'classnames'
import useCart from '@bigcommerce/storefront-data-hooks/cart/use-cart' import useCart from '@bigcommerce/storefront-data-hooks/cart/use-cart'
import useCustomer from '@bigcommerce/storefront-data-hooks/use-customer' import useCustomer from '@bigcommerce/storefront-data-hooks/use-customer'
import { Menu } from '@headlessui/react'
import { Heart, Bag } from '@components/icons' import { Heart, Bag } from '@components/icons'
import { Avatar } from '@components/common'
import { useUI } from '@components/ui/context' import { useUI } from '@components/ui/context'
import DropdownMenu from './DropdownMenu' import DropdownMenu from './DropdownMenu'
import s from './UserNav.module.css' import s from './UserNav.module.css'
import { Avatar } from '@components/common'
interface Props { interface Props {
className?: string className?: string
@ -21,9 +20,9 @@ const countItems = (count: number, items: any[]) =>
const UserNav: FC<Props> = ({ className, children, ...props }) => { const UserNav: FC<Props> = ({ className, children, ...props }) => {
const { data } = useCart() const { data } = useCart()
const { data: customer } = useCustomer() const { data: customer } = useCustomer()
const { toggleSidebar, closeSidebarIfPresent, openModal } = useUI() const { toggleSidebar, closeSidebarIfPresent, openModal } = useUI()
const itemsCount = Object.values(data?.line_items ?? {}).reduce(countItems, 0) const itemsCount = Object.values(data?.line_items ?? {}).reduce(countItems, 0)
return ( return (
<nav className={cn(s.root, className)}> <nav className={cn(s.root, className)}>
<div className={s.mainContainer}> <div className={s.mainContainer}>
@ -41,16 +40,7 @@ const UserNav: FC<Props> = ({ className, children, ...props }) => {
</li> </li>
<li className={s.item}> <li className={s.item}>
{customer ? ( {customer ? (
<Menu> <DropdownMenu />
{({ open }) => (
<>
<Menu.Button className={s.avatarButton} aria-label="Menu">
<Avatar />
</Menu.Button>
<DropdownMenu open={open} />
</>
)}
</Menu>
) : ( ) : (
<button <button
className={s.avatarButton} className={s.avatarButton}

View File

@ -5,7 +5,6 @@ export { default as Layout } from './Layout'
export { default as Navbar } from './Navbar' export { default as Navbar } from './Navbar'
export { default as Searchbar } from './Searchbar' export { default as Searchbar } from './Searchbar'
export { default as UserNav } from './UserNav' export { default as UserNav } from './UserNav'
export { default as Toggle } from './Toggle'
export { default as Head } from './Head' export { default as Head } from './Head'
export { default as HTMLContent } from './HTMLContent' export { default as HTMLContent } from './HTMLContent'
export { default as I18nWidget } from './I18nWidget' export { default as I18nWidget } from './I18nWidget'

View File

@ -6,7 +6,6 @@ import React, {
useRef, useRef,
} from 'react' } from 'react'
import mergeRefs from 'react-merge-refs' import mergeRefs from 'react-merge-refs'
import { useButton } from 'react-aria'
import s from './Button.module.css' import s from './Button.module.css'
import { LoadingDots } from '@components/ui' import { LoadingDots } from '@components/ui'
@ -34,19 +33,8 @@ const Button: React.FC<ButtonProps> = forwardRef((props, buttonRef) => {
loading = false, loading = false,
disabled = false, disabled = false,
style = {}, style = {},
...rest
} = props } = props
const ref = useRef<typeof Component>(null) const ref = useRef<typeof Component>(null)
const { buttonProps, isPressed } = useButton(
{
...rest,
// @ts-ignore onClick === onPress for our purposes
onPress: onClick,
isDisabled: disabled,
elementType: Component,
},
ref
)
const rootClassName = cn( const rootClassName = cn(
s.root, s.root,
@ -63,8 +51,6 @@ const Button: React.FC<ButtonProps> = forwardRef((props, buttonRef) => {
aria-pressed={active} aria-pressed={active}
data-variant={variant} data-variant={variant}
ref={mergeRefs([ref, buttonRef])} ref={mergeRefs([ref, buttonRef])}
{...buttonProps}
data-active={isPressed ? '' : undefined}
className={rootClassName} className={rootClassName}
disabled={disabled} disabled={disabled}
style={{ style={{

View File

@ -1,10 +1,13 @@
import { FC, useRef } from 'react' import { FC, useRef, useEffect } from 'react'
import s from './Modal.module.css'
import { FocusScope } from '@react-aria/focus'
import { Transition } from '@headlessui/react'
import { Cross } from '@components/icons'
import { useOverlay, OverlayContainer } from '@react-aria/overlays'
import Portal from '@reach/portal' import Portal from '@reach/portal'
import s from './Modal.module.css'
import { Cross } from '@components/icons'
import {
disableBodyScroll,
enableBodyScroll,
clearAllBodyScrollLocks,
} from 'body-scroll-lock'
interface Props { interface Props {
className?: string className?: string
children?: any children?: any
@ -12,32 +15,27 @@ interface Props {
onClose: () => void onClose: () => void
} }
const Modal: FC<Props> = ({ children, open = false, onClose, ...props }) => { const Modal: FC<Props> = ({ children, open, onClose }) => {
let ref = useRef() as React.MutableRefObject<HTMLInputElement> const ref = useRef() as React.MutableRefObject<HTMLDivElement>
let { overlayProps } = useOverlay(
{ useEffect(() => {
isOpen: open, if (ref.current) {
isDismissable: false, if (open) {
onClose: onClose, disableBodyScroll(ref.current)
...props, } else {
}, enableBodyScroll(ref.current)
ref }
) }
return () => {
clearAllBodyScrollLocks()
}
}, [open])
return ( return (
<Transition show={open}> <Portal>
<OverlayContainer> {open ? (
<FocusScope contain restoreFocus autoFocus> <div className={s.root} ref={ref}>
<div className={s.root}> <div className={s.modal}>
<Transition.Child
enter="transition-opacity ease-linear duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="transition-opacity ease-linear duration-300"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div className={s.modal} {...overlayProps} ref={ref}>
<div className="h-7 flex items-center justify-end w-full"> <div className="h-7 flex items-center justify-end w-full">
<button <button
onClick={() => onClose()} onClick={() => onClose()}
@ -49,11 +47,9 @@ const Modal: FC<Props> = ({ children, open = false, onClose, ...props }) => {
</div> </div>
{children} {children}
</div> </div>
</Transition.Child>
</div> </div>
</FocusScope> ) : null}
</OverlayContainer> </Portal>
</Transition>
) )
} }

View File

@ -1,9 +1,11 @@
import { FC, useRef } from 'react'
import s from './Sidebar.module.css' import s from './Sidebar.module.css'
import { Transition } from '@headlessui/react'
import { useOverlay, OverlayContainer } from '@react-aria/overlays'
import { FocusScope } from '@react-aria/focus'
import Portal from '@reach/portal' import Portal from '@reach/portal'
import { FC, useEffect, useRef } from 'react'
import {
disableBodyScroll,
enableBodyScroll,
clearAllBodyScrollLocks,
} from 'body-scroll-lock'
interface Props { interface Props {
children: any children: any
@ -12,62 +14,40 @@ interface Props {
} }
const Sidebar: FC<Props> = ({ children, open = false, onClose }) => { const Sidebar: FC<Props> = ({ children, open = false, onClose }) => {
const ref = useRef<HTMLDivElement>(null) const ref = useRef() as React.MutableRefObject<HTMLDivElement>
const { overlayProps } = useOverlay(
{ useEffect(() => {
isOpen: open, if (ref.current) {
isDismissable: true, if (open) {
onClose: onClose, disableBodyScroll(ref.current)
}, } else {
ref enableBodyScroll(ref.current)
) }
}
return () => {
clearAllBodyScrollLocks()
}
}, [open])
return ( return (
<Portal> <Portal>
<Transition show={open}> {open ? (
<OverlayContainer> <div className={s.root} ref={ref}>
<FocusScope contain restoreFocus autoFocus>
<div className={s.root}>
<div className="absolute inset-0 overflow-hidden"> <div className="absolute inset-0 overflow-hidden">
<Transition.Child
enter="transition-opacity ease-linear duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="transition-opacity ease-linear duration-300"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div <div
className="absolute inset-0 bg-black bg-opacity-50 transition-opacity" className="absolute inset-0 bg-black bg-opacity-50 transition-opacity"
// Close the sidebar when clicking on the backdrop
onClick={onClose} onClick={onClose}
/> />
</Transition.Child> <section className="absolute inset-y-0 right-0 pl-10 max-w-full flex sm:pl-16 outline-none">
<section
className="absolute inset-y-0 right-0 pl-10 max-w-full flex sm:pl-16 outline-none"
{...overlayProps}
ref={ref}
>
<Transition.Child
enter="transition ease-in-out duration-300 transform"
enterFrom="translate-x-full"
enterTo="translate-x-0"
leave="transition ease-in-out duration-300 transform"
leaveFrom="translate-x-0"
leaveTo="translate-x-full"
>
<div className="h-full md:w-screen md:max-w-md"> <div className="h-full md:w-screen md:max-w-md">
<div className="h-full flex flex-col text-base bg-accents-1 shadow-xl overflow-y-auto"> <div className="h-full flex flex-col text-base bg-accents-1 shadow-xl overflow-y-auto">
{children} {children}
</div> </div>
</div> </div>
</Transition.Child>
</section> </section>
</div> </div>
</div> </div>
</FocusScope> ) : null}
</OverlayContainer>
</Transition>
</Portal> </Portal>
) )
} }

View File

@ -1,9 +0,0 @@
.root {
}
.toast {
@apply absolute bg-primary text-primary flex items-center border border-accents-1
rounded-md z-50 shadow-2xl top-0 right-0 p-6 my-6 mx-3;
width: 420px;
z-index: 20000;
}

View File

@ -1,73 +0,0 @@
import cn from 'classnames'
import { FC, useRef, useEffect, useCallback } from 'react'
import s from './Toast.module.css'
import { useDialog } from '@react-aria/dialog'
import { FocusScope } from '@react-aria/focus'
import { Transition } from '@headlessui/react'
import { useOverlay, useModal, OverlayContainer } from '@react-aria/overlays'
interface Props {
className?: string
children?: any
open?: boolean
onClose: () => void
}
const Toast: FC<Props> = ({
className,
children,
open = false,
onClose,
...props
}) => {
const rootClassName = cn(s.root, className)
let ref = useRef() as React.MutableRefObject<HTMLInputElement>
let { modalProps } = useModal()
let { dialogProps } = useDialog({}, ref)
let { overlayProps } = useOverlay(
{
isOpen: open,
isDismissable: true,
onClose: onClose,
...props,
},
ref
)
// useEffect(() => {
// setTimeout(() => {
// useCallback(onClose, [])
// }, 400)
// })
return (
<Transition show={open}>
<OverlayContainer>
<FocusScope contain restoreFocus autoFocus>
<div className={rootClassName}>
<Transition.Child
enter="transition-opacity ease-linear duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="transition-opacity ease-linear duration-300"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div
className={s.toast}
{...overlayProps}
{...dialogProps}
{...modalProps}
ref={ref}
>
{children}
</div>
</Transition.Child>
</div>
</FocusScope>
</OverlayContainer>
</Transition>
)
}
export default Toast

View File

@ -1 +0,0 @@
export { default } from './Toast'

View File

@ -1,6 +1,5 @@
import React, { FC, useMemo } from 'react' import React, { FC, useMemo } from 'react'
import { ThemeProvider } from 'next-themes' import { ThemeProvider } from 'next-themes'
import { SSRProvider, OverlayProvider } from 'react-aria'
export interface State { export interface State {
displaySidebar: boolean displaySidebar: boolean
@ -181,10 +180,6 @@ export const useUI = () => {
export const ManagedUIContext: FC = ({ children }) => ( export const ManagedUIContext: FC = ({ children }) => (
<UIProvider> <UIProvider>
<ThemeProvider> <ThemeProvider>{children}</ThemeProvider>
<SSRProvider>
<OverlayProvider>{children}</OverlayProvider>
</SSRProvider>
</ThemeProvider>
</UIProvider> </UIProvider>
) )

View File

@ -10,4 +10,3 @@ export { default as Skeleton } from './Skeleton'
export { default as Modal } from './Modal' export { default as Modal } from './Modal'
export { default as Text } from './Text' export { default as Text } from './Text'
export { default as Input } from './Input' export { default as Input } from './Input'
export { default as Toast } from './Toast'

14
lib/defaults.ts Normal file
View File

@ -0,0 +1,14 @@
// Fallback to CMS Data
export const defatultPageProps = {
header: {
links: [
{
link: {
title: 'New Arrivals',
url: '/',
},
},
],
},
}

View File

@ -43,25 +43,25 @@
}, },
"dependencies": { "dependencies": {
"@bigcommerce/storefront-data-hooks": "^1.0.2", "@bigcommerce/storefront-data-hooks": "^1.0.2",
"@headlessui/react": "^0.2.0",
"@reach/portal": "^0.11.2", "@reach/portal": "^0.11.2",
"@react-aria/overlays": "^3.4.0",
"@tailwindcss/ui": "^0.6.2", "@tailwindcss/ui": "^0.6.2",
"@types/body-scroll-lock": "^2.6.1",
"@types/lodash.throttle": "^4.1.6", "@types/lodash.throttle": "^4.1.6",
"@vercel/fetch": "^6.1.0", "@vercel/fetch": "^6.1.0",
"body-scroll-lock": "^3.1.5",
"bowser": "^2.11.0", "bowser": "^2.11.0",
"classnames": "^2.2.6", "classnames": "^2.2.6",
"contentstack": "^3.11.0",
"email-validator": "^2.0.4", "email-validator": "^2.0.4",
"js-cookie": "^2.2.1", "js-cookie": "^2.2.1",
"keen-slider": "^5.2.4", "keen-slider": "^5.2.4",
"lodash.random": "^3.2.0", "lodash.random": "^3.2.0",
"lodash.throttle": "^4.1.1", "lodash.throttle": "^4.1.1",
"next": "^10.0.1-canary.7", "next": "^10.0.2-canary.18",
"next-seo": "^4.11.0", "next-seo": "^4.11.0",
"next-themes": "^0.0.4", "next-themes": "^0.0.4",
"postcss-nesting": "^7.0.1", "postcss-nesting": "^7.0.1",
"react": "^16.14.0", "react": "^16.14.0",
"react-aria": "^3.0.0",
"react-dom": "^16.14.0", "react-dom": "^16.14.0",
"react-intersection-observer": "^8.30.1", "react-intersection-observer": "^8.30.1",
"react-merge-refs": "^1.1.0", "react-merge-refs": "^1.1.0",

View File

@ -4,9 +4,9 @@ import getAllPages from '@bigcommerce/storefront-data-hooks/api/operations/get-a
import useWishlist from '@bigcommerce/storefront-data-hooks/wishlist/use-wishlist' import useWishlist from '@bigcommerce/storefront-data-hooks/wishlist/use-wishlist'
import { Layout } from '@components/common' import { Layout } from '@components/common'
import { Heart } from '@components/icons' import { Heart } from '@components/icons'
import { Container, Text } from '@components/ui' import { Text } from '@components/ui'
import { WishlistCard } from '@components/wishlist' import { WishlistCard } from '@components/wishlist'
import { Transition } from '@headlessui/react' import { defatultPageProps } from '@lib/defaults'
export async function getStaticProps({ export async function getStaticProps({
preview, preview,
@ -15,7 +15,7 @@ export async function getStaticProps({
const config = getConfig({ locale }) const config = getConfig({ locale })
const { pages } = await getAllPages({ config, preview }) const { pages } = await getAllPages({ config, preview })
return { return {
props: { pages }, props: { ...defatultPageProps, pages },
} }
} }
@ -23,20 +23,10 @@ export default function Wishlist() {
const { data, isEmpty } = useWishlist({ includeProducts: true }) const { data, isEmpty } = useWishlist({ includeProducts: true })
return ( return (
<Container> <div className="mt-3 mb-20 px-3">
<div className="mt-3 mb-20">
<Text variant="pageHeading">My Wishlist</Text> <Text variant="pageHeading">My Wishlist</Text>
<div className="group flex flex-col"> <div className="group flex flex-col">
{isEmpty ? ( {isEmpty ? (
<Transition show>
<Transition.Child
enter="transition-opacity ease-linear duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="transition-opacity ease-linear duration-300"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div className="flex-1 px-12 py-24 flex flex-col justify-center items-center "> <div className="flex-1 px-12 py-24 flex flex-col justify-center items-center ">
<span className="border border-dashed border-secondary rounded-full flex items-center justify-center w-16 h-16 bg-primary p-12 rounded-lg text-primary"> <span className="border border-dashed border-secondary rounded-full flex items-center justify-center w-16 h-16 bg-primary p-12 rounded-lg text-primary">
<Heart className="absolute" /> <Heart className="absolute" />
@ -45,32 +35,15 @@ export default function Wishlist() {
Your wishlist is empty Your wishlist is empty
</h2> </h2>
<p className="text-accents-6 px-10 text-center pt-2"> <p className="text-accents-6 px-10 text-center pt-2">
Biscuit oat cake wafer icing ice cream tiramisu pudding Biscuit oat cake wafer icing ice cream tiramisu pudding cupcake.
cupcake.
</p> </p>
</div> </div>
</Transition.Child>
</Transition>
) : ( ) : (
<Transition show> data &&
{data && data.items?.map((item) => <WishlistCard key={item.id} item={item} />)
data.items?.map((item) => (
<Transition.Child
enter="transition-opacity ease-linear duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="transition-opacity ease-linear duration-300"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<WishlistCard key={item.id} item={item} />
</Transition.Child>
))}
</Transition>
)} )}
</div> </div>
</div> </div>
</Container>
) )
} }

2334
yarn.lock

File diff suppressed because it is too large Load Diff