diff --git a/app/components/Aside.tsx b/app/components/Aside.tsx deleted file mode 100644 index f486f19..0000000 --- a/app/components/Aside.tsx +++ /dev/null @@ -1,47 +0,0 @@ -/** - * A side bar component with Overlay that works without JavaScript. - * @example - * ```jsx - * - * ``` - */ -export function Aside({ - children, - heading, - id = 'aside', -}: { - children?: React.ReactNode; - heading: React.ReactNode; - id?: string; -}) { - return ( - - ); -} - -function CloseAside() { - return ( - /* eslint-disable-next-line jsx-a11y/anchor-is-valid */ - history.go(-1)}> - × - - ); -} diff --git a/app/components/Header/Header.tsx b/app/components/Header/Header.tsx index f3cbb37..f973a30 100644 --- a/app/components/Header/Header.tsx +++ b/app/components/Header/Header.tsx @@ -4,8 +4,6 @@ import { cva } from "class-variance-authority"; import { cn, useIsHomePath } from "~/lib/utils"; import useWindowScroll from "react-use/lib/useWindowScroll"; import { useEffect, useState } from "react"; -import { useDrawer } from "../Drawer"; -import clsx from "clsx"; import { Logo } from "../Logo"; import { MegaMenu } from "./menu/MegaMenu"; import { SearchToggle } from "./SearchToggle"; @@ -13,7 +11,7 @@ import { AccountLink } from "../account/AccountLink"; import { CartDrawer } from "../cart/CartDrawer"; import { HeaderMenuDrawer } from "./menu/DrawerMenu"; import { useShopMenu } from "~/hooks/use-menu-shop"; - +import { useRouteError } from "@remix-run/react"; let variants = cva("", { variants: { @@ -43,64 +41,65 @@ export function Header() { } = settings; const isHome = useIsHomePath(); const { y } = useWindowScroll(); - let [hovered, setHovered] = useState(false); const [top, setCalculatedTop] = useState(0); - let { isOpen } = useDrawer(); + let routeError = useRouteError(); - let onHover = () => setHovered(true); - let onLeave = () => setHovered(false); + let scrolled = y < 50; - let enableTransparent = settings?.enableTransparentHeader && isHome; - let isTransparent = enableTransparent && y < 50 && !isOpen && !hovered; + let enableTransparent = enableTransparentHeader && isHome && !routeError; + let isTransparent = enableTransparent && scrolled; useEffect(() => { let calculatedTop = stickyAnnouncementBar ? announcementBarHeight : Math.max(announcementBarHeight - y, 0); setCalculatedTop(calculatedTop); }, [y, stickyAnnouncementBar, announcementBarHeight]); - + return ( <> {enableTrialShipping && }
-
{typeMenuHeader === "drawer" ? ( ) : ( - + )} {typeMenuHeader === "mega" && }
- {typeMenuHeader === "mega" && } + {typeMenuHeader === "mega" && ( + + )}
diff --git a/app/components/Header/menu/DrawerMenu.tsx b/app/components/Header/menu/DrawerMenu.tsx index b5aa945..6a2348d 100644 --- a/app/components/Header/menu/DrawerMenu.tsx +++ b/app/components/Header/menu/DrawerMenu.tsx @@ -1,11 +1,11 @@ -import {Disclosure} from '@headlessui/react'; -import {Link} from '@remix-run/react'; -import {Image} from '@shopify/hydrogen'; -import {Drawer, useDrawer} from '../../Drawer'; -import {IconCaret, IconListMenu} from '../../Icon'; -import { EnhancedMenu, getMaxDepth, SingleMenuItem } from '~/lib/types/menu'; -import { SearchToggle } from '../SearchToggle'; -import clsx from 'clsx'; +import { Disclosure } from "@headlessui/react"; +import { Link } from "@remix-run/react"; +import { Image } from "@shopify/hydrogen"; +import { Drawer, useDrawer } from "../../Drawer"; +import { IconCaret, IconListMenu } from "../../Icon"; +import { EnhancedMenu, getMaxDepth, SingleMenuItem } from "~/lib/types/menu"; +import { SearchToggle } from "../SearchToggle"; +import clsx from "clsx"; export function HeaderMenuDrawer({ menu, @@ -31,13 +31,19 @@ export function HeaderMenuDrawer({ heading="MENU" isForm="menu" > - + ); } -export function DrawerMenu({ menu }: { menu: EnhancedMenu | null | undefined }) { +function DrawerMenu({ + menu, + closeDrawer, +}: { + menu: EnhancedMenu | null | undefined; + closeDrawer: () => void; +}) { let items = menu?.items as unknown as SingleMenuItem[]; return ( ); } -function ItemHeader({title, to}: {title: string; to: string}) { +function ItemHeader({ + title, + to, + closeDrawer, +}: { + title: string; + to: string; + closeDrawer: () => void; +}) { return ( -
+
-
{title}
+
+ {title} +
); } -function MultiMenu(props: SingleMenuItem) { +function MultiMenu(props: SingleMenuItem & { closeDrawer: () => void }) { const { isOpen: isMenuOpen, openDrawer: openMenu, closeDrawer: closeMenu, } = useDrawer(); - let {title, items, to} = props; + let { title, items, to, closeDrawer } = props; + const handleCloseAll = () => { + closeMenu(); + closeDrawer(); + }; let content = ( (
- {({open}) => ( + {({ open }) => ( <>
- {item.title} - {item.items.length > 0 && - - } + {item.items.length > 0 ? ( + {item.title} + ) : ( + + {item.title} + + )} + {item.items.length > 0 && ( + + + + )}
{item?.items?.length > 0 ? ( @@ -116,10 +157,13 @@ function MultiMenu(props: SingleMenuItem) { - {subItem.title} + + {subItem.title} + ))} @@ -142,9 +186,7 @@ function MultiMenu(props: SingleMenuItem) { role="button" onClick={openMenu} > - -
{title}
- +
{title}
{content} @@ -152,12 +194,21 @@ function MultiMenu(props: SingleMenuItem) { ); } -function ImageMenu({title, items, to}: SingleMenuItem) { +function ImageMenu({ + title, + items, + to, + closeDrawer, +}: SingleMenuItem & { closeDrawer: () => void }) { const { isOpen: isMenuOpen, openDrawer: openMenu, closeDrawer: closeMenu, } = useDrawer(); + const handleCloseAll = () => { + closeMenu(); + closeDrawer(); + }; let content = (
{items.map((item, id) => ( - +
-
-

{item.title}

+
+ + {item.title} +
-
+
))} @@ -193,9 +251,7 @@ function ImageMenu({title, items, to}: SingleMenuItem) { role="button" onClick={openMenu} > - -
{title}
- +
{title}
{content} @@ -203,13 +259,17 @@ function ImageMenu({title, items, to}: SingleMenuItem) { ); } -function SingleMenu(props: SingleMenuItem) { +function SingleMenu(props: SingleMenuItem & { closeDrawer: () => void }) { const { isOpen: isMenuOpen, openDrawer: openMenu, closeDrawer: closeMenu, } = useDrawer(); - let {title, items, to} = props; + let { title, items, to, closeDrawer } = props; + const handleCloseAll = () => { + closeMenu(); + closeDrawer(); + }; let content = (
    {items.map((subItem, ind) => ( -
  • +
  • - {subItem.title} + + {subItem.title} +
  • ))} @@ -244,9 +306,7 @@ function SingleMenu(props: SingleMenuItem) { role="button" onClick={openMenu} > - -
    {title}
    - +
    {title}
{content} diff --git a/app/components/Header/menu/MegaMenu.tsx b/app/components/Header/menu/MegaMenu.tsx index 012a35f..dec5745 100644 --- a/app/components/Header/menu/MegaMenu.tsx +++ b/app/components/Header/menu/MegaMenu.tsx @@ -4,7 +4,6 @@ import * as Menubar from "@radix-ui/react-menubar"; import { cn } from "~/lib/utils"; import clsx from "clsx"; import React, { useState } from "react"; -import { IconCaret } from "../../Icon"; import { useThemeSettings } from "@weaverse/hydrogen"; import { EnhancedMenu, getMaxDepth, SingleMenuItem } from "~/lib/types/menu"; @@ -35,7 +34,6 @@ export function MegaMenu(props: { menu: EnhancedMenu | null | undefined }) { asChild={!hasSubmenu} className={clsx([ "cursor-pointer px-3 py-2 h-full flex items-center gap-1.5", - '[&>svg]:data-[state="open"]:rotate-90', "focus:outline-none uppercase", ])} onMouseEnter={() => { @@ -46,15 +44,11 @@ export function MegaMenu(props: { menu: EnhancedMenu | null | undefined }) { > {hasSubmenu ? ( <> - {title} - + {title} ) : ( - {title} + {title} )} @@ -62,7 +56,7 @@ export function MegaMenu(props: { menu: EnhancedMenu | null | undefined }) { @@ -96,7 +90,7 @@ function DropdownSubMenu({ items }: { items: SingleMenuItem[] }) { prefetch="intent" className="transition-none block" > - {title} + {title} ))} diff --git a/app/components/Logo.tsx b/app/components/Logo.tsx index bf1e96f..3c447bf 100644 --- a/app/components/Logo.tsx +++ b/app/components/Logo.tsx @@ -1,14 +1,17 @@ -import {Image} from '@shopify/hydrogen'; -import {useThemeSettings} from '@weaverse/hydrogen'; -import clsx from 'clsx'; -import { Link } from './Link'; +import { Image } from "@shopify/hydrogen"; +import { useThemeSettings } from "@weaverse/hydrogen"; +import clsx from "clsx"; +import { Link } from "./Link"; -export function Logo({className, showTransparent} : {className?: string, showTransparent?: boolean}) { +export function Logo({ className }: { className?: string }) { let settings = useThemeSettings(); - let {logoData, transparentLogoData, logoWidth} = settings; + let { logoData, transparentLogoData, logoWidth } = settings; return ( @@ -16,25 +19,30 @@ export function Logo({className, showTransparent} : {className?: string, showTra className="relative" style={{ width: logoData ? logoWidth : "auto" }} > - {logoData && - <> + <> + {logoData && ( + )} + {transparentLogoData && ( - } + )} +
); diff --git a/app/components/button.tsx b/app/components/button.tsx index 8f1f5f3..f405737 100644 --- a/app/components/button.tsx +++ b/app/components/button.tsx @@ -1,8 +1,7 @@ import * as React from 'react'; -import {Link} from '@remix-run/react'; import {cva, type VariantProps} from 'class-variance-authority'; - import { cn } from "~/lib/utils"; +import { Link } from './Link'; const buttonVariants = cva( 'inline-flex items-center justify-center whitespace-nowrap font-normal transition-colors focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50', diff --git a/app/components/cart/Cart.tsx b/app/components/cart/Cart.tsx index 47f0317..564f434 100644 --- a/app/components/cart/Cart.tsx +++ b/app/components/cart/Cart.tsx @@ -16,6 +16,7 @@ import type { CartApiQueryFragment } from "storefrontapi.generated"; import { useVariantUrl } from "~/lib/utils/variants"; import { cn } from "~/lib/utils"; import { IconRemove } from "../Icon"; +import { CartPopularCollections } from "./CartPopularCollections"; type CartLine = OptimisticCart["lines"]["nodes"][0]; @@ -42,7 +43,7 @@ export function CartMain({ layout, cart }: CartMainProps) { return (
); } @@ -483,9 +484,12 @@ export function CartEmpty({ window.location.href = "/collections"; } }} + className="text-animation" > Continue shopping → +
+
); } diff --git a/app/components/cart/CartPopularCollections.tsx b/app/components/cart/CartPopularCollections.tsx new file mode 100644 index 0000000..2a001a3 --- /dev/null +++ b/app/components/cart/CartPopularCollections.tsx @@ -0,0 +1,117 @@ +import { useFetcher } from "@remix-run/react"; +import { Grid } from "../Grid"; +import { Link } from "../Link"; +import { Image } from "@shopify/hydrogen"; +import type { Collection } from "@shopify/hydrogen/storefront-api-types"; +import { useThemeSettings } from "@weaverse/hydrogen"; +import { CSSProperties, useEffect } from "react"; +import { getImageLoadingPriority } from "~/lib/utils/const"; +import { cn, usePrefixPathWithLocale } from "~/lib/utils"; + +type CollectionResponse = { + collections: { + nodes: Collection[]; + }; +}; + +export function CartPopularCollections({ layout }: { layout?: string }) { + let { load, data } = useFetcher(); + let productsApiPath = usePrefixPathWithLocale(`/api/collections`); + useEffect(() => { + load(productsApiPath); + }, [load, productsApiPath]); + if (!data) return null; + let { collections } = data; + let nodes = collections.nodes.slice(0, layout === "aside" ? 4 : 6); + + return ( +
+
Popular collections
+ + {nodes.map((collection: any, i: any) => ( + + ))} + +
+ ); +} + +function PopularCard({ + collection, + imageAspectRatio, + loading, +}: { + collection: Collection; + imageAspectRatio: string; + loading?: HTMLImageElement["loading"]; +}) { + let settings = useThemeSettings(); + let { colorBackground } = settings; + const calculateColor = (hex: string) => + `#${[...Array(3)] + .map((_, i) => + Math.max( + 0, + parseInt(hex.slice(1 + i * 2, 3 + i * 2), 16) - [177, 166, 223][i] + ) + .toString(16) + .padStart(2, "0") + ) + .join("")}`; + + let style: CSSProperties = { + "--calculate-color": calculateColor(colorBackground), + } as CSSProperties; + return ( + +
+
+ {collection?.image && ( + + )} +
+
+
+

+ {collection.title} +

+
+
+ + ); +} diff --git a/app/components/CountrySelector.tsx b/app/components/footer/CountrySelector.tsx similarity index 100% rename from app/components/CountrySelector.tsx rename to app/components/footer/CountrySelector.tsx diff --git a/app/components/Footer.tsx b/app/components/footer/Footer.tsx similarity index 71% rename from app/components/Footer.tsx rename to app/components/footer/Footer.tsx index a38d949..a3c300d 100644 --- a/app/components/Footer.tsx +++ b/app/components/footer/Footer.tsx @@ -1,15 +1,15 @@ -import {Button} from '~/components/button'; -import {Input} from '~/components/input'; -import {Disclosure} from '@headlessui/react'; -import {NavLink, useFetcher} from '@remix-run/react'; -import {useThemeSettings} from '@weaverse/hydrogen'; -import {EnhancedMenu, getMaxDepth, SingleMenuItem} from '~/lib/types/menu'; -import {cn} from '~/lib/utils'; -import React from 'react'; -import {CountrySelector} from './CountrySelector'; -import {IconPlusLinkFooter} from './Icon'; -import { cva } from 'class-variance-authority'; -import { useShopMenu } from '~/hooks/use-menu-shop'; +import { Button } from "~/components/button"; +import { Input } from "~/components/input"; +import { Disclosure } from "@headlessui/react"; +import { NavLink, useFetcher } from "@remix-run/react"; +import { useThemeSettings } from "@weaverse/hydrogen"; +import { EnhancedMenu, getMaxDepth, SingleMenuItem } from "~/lib/types/menu"; +import { cn } from "~/lib/utils"; +import React from "react"; +import { cva } from "class-variance-authority"; +import { useShopMenu } from "~/hooks/use-menu-shop"; +import { CountrySelector } from "./CountrySelector"; +import { IconPlusLinkFooter } from "../Icon"; let variants = cva("", { variants: { @@ -29,7 +29,7 @@ let variants = cva("", { export function Footer() { let { footerMenu } = useShopMenu(); let fetcher = useFetcher(); - let isError = fetcher.state === 'idle' && fetcher.data?.errors; + let isError = fetcher.state === "idle" && fetcher.data?.errors; const settings = useThemeSettings(); let { footerWidth, @@ -38,14 +38,31 @@ export function Footer() { newsletterDescription, newsletterPlaceholder, newsletterButtonText, - tagNameTitle: Tag = 'h6', + tagNameTitle: Tag = "h6", } = settings; return ( -