@shopbb/helium 0.6.3 → 0.7.0
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/components/AddToCartButton.d.ts +17 -22
- package/dist/components/AddToCartButton.d.ts.map +1 -1
- package/dist/components/AddToCartButton.js +8 -45
- package/dist/components/AddToCartButton.js.map +1 -1
- package/dist/components/AddressForm.d.ts +42 -18
- package/dist/components/AddressForm.d.ts.map +1 -1
- package/dist/components/AddressForm.js +23 -20
- package/dist/components/AddressForm.js.map +1 -1
- package/dist/components/AddressList.d.ts +34 -17
- package/dist/components/AddressList.d.ts.map +1 -1
- package/dist/components/AddressList.js +7 -21
- package/dist/components/AddressList.js.map +1 -1
- package/dist/components/AddressPicker.d.ts +14 -16
- package/dist/components/AddressPicker.d.ts.map +1 -1
- package/dist/components/AddressPicker.js +10 -26
- package/dist/components/AddressPicker.js.map +1 -1
- package/dist/components/AnalyticsProvider.d.ts +5 -2
- package/dist/components/AnalyticsProvider.d.ts.map +1 -1
- package/dist/components/AnalyticsProvider.js +13 -11
- package/dist/components/AnalyticsProvider.js.map +1 -1
- package/dist/components/BuyNowButton.d.ts +7 -24
- package/dist/components/BuyNowButton.d.ts.map +1 -1
- package/dist/components/BuyNowButton.js +9 -43
- package/dist/components/BuyNowButton.js.map +1 -1
- package/dist/components/CartCheckoutButton.d.ts +10 -21
- package/dist/components/CartCheckoutButton.d.ts.map +1 -1
- package/dist/components/CartCheckoutButton.js +6 -11
- package/dist/components/CartCheckoutButton.js.map +1 -1
- package/dist/components/CartCost.d.ts +15 -23
- package/dist/components/CartCost.d.ts.map +1 -1
- package/dist/components/CartCost.js +1 -3
- package/dist/components/CartCost.js.map +1 -1
- package/dist/components/CartForm.d.ts +30 -102
- package/dist/components/CartForm.d.ts.map +1 -1
- package/dist/components/CartForm.js +32 -172
- package/dist/components/CartForm.js.map +1 -1
- package/dist/components/DiscountComponents.d.ts +67 -17
- package/dist/components/DiscountComponents.d.ts.map +1 -1
- package/dist/components/DiscountComponents.js +28 -74
- package/dist/components/DiscountComponents.js.map +1 -1
- package/dist/components/DiscountSelector.d.ts +50 -15
- package/dist/components/DiscountSelector.d.ts.map +1 -1
- package/dist/components/DiscountSelector.js +16 -44
- package/dist/components/DiscountSelector.js.map +1 -1
- package/dist/components/hooks/useOptimisticCart.d.ts +36 -37
- package/dist/components/hooks/useOptimisticCart.d.ts.map +1 -1
- package/dist/components/hooks/useOptimisticCart.js +95 -127
- package/dist/components/hooks/useOptimisticCart.js.map +1 -1
- package/dist/components/index.d.ts +24 -45
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +21 -37
- package/dist/components/index.js.map +1 -1
- package/dist/createCartHandler.d.ts.map +1 -1
- package/dist/createCartHandler.js +8 -1
- package/dist/createCartHandler.js.map +1 -1
- package/dist/index.d.ts +0 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/package.json +4 -10
- package/src/components/AddToCartButton.tsx +34 -92
- package/src/components/AddressForm.tsx +56 -26
- package/src/components/AddressList.tsx +42 -33
- package/src/components/AddressPicker.tsx +19 -29
- package/src/components/AnalyticsProvider.tsx +18 -13
- package/src/components/BuyNowButton.tsx +28 -93
- package/src/components/CartCheckoutButton.tsx +16 -33
- package/src/components/CartCost.tsx +16 -28
- package/src/components/CartForm.tsx +87 -231
- package/src/components/DiscountComponents.tsx +94 -100
- package/src/components/DiscountSelector.tsx +68 -49
- package/src/components/hooks/useOptimisticCart.ts +122 -156
- package/src/components/index.ts +51 -99
- package/src/createCartHandler.ts +10 -1
- package/src/index.ts +0 -2
- /package/src/components/{AddressBookProvider.tsx → AddressBookProvider.tsx.deleted-0.7} +0 -0
- /package/src/components/{CartLineQuantityAdjustButton.tsx → CartLineQuantityAdjustButton.tsx.deleted-0.7} +0 -0
- /package/src/components/{CartProvider.tsx → CartProvider.tsx.deleted-0.7} +0 -0
- /package/src/components/{DiscountProvider.tsx → DiscountProvider.tsx.deleted-0.7} +0 -0
- /package/src/components/hooks/{useMounted.ts → useMounted.ts.deleted-0.7} +0 -0
- /package/src/{handleCartFormAction.ts → handleCartFormAction.ts.deleted-0.7} +0 -0
|
@@ -1,90 +1,52 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* <CartForm> —
|
|
2
|
+
* <CartForm> — 严格对齐 Shopify Hydrogen 的 CartForm 实现
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* 源文件参考:packages/hydrogen/src/cart/CartForm.tsx
|
|
5
5
|
*
|
|
6
|
-
*
|
|
6
|
+
* 核心机制:
|
|
7
|
+
* - 用 react-router 的 useFetcher() + <fetcher.Form>
|
|
8
|
+
* - submit 后 RR7 自动调对应 route 的 action(),完成后自动 revalidate 所有 loader
|
|
9
|
+
* - children 是 render prop 可以接 fetcher 对象(state / data / formData)
|
|
10
|
+
* - fetcherKey 让相同的 mutation 互相 cancel(例如多次点 +/- 只跑最后一次)
|
|
7
11
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* <CartForm
|
|
12
|
-
* action={CartForm.ACTIONS.LinesAdd}
|
|
13
|
-
* inputs={{ lines: [{ merchandiseId, quantity: 1 }] }}
|
|
14
|
-
* route="/cart"
|
|
15
|
-
* >
|
|
16
|
-
* <button type="submit">加入购物车</button>
|
|
17
|
-
* </CartForm>
|
|
18
|
-
*
|
|
19
|
-
* // 自定义按钮渲染
|
|
20
|
-
* <CartForm action={CartForm.ACTIONS.LinesAdd} inputs={{ lines }}>
|
|
21
|
-
* {(fetcher) => (
|
|
22
|
-
* <button disabled={fetcher.state !== 'idle'}>
|
|
23
|
-
* {fetcher.state === 'submitting' ? '添加中…' : '加入购物车'}
|
|
24
|
-
* </button>
|
|
25
|
-
* )}
|
|
26
|
-
* </CartForm>
|
|
27
|
-
*
|
|
28
|
-
* 服务端(route action):
|
|
29
|
-
*
|
|
30
|
-
* import { CartForm } from '@shopbb/helium';
|
|
31
|
-
*
|
|
32
|
-
* export async function action(request, context) {
|
|
33
|
-
* const formData = await request.formData();
|
|
34
|
-
* const { action, inputs } = CartForm.getFormInput(formData);
|
|
35
|
-
* // ... switch(action) { ... }
|
|
36
|
-
* }
|
|
37
|
-
*
|
|
38
|
-
* ─────────────────────────────────────────────────────────────────
|
|
39
|
-
*
|
|
40
|
-
* 实现说明:
|
|
41
|
-
*
|
|
42
|
-
* - 渲染原生 <form method="POST">,无 JS 也能工作(form 默认提交 = 整页 POST)
|
|
43
|
-
* - INPUT_NAME = "cartFormInput"(hidden input,value = JSON.stringify({action, inputs}))
|
|
44
|
-
* - JS 加载后,由 helium 提供的 useCartFormFetcher hook(或 useFetcher 实现) 拦截 submit 实现"不跳页"
|
|
45
|
-
* - 当前简化实现:hydrate 后 onSubmit preventDefault,自己用 fetch 调,调完后通过 CartProvider.applyCart 更新
|
|
12
|
+
* 与 helium 0.6.x 之前的差异:
|
|
13
|
+
* - 删除自己造的 FetcherContext + raw fetch 实现
|
|
14
|
+
* - peerDep 加 react-router(这就是 Hydrogen 自己的依赖)
|
|
46
15
|
*/
|
|
47
16
|
import * as React from 'react';
|
|
17
|
+
import { type FetcherWithComponents } from 'react-router';
|
|
48
18
|
export declare const CART_FORM_ACTIONS: {
|
|
49
|
-
/** Update cart attributes */
|
|
50
19
|
readonly AttributesUpdateInput: "AttributesUpdateInput";
|
|
51
|
-
/** Update buyer identity (email, customerAccessToken, country, etc.) */
|
|
52
20
|
readonly BuyerIdentityUpdate: "BuyerIdentityUpdate";
|
|
53
|
-
/** Create a new cart */
|
|
54
21
|
readonly Create: "Create";
|
|
55
|
-
/** Replace discount codes */
|
|
56
22
|
readonly DiscountCodesUpdate: "DiscountCodesUpdate";
|
|
57
|
-
/** Replace gift card codes */
|
|
58
23
|
readonly GiftCardCodesUpdate: "GiftCardCodesUpdate";
|
|
59
|
-
/** Append gift card codes */
|
|
60
24
|
readonly GiftCardCodesAdd: "GiftCardCodesAdd";
|
|
61
|
-
/** Remove specific gift card codes */
|
|
62
25
|
readonly GiftCardCodesRemove: "GiftCardCodesRemove";
|
|
63
|
-
/** Add cart lines */
|
|
64
26
|
readonly LinesAdd: "LinesAdd";
|
|
65
|
-
/** Update cart lines (quantity / attributes) */
|
|
66
|
-
readonly LinesUpdate: "LinesUpdate";
|
|
67
|
-
/** Remove cart lines */
|
|
68
27
|
readonly LinesRemove: "LinesRemove";
|
|
69
|
-
|
|
28
|
+
readonly LinesUpdate: "LinesUpdate";
|
|
70
29
|
readonly NoteUpdate: "NoteUpdate";
|
|
71
|
-
/** Update selected delivery options */
|
|
72
30
|
readonly SelectedDeliveryOptionsUpdate: "SelectedDeliveryOptionsUpdate";
|
|
73
|
-
/** Set metafields */
|
|
74
31
|
readonly MetafieldsSet: "MetafieldsSet";
|
|
75
|
-
|
|
76
|
-
readonly
|
|
32
|
+
readonly MetafieldDelete: "MetafieldDelete";
|
|
33
|
+
readonly DeliveryAddressesAdd: "DeliveryAddressesAdd";
|
|
34
|
+
readonly DeliveryAddressesUpdate: "DeliveryAddressesUpdate";
|
|
35
|
+
readonly DeliveryAddressesRemove: "DeliveryAddressesRemove";
|
|
36
|
+
readonly DeliveryAddressesReplace: "DeliveryAddressesReplace";
|
|
77
37
|
};
|
|
78
38
|
export type CartFormAction = (typeof CART_FORM_ACTIONS)[keyof typeof CART_FORM_ACTIONS] | `Custom${string}`;
|
|
79
|
-
export
|
|
39
|
+
export interface CartLineInput {
|
|
80
40
|
merchandiseId: string;
|
|
81
41
|
quantity?: number;
|
|
82
42
|
attributes?: Array<{
|
|
83
43
|
key: string;
|
|
84
44
|
value: string;
|
|
85
45
|
}>;
|
|
86
|
-
|
|
87
|
-
|
|
46
|
+
/** 用于 optimistic UI 展示(不会发到服务端) */
|
|
47
|
+
selectedVariant?: unknown;
|
|
48
|
+
}
|
|
49
|
+
export interface CartLineUpdateInput {
|
|
88
50
|
id: string;
|
|
89
51
|
quantity?: number;
|
|
90
52
|
merchandiseId?: string;
|
|
@@ -92,7 +54,7 @@ export type CartLineUpdateInput = {
|
|
|
92
54
|
key: string;
|
|
93
55
|
value: string;
|
|
94
56
|
}>;
|
|
95
|
-
}
|
|
57
|
+
}
|
|
96
58
|
interface OtherFormData {
|
|
97
59
|
[key: string]: unknown;
|
|
98
60
|
}
|
|
@@ -143,59 +105,25 @@ export type CartFormInput = {
|
|
|
143
105
|
action: `Custom${string}`;
|
|
144
106
|
inputs: Record<string, unknown>;
|
|
145
107
|
};
|
|
146
|
-
/** 服务端 / 客户端共享的 hidden field name — 对齐 Hydrogen */
|
|
147
108
|
declare const INPUT_NAME = "cartFormInput";
|
|
148
|
-
/**
|
|
149
|
-
* Fetcher 状态对象 — 模仿 Remix useFetcher
|
|
150
|
-
*
|
|
151
|
-
* 关键属性:
|
|
152
|
-
* - state: 'idle' | 'submitting' | 'loading'
|
|
153
|
-
* - data: 服务端 action 返回的 JSON(成功时)
|
|
154
|
-
* - error: 错误信息
|
|
155
|
-
*/
|
|
156
|
-
export interface CartFormFetcher {
|
|
157
|
-
state: 'idle' | 'submitting' | 'loading';
|
|
158
|
-
data: any;
|
|
159
|
-
error: string | null;
|
|
160
|
-
/** 取最近一次提交的 form data(optimistic UI 用) */
|
|
161
|
-
formData: FormData | null;
|
|
162
|
-
}
|
|
163
|
-
/**
|
|
164
|
-
* 在 <CartForm> 内部任何深度的组件里拿 fetcher 状态。
|
|
165
|
-
*
|
|
166
|
-
* <CartForm action="LinesAdd" inputs={{lines}}>
|
|
167
|
-
* <MyButton />
|
|
168
|
-
* </CartForm>
|
|
169
|
-
*
|
|
170
|
-
* function MyButton() {
|
|
171
|
-
* const fetcher = useFetcher();
|
|
172
|
-
* return <button disabled={fetcher.state !== 'idle'}>添加</button>;
|
|
173
|
-
* }
|
|
174
|
-
*/
|
|
175
|
-
export declare function useFetcher(): CartFormFetcher;
|
|
176
109
|
export interface CartFormCommonProps {
|
|
177
|
-
/** children
|
|
178
|
-
children: React.ReactNode | ((fetcher:
|
|
179
|
-
/** 提交的 route
|
|
110
|
+
/** children 可以是普通 React 节点,也可以是 render prop 接收 fetcher 对象 */
|
|
111
|
+
children: React.ReactNode | ((fetcher: FetcherWithComponents<any>) => React.ReactNode);
|
|
112
|
+
/** 提交的 route。默认空字符串表示当前 route */
|
|
180
113
|
route?: string;
|
|
181
|
-
/**
|
|
114
|
+
/** Fetcher key — 相同 key 的 fetcher 会互相 cancel(用于幂等操作)*/
|
|
182
115
|
fetcherKey?: string;
|
|
183
|
-
/** 表单 className(不影响行为) */
|
|
184
|
-
className?: string;
|
|
185
116
|
}
|
|
186
117
|
export type CartFormProps = CartFormInput & CartFormCommonProps;
|
|
187
118
|
interface CartFormImpl {
|
|
188
119
|
(props: CartFormProps): React.ReactElement;
|
|
189
120
|
ACTIONS: typeof CART_FORM_ACTIONS;
|
|
190
121
|
INPUT_NAME: typeof INPUT_NAME;
|
|
191
|
-
/**
|
|
192
|
-
* 服务端 helper:从 request.formData() 解析出 { action, inputs }
|
|
193
|
-
*
|
|
194
|
-
* const formData = await request.formData();
|
|
195
|
-
* const { action, inputs } = CartForm.getFormInput(formData);
|
|
196
|
-
*/
|
|
197
122
|
getFormInput: (formData: FormData) => CartFormInput;
|
|
198
123
|
}
|
|
199
124
|
declare const CartForm: CartFormImpl;
|
|
200
125
|
export { CartForm };
|
|
126
|
+
export { useFetcher } from 'react-router';
|
|
127
|
+
export type { FetcherWithComponents } from 'react-router';
|
|
128
|
+
export type CartFormFetcher = FetcherWithComponents<any>;
|
|
201
129
|
//# sourceMappingURL=CartForm.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CartForm.d.ts","sourceRoot":"","sources":["../../src/components/CartForm.tsx"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"CartForm.d.ts","sourceRoot":"","sources":["../../src/components/CartForm.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,213 +1,73 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
|
|
3
|
-
* <CartForm> — 对齐 Shopify Hydrogen 的 CartForm 组件
|
|
4
|
-
*
|
|
5
|
-
* Hydrogen 文档:https://shopify.dev/docs/api/hydrogen/latest/components/cartform
|
|
6
|
-
*
|
|
7
|
-
* 用法:
|
|
8
|
-
*
|
|
9
|
-
* import { CartForm } from '@shopby/helium';
|
|
10
|
-
*
|
|
11
|
-
* // 加入购物车
|
|
12
|
-
* <CartForm
|
|
13
|
-
* action={CartForm.ACTIONS.LinesAdd}
|
|
14
|
-
* inputs={{ lines: [{ merchandiseId, quantity: 1 }] }}
|
|
15
|
-
* route="/cart"
|
|
16
|
-
* >
|
|
17
|
-
* <button type="submit">加入购物车</button>
|
|
18
|
-
* </CartForm>
|
|
19
|
-
*
|
|
20
|
-
* // 自定义按钮渲染
|
|
21
|
-
* <CartForm action={CartForm.ACTIONS.LinesAdd} inputs={{ lines }}>
|
|
22
|
-
* {(fetcher) => (
|
|
23
|
-
* <button disabled={fetcher.state !== 'idle'}>
|
|
24
|
-
* {fetcher.state === 'submitting' ? '添加中…' : '加入购物车'}
|
|
25
|
-
* </button>
|
|
26
|
-
* )}
|
|
27
|
-
* </CartForm>
|
|
28
|
-
*
|
|
29
|
-
* 服务端(route action):
|
|
30
|
-
*
|
|
31
|
-
* import { CartForm } from '@shopbb/helium';
|
|
32
|
-
*
|
|
33
|
-
* export async function action(request, context) {
|
|
34
|
-
* const formData = await request.formData();
|
|
35
|
-
* const { action, inputs } = CartForm.getFormInput(formData);
|
|
36
|
-
* // ... switch(action) { ... }
|
|
37
|
-
* }
|
|
38
|
-
*
|
|
39
|
-
* ─────────────────────────────────────────────────────────────────
|
|
40
|
-
*
|
|
41
|
-
* 实现说明:
|
|
42
|
-
*
|
|
43
|
-
* - 渲染原生 <form method="POST">,无 JS 也能工作(form 默认提交 = 整页 POST)
|
|
44
|
-
* - INPUT_NAME = "cartFormInput"(hidden input,value = JSON.stringify({action, inputs}))
|
|
45
|
-
* - JS 加载后,由 helium 提供的 useCartFormFetcher hook(或 useFetcher 实现) 拦截 submit 实现"不跳页"
|
|
46
|
-
* - 当前简化实现:hydrate 后 onSubmit preventDefault,自己用 fetch 调,调完后通过 CartProvider.applyCart 更新
|
|
47
|
-
*/
|
|
48
|
-
import * as React from 'react';
|
|
49
|
-
import { useCartOptional } from './CartProvider';
|
|
50
|
-
import { __registerPendingMutation } from './hooks/useOptimisticCart';
|
|
2
|
+
import { useFetcher } from 'react-router';
|
|
51
3
|
// ============================================================
|
|
52
4
|
// Action 枚举 — 对齐 Hydrogen CartForm.ACTIONS
|
|
53
5
|
// ============================================================
|
|
54
6
|
export const CART_FORM_ACTIONS = {
|
|
55
|
-
/** Update cart attributes */
|
|
56
7
|
AttributesUpdateInput: 'AttributesUpdateInput',
|
|
57
|
-
/** Update buyer identity (email, customerAccessToken, country, etc.) */
|
|
58
8
|
BuyerIdentityUpdate: 'BuyerIdentityUpdate',
|
|
59
|
-
/** Create a new cart */
|
|
60
9
|
Create: 'Create',
|
|
61
|
-
/** Replace discount codes */
|
|
62
10
|
DiscountCodesUpdate: 'DiscountCodesUpdate',
|
|
63
|
-
/** Replace gift card codes */
|
|
64
11
|
GiftCardCodesUpdate: 'GiftCardCodesUpdate',
|
|
65
|
-
/** Append gift card codes */
|
|
66
12
|
GiftCardCodesAdd: 'GiftCardCodesAdd',
|
|
67
|
-
/** Remove specific gift card codes */
|
|
68
13
|
GiftCardCodesRemove: 'GiftCardCodesRemove',
|
|
69
|
-
/** Add cart lines */
|
|
70
14
|
LinesAdd: 'LinesAdd',
|
|
71
|
-
/** Update cart lines (quantity / attributes) */
|
|
72
|
-
LinesUpdate: 'LinesUpdate',
|
|
73
|
-
/** Remove cart lines */
|
|
74
15
|
LinesRemove: 'LinesRemove',
|
|
75
|
-
|
|
16
|
+
LinesUpdate: 'LinesUpdate',
|
|
76
17
|
NoteUpdate: 'NoteUpdate',
|
|
77
|
-
/** Update selected delivery options */
|
|
78
18
|
SelectedDeliveryOptionsUpdate: 'SelectedDeliveryOptionsUpdate',
|
|
79
|
-
/** Set metafields */
|
|
80
19
|
MetafieldsSet: 'MetafieldsSet',
|
|
81
|
-
|
|
82
|
-
|
|
20
|
+
MetafieldDelete: 'MetafieldDelete',
|
|
21
|
+
DeliveryAddressesAdd: 'DeliveryAddressesAdd',
|
|
22
|
+
DeliveryAddressesUpdate: 'DeliveryAddressesUpdate',
|
|
23
|
+
DeliveryAddressesRemove: 'DeliveryAddressesRemove',
|
|
24
|
+
DeliveryAddressesReplace: 'DeliveryAddressesReplace',
|
|
83
25
|
};
|
|
84
26
|
// ============================================================
|
|
85
|
-
//
|
|
27
|
+
// CartForm
|
|
86
28
|
// ============================================================
|
|
87
|
-
/** 服务端 / 客户端共享的 hidden field name — 对齐 Hydrogen */
|
|
88
29
|
const INPUT_NAME = 'cartFormInput';
|
|
89
30
|
/**
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
* Hydrogen 是用 Remix global fetcher,我们用一个本地 Context。children 既可以是
|
|
93
|
-
* render prop(推荐),也可以是普通节点 + useFetcher() 调用。
|
|
31
|
+
* 严格照抄 Hydrogen 实现(packages/hydrogen/src/cart/CartForm.tsx)
|
|
94
32
|
*/
|
|
95
|
-
const FetcherContext = React.createContext(null);
|
|
96
|
-
/**
|
|
97
|
-
* 在 <CartForm> 内部任何深度的组件里拿 fetcher 状态。
|
|
98
|
-
*
|
|
99
|
-
* <CartForm action="LinesAdd" inputs={{lines}}>
|
|
100
|
-
* <MyButton />
|
|
101
|
-
* </CartForm>
|
|
102
|
-
*
|
|
103
|
-
* function MyButton() {
|
|
104
|
-
* const fetcher = useFetcher();
|
|
105
|
-
* return <button disabled={fetcher.state !== 'idle'}>添加</button>;
|
|
106
|
-
* }
|
|
107
|
-
*/
|
|
108
|
-
export function useFetcher() {
|
|
109
|
-
const ctx = React.useContext(FetcherContext);
|
|
110
|
-
if (!ctx) {
|
|
111
|
-
throw new Error('useFetcher must be used inside a <CartForm>');
|
|
112
|
-
}
|
|
113
|
-
return ctx;
|
|
114
|
-
}
|
|
115
33
|
const CartFormBase = (props) => {
|
|
116
|
-
const { children,
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
// 服务端用 CartForm.getFormInput(formData) 反序列化
|
|
120
|
-
const payload = React.useMemo(() => JSON.stringify({ action, inputs }), [action, inputs]);
|
|
121
|
-
const [fetcher, setFetcher] = React.useState({
|
|
122
|
-
state: 'idle',
|
|
123
|
-
data: null,
|
|
124
|
-
error: null,
|
|
125
|
-
formData: null,
|
|
126
|
-
});
|
|
127
|
-
// hydrate 后拦截 submit;SSR 时 onSubmit 不存在 → form 原生 POST
|
|
128
|
-
const handleSubmit = React.useCallback(async (e) => {
|
|
129
|
-
e.preventDefault();
|
|
130
|
-
const form = e.currentTarget;
|
|
131
|
-
const formData = new FormData(form);
|
|
132
|
-
setFetcher({ state: 'submitting', data: null, error: null, formData });
|
|
133
|
-
// 注册到 pending store — useOptimisticCart 会看到这个 mutation 立刻应用
|
|
134
|
-
// 只对 cart line 类型的 action 做(DiscountCodesUpdate / Custom* 等不做 optimistic)
|
|
135
|
-
let unregisterPending = null;
|
|
136
|
-
if (action === 'LinesAdd' || action === 'LinesUpdate' || action === 'LinesRemove') {
|
|
137
|
-
const pendingId = `${action}_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
138
|
-
unregisterPending = __registerPendingMutation({ id: pendingId, action: action, inputs });
|
|
139
|
-
}
|
|
140
|
-
try {
|
|
141
|
-
// 显式标记 X-Helium-Fetch — 让服务端知道这是 JS fetch 不是原生 form POST
|
|
142
|
-
// 服务端 handleCartFormAction 看到此 header 会返回 JSON 而不是 303 redirect
|
|
143
|
-
const res = await fetch(route, {
|
|
144
|
-
method: 'POST',
|
|
145
|
-
body: formData,
|
|
146
|
-
credentials: 'include',
|
|
147
|
-
headers: { 'Accept': 'application/json', 'X-Helium-Fetch': '1' },
|
|
148
|
-
});
|
|
149
|
-
const data = await res.json().catch(() => null);
|
|
150
|
-
if (!res.ok || data?.error || data?.userErrors?.length) {
|
|
151
|
-
throw new Error(data?.error || data?.userErrors?.[0]?.message || `HTTP ${res.status}`);
|
|
152
|
-
}
|
|
153
|
-
// 服务端约定:成功时返回 { cart: Cart }
|
|
154
|
-
// 这里直接 applyCart 到 CartProvider,避免 refetch
|
|
155
|
-
if (data?.cart && cartCtx?.applyCart) {
|
|
156
|
-
cartCtx.applyCart(data.cart);
|
|
157
|
-
}
|
|
158
|
-
setFetcher({ state: 'idle', data, error: null, formData: null });
|
|
159
|
-
}
|
|
160
|
-
catch (err) {
|
|
161
|
-
setFetcher({ state: 'idle', data: null, error: err.message || String(err), formData: null });
|
|
162
|
-
}
|
|
163
|
-
finally {
|
|
164
|
-
unregisterPending?.();
|
|
165
|
-
}
|
|
166
|
-
}, [route, cartCtx, action, inputs]);
|
|
167
|
-
const renderedChildren = typeof children === 'function' ? children(fetcher) : children;
|
|
168
|
-
return (_jsx(FetcherContext.Provider, { value: fetcher, children: _jsxs("form", { method: "POST", action: route, onSubmit: handleSubmit, className: className, "data-cart-form": true, "data-cart-action": action, children: [_jsx("input", { type: "hidden", name: INPUT_NAME, value: payload }), renderedChildren] }) }));
|
|
34
|
+
const { children, action, inputs, route, fetcherKey } = props;
|
|
35
|
+
const fetcher = useFetcher({ key: fetcherKey });
|
|
36
|
+
return (_jsxs(fetcher.Form, { action: route || '', method: "post", children: [(action || inputs) && (_jsx("input", { type: "hidden", name: INPUT_NAME, value: JSON.stringify({ action, inputs }) })), typeof children === 'function' ? children(fetcher) : children] }));
|
|
169
37
|
};
|
|
170
38
|
/**
|
|
171
39
|
* 服务端 helper:从 request.formData() 还原出 { action, inputs }
|
|
172
40
|
*
|
|
173
|
-
*
|
|
174
|
-
*
|
|
175
|
-
* const formData = await request.formData();
|
|
176
|
-
* const { action, inputs } = CartForm.getFormInput(formData);
|
|
41
|
+
* 严格照抄 Hydrogen 实现:把 form 内其它 input(如 <input name="note">)合并进 inputs。
|
|
177
42
|
*/
|
|
178
43
|
function getFormInput(formData) {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
if (!parsed || typeof parsed.action !== 'string') {
|
|
191
|
-
throw new Error('CartForm.getFormInput: missing "action" in parsed payload');
|
|
192
|
-
}
|
|
193
|
-
// 合并 form 里的其它字段进 inputs(对齐 Hydrogen 的 OtherFormData 设计)
|
|
194
|
-
// <CartForm action=NoteUpdate><input name="note" /></CartForm> 这种场景
|
|
195
|
-
// FormData 里同时有 cartFormInput 和 note 两个字段,inputs.note 来自 FormData 而不是 JSON。
|
|
196
|
-
const otherInputs = {};
|
|
197
|
-
for (const [key, value] of formData.entries()) {
|
|
198
|
-
if (key === INPUT_NAME)
|
|
199
|
-
continue;
|
|
200
|
-
otherInputs[key] = value;
|
|
44
|
+
// 拿全部 form data
|
|
45
|
+
const data = {};
|
|
46
|
+
for (const pair of formData.entries()) {
|
|
47
|
+
const key = pair[0];
|
|
48
|
+
const values = formData.getAll(key);
|
|
49
|
+
data[key] = values.length > 1 ? values : pair[1];
|
|
50
|
+
// checkbox → boolean
|
|
51
|
+
if (data[key] === 'on')
|
|
52
|
+
data[key] = true;
|
|
53
|
+
else if (data[key] === 'off')
|
|
54
|
+
data[key] = false;
|
|
201
55
|
}
|
|
56
|
+
const { cartFormInput, ...otherData } = data;
|
|
57
|
+
const parsed = cartFormInput ? JSON.parse(String(cartFormInput)) : {};
|
|
202
58
|
return {
|
|
203
59
|
action: parsed.action,
|
|
204
|
-
inputs: {
|
|
60
|
+
inputs: {
|
|
61
|
+
...(parsed.inputs || {}),
|
|
62
|
+
...otherData,
|
|
63
|
+
},
|
|
205
64
|
};
|
|
206
65
|
}
|
|
207
|
-
// 把 ACTIONS / INPUT_NAME / getFormInput 挂到 CartForm 对象上 — 对齐 Hydrogen
|
|
208
66
|
const CartForm = CartFormBase;
|
|
209
67
|
CartForm.ACTIONS = CART_FORM_ACTIONS;
|
|
210
68
|
CartForm.INPUT_NAME = INPUT_NAME;
|
|
211
69
|
CartForm.getFormInput = getFormInput;
|
|
212
70
|
export { CartForm };
|
|
71
|
+
// useFetcher 透传 — 让商家也能用同款 API(其实就是 RR7 原生)
|
|
72
|
+
export { useFetcher } from 'react-router';
|
|
213
73
|
//# sourceMappingURL=CartForm.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CartForm.js","sourceRoot":"","sources":["../../src/components/CartForm.tsx"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"CartForm.js","sourceRoot":"","sources":["../../src/components/CartForm.tsx"],"names":[],"mappings":"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"}
|
|
@@ -6,44 +6,94 @@
|
|
|
6
6
|
* <DiscountClaimButton> 单个领取按钮
|
|
7
7
|
* <MyDiscountList> 我的卡包
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* - <BestDiscountHint>: 服务端自动选择最佳券,不需要前端提示。用户在 <DiscountSelector> 看到 / 切换。
|
|
12
|
-
*
|
|
13
|
-
* 全部无样式 + data-* 钩子。
|
|
9
|
+
* helium 0.7:所有组件**接 props 不靠 Provider**。
|
|
10
|
+
* 商家从 loader 拉 publicDiscounts / myClaims / cart.discountAllocations 传入。
|
|
14
11
|
*/
|
|
15
12
|
import * as React from 'react';
|
|
16
|
-
|
|
13
|
+
export type DiscountValueType = 'PERCENTAGE' | 'FIXED_AMOUNT' | 'FREE_SHIPPING';
|
|
14
|
+
export interface DiscountValuePercentage {
|
|
15
|
+
__typename: 'DiscountPercentage';
|
|
16
|
+
percentage: number;
|
|
17
|
+
}
|
|
18
|
+
export interface DiscountValueAmount {
|
|
19
|
+
__typename: 'DiscountAmount';
|
|
20
|
+
amount: {
|
|
21
|
+
amount: string;
|
|
22
|
+
currencyCode: string;
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
export interface DiscountValueFreeShipping {
|
|
26
|
+
__typename: 'DiscountFreeShipping';
|
|
27
|
+
freeShipping: boolean;
|
|
28
|
+
}
|
|
29
|
+
export interface Discount {
|
|
30
|
+
id: string;
|
|
31
|
+
code: string | null;
|
|
32
|
+
title: string;
|
|
33
|
+
description: string | null;
|
|
34
|
+
valueType: DiscountValueType;
|
|
35
|
+
value: DiscountValuePercentage | DiscountValueAmount | DiscountValueFreeShipping;
|
|
36
|
+
minSubtotal: {
|
|
37
|
+
amount: string;
|
|
38
|
+
currencyCode: string;
|
|
39
|
+
} | null;
|
|
40
|
+
startsAt: string | null;
|
|
41
|
+
endsAt: string | null;
|
|
42
|
+
}
|
|
43
|
+
export interface DiscountClaim {
|
|
44
|
+
id: string;
|
|
45
|
+
claimedAt: string;
|
|
46
|
+
expiresAt: string | null;
|
|
47
|
+
isExpired: boolean;
|
|
48
|
+
remainingUses: number;
|
|
49
|
+
usedCount: number;
|
|
50
|
+
discount: Discount;
|
|
51
|
+
}
|
|
52
|
+
export interface DiscountAllocation {
|
|
53
|
+
discountedAmount: {
|
|
54
|
+
amount: string;
|
|
55
|
+
currencyCode: string;
|
|
56
|
+
};
|
|
57
|
+
title?: string | null;
|
|
58
|
+
code?: string | null;
|
|
59
|
+
}
|
|
17
60
|
export interface AppliedDiscountListProps {
|
|
61
|
+
/** 从 cart.discountAllocations 传入 */
|
|
62
|
+
allocations?: DiscountAllocation[];
|
|
18
63
|
className?: string;
|
|
19
64
|
emptyText?: React.ReactNode;
|
|
20
65
|
}
|
|
21
66
|
export declare function AppliedDiscountList(props: AppliedDiscountListProps): import("react/jsx-runtime").JSX.Element;
|
|
22
67
|
export interface ClaimableDiscountListProps {
|
|
23
|
-
|
|
24
|
-
|
|
68
|
+
/** 可领取的折扣(从 loader 拉,例如 publicDiscounts 或 productDiscounts) */
|
|
69
|
+
discounts?: Discount[];
|
|
70
|
+
/** 一次最多渲染几张,默认 10 */
|
|
25
71
|
first?: number;
|
|
26
72
|
className?: string;
|
|
27
73
|
emptyText?: React.ReactNode;
|
|
28
74
|
renderItem?: (discount: Discount) => React.ReactNode;
|
|
29
75
|
}
|
|
30
|
-
export declare function ClaimableDiscountList(props: ClaimableDiscountListProps): import("react/jsx-runtime").JSX.Element
|
|
76
|
+
export declare function ClaimableDiscountList(props: ClaimableDiscountListProps): import("react/jsx-runtime").JSX.Element;
|
|
31
77
|
export interface DiscountClaimButtonProps {
|
|
32
78
|
discount: Discount;
|
|
33
|
-
|
|
79
|
+
/** 点击触发的回调(商家实现 claim 逻辑) */
|
|
80
|
+
onClaim?: (discount: Discount) => Promise<void> | void;
|
|
81
|
+
/** 是否已领(外部判断后传入,按钮 disabled) */
|
|
82
|
+
claimed?: boolean;
|
|
83
|
+
/** 加载中文本 */
|
|
34
84
|
loadingText?: React.ReactNode;
|
|
85
|
+
/** 已领文本 */
|
|
35
86
|
claimedText?: React.ReactNode;
|
|
36
|
-
|
|
37
|
-
loginPath?: string;
|
|
38
|
-
onClaimed?: () => void;
|
|
39
|
-
onError?: (msg: string) => void;
|
|
87
|
+
children?: React.ReactNode;
|
|
40
88
|
className?: string;
|
|
41
89
|
}
|
|
42
90
|
export declare function DiscountClaimButton(props: DiscountClaimButtonProps): import("react/jsx-runtime").JSX.Element;
|
|
43
91
|
export interface MyDiscountListProps {
|
|
44
|
-
|
|
45
|
-
|
|
92
|
+
/** 从 customer GraphQL 拉的 claims */
|
|
93
|
+
claims?: DiscountClaim[];
|
|
46
94
|
filter?: 'available' | 'used' | 'expired' | 'all';
|
|
95
|
+
emptyText?: React.ReactNode;
|
|
96
|
+
className?: string;
|
|
47
97
|
}
|
|
48
|
-
export declare function MyDiscountList(props: MyDiscountListProps): import("react/jsx-runtime").JSX.Element
|
|
98
|
+
export declare function MyDiscountList(props: MyDiscountListProps): import("react/jsx-runtime").JSX.Element;
|
|
49
99
|
//# sourceMappingURL=DiscountComponents.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DiscountComponents.d.ts","sourceRoot":"","sources":["../../src/components/DiscountComponents.tsx"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"DiscountComponents.d.ts","sourceRoot":"","sources":["../../src/components/DiscountComponents.tsx"],"names":[],"mappings":"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"}
|