mirror of
https://github.com/vercel/commerce.git
synced 2025-05-18 23:46:58 +00:00
Suspense
This commit is contained in:
parent
15fe8a1da7
commit
f0105f9f59
@ -84,12 +84,18 @@ export default async function ProductPage({ params }: { params: { handle: string
|
||||
<div className="mx-auto max-w-screen-2xl px-4">
|
||||
<div className="flex flex-col rounded-lg border border-neutral-200 bg-white p-8 dark:border-neutral-800 dark:bg-black md:p-12 lg:flex-row lg:gap-8">
|
||||
<div className="h-full w-full basis-full lg:basis-4/6">
|
||||
<Gallery
|
||||
images={product.images.map((image: Image) => ({
|
||||
src: image.url,
|
||||
altText: image.altText
|
||||
}))}
|
||||
/>
|
||||
<Suspense
|
||||
fallback={
|
||||
<div className="relative aspect-square h-full max-h-[550px] w-full overflow-hidden" />
|
||||
}
|
||||
>
|
||||
<Gallery
|
||||
images={product.images.map((image: Image) => ({
|
||||
src: image.url,
|
||||
altText: image.altText
|
||||
}))}
|
||||
/>
|
||||
</Suspense>
|
||||
</div>
|
||||
|
||||
<div className="basis-full lg:basis-2/6">
|
||||
|
@ -6,7 +6,7 @@ import { Menu } from 'lib/shopify/types';
|
||||
import Link from 'next/link';
|
||||
import { Suspense } from 'react';
|
||||
import MobileMenu from './mobile-menu';
|
||||
import Search from './search';
|
||||
import Search, { SearchSkeleton } from './search';
|
||||
const { SITE_NAME } = process.env;
|
||||
|
||||
export default async function Navbar() {
|
||||
@ -15,8 +15,9 @@ export default async function Navbar() {
|
||||
return (
|
||||
<nav className="relative flex items-center justify-between p-4 lg:px-6">
|
||||
<div className="block flex-none md:hidden">
|
||||
<MobileMenu menu={menu} />
|
||||
</div>
|
||||
<Suspense fallback={null}>
|
||||
<MobileMenu menu={menu} />
|
||||
</Suspense> </div>
|
||||
<div className="flex w-full items-center">
|
||||
<div className="flex w-full md:w-1/3">
|
||||
<Link href="/" className="mr-2 flex w-full items-center justify-center md:w-auto lg:mr-6">
|
||||
@ -41,7 +42,9 @@ export default async function Navbar() {
|
||||
) : null}
|
||||
</div>
|
||||
<div className="hidden justify-center md:flex md:w-1/3">
|
||||
<Search />
|
||||
<Suspense fallback={<SearchSkeleton />}>
|
||||
<Search />
|
||||
</Suspense>
|
||||
</div>
|
||||
<div className="flex justify-end md:w-1/3">
|
||||
<Suspense fallback={<OpenCart />}>
|
||||
|
@ -3,11 +3,11 @@
|
||||
import { Dialog, Transition } from '@headlessui/react';
|
||||
import Link from 'next/link';
|
||||
import { usePathname, useSearchParams } from 'next/navigation';
|
||||
import { Fragment, useEffect, useState } from 'react';
|
||||
import { Fragment, Suspense, useEffect, useState } from 'react';
|
||||
|
||||
import { Bars3Icon, XMarkIcon } from '@heroicons/react/24/outline';
|
||||
import { Menu } from 'lib/shopify/types';
|
||||
import Search from './search';
|
||||
import Search, { SearchSkeleton } from './search';
|
||||
|
||||
export default function MobileMenu({ menu }: { menu: Menu[] }) {
|
||||
const pathname = usePathname();
|
||||
@ -72,7 +72,9 @@ export default function MobileMenu({ menu }: { menu: Menu[] }) {
|
||||
</button>
|
||||
|
||||
<div className="mb-4 w-full">
|
||||
<Search />
|
||||
<Suspense fallback={<SearchSkeleton />}>
|
||||
<Search />
|
||||
</Suspense>
|
||||
</div>
|
||||
{menu.length ? (
|
||||
<ul className="flex w-full flex-col">
|
||||
|
@ -41,3 +41,17 @@ export default function Search() {
|
||||
</form>
|
||||
);
|
||||
}
|
||||
|
||||
export function SearchSkeleton() {
|
||||
return (
|
||||
<form className="w-max-[550px] relative w-full lg:w-80 xl:w-full">
|
||||
<input
|
||||
placeholder="Search for products..."
|
||||
className="w-full rounded-lg border bg-white px-4 py-2 text-sm text-black placeholder:text-neutral-500 dark:border-neutral-800 dark:bg-transparent dark:text-white dark:placeholder:text-neutral-400"
|
||||
/>
|
||||
<div className="absolute right-0 top-0 mr-3 flex h-full items-center">
|
||||
<MagnifyingGlassIcon className="h-4" />
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
import { SortFilterItem } from 'lib/constants';
|
||||
import { Suspense } from 'react';
|
||||
import FilterItemDropdown from './dropdown';
|
||||
import { FilterItem } from './item';
|
||||
|
||||
@ -25,11 +26,13 @@ export default function FilterList({ list, title }: { list: ListItem[]; title?:
|
||||
</h3>
|
||||
) : null}
|
||||
<ul className="hidden md:block">
|
||||
<FilterItemList list={list} />
|
||||
</ul>
|
||||
<Suspense fallback={null}>
|
||||
<FilterItemList list={list} />
|
||||
</Suspense> </ul>
|
||||
<ul className="md:hidden">
|
||||
<FilterItemDropdown list={list} />
|
||||
</ul>
|
||||
<Suspense fallback={null}>
|
||||
<FilterItemDropdown list={list} />
|
||||
</Suspense> </ul>
|
||||
</nav>
|
||||
</>
|
||||
);
|
||||
|
@ -2,6 +2,7 @@ import { AddToCart } from 'components/cart/add-to-cart';
|
||||
import Price from 'components/price';
|
||||
import Prose from 'components/prose';
|
||||
import { Product } from 'lib/shopify/types';
|
||||
import { Suspense } from 'react';
|
||||
import { VariantSelector } from './variant-selector';
|
||||
|
||||
export function ProductDescription({ product }: { product: Product }) {
|
||||
@ -16,7 +17,9 @@ export function ProductDescription({ product }: { product: Product }) {
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<VariantSelector options={product.options} variants={product.variants} />
|
||||
<Suspense fallback={null}>
|
||||
<VariantSelector options={product.options} variants={product.variants} />
|
||||
</Suspense>
|
||||
|
||||
{product.descriptionHtml ? (
|
||||
<Prose
|
||||
@ -25,7 +28,9 @@ export function ProductDescription({ product }: { product: Product }) {
|
||||
/>
|
||||
) : null}
|
||||
|
||||
<AddToCart variants={product.variants} availableForSale={product.availableForSale} />
|
||||
<Suspense fallback={null}>
|
||||
<AddToCart variants={product.variants} availableForSale={product.availableForSale} />
|
||||
</Suspense>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user