@shopbb/helium 0.6.4 → 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.
Files changed (77) hide show
  1. package/dist/components/AddToCartButton.d.ts +17 -22
  2. package/dist/components/AddToCartButton.d.ts.map +1 -1
  3. package/dist/components/AddToCartButton.js +8 -45
  4. package/dist/components/AddToCartButton.js.map +1 -1
  5. package/dist/components/AddressForm.d.ts +42 -18
  6. package/dist/components/AddressForm.d.ts.map +1 -1
  7. package/dist/components/AddressForm.js +23 -20
  8. package/dist/components/AddressForm.js.map +1 -1
  9. package/dist/components/AddressList.d.ts +34 -17
  10. package/dist/components/AddressList.d.ts.map +1 -1
  11. package/dist/components/AddressList.js +7 -21
  12. package/dist/components/AddressList.js.map +1 -1
  13. package/dist/components/AddressPicker.d.ts +14 -16
  14. package/dist/components/AddressPicker.d.ts.map +1 -1
  15. package/dist/components/AddressPicker.js +10 -26
  16. package/dist/components/AddressPicker.js.map +1 -1
  17. package/dist/components/AnalyticsProvider.d.ts +5 -2
  18. package/dist/components/AnalyticsProvider.d.ts.map +1 -1
  19. package/dist/components/AnalyticsProvider.js +13 -11
  20. package/dist/components/AnalyticsProvider.js.map +1 -1
  21. package/dist/components/BuyNowButton.d.ts +7 -24
  22. package/dist/components/BuyNowButton.d.ts.map +1 -1
  23. package/dist/components/BuyNowButton.js +9 -43
  24. package/dist/components/BuyNowButton.js.map +1 -1
  25. package/dist/components/CartCheckoutButton.d.ts +10 -21
  26. package/dist/components/CartCheckoutButton.d.ts.map +1 -1
  27. package/dist/components/CartCheckoutButton.js +6 -11
  28. package/dist/components/CartCheckoutButton.js.map +1 -1
  29. package/dist/components/CartCost.d.ts +15 -23
  30. package/dist/components/CartCost.d.ts.map +1 -1
  31. package/dist/components/CartCost.js +1 -3
  32. package/dist/components/CartCost.js.map +1 -1
  33. package/dist/components/CartForm.d.ts +30 -102
  34. package/dist/components/CartForm.d.ts.map +1 -1
  35. package/dist/components/CartForm.js +32 -172
  36. package/dist/components/CartForm.js.map +1 -1
  37. package/dist/components/DiscountComponents.d.ts +67 -17
  38. package/dist/components/DiscountComponents.d.ts.map +1 -1
  39. package/dist/components/DiscountComponents.js +28 -74
  40. package/dist/components/DiscountComponents.js.map +1 -1
  41. package/dist/components/DiscountSelector.d.ts +50 -15
  42. package/dist/components/DiscountSelector.d.ts.map +1 -1
  43. package/dist/components/DiscountSelector.js +16 -44
  44. package/dist/components/DiscountSelector.js.map +1 -1
  45. package/dist/components/hooks/useOptimisticCart.d.ts +36 -37
  46. package/dist/components/hooks/useOptimisticCart.d.ts.map +1 -1
  47. package/dist/components/hooks/useOptimisticCart.js +95 -127
  48. package/dist/components/hooks/useOptimisticCart.js.map +1 -1
  49. package/dist/components/index.d.ts +24 -45
  50. package/dist/components/index.d.ts.map +1 -1
  51. package/dist/components/index.js +21 -37
  52. package/dist/components/index.js.map +1 -1
  53. package/dist/index.d.ts +0 -2
  54. package/dist/index.d.ts.map +1 -1
  55. package/dist/index.js +0 -1
  56. package/dist/index.js.map +1 -1
  57. package/package.json +4 -10
  58. package/src/components/AddToCartButton.tsx +34 -92
  59. package/src/components/AddressForm.tsx +56 -26
  60. package/src/components/AddressList.tsx +42 -33
  61. package/src/components/AddressPicker.tsx +19 -29
  62. package/src/components/AnalyticsProvider.tsx +18 -13
  63. package/src/components/BuyNowButton.tsx +28 -93
  64. package/src/components/CartCheckoutButton.tsx +16 -33
  65. package/src/components/CartCost.tsx +16 -28
  66. package/src/components/CartForm.tsx +87 -231
  67. package/src/components/DiscountComponents.tsx +94 -100
  68. package/src/components/DiscountSelector.tsx +68 -49
  69. package/src/components/hooks/useOptimisticCart.ts +122 -156
  70. package/src/components/index.ts +51 -99
  71. package/src/index.ts +0 -2
  72. /package/src/components/{AddressBookProvider.tsx → AddressBookProvider.tsx.deleted-0.7} +0 -0
  73. /package/src/components/{CartLineQuantityAdjustButton.tsx → CartLineQuantityAdjustButton.tsx.deleted-0.7} +0 -0
  74. /package/src/components/{CartProvider.tsx → CartProvider.tsx.deleted-0.7} +0 -0
  75. /package/src/components/{DiscountProvider.tsx → DiscountProvider.tsx.deleted-0.7} +0 -0
  76. /package/src/components/hooks/{useMounted.ts → useMounted.ts.deleted-0.7} +0 -0
  77. /package/src/{handleCartFormAction.ts → handleCartFormAction.ts.deleted-0.7} +0 -0
@@ -7,50 +7,30 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
7
7
  * <DiscountClaimButton> 单个领取按钮
8
8
  * <MyDiscountList> 我的卡包
9
9
  *
10
- * 注:W5 已删除以下组件(旧设计):
11
- * - <DiscountCodeInput>: 输入框范式已过时。请用 <DiscountSelector> + <ClaimableDiscountList>。
12
- * - <BestDiscountHint>: 服务端自动选择最佳券,不需要前端提示。用户在 <DiscountSelector> 看到 / 切换。
13
- *
14
- * 全部无样式 + data-* 钩子。
10
+ * helium 0.7:所有组件**接 props 不靠 Provider**。
11
+ * 商家从 loader publicDiscounts / myClaims / cart.discountAllocations 传入。
15
12
  */
16
13
  import * as React from 'react';
17
- import { useDiscounts, useProductDiscounts } from './DiscountProvider';
18
- import { useAnalytics } from './AnalyticsProvider';
19
14
  import { Money } from './Money';
20
- import { useMounted } from './hooks/useMounted';
21
15
  import { formatDate } from '../utils/formatDate';
22
16
  export function AppliedDiscountList(props) {
23
- const { className, emptyText = null } = props;
24
- const { cartAllocations } = useDiscounts();
25
- if (cartAllocations.length === 0)
17
+ const { allocations = [], className, emptyText = null } = props;
18
+ if (allocations.length === 0)
26
19
  return _jsx(_Fragment, { children: emptyText });
27
- return (_jsx("div", { "data-applied-discount-list": true, className: className, children: cartAllocations.map((alloc, i) => (_jsxs("div", { "data-applied-item": true, children: [_jsxs("div", { "data-info": true, children: [_jsx("span", { "data-title": true, children: alloc.title }), alloc.code && _jsx("span", { "data-code": true, children: alloc.code })] }), _jsxs("span", { "data-discount-amount": true, children: ["\u2212 ", _jsx(Money, { data: { amount: alloc.discountedAmount.amount, currencyCode: alloc.discountedAmount.currencyCode } })] })] }, alloc.code || i))) }));
20
+ return (_jsx("div", { "data-applied-discount-list": true, className: className, children: allocations.map((alloc, i) => (_jsxs("div", { "data-applied-item": true, children: [_jsxs("div", { "data-info": true, children: [_jsx("span", { "data-title": true, children: alloc.title }), alloc.code && _jsx("span", { "data-code": true, children: alloc.code })] }), _jsxs("span", { "data-discount-amount": true, children: ["\u2212 ", _jsx(Money, { data: { amount: alloc.discountedAmount.amount, currencyCode: alloc.discountedAmount.currencyCode } })] })] }, alloc.code || i))) }));
28
21
  }
29
22
  export function ClaimableDiscountList(props) {
30
- const { scope = 'store', productHandle, first = 10, className, emptyText = null, renderItem } = props;
31
- const mounted = useMounted();
32
- const { publicDiscounts, publicDiscountsStatus } = useDiscounts();
33
- const { discounts: productDiscs, loading: productLoading } = useProductDiscounts(scope === 'product' ? productHandle : null);
34
- const list = scope === 'product' ? productDiscs : publicDiscounts;
35
- const loading = scope === 'product' ? productLoading : publicDiscountsStatus === 'loading';
36
- // SSR 安全:首次渲染返回固定占位(空容器),避免和 client 拉到数据后的渲染 mismatch
37
- if (!mounted) {
38
- return _jsx("div", { "data-claimable-discount-list": true, "data-scope": scope, "data-ssr-placeholder": true, className: className });
39
- }
40
- if (loading)
41
- return null;
42
- if (list.length === 0)
23
+ const { discounts = [], first = 10, className, emptyText = null, renderItem } = props;
24
+ if (discounts.length === 0)
43
25
  return _jsx(_Fragment, { children: emptyText });
44
- return (_jsx("div", { "data-claimable-discount-list": true, "data-scope": scope, className: className, children: list.slice(0, first).map((d) => (_jsx(React.Fragment, { children: renderItem ? renderItem(d) : _jsx(DefaultClaimableItem, { discount: d }) }, d.id))) }));
26
+ return (_jsx("div", { "data-claimable-discount-list": true, className: className, children: discounts.slice(0, first).map((d) => (_jsx(React.Fragment, { children: renderItem ? renderItem(d) : _jsx(DefaultClaimableItem, { discount: d }) }, d.id))) }));
45
27
  }
46
28
  function DefaultClaimableItem({ discount: d }) {
47
29
  return (_jsxs("div", { "data-claimable-item": true, children: [_jsxs("div", { "data-info": true, children: [_jsx("div", { "data-title": true, children: d.title }), _jsx("div", { "data-value": true, children: formatDiscountValue(d) }), d.minSubtotal && (_jsxs("div", { "data-condition": true, children: ["\u6EE1 ", _jsx(Money, { data: { amount: d.minSubtotal.amount, currencyCode: d.minSubtotal.currencyCode } }), " \u53EF\u7528"] })), d.endsAt && (_jsxs("div", { "data-deadline": true, children: [formatDate(d.endsAt), " \u8FC7\u671F"] }))] }), d.code && _jsx(DiscountClaimButton, { discount: d, children: "\u9886\u53D6" })] }));
48
30
  }
49
31
  function formatDiscountValue(d) {
50
32
  if (d.value.__typename === 'DiscountPercentage') {
51
- // percentage 表示折扣比例(10 = 减 10%)→ 中文"折"是付款比例(10% off = 付 90% = 9 折)
52
33
  const pay = (100 - d.value.percentage) / 10;
53
- // 整数省点:8 折 / 7.5 折
54
34
  const txt = Number.isInteger(pay) ? String(pay) : pay.toFixed(1);
55
35
  return `${txt} 折`;
56
36
  }
@@ -59,58 +39,31 @@ function formatDiscountValue(d) {
59
39
  return '免运费';
60
40
  }
61
41
  export function DiscountClaimButton(props) {
62
- const { discount, children = '领取', loadingText = '领取中…', claimedText = '已领取', loginPath, onClaimed, onError, className, } = props;
63
- const { claim, myDiscounts, myDiscountsStatus } = useDiscounts();
64
- const analytics = useAnalytics();
65
- const [loading, setLoading] = React.useState(false);
42
+ const { discount, onClaim, claimed = false, loadingText = '领取中...', claimedText = '已领取', children = '领取', className, } = props;
43
+ const [pending, setPending] = React.useState(false);
66
44
  const [err, setErr] = React.useState(null);
67
- const alreadyClaimed = myDiscounts.some((c) => c.discount.id === discount.id);
68
- const handleClaim = async () => {
69
- // 未登录 跳 login
70
- if (myDiscountsStatus === 'unauthenticated') {
71
- if (typeof window === 'undefined')
72
- return;
73
- const next = encodeURIComponent(window.location.pathname + window.location.search);
74
- window.location.href = loginPath || `/login?next=${next}`;
75
- return;
76
- }
77
- if (!discount.code)
45
+ const [done, setDone] = React.useState(claimed);
46
+ const handleClick = async () => {
47
+ if (done || pending)
78
48
  return;
79
- setLoading(true);
49
+ setPending(true);
80
50
  setErr(null);
81
51
  try {
82
- const r = await claim(discount.code);
83
- if (r.userErrors.length > 0) {
84
- const msg = r.userErrors[0].message;
85
- setErr(msg);
86
- onError?.(msg);
87
- }
88
- else {
89
- onClaimed?.();
90
- analytics.emit('discount_claim', { code: discount.code });
91
- }
52
+ await onClaim?.(discount);
53
+ setDone(true);
54
+ }
55
+ catch (e) {
56
+ setErr(e?.message || '领取失败');
92
57
  }
93
58
  finally {
94
- setLoading(false);
59
+ setPending(false);
95
60
  }
96
61
  };
97
- if (alreadyClaimed) {
98
- return _jsx("button", { type: "button", className: className, disabled: true, "data-discount-claim": true, "data-claimed": true, children: claimedText });
99
- }
100
- return (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", className: className, onClick: handleClaim, disabled: loading, "data-discount-claim": true, "data-loading": loading ? '' : undefined, children: loading ? loadingText : children }), err && _jsx("div", { "data-error": true, children: err })] }));
62
+ return (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", "data-discount-claim": true, "data-claimed": done ? '' : undefined, disabled: done || pending, onClick: handleClick, className: className, children: pending ? loadingText : done ? claimedText : children }), err && _jsx("div", { "data-error": true, children: err })] }));
101
63
  }
102
64
  export function MyDiscountList(props) {
103
- const { className, emptyText = '还没有优惠券', filter = 'available' } = props;
104
- const mounted = useMounted();
105
- const { myDiscounts, myDiscountsStatus } = useDiscounts();
106
- if (!mounted) {
107
- return _jsx("div", { "data-my-discount-list": true, "data-ssr-placeholder": true, className: className });
108
- }
109
- if (myDiscountsStatus === 'loading')
110
- return null;
111
- if (myDiscountsStatus === 'unauthenticated')
112
- return null;
113
- const filtered = myDiscounts.filter((c) => {
65
+ const { claims = [], filter = 'available', emptyText = '还没有优惠券', className } = props;
66
+ const filtered = claims.filter((c) => {
114
67
  if (filter === 'all')
115
68
  return true;
116
69
  if (filter === 'expired')
@@ -124,13 +77,14 @@ export function MyDiscountList(props) {
124
77
  return (_jsx("div", { "data-my-discount-list": true, className: className, children: filtered.map((c) => (_jsxs("div", { "data-my-discount-item": true, "data-expired": c.isExpired ? '' : undefined, "data-used": c.remainingUses === 0 ? '' : undefined, children: [_jsxs("div", { "data-info": true, children: [_jsx("div", { "data-title": true, children: c.discount.title }), _jsx("div", { "data-value": true, children: formatClaimValue(c) }), c.discount.minSubtotal && (_jsxs("div", { "data-condition": true, children: ["\u6EE1 ", _jsx(Money, { data: { amount: c.discount.minSubtotal.amount, currencyCode: c.discount.minSubtotal.currencyCode } }), " \u53EF\u7528"] })), c.expiresAt && (_jsxs("div", { "data-deadline": true, children: [formatDate(c.expiresAt), " \u8FC7\u671F"] }))] }), c.discount.code && _jsx("code", { "data-code": true, children: c.discount.code })] }, c.id))) }));
125
78
  }
126
79
  function formatClaimValue(c) {
127
- if (c.discount.valueType === 'PERCENTAGE' && c.discount.valuePercentage != null) {
128
- const pay = (100 - c.discount.valuePercentage) / 10;
80
+ if (c.discount.value.__typename === 'DiscountPercentage') {
81
+ const pct = c.discount.value.percentage;
82
+ const pay = (100 - pct) / 10;
129
83
  const txt = Number.isInteger(pay) ? String(pay) : pay.toFixed(1);
130
84
  return `${txt} 折`;
131
85
  }
132
- if (c.discount.valueType === 'FIXED_AMOUNT' && c.discount.valueAmount) {
133
- return `减 ¥${c.discount.valueAmount.amount}`;
86
+ if (c.discount.value.__typename === 'DiscountAmount') {
87
+ return `减 ¥${c.discount.value.amount.amount}`;
134
88
  }
135
89
  return '免运费';
136
90
  }
@@ -1 +1 @@
1
- {"version":3,"file":"DiscountComponents.js","sourceRoot":"","sources":["../../src/components/DiscountComponents.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"DiscountComponents.js","sourceRoot":"","sources":["../../src/components/DiscountComponents.tsx"],"names":[],"mappings":"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"}
@@ -1,26 +1,61 @@
1
1
  /**
2
2
  * <DiscountSelector>
3
3
  *
4
- * Cart 上的优惠券选择器 — 卡片式 UI,对齐拼多多 / 京东体验。
4
+ * Cart 上的优惠券选择器 — 卡片式 UI
5
5
  *
6
- * 行为:
7
- * - 默认显示当前应用的券(服务端自动选了最佳,或买家显式选的)
8
- * - "切换"打开抽屉/弹窗,列出该买家所有可用券(从 useDiscounts().myDiscounts)
9
- * - 选另一张 cartDiscountSelect mutation
10
- * - 点"不使用优惠券" → cartDiscountClear
11
- *
12
- * 未登录买家:渲染"登录后享受优惠"提示。
13
- *
14
- * 设计目标:
15
- * - 这是 helium "脚手架" 的卡片式实现。商家可以替换为抽屉式 / 弹窗式自定义 UI。
16
- * - 商家也可以直接用 useDiscounts() 自己渲染(提供 hook-only 路径)。
6
+ * helium 0.7 改造:
7
+ * - 数据通过 props 传入(不再用 DiscountProvider)
8
+ * - mutation 通过 <CartForm action="CustomDiscountSelect" inputs={{claimId}}>
9
+ * - 商家 loader myDiscountClaims + cart.appliedDiscountClaim,传给本组件
17
10
  */
18
11
  import * as React from 'react';
12
+ export interface DiscountClaim {
13
+ id: string;
14
+ claimedAt: string;
15
+ expiresAt: string | null;
16
+ isExpired: boolean;
17
+ remainingUses: number;
18
+ discount: {
19
+ id: string;
20
+ code: string | null;
21
+ title: string;
22
+ valueType: 'PERCENTAGE' | 'FIXED_AMOUNT' | 'FREE_SHIPPING';
23
+ valuePercentage: number | null;
24
+ valueAmount: {
25
+ amount: string;
26
+ currencyCode: string;
27
+ } | null;
28
+ minSubtotal: {
29
+ amount: string;
30
+ currencyCode: string;
31
+ } | null;
32
+ };
33
+ }
34
+ export interface AppliedDiscountClaim {
35
+ claimId: string;
36
+ code: string | null;
37
+ title: string;
38
+ }
39
+ export interface DiscountAllocation {
40
+ discountedAmount: {
41
+ amount: string;
42
+ currencyCode: string;
43
+ };
44
+ title?: string | null;
45
+ code?: string | null;
46
+ }
19
47
  export interface DiscountSelectorProps {
20
- className?: string;
21
- /** 未登录时显示的内容;不传则显示默认 */
48
+ /** 买家已领的所有 claim(从 customer GraphQL 拉,商家传入) */
49
+ myClaims?: DiscountClaim[];
50
+ /** cart 上当前已应用的 claim(cart.appliedDiscountClaim) */
51
+ appliedClaim?: AppliedDiscountClaim | null;
52
+ /** cart 折扣金额(cart.discountAllocations[0]) */
53
+ appliedAllocation?: DiscountAllocation | null;
54
+ /** 未登录时显示内容 */
55
+ unauthenticated?: boolean;
22
56
  unauthenticatedFallback?: React.ReactNode;
23
- /** 自定义渲染 */
57
+ className?: string;
58
+ /** 自定义渲染已选 state */
24
59
  renderApplied?: (props: {
25
60
  code: string | null;
26
61
  title: string;
@@ -1 +1 @@
1
- {"version":3,"file":"DiscountSelector.d.ts","sourceRoot":"","sources":["../../src/components/DiscountSelector.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAO/B,MAAM,WAAW,qBAAqB;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wBAAwB;IACxB,uBAAuB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1C,YAAY;IACZ,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,YAAY,EAAE,MAAM,CAAA;SAAE,CAAC;QAAC,QAAQ,EAAE,MAAM,IAAI,CAAA;KAAE,KAAK,KAAK,CAAC,SAAS,CAAC;CAC5J;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,2CAsF5D"}
1
+ {"version":3,"file":"DiscountSelector.d.ts","sourceRoot":"","sources":["../../src/components/DiscountSelector.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAM/B,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE;QACR,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;QACpB,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,EAAE,YAAY,GAAG,cAAc,GAAG,eAAe,CAAC;QAC3D,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;QAC/B,WAAW,EAAE;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,YAAY,EAAE,MAAM,CAAA;SAAE,GAAG,IAAI,CAAC;QAC7D,WAAW,EAAE;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,YAAY,EAAE,MAAM,CAAA;SAAE,GAAG,IAAI,CAAC;KAC9D,CAAC;CACH;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB;IACjC,gBAAgB,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3D,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,MAAM,WAAW,qBAAqB;IACpC,+CAA+C;IAC/C,QAAQ,CAAC,EAAE,aAAa,EAAE,CAAC;IAC3B,oDAAoD;IACpD,YAAY,CAAC,EAAE,oBAAoB,GAAG,IAAI,CAAC;IAC3C,6CAA6C;IAC7C,iBAAiB,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAC;IAC9C,eAAe;IACf,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,uBAAuB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oBAAoB;IACpB,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE;QACtB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;QACpB,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,YAAY,EAAE,MAAM,CAAA;SAAE,CAAC;QACjD,QAAQ,EAAE,MAAM,IAAI,CAAC;KACtB,KAAK,KAAK,CAAC,SAAS,CAAC;CACvB;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,2CA8E5D"}
@@ -1,71 +1,43 @@
1
- import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  /**
3
3
  * <DiscountSelector>
4
4
  *
5
- * Cart 上的优惠券选择器 — 卡片式 UI,对齐拼多多 / 京东体验。
5
+ * Cart 上的优惠券选择器 — 卡片式 UI
6
6
  *
7
- * 行为:
8
- * - 默认显示当前应用的券(服务端自动选了最佳,或买家显式选的)
9
- * - "切换"打开抽屉/弹窗,列出该买家所有可用券(从 useDiscounts().myDiscounts)
10
- * - 选另一张 cartDiscountSelect mutation
11
- * - 点"不使用优惠券" → cartDiscountClear
12
- *
13
- * 未登录买家:渲染"登录后享受优惠"提示。
14
- *
15
- * 设计目标:
16
- * - 这是 helium "脚手架" 的卡片式实现。商家可以替换为抽屉式 / 弹窗式自定义 UI。
17
- * - 商家也可以直接用 useDiscounts() 自己渲染(提供 hook-only 路径)。
7
+ * helium 0.7 改造:
8
+ * - 数据通过 props 传入(不再用 DiscountProvider)
9
+ * - mutation 通过 <CartForm action="CustomDiscountSelect" inputs={{claimId}}>
10
+ * - 商家 loader myDiscountClaims + cart.appliedDiscountClaim,传给本组件
18
11
  */
19
12
  import * as React from 'react';
20
- import { useDiscounts } from './DiscountProvider';
21
13
  import { Money } from './Money';
22
- import { useMounted } from './hooks/useMounted';
23
14
  import { CartForm } from './CartForm';
24
15
  import { formatDate } from '../utils/formatDate';
25
16
  export function DiscountSelector(props) {
26
- const { className, unauthenticatedFallback, renderApplied } = props;
27
- const mounted = useMounted();
28
- const { myDiscounts, myDiscountsStatus, cartAllocations, appliedClaim, } = useDiscounts();
17
+ const { myClaims = [], appliedClaim, appliedAllocation, unauthenticated = false, unauthenticatedFallback, className, renderApplied, } = props;
29
18
  const [open, setOpen] = React.useState(false);
30
- // SSR + client 首次 render:返回固定占位,保证 hydration 不 mismatch。
31
- if (!mounted) {
32
- return _jsx("div", { "data-discount-selector": true, "data-ssr-placeholder": true, className: className });
33
- }
34
- // 服务端已经决定了 cart 上是哪张券
35
- const appliedAlloc = cartAllocations[0];
36
- const appliedClaimId = appliedClaim?.claimId ?? null;
37
- const appliedTitle = appliedClaim?.title ?? appliedAlloc?.title;
38
- const appliedCode = appliedClaim?.code ?? appliedAlloc?.code;
39
- // 未登录
40
- if (myDiscountsStatus === 'unauthenticated') {
19
+ if (unauthenticated) {
41
20
  return unauthenticatedFallback !== undefined ? _jsx(_Fragment, { children: unauthenticatedFallback }) : (_jsxs("div", { "data-discount-selector": true, "data-unauth": true, className: className, children: [_jsx("span", { children: "\u767B\u5F55\u540E\u53EF\u4F7F\u7528\u4F18\u60E0\u5238" }), _jsx("a", { href: "/login?next=/cart", children: "\u53BB\u767B\u5F55" })] }));
42
21
  }
43
- if (myDiscountsStatus === 'loading') {
44
- return _jsx("div", { "data-discount-selector": true, "data-loading": true, className: className, children: "\u52A0\u8F7D\u4F18\u60E0\u5238\u2026" });
45
- }
46
- const availableClaims = myDiscounts.filter((c) => !c.isExpired && c.remainingUses > 0);
47
- if (availableClaims.length === 0) {
22
+ const appliedClaimId = appliedClaim?.claimId ?? null;
23
+ const appliedTitle = appliedClaim?.title ?? appliedAllocation?.title;
24
+ const appliedCode = appliedClaim?.code ?? appliedAllocation?.code;
25
+ const availableClaims = myClaims.filter((c) => !c.isExpired && c.remainingUses > 0);
26
+ if (availableClaims.length === 0 && !appliedClaimId) {
48
27
  return (_jsx("div", { "data-discount-selector": true, "data-no-discount": true, className: className, children: _jsx("span", { children: "\u6682\u65E0\u53EF\u7528\u4F18\u60E0\u5238" }) }));
49
28
  }
50
29
  return (_jsxs(_Fragment, { children: [_jsx("div", { "data-discount-selector": true, className: className, children: appliedClaimId ? (renderApplied ? renderApplied({
51
30
  code: appliedCode ?? null,
52
31
  title: appliedTitle ?? '',
53
- amount: appliedAlloc?.discountedAmount ?? { amount: '0', currencyCode: 'CNY' },
32
+ amount: appliedAllocation?.discountedAmount ?? { amount: '0', currencyCode: 'CNY' },
54
33
  onChange: () => setOpen(true),
55
- }) : (_jsxs("div", { "data-applied": true, children: [_jsxs("div", { "data-info": true, children: [_jsx("span", { "data-label": true, children: "\u5DF2\u4F7F\u7528" }), _jsx("strong", { "data-title": true, children: appliedTitle }), appliedAlloc && (_jsxs("span", { "data-amount": true, children: ["\u2212 ", _jsx(Money, { data: { amount: appliedAlloc.discountedAmount.amount, currencyCode: appliedAlloc.discountedAmount.currencyCode } })] }))] }), _jsx("div", { "data-actions": true, children: _jsx("button", { type: "button", onClick: () => setOpen(true), children: "\u5207\u6362" }) })] }))) : (_jsxs("div", { "data-empty-applied": true, children: [_jsx("div", { "data-info": true, children: _jsxs("span", { "data-label": true, children: ["\u6709 ", availableClaims.length, " \u5F20\u53EF\u7528\u4F18\u60E0\u5238"] }) }), _jsx("button", { type: "button", onClick: () => setOpen(true), children: "\u9009\u62E9" })] })) }), open && (_jsx(DiscountPickerSheet, { claims: availableClaims, currentClaimId: appliedClaimId, onClose: () => setOpen(false) }))] }));
34
+ }) : (_jsxs("div", { "data-applied": true, children: [_jsxs("div", { "data-info": true, children: [_jsx("span", { "data-label": true, children: "\u5DF2\u4F7F\u7528" }), _jsx("strong", { "data-title": true, children: appliedTitle }), appliedAllocation && (_jsxs("span", { "data-amount": true, children: ["\u2212 ", _jsx(Money, { data: { amount: appliedAllocation.discountedAmount.amount, currencyCode: appliedAllocation.discountedAmount.currencyCode } })] }))] }), _jsx("div", { "data-actions": true, children: _jsx("button", { type: "button", onClick: () => setOpen(true), children: "\u5207\u6362" }) })] }))) : (_jsxs("div", { "data-empty-applied": true, children: [_jsx("div", { "data-info": true, children: _jsxs("span", { "data-label": true, children: ["\u6709 ", availableClaims.length, " \u5F20\u53EF\u7528\u4F18\u60E0\u5238"] }) }), _jsx("button", { type: "button", onClick: () => setOpen(true), children: "\u9009\u62E9" })] })) }), open && (_jsx(DiscountPickerSheet, { claims: availableClaims, currentClaimId: appliedClaimId, onClose: () => setOpen(false) }))] }));
56
35
  }
57
- /**
58
- * 抽屉式选券面板。
59
- * Demo 实现为屏底固定面板;商家可以替换为 modal / 抽屉等。
60
- */
61
36
  function DiscountPickerSheet({ claims, currentClaimId, onClose, }) {
62
37
  return (_jsx("div", { "data-discount-picker-overlay": true, onClick: onClose, children: _jsxs("div", { "data-discount-picker-sheet": true, onClick: (e) => e.stopPropagation(), children: [_jsxs("div", { "data-sheet-header": true, children: [_jsx("h3", { children: "\u9009\u62E9\u4F18\u60E0\u5238" }), _jsx("button", { type: "button", onClick: onClose, "data-sheet-close": true, children: "\u00D7" })] }), _jsx("div", { "data-sheet-list": true, children: claims.map((c) => {
63
- // claim_id 既可能是 gid 也可能是 raw —— oxygen mutation 接受两种
64
38
  const id = c.id.replace(/^gid:\/\/shopbb\/DiscountClaim\//, '');
65
39
  const isCurrent = currentClaimId === id;
66
- return (
67
- // 每张券一个 <CartForm>,submit 走 /cart action → cart.selectDiscount
68
- _jsx(CartForm, { action: "CustomDiscountSelect", inputs: { claimId: id }, children: (fetcher) => (_jsxs("button", { type: "submit", "data-claim-card": true, "data-current": isCurrent ? '' : undefined, disabled: fetcher.state !== 'idle', children: [_jsxs("div", { "data-claim-left": true, children: [_jsx("div", { "data-claim-value": true, children: formatValue(c) }), c.discount.minSubtotal && (_jsxs("div", { "data-claim-min": true, children: ["\u6EE1 ", _jsx(Money, { data: { amount: c.discount.minSubtotal.amount, currencyCode: c.discount.minSubtotal.currencyCode } }), " \u53EF\u7528"] }))] }), _jsxs("div", { "data-claim-right": true, children: [_jsx("div", { "data-claim-title": true, children: c.discount.title }), c.discount.code && _jsx("div", { "data-claim-code": true, children: c.discount.code }), c.expiresAt && (_jsxs("div", { "data-claim-expiry": true, children: [formatDate(c.expiresAt), " \u8FC7\u671F"] }))] }), isCurrent && _jsx("span", { "data-claim-current-tag": true, children: "\u5F53\u524D\u4F7F\u7528" })] })) }, c.id));
40
+ return (_jsx(CartForm, { action: "CustomDiscountSelect", inputs: { claimId: id }, children: (fetcher) => (_jsxs("button", { type: "submit", "data-claim-card": true, "data-current": isCurrent ? '' : undefined, disabled: fetcher.state !== 'idle', children: [_jsxs("div", { "data-claim-left": true, children: [_jsx("div", { "data-claim-value": true, children: formatValue(c) }), c.discount.minSubtotal && (_jsxs("div", { "data-claim-min": true, children: ["\u6EE1 ", _jsx(Money, { data: { amount: c.discount.minSubtotal.amount, currencyCode: c.discount.minSubtotal.currencyCode } }), " \u53EF\u7528"] }))] }), _jsxs("div", { "data-claim-right": true, children: [_jsx("div", { "data-claim-title": true, children: c.discount.title }), c.discount.code && _jsx("div", { "data-claim-code": true, children: c.discount.code }), c.expiresAt && (_jsxs("div", { "data-claim-expiry": true, children: [formatDate(c.expiresAt), " \u8FC7\u671F"] }))] }), isCurrent && _jsx("span", { "data-claim-current-tag": true, children: "\u5F53\u524D\u4F7F\u7528" })] })) }, c.id));
69
41
  }) })] }) }));
70
42
  }
71
43
  function formatValue(c) {
@@ -1 +1 @@
1
- {"version":3,"file":"DiscountSelector.js","sourceRoot":"","sources":["../../src/components/DiscountSelector.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"DiscountSelector.js","sourceRoot":"","sources":["../../src/components/DiscountSelector.tsx"],"names":[],"mappings":"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"}
@@ -1,50 +1,49 @@
1
1
  /**
2
- * useOptimisticCart — 对齐 Hydrogen React 同名 hook
2
+ * useOptimisticCart — 严格对齐 Shopify Hydrogen
3
3
  *
4
- * 接受 actualCart(来自 CartProvider),返回一个"叠加了所有 pending mutation"
5
- * 的 cart 视图。让 UI 在网络回来之前立刻反应用户操作(数量+1 / 删除等)。
4
+ * 源文件参考:packages/hydrogen/src/cart/optimistic/useOptimisticCart.tsx
6
5
  *
7
- * const { cart: actualCart } = useCart();
8
- * const cart = useOptimisticCart(actualCart);
9
- * // cart 看起来已经"立刻应用了",但 fetcher 还在跑后端
6
+ * 核心:用 RR7 `useFetchers()` 拿当前所有 in-flight fetcher,遍历它们的 formData
7
+ * CartForm.getFormInput 解析出 action/inputs,合并到 actualCart 上。
10
8
  *
11
- * 实现:
12
- * - <CartForm> submit 时把 pending action 注册到模块内 store
13
- * - 完成后从 store 摘掉
14
- * - useOptimisticCart 订阅 store,把 actualCart 复制一份 + 应用所有 pending
9
+ * 用法:
10
+ * const data = useLoaderData<typeof loader>();
11
+ * const cart = useOptimisticCart(data.cart);
12
+ * // cart 包含 isOptimistic 字段、cart.lines 包含 in-flight 添加的 line(也带 isOptimistic)
15
13
  *
16
- * 简化点(vs Hydrogen 完整实现):
17
- * - 只支持 LinesAdd / LinesUpdate / LinesRemove(足够 cart 主流操作)
18
- * - DiscountCodesUpdate / NoteUpdate 等不做 optimistic(这些在网络层用 applyCart 兜底)
19
- * - 不持久化(页面刷新清空)
14
+ * 与之前 helium 0.6.x 区别:
15
+ * - 删除自造 pendingStore 全局变量
16
+ * - 直接用 RR7 useFetchers()
20
17
  */
21
- export interface PendingMutation {
22
- id: string;
23
- action: 'LinesAdd' | 'LinesUpdate' | 'LinesRemove';
24
- inputs: any;
18
+ interface LikeACart {
19
+ lines: {
20
+ nodes: Array<any>;
21
+ };
25
22
  }
26
- /**
27
- * Internal: CartForm 提交时调用,注册一个 pending mutation。返回 unregister。
28
- */
29
- export declare function __registerPendingMutation(m: PendingMutation): () => void;
30
- export interface OptimisticCartLine {
31
- id: string;
32
- quantity: number;
23
+ export type OptimisticCartLine<T = any> = T extends LikeACart ? T['lines']['nodes'][number] & {
33
24
  isOptimistic?: boolean;
34
- merchandise?: any;
35
- cost?: any;
36
- attributes?: any;
37
- [key: string]: any;
38
- }
39
- export interface OptimisticCart<TCart = any> {
25
+ } : T & {
40
26
  isOptimistic?: boolean;
27
+ };
28
+ export type OptimisticCart<T = any> = T extends undefined | null ? {
29
+ isOptimistic?: boolean;
30
+ lines: {
31
+ nodes: Array<OptimisticCartLine>;
32
+ };
41
33
  totalQuantity?: number;
42
- lines?: {
43
- nodes: OptimisticCartLine[];
44
- edges?: any;
34
+ } : Omit<T, 'lines'> & {
35
+ isOptimistic?: boolean;
36
+ lines: {
37
+ nodes: Array<OptimisticCartLine<T>>;
45
38
  };
46
- cost?: any;
47
- [key: string]: any;
39
+ totalQuantity?: number;
40
+ };
41
+ export declare function useOptimisticCart<DefaultCart = any>(cart?: DefaultCart): OptimisticCart<DefaultCart>;
42
+ export declare function __registerPendingMutation(): () => void;
43
+ export interface PendingMutation {
44
+ id: string;
45
+ action: 'LinesAdd' | 'LinesUpdate' | 'LinesRemove';
46
+ inputs: any;
48
47
  }
49
- export declare function useOptimisticCart<TCart extends OptimisticCart = OptimisticCart>(actualCart: TCart | null): TCart | null;
48
+ export {};
50
49
  //# sourceMappingURL=useOptimisticCart.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useOptimisticCart.d.ts","sourceRoot":"","sources":["../../../src/components/hooks/useOptimisticCart.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AASH,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,UAAU,GAAG,aAAa,GAAG,aAAa,CAAC;IACnD,MAAM,EAAE,GAAG,CAAC;CACb;AAmCD;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,CAAC,EAAE,eAAe,GAAG,MAAM,IAAI,CAGxE;AAMD,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,WAAW,CAAC,EAAE,GAAG,CAAC;IAClB,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,UAAU,CAAC,EAAE,GAAG,CAAC;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED,MAAM,WAAW,cAAc,CAAC,KAAK,GAAG,GAAG;IACzC,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE;QAAE,KAAK,EAAE,kBAAkB,EAAE,CAAC;QAAC,KAAK,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IACrD,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED,wBAAgB,iBAAiB,CAAC,KAAK,SAAS,cAAc,GAAG,cAAc,EAC7E,UAAU,EAAE,KAAK,GAAG,IAAI,GACvB,KAAK,GAAG,IAAI,CAmFd"}
1
+ {"version":3,"file":"useOptimisticCart.d.ts","sourceRoot":"","sources":["../../../src/components/hooks/useOptimisticCart.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAKH,UAAU,SAAS;IACjB,KAAK,EAAE;QAAE,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAA;KAAE,CAAC;CAC9B;AAED,MAAM,MAAM,kBAAkB,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,SAAS,SAAS,GACzD,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,GAAG;IAAE,YAAY,CAAC,EAAE,OAAO,CAAA;CAAE,GACxD,CAAC,GAAG;IAAE,YAAY,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAEnC,MAAM,MAAM,cAAc,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,SAAS,SAAS,GAAG,IAAI,GAC5D;IACE,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,KAAK,EAAE;QAAE,KAAK,EAAE,KAAK,CAAC,kBAAkB,CAAC,CAAA;KAAE,CAAC;IAC5C,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,GACD,IAAI,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG;IACjB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,KAAK,EAAE;QAAE,KAAK,EAAE,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAA;KAAE,CAAC;IAC/C,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAcN,wBAAgB,iBAAiB,CAAC,WAAW,GAAG,GAAG,EACjD,IAAI,CAAC,EAAE,WAAW,GACjB,cAAc,CAAC,WAAW,CAAC,CAkF7B;AAGD,wBAAgB,yBAAyB,IAAI,MAAM,IAAI,CAEtD;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,UAAU,GAAG,aAAa,GAAG,aAAa,CAAC;IACnD,MAAM,EAAE,GAAG,CAAC;CACb"}