@shopify/cli 3.65.1 → 3.65.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/hydrogen/i18n/domains.ts +4 -11
- package/dist/assets/hydrogen/i18n/mock-i18n-types.ts +4 -2
- package/dist/assets/hydrogen/i18n/subdomains.ts +4 -11
- package/dist/assets/hydrogen/i18n/subfolders.ts +4 -11
- package/dist/assets/hydrogen/starter/CHANGELOG.md +165 -0
- package/dist/assets/hydrogen/starter/app/components/CartLineItem.tsx +5 -2
- package/dist/assets/hydrogen/starter/app/components/CartMain.tsx +2 -2
- package/dist/assets/hydrogen/starter/app/components/PageLayout.tsx +65 -19
- package/dist/assets/hydrogen/starter/app/components/PaginatedResourceSection.tsx +42 -0
- package/dist/assets/hydrogen/starter/app/components/SearchForm.tsx +68 -0
- package/dist/assets/hydrogen/starter/app/components/SearchFormPredictive.tsx +76 -0
- package/dist/assets/hydrogen/starter/app/components/SearchResults.tsx +164 -0
- package/dist/assets/hydrogen/starter/app/components/SearchResultsPredictive.tsx +322 -0
- package/dist/assets/hydrogen/starter/app/entry.client.tsx +10 -8
- package/dist/assets/hydrogen/starter/app/entry.server.tsx +1 -1
- package/dist/assets/hydrogen/starter/app/lib/context.ts +43 -0
- package/dist/assets/hydrogen/starter/app/lib/fragments.ts +53 -0
- package/dist/assets/hydrogen/starter/app/lib/search.ts +74 -24
- package/dist/assets/hydrogen/starter/app/root.tsx +4 -7
- package/dist/assets/hydrogen/starter/app/routes/account.addresses.tsx +2 -3
- package/dist/assets/hydrogen/starter/app/routes/account.orders._index.tsx +5 -19
- package/dist/assets/hydrogen/starter/app/routes/blogs.$blogHandle._index.tsx +11 -24
- package/dist/assets/hydrogen/starter/app/routes/blogs._index.tsx +14 -27
- package/dist/assets/hydrogen/starter/app/routes/collections.$handle.tsx +12 -30
- package/dist/assets/hydrogen/starter/app/routes/collections._index.tsx +13 -27
- package/dist/assets/hydrogen/starter/app/routes/collections.all.tsx +9 -31
- package/dist/assets/hydrogen/starter/app/routes/search.tsx +312 -73
- package/dist/assets/hydrogen/starter/app/styles/reset.css +12 -2
- package/dist/assets/hydrogen/starter/env.d.ts +11 -30
- package/dist/assets/hydrogen/starter/guides/predictiveSearch/predictiveSearch.jpg +0 -0
- package/dist/assets/hydrogen/starter/guides/predictiveSearch/predictiveSearch.md +391 -0
- package/dist/assets/hydrogen/starter/guides/search/search.jpg +0 -0
- package/dist/assets/hydrogen/starter/guides/search/search.md +333 -0
- package/dist/assets/hydrogen/starter/package.json +4 -4
- package/dist/assets/hydrogen/starter/server.ts +18 -74
- package/dist/assets/hydrogen/starter/storefrontapi.generated.d.ts +242 -172
- package/dist/assets/hydrogen/virtual-routes/components/{PageLayout.jsx → Layout.jsx} +2 -2
- package/dist/assets/hydrogen/virtual-routes/virtual-root.jsx +7 -6
- package/dist/{chunk-H42RFZDD.js → chunk-3ABSSTBQ.js} +4 -4
- package/dist/{chunk-M7WMYV4S.js → chunk-3D4VZQOH.js} +2 -2
- package/dist/{chunk-J7BYFGNJ.js → chunk-3GSKXZGY.js} +2 -2
- package/dist/{chunk-TDWX3KIR.js → chunk-3LDWVYMD.js} +2 -2
- package/dist/{chunk-N2BXKOJG.js → chunk-646BIVHE.js} +4 -4
- package/dist/{chunk-CZ3SHYYH.js → chunk-7WAEFADN.js} +4 -4
- package/dist/{chunk-EKT2GUGH.js → chunk-7WGBIPDW.js} +2 -2
- package/dist/{chunk-M6KGRVDD.js → chunk-AX77SAMU.js} +3 -3
- package/dist/{chunk-4HAEQQTQ.js → chunk-BQBBVYYU.js} +4 -4
- package/dist/{chunk-5YD4FDOS.js → chunk-BZLNTDGG.js} +3 -3
- package/dist/{chunk-VWALMO2Z.js → chunk-CSCEGIBZ.js} +3 -3
- package/dist/{chunk-F2Y7KYHZ.js → chunk-EIUQV76I.js} +5 -5
- package/dist/{chunk-MODBIZ4R.js → chunk-GN74L7IW.js} +2 -2
- package/dist/{chunk-5EAVIJTQ.js → chunk-HYCRESCR.js} +2 -2
- package/dist/{chunk-GDARYUPU.js → chunk-K7KD247K.js} +188 -243
- package/dist/{chunk-PZM45AUI.js → chunk-KIUXMPTX.js} +3 -3
- package/dist/{chunk-PYMSCBPA.js → chunk-LAJ4OEME.js} +2 -2
- package/dist/{chunk-YVHV3H5H.js → chunk-MIQBXNSN.js} +4 -4
- package/dist/{chunk-BLKDGMHM.js → chunk-MV6A3QHA.js} +4 -4
- package/dist/{chunk-CFFAWVDL.js → chunk-N3YORLAS.js} +2 -2
- package/dist/{chunk-EU5ZOEUT.js → chunk-NBTEOGQW.js} +2 -2
- package/dist/{chunk-ZXJU6UP4.js → chunk-O3JOUAA5.js} +4 -4
- package/dist/{chunk-EZ5DG73H.js → chunk-PEAIOYXD.js} +4 -4
- package/dist/{chunk-YDS7NZBQ.js → chunk-R5GT4GBL.js} +4 -4
- package/dist/{chunk-6M65VRAT.js → chunk-S7FJTFYR.js} +5 -5
- package/dist/{chunk-DX2RXOQ5.js → chunk-S7RH664J.js} +3 -3
- package/dist/{chunk-WMECC32P.js → chunk-SKF2SKWO.js} +3 -3
- package/dist/{chunk-27HGZPUX.js → chunk-SMKCVFDT.js} +3 -3
- package/dist/{chunk-EID6L4PR.js → chunk-T4Y7NDNJ.js} +2 -2
- package/dist/{chunk-PY33KMCK.js → chunk-TWWJNMTO.js} +2 -2
- package/dist/{chunk-YXPGPWR2.js → chunk-U2PN6QZ2.js} +5 -5
- package/dist/{chunk-3REVOIEW.js → chunk-UBCH575K.js} +5 -5
- package/dist/{chunk-A4NQWDPT.js → chunk-XLURAR5E.js} +3 -3
- package/dist/{chunk-ZZKUI3DP.js → chunk-YPG7LXPN.js} +3 -3
- package/dist/cli/commands/auth/logout.js +10 -10
- package/dist/cli/commands/auth/logout.test.js +11 -11
- package/dist/cli/commands/debug/command-flags.js +9 -9
- package/dist/cli/commands/demo/catalog.js +10 -10
- package/dist/cli/commands/demo/generate-file.js +10 -10
- package/dist/cli/commands/demo/index.js +10 -10
- package/dist/cli/commands/demo/print-ai-prompt.js +10 -10
- package/dist/cli/commands/docs/generate.js +9 -9
- package/dist/cli/commands/docs/generate.test.js +9 -9
- package/dist/cli/commands/help.js +9 -9
- package/dist/cli/commands/kitchen-sink/async.js +10 -10
- package/dist/cli/commands/kitchen-sink/async.test.js +10 -10
- package/dist/cli/commands/kitchen-sink/index.js +12 -12
- package/dist/cli/commands/kitchen-sink/index.test.js +12 -12
- package/dist/cli/commands/kitchen-sink/prompts.js +10 -10
- package/dist/cli/commands/kitchen-sink/prompts.test.js +10 -10
- package/dist/cli/commands/kitchen-sink/static.js +10 -10
- package/dist/cli/commands/kitchen-sink/static.test.js +10 -10
- package/dist/cli/commands/search.js +10 -10
- package/dist/cli/commands/upgrade.js +9 -9
- package/dist/cli/commands/version.js +10 -10
- package/dist/cli/commands/version.test.js +10 -10
- package/dist/cli/services/commands/search.js +2 -2
- package/dist/cli/services/commands/search.test.js +2 -2
- package/dist/cli/services/commands/version.js +4 -4
- package/dist/cli/services/commands/version.test.js +5 -5
- package/dist/cli/services/demo.js +2 -2
- package/dist/cli/services/demo.test.js +2 -2
- package/dist/cli/services/kitchen-sink/async.js +2 -2
- package/dist/cli/services/kitchen-sink/prompts.js +2 -2
- package/dist/cli/services/kitchen-sink/static.js +2 -2
- package/dist/cli/services/upgrade.js +3 -3
- package/dist/cli/services/upgrade.test.js +5 -5
- package/dist/{custom-oclif-loader-JHNX2EGV.js → custom-oclif-loader-BT7EH2NN.js} +3 -3
- package/dist/{error-handler-4UJ6363X.js → error-handler-OSEY6KVA.js} +8 -8
- package/dist/hooks/postrun.js +6 -6
- package/dist/hooks/prerun.js +4 -4
- package/dist/index.js +1333 -1279
- package/dist/{local-V7RONWNU.js → local-OQXN5NM2.js} +2 -2
- package/dist/{morph-DN4AZJZW.js → morph-IQTWRBBT.js} +16 -12
- package/dist/{node-3H4OKRLA.js → node-YQVH3Y7J.js} +13 -13
- package/dist/{node-package-manager-XM7EXHQA.js → node-package-manager-VW2DN7R4.js} +3 -3
- package/dist/{system-F63VIZ5U.js → system-347PZWVP.js} +2 -2
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/{ui-BXWWRIFS.js → ui-S7L55PBH.js} +2 -2
- package/dist/{workerd-A5NCF6UA.js → workerd-OLKE7G4X.js} +12 -12
- package/oclif.manifest.json +39 -2
- package/package.json +7 -7
- package/dist/assets/hydrogen/starter/app/components/Search.tsx +0 -514
- package/dist/assets/hydrogen/starter/app/routes/api.predictive-search.tsx +0 -318
|
@@ -1,29 +1,79 @@
|
|
|
1
1
|
import type {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
PredictiveProductFragment,
|
|
5
|
-
PredictiveCollectionFragment,
|
|
6
|
-
PredictivePageFragment,
|
|
7
|
-
PredictiveArticleFragment,
|
|
2
|
+
PredictiveSearchQuery,
|
|
3
|
+
RegularSearchQuery,
|
|
8
4
|
} from 'storefrontapi.generated';
|
|
9
5
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
6
|
+
type ResultWithItems<Type extends 'predictive' | 'regular', Items> = {
|
|
7
|
+
type: Type;
|
|
8
|
+
term: string;
|
|
9
|
+
error?: string;
|
|
10
|
+
result: {total: number; items: Items};
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export type RegularSearchReturn = ResultWithItems<
|
|
14
|
+
'regular',
|
|
15
|
+
RegularSearchQuery
|
|
16
|
+
>;
|
|
17
|
+
export type PredictiveSearchReturn = ResultWithItems<
|
|
18
|
+
'predictive',
|
|
19
|
+
NonNullable<PredictiveSearchQuery['predictiveSearch']>
|
|
20
|
+
>;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Returns the empty state of a predictive search result to reset the search state.
|
|
24
|
+
*/
|
|
25
|
+
export function getEmptyPredictiveSearchResult(): PredictiveSearchReturn['result'] {
|
|
26
|
+
return {
|
|
27
|
+
total: 0,
|
|
28
|
+
items: {
|
|
29
|
+
articles: [],
|
|
30
|
+
collections: [],
|
|
31
|
+
products: [],
|
|
32
|
+
pages: [],
|
|
33
|
+
queries: [],
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
interface UrlWithTrackingParams {
|
|
39
|
+
/** The base URL to which the tracking parameters will be appended. */
|
|
40
|
+
baseUrl: string;
|
|
41
|
+
/** The trackingParams returned by the Storefront API. */
|
|
42
|
+
trackingParams?: string | null;
|
|
43
|
+
/** Any additional query parameters to be appended to the URL. */
|
|
44
|
+
params?: Record<string, string>;
|
|
45
|
+
/** The search term to be appended to the URL. */
|
|
46
|
+
term: string;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* A utility function that appends tracking parameters to a URL. Tracking parameters are
|
|
51
|
+
* used internally by shopify to enhance search results and admin dashboards.
|
|
52
|
+
* @example
|
|
53
|
+
* ```ts
|
|
54
|
+
* const url = 'www.example.com';
|
|
55
|
+
* const trackingParams = 'utm_source=shopify&utm_medium=shopify_app&utm_campaign=storefront';
|
|
56
|
+
* const params = { foo: 'bar' };
|
|
57
|
+
* const term = 'search term';
|
|
58
|
+
* const url = urlWithTrackingParams({ baseUrl, trackingParams, params, term });
|
|
59
|
+
* console.log(url);
|
|
60
|
+
* // Output: 'https://www.example.com?foo=bar&q=search%20term&utm_source=shopify&utm_medium=shopify_app&utm_campaign=storefront'
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
export function urlWithTrackingParams({
|
|
64
|
+
baseUrl,
|
|
65
|
+
trackingParams,
|
|
66
|
+
params: extraParams,
|
|
67
|
+
term,
|
|
68
|
+
}: UrlWithTrackingParams) {
|
|
69
|
+
let search = new URLSearchParams({
|
|
70
|
+
...extraParams,
|
|
71
|
+
q: encodeURIComponent(term),
|
|
72
|
+
}).toString();
|
|
73
|
+
|
|
74
|
+
if (trackingParams) {
|
|
75
|
+
search = `${search}&${trackingParams}`;
|
|
28
76
|
}
|
|
77
|
+
|
|
78
|
+
return `${baseUrl}?${search}`;
|
|
29
79
|
}
|
|
@@ -26,18 +26,15 @@ export const shouldRevalidate: ShouldRevalidateFunction = ({
|
|
|
26
26
|
formMethod,
|
|
27
27
|
currentUrl,
|
|
28
28
|
nextUrl,
|
|
29
|
+
defaultShouldRevalidate,
|
|
29
30
|
}) => {
|
|
30
31
|
// revalidate when a mutation is performed e.g add to cart, login...
|
|
31
|
-
if (formMethod && formMethod !== 'GET')
|
|
32
|
-
return true;
|
|
33
|
-
}
|
|
32
|
+
if (formMethod && formMethod !== 'GET') return true;
|
|
34
33
|
|
|
35
34
|
// revalidate when manually revalidating via useRevalidator
|
|
36
|
-
if (currentUrl.toString() === nextUrl.toString())
|
|
37
|
-
return true;
|
|
38
|
-
}
|
|
35
|
+
if (currentUrl.toString() === nextUrl.toString()) return true;
|
|
39
36
|
|
|
40
|
-
return
|
|
37
|
+
return defaultShouldRevalidate;
|
|
41
38
|
};
|
|
42
39
|
|
|
43
40
|
export function links() {
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
useNavigation,
|
|
15
15
|
useOutletContext,
|
|
16
16
|
type MetaFunction,
|
|
17
|
+
type Fetcher,
|
|
17
18
|
} from '@remix-run/react';
|
|
18
19
|
import {
|
|
19
20
|
UPDATE_ADDRESS_MUTATION,
|
|
@@ -364,9 +365,7 @@ export function AddressForm({
|
|
|
364
365
|
address: CustomerAddressInput;
|
|
365
366
|
defaultAddress: CustomerFragment['defaultAddress'];
|
|
366
367
|
children: (props: {
|
|
367
|
-
stateForMethod: (
|
|
368
|
-
method: 'PUT' | 'POST' | 'DELETE',
|
|
369
|
-
) => ReturnType<typeof useNavigation>['state'];
|
|
368
|
+
stateForMethod: (method: 'PUT' | 'POST' | 'DELETE') => Fetcher['state'];
|
|
370
369
|
}) => React.ReactNode;
|
|
371
370
|
}) {
|
|
372
371
|
const {state, formMethod} = useNavigation();
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import {Link, useLoaderData, type MetaFunction} from '@remix-run/react';
|
|
2
2
|
import {
|
|
3
3
|
Money,
|
|
4
|
-
Pagination,
|
|
5
4
|
getPaginationVariables,
|
|
6
5
|
flattenConnection,
|
|
7
6
|
} from '@shopify/hydrogen';
|
|
8
|
-
import {json,
|
|
7
|
+
import {json, type LoaderFunctionArgs} from '@shopify/remix-oxygen';
|
|
9
8
|
import {CUSTOMER_ORDERS_QUERY} from '~/graphql/customer-account/CustomerOrdersQuery';
|
|
10
9
|
import type {
|
|
11
10
|
CustomerOrdersFragment,
|
|
12
11
|
OrderItemFragment,
|
|
13
12
|
} from 'customer-accountapi.generated';
|
|
13
|
+
import {PaginatedResourceSection} from '~/components/PaginatedResourceSection';
|
|
14
14
|
|
|
15
15
|
export const meta: MetaFunction = () => {
|
|
16
16
|
return [{title: 'Orders'}];
|
|
@@ -51,23 +51,9 @@ function OrdersTable({orders}: Pick<CustomerOrdersFragment, 'orders'>) {
|
|
|
51
51
|
return (
|
|
52
52
|
<div className="acccount-orders">
|
|
53
53
|
{orders?.nodes.length ? (
|
|
54
|
-
<
|
|
55
|
-
{({
|
|
56
|
-
|
|
57
|
-
<>
|
|
58
|
-
<PreviousLink>
|
|
59
|
-
{isLoading ? 'Loading...' : <span>↑ Load previous</span>}
|
|
60
|
-
</PreviousLink>
|
|
61
|
-
{nodes.map((order) => {
|
|
62
|
-
return <OrderItem key={order.id} order={order} />;
|
|
63
|
-
})}
|
|
64
|
-
<NextLink>
|
|
65
|
-
{isLoading ? 'Loading...' : <span>Load more ↓</span>}
|
|
66
|
-
</NextLink>
|
|
67
|
-
</>
|
|
68
|
-
);
|
|
69
|
-
}}
|
|
70
|
-
</Pagination>
|
|
54
|
+
<PaginatedResourceSection connection={orders}>
|
|
55
|
+
{({node: order}) => <OrderItem key={order.id} order={order} />}
|
|
56
|
+
</PaginatedResourceSection>
|
|
71
57
|
) : (
|
|
72
58
|
<EmptyOrders />
|
|
73
59
|
)}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import {defer, type LoaderFunctionArgs} from '@shopify/remix-oxygen';
|
|
2
2
|
import {Link, useLoaderData, type MetaFunction} from '@remix-run/react';
|
|
3
|
-
import {Image,
|
|
3
|
+
import {Image, getPaginationVariables} from '@shopify/hydrogen';
|
|
4
4
|
import type {ArticleItemFragment} from 'storefrontapi.generated';
|
|
5
|
+
import {PaginatedResourceSection} from '~/components/PaginatedResourceSection';
|
|
5
6
|
|
|
6
7
|
export const meta: MetaFunction<typeof loader> = ({data}) => {
|
|
7
8
|
return [{title: `Hydrogen | ${data?.blog.title ?? ''} blog`}];
|
|
@@ -68,29 +69,15 @@ export default function Blog() {
|
|
|
68
69
|
<div className="blog">
|
|
69
70
|
<h1>{blog.title}</h1>
|
|
70
71
|
<div className="blog-grid">
|
|
71
|
-
<
|
|
72
|
-
{({
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
<ArticleItem
|
|
81
|
-
article={article}
|
|
82
|
-
key={article.id}
|
|
83
|
-
loading={index < 2 ? 'eager' : 'lazy'}
|
|
84
|
-
/>
|
|
85
|
-
);
|
|
86
|
-
})}
|
|
87
|
-
<NextLink>
|
|
88
|
-
{isLoading ? 'Loading...' : <span>Load more ↓</span>}
|
|
89
|
-
</NextLink>
|
|
90
|
-
</>
|
|
91
|
-
);
|
|
92
|
-
}}
|
|
93
|
-
</Pagination>
|
|
72
|
+
<PaginatedResourceSection connection={articles}>
|
|
73
|
+
{({node: article, index}) => (
|
|
74
|
+
<ArticleItem
|
|
75
|
+
article={article}
|
|
76
|
+
key={article.id}
|
|
77
|
+
loading={index < 2 ? 'eager' : 'lazy'}
|
|
78
|
+
/>
|
|
79
|
+
)}
|
|
80
|
+
</PaginatedResourceSection>
|
|
94
81
|
</div>
|
|
95
82
|
</div>
|
|
96
83
|
);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import {defer, type LoaderFunctionArgs} from '@shopify/remix-oxygen';
|
|
2
2
|
import {Link, useLoaderData, type MetaFunction} from '@remix-run/react';
|
|
3
|
-
import {
|
|
3
|
+
import {getPaginationVariables} from '@shopify/hydrogen';
|
|
4
|
+
import {PaginatedResourceSection} from '~/components/PaginatedResourceSection';
|
|
4
5
|
|
|
5
6
|
export const meta: MetaFunction = () => {
|
|
6
7
|
return [{title: `Hydrogen | Blogs`}];
|
|
@@ -53,32 +54,18 @@ export default function Blogs() {
|
|
|
53
54
|
<div className="blogs">
|
|
54
55
|
<h1>Blogs</h1>
|
|
55
56
|
<div className="blogs-grid">
|
|
56
|
-
<
|
|
57
|
-
{({
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
prefetch="intent"
|
|
69
|
-
to={`/blogs/${blog.handle}`}
|
|
70
|
-
>
|
|
71
|
-
<h2>{blog.title}</h2>
|
|
72
|
-
</Link>
|
|
73
|
-
);
|
|
74
|
-
})}
|
|
75
|
-
<NextLink>
|
|
76
|
-
{isLoading ? 'Loading...' : <span>Load more ↓</span>}
|
|
77
|
-
</NextLink>
|
|
78
|
-
</>
|
|
79
|
-
);
|
|
80
|
-
}}
|
|
81
|
-
</Pagination>
|
|
57
|
+
<PaginatedResourceSection connection={blogs}>
|
|
58
|
+
{({node: blog}) => (
|
|
59
|
+
<Link
|
|
60
|
+
className="blog"
|
|
61
|
+
key={blog.handle}
|
|
62
|
+
prefetch="intent"
|
|
63
|
+
to={`/blogs/${blog.handle}`}
|
|
64
|
+
>
|
|
65
|
+
<h2>{blog.title}</h2>
|
|
66
|
+
</Link>
|
|
67
|
+
)}
|
|
68
|
+
</PaginatedResourceSection>
|
|
82
69
|
</div>
|
|
83
70
|
</div>
|
|
84
71
|
);
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import {defer, redirect, type LoaderFunctionArgs} from '@shopify/remix-oxygen';
|
|
2
2
|
import {useLoaderData, Link, type MetaFunction} from '@remix-run/react';
|
|
3
3
|
import {
|
|
4
|
-
Pagination,
|
|
5
4
|
getPaginationVariables,
|
|
6
5
|
Image,
|
|
7
6
|
Money,
|
|
@@ -9,6 +8,7 @@ import {
|
|
|
9
8
|
} from '@shopify/hydrogen';
|
|
10
9
|
import type {ProductItemFragment} from 'storefrontapi.generated';
|
|
11
10
|
import {useVariantUrl} from '~/lib/variants';
|
|
11
|
+
import {PaginatedResourceSection} from '~/components/PaginatedResourceSection';
|
|
12
12
|
|
|
13
13
|
export const meta: MetaFunction<typeof loader> = ({data}) => {
|
|
14
14
|
return [{title: `Hydrogen | ${data?.collection.title ?? ''} Collection`}];
|
|
@@ -77,20 +77,18 @@ export default function Collection() {
|
|
|
77
77
|
<div className="collection">
|
|
78
78
|
<h1>{collection.title}</h1>
|
|
79
79
|
<p className="collection-description">{collection.description}</p>
|
|
80
|
-
<
|
|
81
|
-
{
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
<
|
|
89
|
-
|
|
90
|
-
</NextLink>
|
|
91
|
-
</>
|
|
80
|
+
<PaginatedResourceSection
|
|
81
|
+
connection={collection.products}
|
|
82
|
+
resourcesClassName="products-grid"
|
|
83
|
+
>
|
|
84
|
+
{({node: product, index}) => (
|
|
85
|
+
<ProductItem
|
|
86
|
+
key={product.id}
|
|
87
|
+
product={product}
|
|
88
|
+
loading={index < 8 ? 'eager' : undefined}
|
|
89
|
+
/>
|
|
92
90
|
)}
|
|
93
|
-
</
|
|
91
|
+
</PaginatedResourceSection>
|
|
94
92
|
<Analytics.CollectionView
|
|
95
93
|
data={{
|
|
96
94
|
collection: {
|
|
@@ -103,22 +101,6 @@ export default function Collection() {
|
|
|
103
101
|
);
|
|
104
102
|
}
|
|
105
103
|
|
|
106
|
-
function ProductsGrid({products}: {products: ProductItemFragment[]}) {
|
|
107
|
-
return (
|
|
108
|
-
<div className="products-grid">
|
|
109
|
-
{products.map((product, index) => {
|
|
110
|
-
return (
|
|
111
|
-
<ProductItem
|
|
112
|
-
key={product.id}
|
|
113
|
-
product={product}
|
|
114
|
-
loading={index < 8 ? 'eager' : undefined}
|
|
115
|
-
/>
|
|
116
|
-
);
|
|
117
|
-
})}
|
|
118
|
-
</div>
|
|
119
|
-
);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
104
|
function ProductItem({
|
|
123
105
|
product,
|
|
124
106
|
loading,
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import {useLoaderData, Link} from '@remix-run/react';
|
|
2
2
|
import {defer, type LoaderFunctionArgs} from '@shopify/remix-oxygen';
|
|
3
|
-
import {
|
|
3
|
+
import {getPaginationVariables, Image} from '@shopify/hydrogen';
|
|
4
4
|
import type {CollectionFragment} from 'storefrontapi.generated';
|
|
5
|
+
import {PaginatedResourceSection} from '~/components/PaginatedResourceSection';
|
|
5
6
|
|
|
6
7
|
export async function loader(args: LoaderFunctionArgs) {
|
|
7
8
|
// Start fetching non-critical data without blocking time to first byte
|
|
@@ -47,33 +48,18 @@ export default function Collections() {
|
|
|
47
48
|
return (
|
|
48
49
|
<div className="collections">
|
|
49
50
|
<h1>Collections</h1>
|
|
50
|
-
<
|
|
51
|
-
{
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
</div>
|
|
51
|
+
<PaginatedResourceSection
|
|
52
|
+
connection={collections}
|
|
53
|
+
resourcesClassName="collections-grid"
|
|
54
|
+
>
|
|
55
|
+
{({node: collection, index}) => (
|
|
56
|
+
<CollectionItem
|
|
57
|
+
key={collection.id}
|
|
58
|
+
collection={collection}
|
|
59
|
+
index={index}
|
|
60
|
+
/>
|
|
61
61
|
)}
|
|
62
|
-
</
|
|
63
|
-
</div>
|
|
64
|
-
);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
function CollectionsGrid({collections}: {collections: CollectionFragment[]}) {
|
|
68
|
-
return (
|
|
69
|
-
<div className="collections-grid">
|
|
70
|
-
{collections.map((collection, index) => (
|
|
71
|
-
<CollectionItem
|
|
72
|
-
key={collection.id}
|
|
73
|
-
collection={collection}
|
|
74
|
-
index={index}
|
|
75
|
-
/>
|
|
76
|
-
))}
|
|
62
|
+
</PaginatedResourceSection>
|
|
77
63
|
</div>
|
|
78
64
|
);
|
|
79
65
|
}
|
|
@@ -1,13 +1,9 @@
|
|
|
1
1
|
import {defer, type LoaderFunctionArgs} from '@shopify/remix-oxygen';
|
|
2
2
|
import {useLoaderData, Link, type MetaFunction} from '@remix-run/react';
|
|
3
|
-
import {
|
|
4
|
-
Pagination,
|
|
5
|
-
getPaginationVariables,
|
|
6
|
-
Image,
|
|
7
|
-
Money,
|
|
8
|
-
} from '@shopify/hydrogen';
|
|
3
|
+
import {getPaginationVariables, Image, Money} from '@shopify/hydrogen';
|
|
9
4
|
import type {ProductItemFragment} from 'storefrontapi.generated';
|
|
10
5
|
import {useVariantUrl} from '~/lib/variants';
|
|
6
|
+
import {PaginatedResourceSection} from '~/components/PaginatedResourceSection';
|
|
11
7
|
|
|
12
8
|
export const meta: MetaFunction<typeof loader> = () => {
|
|
13
9
|
return [{title: `Hydrogen | Products`}];
|
|
@@ -57,36 +53,18 @@ export default function Collection() {
|
|
|
57
53
|
return (
|
|
58
54
|
<div className="collection">
|
|
59
55
|
<h1>Products</h1>
|
|
60
|
-
<
|
|
61
|
-
{
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
</PreviousLink>
|
|
66
|
-
<ProductsGrid products={nodes} />
|
|
67
|
-
<br />
|
|
68
|
-
<NextLink>
|
|
69
|
-
{isLoading ? 'Loading...' : <span>Load more ↓</span>}
|
|
70
|
-
</NextLink>
|
|
71
|
-
</>
|
|
72
|
-
)}
|
|
73
|
-
</Pagination>
|
|
74
|
-
</div>
|
|
75
|
-
);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
function ProductsGrid({products}: {products: ProductItemFragment[]}) {
|
|
79
|
-
return (
|
|
80
|
-
<div className="products-grid">
|
|
81
|
-
{products.map((product, index) => {
|
|
82
|
-
return (
|
|
56
|
+
<PaginatedResourceSection
|
|
57
|
+
connection={products}
|
|
58
|
+
resourcesClassName="products-grid"
|
|
59
|
+
>
|
|
60
|
+
{({node: product, index}) => (
|
|
83
61
|
<ProductItem
|
|
84
62
|
key={product.id}
|
|
85
63
|
product={product}
|
|
86
64
|
loading={index < 8 ? 'eager' : undefined}
|
|
87
65
|
/>
|
|
88
|
-
)
|
|
89
|
-
|
|
66
|
+
)}
|
|
67
|
+
</PaginatedResourceSection>
|
|
90
68
|
</div>
|
|
91
69
|
);
|
|
92
70
|
}
|