pb-sxp-ui 1.20.27 → 1.20.29

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 (35) hide show
  1. package/dist/index.cjs +353 -39
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.js +353 -39
  4. package/dist/index.js.map +1 -1
  5. package/dist/index.min.cjs +9 -9
  6. package/dist/index.min.cjs.map +1 -1
  7. package/dist/index.min.js +9 -9
  8. package/dist/index.min.js.map +1 -1
  9. package/dist/pb-ui.js +353 -39
  10. package/dist/pb-ui.js.map +1 -1
  11. package/dist/pb-ui.min.js +9 -9
  12. package/dist/pb-ui.min.js.map +1 -1
  13. package/es/core/context/SxpDataSourceProvider.d.ts +1 -1
  14. package/es/core/index.d.ts +6 -0
  15. package/es/core/index.js +10 -0
  16. package/es/core/utils/materials.js +30 -7
  17. package/es/core/utils/tool.d.ts +1 -0
  18. package/es/core/utils/tool.js +43 -0
  19. package/es/materials/sxp/popup/AddToCart/index.js +27 -8
  20. package/es/materials/sxp/popup/AddToCart/index.new.js +27 -6
  21. package/es/materials/sxp/popup/AddToCart/index.old.js +13 -2
  22. package/es/materials/sxp/popup/CommodityDetail/index.js +21 -16
  23. package/es/materials/sxp/popup/CommodityDetailDiroNew/index.js +25 -0
  24. package/lib/core/context/SxpDataSourceProvider.d.ts +1 -1
  25. package/lib/core/index.d.ts +6 -0
  26. package/lib/core/index.js +10 -5
  27. package/lib/core/utils/materials.js +29 -6
  28. package/lib/core/utils/tool.d.ts +1 -0
  29. package/lib/core/utils/tool.js +45 -1
  30. package/lib/materials/sxp/popup/AddToCart/index.js +27 -8
  31. package/lib/materials/sxp/popup/AddToCart/index.new.js +27 -6
  32. package/lib/materials/sxp/popup/AddToCart/index.old.js +12 -1
  33. package/lib/materials/sxp/popup/CommodityDetail/index.js +21 -16
  34. package/lib/materials/sxp/popup/CommodityDetailDiroNew/index.js +25 -0
  35. package/package.json +1 -1
@@ -12,7 +12,7 @@ export interface IEventTimeType {
12
12
  time: Date;
13
13
  target: EventTarget;
14
14
  }
15
- export type ICapiEventNameType = 'PageView' | 'ProductView' | 'ViewContent' | 'ClickCTA' | 'ContentSwipe' | 'Engagement' | 'ExitFeed' | 'AddToCart';
15
+ export type ICapiEventNameType = 'PageView' | 'ProductView' | 'ViewContent' | 'ClickCTA' | 'ContentSwipe' | 'Engagement' | 'ExitFeed' | 'AddToCart' | 'sessionCompleted';
16
16
  export interface ISxpDataSourceContext {
17
17
  rtcList: RecItemType[];
18
18
  setRtcList?: React.Dispatch<React.SetStateAction<RecItemType[]>>;
@@ -3,3 +3,9 @@ export type { IEditorCoreRef } from './context/EditorContext';
3
3
  export type { MaterialComponet } from './create';
4
4
  export { default as StructurePage } from './components/StructurePage';
5
5
  export type { IStructurePageProps, IPostData, IProductData, IMultiCtaData, IApiResponse } from './components/StructurePage';
6
+ export * as hooks from './hooks';
7
+ export * from './create';
8
+ export { Pagebuilder } from './Pagebuilder';
9
+ export * as localStore from './utils/localStore';
10
+ export * as sessionStore from './utils/sessionStore';
11
+ export * as tool from './utils/tool';
package/es/core/index.js CHANGED
@@ -1,2 +1,12 @@
1
1
  export { EditorCore } from './context/EditorContext';
2
2
  export { default as StructurePage } from './components/StructurePage';
3
+ import * as hooks_1 from './hooks';
4
+ export { hooks_1 as hooks };
5
+ export * from './create';
6
+ export { Pagebuilder } from './Pagebuilder';
7
+ import * as localStore_1 from './utils/localStore';
8
+ export { localStore_1 as localStore };
9
+ import * as sessionStore_1 from './utils/sessionStore';
10
+ export { sessionStore_1 as sessionStore };
11
+ import * as tool_1 from './utils/tool';
12
+ export { tool_1 as tool };
@@ -1,4 +1,4 @@
1
- import { setFontForText } from './tool';
1
+ import { setFontForText, getCurrencySymbol } from './tool';
2
2
  export const getMediaValueByMode = (obj) => {
3
3
  var _a;
4
4
  if (!obj || typeof obj !== 'object') {
@@ -31,7 +31,7 @@ export const getBgStyleByImg = (data) => {
31
31
  return getBgStyle(imgSrc);
32
32
  };
33
33
  export const getPriceText = ({ product, enableFormattedPrice, globalConfig, isHiddenDef, style }) => {
34
- var _a, _b, _c, _d, _e, _f, _g, _h;
34
+ var _a, _b, _c, _d, _e;
35
35
  let text = '';
36
36
  if ((!(product === null || product === void 0 ? void 0 : product.currency) || !(product === null || product === void 0 ? void 0 : product.price)) && isHiddenDef)
37
37
  return null;
@@ -39,18 +39,41 @@ export const getPriceText = ({ product, enableFormattedPrice, globalConfig, isHi
39
39
  if (typeof price !== 'number')
40
40
  return text;
41
41
  let priceSymbol = globalConfig === null || globalConfig === void 0 ? void 0 : globalConfig.priceSymbol;
42
- let currency = (product === null || product === void 0 ? void 0 : product.currency) ? (_c = (_b = (_a = product === null || product === void 0 ? void 0 : product.currency) === null || _a === void 0 ? void 0 : _a.split('-')[1]) === null || _b === void 0 ? void 0 : _b.toUpperCase()) !== null && _c !== void 0 ? _c : '' : '$';
42
+ let currencyCode = '';
43
+ if (product === null || product === void 0 ? void 0 : product.currency) {
44
+ const parts = product.currency.split('-');
45
+ if (parts.length > 1) {
46
+ const firstPart = parts[0].toUpperCase();
47
+ const secondPart = parts[1].toUpperCase();
48
+ if (/^[A-Z]{3}$/.test(firstPart)) {
49
+ currencyCode = firstPart;
50
+ }
51
+ else if (/^[A-Z]{3}$/.test(secondPart)) {
52
+ currencyCode = secondPart;
53
+ }
54
+ else {
55
+ currencyCode = firstPart;
56
+ }
57
+ }
58
+ else {
59
+ currencyCode = parts[0].toUpperCase();
60
+ }
61
+ }
62
+ else {
63
+ currencyCode = 'USD';
64
+ }
65
+ let currency = getCurrencySymbol(currencyCode);
43
66
  const isToLocStr = enableFormattedPrice === undefined || enableFormattedPrice;
44
67
  let decPic = price === null || price === void 0 ? void 0 : price.toString();
45
68
  if (priceSymbol === null || priceSymbol === void 0 ? void 0 : priceSymbol.showTwoDecimalPoint) {
46
69
  decPic = price === null || price === void 0 ? void 0 : price.toFixed(2);
47
70
  }
48
- let decInd = (_d = decPic === null || decPic === void 0 ? void 0 : decPic.indexOf('.')) !== null && _d !== void 0 ? _d : -1;
71
+ let decInd = (_a = decPic === null || decPic === void 0 ? void 0 : decPic.indexOf('.')) !== null && _a !== void 0 ? _a : -1;
49
72
  if (isToLocStr) {
50
73
  text =
51
- (_e = price === null || price === void 0 ? void 0 : price.toLocaleString('zh', {
74
+ (_b = price === null || price === void 0 ? void 0 : price.toLocaleString('zh', {
52
75
  minimumFractionDigits: (priceSymbol === null || priceSymbol === void 0 ? void 0 : priceSymbol.showTwoDecimalPoint) ? 2 : 0
53
- })) !== null && _e !== void 0 ? _e : '';
76
+ })) !== null && _b !== void 0 ? _b : '';
54
77
  let startIndex = 0;
55
78
  let endIndex = decInd !== null && decInd !== void 0 ? decInd : text === null || text === void 0 ? void 0 : text.length;
56
79
  if ((priceSymbol === null || priceSymbol === void 0 ? void 0 : priceSymbol.millesimalSymbol) === '.') {
@@ -80,7 +103,7 @@ export const getPriceText = ({ product, enableFormattedPrice, globalConfig, isHi
80
103
  }
81
104
  });
82
105
  }
83
- currency = `<span style="font-family:${(_h = (_g = (_f = globalConfig === null || globalConfig === void 0 ? void 0 : globalConfig.priceSymbol) === null || _f === void 0 ? void 0 : _f.fontFamily) !== null && _g !== void 0 ? _g : style === null || style === void 0 ? void 0 : style['fontFamily-en']) !== null && _h !== void 0 ? _h : 'inherit'}">${currency}</span>`;
106
+ currency = `<span style="font-family:${(_e = (_d = (_c = globalConfig === null || globalConfig === void 0 ? void 0 : globalConfig.priceSymbol) === null || _c === void 0 ? void 0 : _c.fontFamily) !== null && _d !== void 0 ? _d : style === null || style === void 0 ? void 0 : style['fontFamily-en']) !== null && _e !== void 0 ? _e : 'inherit'}">${currency}</span>`;
84
107
  text = setFontForText(text, style);
85
108
  if ((priceSymbol === null || priceSymbol === void 0 ? void 0 : priceSymbol.currencyPosition) && (priceSymbol === null || priceSymbol === void 0 ? void 0 : priceSymbol.currencyPosition) !== 'none') {
86
109
  text = (priceSymbol === null || priceSymbol === void 0 ? void 0 : priceSymbol.currencyPosition) === 'left' ? currency + text : text + currency;
@@ -16,4 +16,5 @@ declare function splitUrlParams(urlParams: string): string[] | undefined;
16
16
  declare function deleteCookie(name: string, path?: string, domain?: string): void;
17
17
  declare function setCookie(name: string, value: string, days?: number, path?: string, domain?: string, secure?: boolean, sameSite?: string): void;
18
18
  declare function getUrlParamByKey(key: string): any;
19
+ export declare function getCurrencySymbol(currencyCode: string): string;
19
20
  export { uuid, getIndexByblockType, getBrowserInfo, getDevice, getSystem, getCookie, getScreenReader, splitUrlParams, deleteCookie, setCookie, getUrlParamByKey };
@@ -233,4 +233,47 @@ function getUrlParamByKey(key) {
233
233
  }
234
234
  return (_b = params[key]) !== null && _b !== void 0 ? _b : '';
235
235
  }
236
+ export function getCurrencySymbol(currencyCode) {
237
+ const currencySymbolMap = {
238
+ USD: '$',
239
+ EUR: '€',
240
+ GBP: '£',
241
+ JPY: '¥',
242
+ CNY: '¥',
243
+ KRW: '₩',
244
+ INR: '₹',
245
+ RUB: '₽',
246
+ BRL: 'R$',
247
+ CAD: 'CA$',
248
+ AUD: 'A$',
249
+ CHF: 'CHF',
250
+ SEK: 'kr',
251
+ NOK: 'kr',
252
+ DKK: 'kr',
253
+ PLN: 'zł',
254
+ THB: '฿',
255
+ IDR: 'Rp',
256
+ MYR: 'RM',
257
+ PHP: '₱',
258
+ SGD: 'S$',
259
+ HKD: 'HK$',
260
+ TWD: 'NT$',
261
+ NZD: 'NZ$',
262
+ MXN: 'MX$',
263
+ ZAR: 'R',
264
+ TRY: '₺',
265
+ AED: 'AED',
266
+ SAR: 'SAR',
267
+ ILS: '₪',
268
+ ARS: 'AR$',
269
+ CLP: 'CL$',
270
+ COP: 'CO$',
271
+ VND: '₫',
272
+ EGP: 'E£',
273
+ NGN: '₦',
274
+ PKR: '₨',
275
+ BDT: '৳',
276
+ };
277
+ return currencySymbolMap[currencyCode.toUpperCase()] || currencyCode;
278
+ }
236
279
  export { uuid, getIndexByblockType, getBrowserInfo, getDevice, getSystem, getCookie, getScreenReader, splitUrlParams, deleteCookie, setCookie, getUrlParamByKey };
@@ -2,10 +2,11 @@ import { __awaiter } from "tslib";
2
2
  import React, { useState, useEffect, useCallback } from 'react';
3
3
  import { useSxpDataSource } from '../../../../core/hooks';
4
4
  import Modal from '../../../../core/components/SxpPageRender/Modal';
5
+ import { getCurrencySymbol } from '../../../../core/utils/tool';
5
6
  import './index.less';
6
7
  const AddToCartPopup = ({ isActive = true }) => {
7
8
  var _a, _b, _c, _d, _e, _f, _g, _h, _j;
8
- const { popupDetailData, globalConfig } = useSxpDataSource();
9
+ const { popupDetailData, globalConfig, bffFbReport } = useSxpDataSource();
9
10
  const [productData, setProductData] = useState(null);
10
11
  const [selectedOptions, setSelectedOptions] = useState({});
11
12
  const [selectedVariant, setSelectedVariant] = useState(null);
@@ -137,6 +138,17 @@ const AddToCartPopup = ({ isActive = true }) => {
137
138
  shopifyDomain,
138
139
  selectedVariant
139
140
  });
141
+ bffFbReport === null || bffFbReport === void 0 ? void 0 : bffFbReport({
142
+ eventName: 'sessionCompleted',
143
+ product: product ? [product] : undefined,
144
+ contentType: 'product',
145
+ rec: data,
146
+ position: data === null || data === void 0 ? void 0 : data.index,
147
+ cta_text: 'Add To Cart',
148
+ cta_action_type: 'add_to_cart',
149
+ target_content_id: product === null || product === void 0 ? void 0 : product.itemId,
150
+ target_url: `https://${shopifyDomain}/cart/add`
151
+ });
140
152
  const params = new URLSearchParams({
141
153
  id: variantId,
142
154
  quantity: quantity.toString()
@@ -148,6 +160,9 @@ const AddToCartPopup = ({ isActive = true }) => {
148
160
  const totalPrice = selectedVariant
149
161
  ? (parseFloat(selectedVariant.price.amount) * quantity).toFixed(2)
150
162
  : '0.00';
163
+ const displayPrice = selectedVariant
164
+ ? `${getCurrencySymbol(selectedVariant.price.currencyCode)}${totalPrice}`
165
+ : totalPrice;
151
166
  if (loading) {
152
167
  return (React.createElement("div", { className: 'add-to-cart-popup' },
153
168
  React.createElement("div", { className: 'loading' }, "Loading...")));
@@ -181,9 +196,7 @@ const AddToCartPopup = ({ isActive = true }) => {
181
196
  "Available: ",
182
197
  selectedVariant.quantityAvailable))),
183
198
  React.createElement("div", { className: 'variant-price-row' },
184
- React.createElement("div", { className: 'price' },
185
- "$",
186
- totalPrice),
199
+ React.createElement("div", { className: 'price' }, displayPrice),
187
200
  React.createElement("div", { className: 'quantity-selector' },
188
201
  React.createElement("button", { className: 'qty-btn', onClick: () => setQuantity(Math.max(1, quantity - 1)), disabled: quantity <= 1 }, "\u2212"),
189
202
  React.createElement("span", { className: 'qty-value' }, quantity),
@@ -193,11 +206,17 @@ const AddToCartPopup = ({ isActive = true }) => {
193
206
  React.createElement("div", { className: 'option-values' }, option.values.map(value => {
194
207
  const isAvailable = productData.variants.edges.some(({ node: variant }) => {
195
208
  const hasThisOption = variant.selectedOptions.some(opt => opt.name === option.name && opt.value === value);
196
- if (!hasThisOption || !variant.availableForSale)
209
+ if (!hasThisOption)
210
+ return false;
211
+ const matchesOtherSelections = Object.entries(selectedOptions).every(([key, val]) => {
212
+ if (key === option.name)
213
+ return true;
214
+ return variant.selectedOptions.some(opt => opt.name === key && opt.value === val);
215
+ });
216
+ if (!matchesOtherSelections)
217
+ return false;
218
+ if (!variant.availableForSale)
197
219
  return false;
198
- if (variant.quantityAvailable !== undefined) {
199
- return variant.quantityAvailable > 0;
200
- }
201
220
  return true;
202
221
  });
203
222
  const isSelected = selectedOptions[option.name] === value;
@@ -1,10 +1,11 @@
1
1
  import { __awaiter } from "tslib";
2
2
  import React, { useState, useEffect, useCallback } from 'react';
3
3
  import { useSxpDataSource } from '../../../../core/hooks';
4
+ import { getCurrencySymbol } from '../../../../core/utils/tool';
4
5
  import './index.less';
5
6
  const AddToCartPopup = ({ isActive = true, onClose }) => {
6
7
  var _a, _b, _c, _d, _e, _f, _g;
7
- const { popupDetailData, globalConfig } = useSxpDataSource();
8
+ const { popupDetailData, globalConfig, bffFbReport } = useSxpDataSource();
8
9
  const [productData, setProductData] = useState(null);
9
10
  const [selectedOptions, setSelectedOptions] = useState({});
10
11
  const [selectedVariant, setSelectedVariant] = useState(null);
@@ -120,6 +121,17 @@ const AddToCartPopup = ({ isActive = true, onClose }) => {
120
121
  alert('Please select all options');
121
122
  return;
122
123
  }
124
+ bffFbReport === null || bffFbReport === void 0 ? void 0 : bffFbReport({
125
+ eventName: 'sessionCompleted',
126
+ product: product ? [product] : undefined,
127
+ contentType: 'product',
128
+ rec: data,
129
+ position: data === null || data === void 0 ? void 0 : data.index,
130
+ cta_text: 'Add To Cart',
131
+ cta_action_type: 'add_to_cart',
132
+ target_content_id: product === null || product === void 0 ? void 0 : product.itemId,
133
+ target_url: `https://${shopifyDomain}/cart`
134
+ });
123
135
  const variantId = selectedVariant.id.split('/').pop();
124
136
  const checkoutUrl = `https://${shopifyDomain}/cart/${variantId}:${quantity}`;
125
137
  window.location.href = checkoutUrl;
@@ -127,7 +139,9 @@ const AddToCartPopup = ({ isActive = true, onClose }) => {
127
139
  const totalPrice = selectedVariant
128
140
  ? (parseFloat(selectedVariant.price.amount) * quantity).toFixed(2)
129
141
  : '0.00';
130
- const currency = (selectedVariant === null || selectedVariant === void 0 ? void 0 : selectedVariant.price.currencyCode) || 'USD';
142
+ const displayPrice = selectedVariant
143
+ ? `${getCurrencySymbol(selectedVariant.price.currencyCode)}${totalPrice}`
144
+ : totalPrice;
131
145
  if (loading) {
132
146
  return (React.createElement("div", { className: "add-to-cart-popup" },
133
147
  React.createElement("div", { className: "loading" }, "Loading...")));
@@ -152,9 +166,7 @@ const AddToCartPopup = ({ isActive = true, onClose }) => {
152
166
  React.createElement("div", { className: "variant-info" },
153
167
  React.createElement("div", { className: "variant-specs" }, Object.keys(selectedOptions).length > 0 ? (Object.entries(selectedOptions).map(([key, value]) => (React.createElement("span", { key: key, className: "spec-item" }, value)))) : (React.createElement("span", { className: "spec-placeholder" }, "Please select options"))),
154
168
  React.createElement("div", { className: "variant-price-row" },
155
- React.createElement("div", { className: "price" },
156
- "$",
157
- totalPrice),
169
+ React.createElement("div", { className: "price" }, displayPrice),
158
170
  React.createElement("div", { className: "quantity-selector" },
159
171
  React.createElement("button", { className: "qty-btn", onClick: () => setQuantity(Math.max(1, quantity - 1)), disabled: quantity <= 1 }, "\u2212"),
160
172
  React.createElement("span", { className: "qty-value" }, quantity),
@@ -164,7 +176,16 @@ const AddToCartPopup = ({ isActive = true, onClose }) => {
164
176
  React.createElement("div", { className: "option-values" }, option.values.map(value => {
165
177
  const isAvailable = productData.variants.edges.some(({ node: variant }) => {
166
178
  const hasThisOption = variant.selectedOptions.some(opt => opt.name === option.name && opt.value === value);
167
- return hasThisOption && variant.availableForSale;
179
+ if (!hasThisOption)
180
+ return false;
181
+ const matchesOtherSelections = Object.entries(selectedOptions).every(([key, val]) => {
182
+ if (key === option.name)
183
+ return true;
184
+ return variant.selectedOptions.some(opt => opt.name === key && opt.value === val);
185
+ });
186
+ if (!matchesOtherSelections)
187
+ return false;
188
+ return variant.availableForSale;
168
189
  });
169
190
  const isSelected = selectedOptions[option.name] === value;
170
191
  return (React.createElement("button", { key: value, className: `option-btn ${isSelected ? 'selected' : ''} ${!isAvailable ? 'disabled' : ''}`, onClick: () => isAvailable && handleOptionSelect(option.name, value), disabled: !isAvailable }, value));
@@ -2,7 +2,7 @@ import { __awaiter, __rest } from "tslib";
2
2
  import React, { useState, useEffect, useCallback, useMemo, useRef } from 'react';
3
3
  import { useSxpDataSource } from '../../../../core/hooks';
4
4
  import { useEventReport } from '../../../../core/hooks/useEventReport';
5
- import { setFontForText } from '../../../../core/utils/tool';
5
+ import { setFontForText, getCurrencySymbol } from '../../../../core/utils/tool';
6
6
  import './index.less';
7
7
  const AddToCartPopup = (_a) => {
8
8
  var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
@@ -227,6 +227,17 @@ const AddToCartPopup = (_a) => {
227
227
  quantity
228
228
  }]
229
229
  });
230
+ bffFbReport === null || bffFbReport === void 0 ? void 0 : bffFbReport({
231
+ eventName: 'sessionCompleted',
232
+ product: product ? [product] : undefined,
233
+ contentType: 'product',
234
+ rec: data,
235
+ position,
236
+ cta_text: 'Add To Cart',
237
+ cta_action_type: 'add_to_cart',
238
+ target_content_id: product === null || product === void 0 ? void 0 : product.itemId,
239
+ target_url: cartUrl
240
+ });
230
241
  window.location.href = cartUrl;
231
242
  }, [selectedVariant, quantity, finalShopifyDomain, bffFbReport, product, data, position]);
232
243
  const totalPrice = useMemo(() => {
@@ -275,7 +286,7 @@ const AddToCartPopup = (_a) => {
275
286
  option.value)))),
276
287
  React.createElement("div", { className: "price-display" },
277
288
  React.createElement("span", { className: "price-value", style: variantStyles.price, dangerouslySetInnerHTML: {
278
- __html: setFontForText(`${selectedVariant.price.currencyCode} $${totalPrice}`, variantStyles.price)
289
+ __html: setFontForText(selectedVariant ? `${getCurrencySymbol(selectedVariant.price.currencyCode)}${totalPrice}` : totalPrice, variantStyles.price)
279
290
  } })),
280
291
  React.createElement("div", { className: "quantity-selector-wrapper", style: quantityStyle },
281
292
  React.createElement("button", { className: "quantity-btn quantity-decrease", onClick: () => handleQuantityChange(-1), disabled: quantity <= 1, "aria-label": "Decrease quantity" }, "-"),
@@ -39,25 +39,30 @@ const CommodityDetail = (_a) => {
39
39
  }
40
40
  const handleLink = (e) => {
41
41
  if (enableAddToCart && addToCartPopupId) {
42
- setPopupDetailData === null || setPopupDetailData === void 0 ? void 0 : setPopupDetailData(Object.assign(Object.assign({}, data), { index: position }));
43
- bffFbReport === null || bffFbReport === void 0 ? void 0 : bffFbReport({
44
- eventName: 'ClickCTA',
45
- product: product ? [product] : undefined,
46
- contentType: 'product',
47
- data,
48
- position,
49
- cta_text: cta === null || cta === void 0 ? void 0 : cta.enTitle,
50
- cta_action_type: 'open_internal_popup',
51
- target_content_id: product === null || product === void 0 ? void 0 : product.itemId
52
- });
53
- console.log('[CommodityDetail] 打开加购弹窗:', addToCartPopupId);
54
- if (typeof window !== 'undefined' && window.sxpPopup) {
55
- window.sxpPopup(addToCartPopupId);
42
+ if (!(product === null || product === void 0 ? void 0 : product.shopifyId)) {
43
+ console.warn('[CommodityDetail] Shopify 商品,跳过加购弹窗');
56
44
  }
57
45
  else {
58
- console.warn('[CommodityDetail] sxpPopup 方法不存在');
46
+ setPopupDetailData === null || setPopupDetailData === void 0 ? void 0 : setPopupDetailData(Object.assign(Object.assign({}, data), { index: position }));
47
+ bffFbReport === null || bffFbReport === void 0 ? void 0 : bffFbReport({
48
+ eventName: 'ClickCTA',
49
+ product: product ? [product] : undefined,
50
+ contentType: 'product',
51
+ data,
52
+ position,
53
+ cta_text: cta === null || cta === void 0 ? void 0 : cta.enTitle,
54
+ cta_action_type: 'open_internal_popup',
55
+ target_content_id: product === null || product === void 0 ? void 0 : product.itemId
56
+ });
57
+ console.log('[CommodityDetail] 打开加购弹窗:', addToCartPopupId);
58
+ if (typeof window !== 'undefined' && window.sxpPopup) {
59
+ window.sxpPopup(addToCartPopupId);
60
+ }
61
+ else {
62
+ console.warn('[CommodityDetail] sxpPopup 方法不存在');
63
+ }
64
+ return;
59
65
  }
60
- return;
61
66
  }
62
67
  if (product === null || product === void 0 ? void 0 : product.link) {
63
68
  jumpToWeb(e, data, product, cta, position);
@@ -41,6 +41,31 @@ const CommodityDetailDiroNew = (_a) => {
41
41
  }
42
42
  const handleLink = (e) => {
43
43
  e.preventDefault();
44
+ if (!(product === null || product === void 0 ? void 0 : product.shopifyId)) {
45
+ console.warn('[CommodityDetailDiroNew] 非 Shopify 商品,跳转到外链');
46
+ ctaEvent === null || ctaEvent === void 0 ? void 0 : ctaEvent({
47
+ eventSubject: 'clickCta',
48
+ eventDescription: 'User clicked the CTA'
49
+ }, data, product, position);
50
+ bffFbReport === null || bffFbReport === void 0 ? void 0 : bffFbReport({
51
+ eventName: 'ClickCTA',
52
+ product: product ? [product] : undefined,
53
+ contentType: 'product',
54
+ data,
55
+ position,
56
+ cta_text: cta === null || cta === void 0 ? void 0 : cta.enTitle,
57
+ cta_action_type: 'open_external_link',
58
+ target_content_id: product === null || product === void 0 ? void 0 : product.itemId,
59
+ target_url: product === null || product === void 0 ? void 0 : product.link
60
+ });
61
+ if (!isPost) {
62
+ productView(data, product, cta, viewTime || curTimeRef.current, position);
63
+ }
64
+ if (product === null || product === void 0 ? void 0 : product.link) {
65
+ window.location.href = window.getJointUtmLink(product.link);
66
+ }
67
+ return;
68
+ }
44
69
  ctaEvent === null || ctaEvent === void 0 ? void 0 : ctaEvent({
45
70
  eventSubject: 'clickCta',
46
71
  eventDescription: 'User clicked the CTA'
@@ -12,7 +12,7 @@ export interface IEventTimeType {
12
12
  time: Date;
13
13
  target: EventTarget;
14
14
  }
15
- export type ICapiEventNameType = 'PageView' | 'ProductView' | 'ViewContent' | 'ClickCTA' | 'ContentSwipe' | 'Engagement' | 'ExitFeed' | 'AddToCart';
15
+ export type ICapiEventNameType = 'PageView' | 'ProductView' | 'ViewContent' | 'ClickCTA' | 'ContentSwipe' | 'Engagement' | 'ExitFeed' | 'AddToCart' | 'sessionCompleted';
16
16
  export interface ISxpDataSourceContext {
17
17
  rtcList: RecItemType[];
18
18
  setRtcList?: React.Dispatch<React.SetStateAction<RecItemType[]>>;
@@ -3,3 +3,9 @@ export type { IEditorCoreRef } from './context/EditorContext';
3
3
  export type { MaterialComponet } from './create';
4
4
  export { default as StructurePage } from './components/StructurePage';
5
5
  export type { IStructurePageProps, IPostData, IProductData, IMultiCtaData, IApiResponse } from './components/StructurePage';
6
+ export * as hooks from './hooks';
7
+ export * from './create';
8
+ export { Pagebuilder } from './Pagebuilder';
9
+ export * as localStore from './utils/localStore';
10
+ export * as sessionStore from './utils/sessionStore';
11
+ export * as tool from './utils/tool';
package/lib/core/index.js CHANGED
@@ -1,10 +1,15 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.StructurePage = exports.EditorCore = void 0;
3
+ exports.tool = exports.sessionStore = exports.localStore = exports.Pagebuilder = exports.hooks = exports.StructurePage = exports.EditorCore = void 0;
4
+ const tslib_1 = require("tslib");
7
5
  var EditorContext_1 = require("./context/EditorContext");
8
6
  Object.defineProperty(exports, "EditorCore", { enumerable: true, get: function () { return EditorContext_1.EditorCore; } });
9
7
  var StructurePage_1 = require("./components/StructurePage");
10
- Object.defineProperty(exports, "StructurePage", { enumerable: true, get: function () { return __importDefault(StructurePage_1).default; } });
8
+ Object.defineProperty(exports, "StructurePage", { enumerable: true, get: function () { return tslib_1.__importDefault(StructurePage_1).default; } });
9
+ exports.hooks = tslib_1.__importStar(require("./hooks"));
10
+ tslib_1.__exportStar(require("./create"), exports);
11
+ var Pagebuilder_1 = require("./Pagebuilder");
12
+ Object.defineProperty(exports, "Pagebuilder", { enumerable: true, get: function () { return Pagebuilder_1.Pagebuilder; } });
13
+ exports.localStore = tslib_1.__importStar(require("./utils/localStore"));
14
+ exports.sessionStore = tslib_1.__importStar(require("./utils/sessionStore"));
15
+ exports.tool = tslib_1.__importStar(require("./utils/tool"));
@@ -37,7 +37,7 @@ const getBgStyleByImg = (data) => {
37
37
  };
38
38
  exports.getBgStyleByImg = getBgStyleByImg;
39
39
  const getPriceText = ({ product, enableFormattedPrice, globalConfig, isHiddenDef, style }) => {
40
- var _a, _b, _c, _d, _e, _f, _g, _h;
40
+ var _a, _b, _c, _d, _e;
41
41
  let text = '';
42
42
  if ((!(product === null || product === void 0 ? void 0 : product.currency) || !(product === null || product === void 0 ? void 0 : product.price)) && isHiddenDef)
43
43
  return null;
@@ -45,18 +45,41 @@ const getPriceText = ({ product, enableFormattedPrice, globalConfig, isHiddenDef
45
45
  if (typeof price !== 'number')
46
46
  return text;
47
47
  let priceSymbol = globalConfig === null || globalConfig === void 0 ? void 0 : globalConfig.priceSymbol;
48
- let currency = (product === null || product === void 0 ? void 0 : product.currency) ? (_c = (_b = (_a = product === null || product === void 0 ? void 0 : product.currency) === null || _a === void 0 ? void 0 : _a.split('-')[1]) === null || _b === void 0 ? void 0 : _b.toUpperCase()) !== null && _c !== void 0 ? _c : '' : '$';
48
+ let currencyCode = '';
49
+ if (product === null || product === void 0 ? void 0 : product.currency) {
50
+ const parts = product.currency.split('-');
51
+ if (parts.length > 1) {
52
+ const firstPart = parts[0].toUpperCase();
53
+ const secondPart = parts[1].toUpperCase();
54
+ if (/^[A-Z]{3}$/.test(firstPart)) {
55
+ currencyCode = firstPart;
56
+ }
57
+ else if (/^[A-Z]{3}$/.test(secondPart)) {
58
+ currencyCode = secondPart;
59
+ }
60
+ else {
61
+ currencyCode = firstPart;
62
+ }
63
+ }
64
+ else {
65
+ currencyCode = parts[0].toUpperCase();
66
+ }
67
+ }
68
+ else {
69
+ currencyCode = 'USD';
70
+ }
71
+ let currency = (0, tool_1.getCurrencySymbol)(currencyCode);
49
72
  const isToLocStr = enableFormattedPrice === undefined || enableFormattedPrice;
50
73
  let decPic = price === null || price === void 0 ? void 0 : price.toString();
51
74
  if (priceSymbol === null || priceSymbol === void 0 ? void 0 : priceSymbol.showTwoDecimalPoint) {
52
75
  decPic = price === null || price === void 0 ? void 0 : price.toFixed(2);
53
76
  }
54
- let decInd = (_d = decPic === null || decPic === void 0 ? void 0 : decPic.indexOf('.')) !== null && _d !== void 0 ? _d : -1;
77
+ let decInd = (_a = decPic === null || decPic === void 0 ? void 0 : decPic.indexOf('.')) !== null && _a !== void 0 ? _a : -1;
55
78
  if (isToLocStr) {
56
79
  text =
57
- (_e = price === null || price === void 0 ? void 0 : price.toLocaleString('zh', {
80
+ (_b = price === null || price === void 0 ? void 0 : price.toLocaleString('zh', {
58
81
  minimumFractionDigits: (priceSymbol === null || priceSymbol === void 0 ? void 0 : priceSymbol.showTwoDecimalPoint) ? 2 : 0
59
- })) !== null && _e !== void 0 ? _e : '';
82
+ })) !== null && _b !== void 0 ? _b : '';
60
83
  let startIndex = 0;
61
84
  let endIndex = decInd !== null && decInd !== void 0 ? decInd : text === null || text === void 0 ? void 0 : text.length;
62
85
  if ((priceSymbol === null || priceSymbol === void 0 ? void 0 : priceSymbol.millesimalSymbol) === '.') {
@@ -86,7 +109,7 @@ const getPriceText = ({ product, enableFormattedPrice, globalConfig, isHiddenDef
86
109
  }
87
110
  });
88
111
  }
89
- currency = `<span style="font-family:${(_h = (_g = (_f = globalConfig === null || globalConfig === void 0 ? void 0 : globalConfig.priceSymbol) === null || _f === void 0 ? void 0 : _f.fontFamily) !== null && _g !== void 0 ? _g : style === null || style === void 0 ? void 0 : style['fontFamily-en']) !== null && _h !== void 0 ? _h : 'inherit'}">${currency}</span>`;
112
+ currency = `<span style="font-family:${(_e = (_d = (_c = globalConfig === null || globalConfig === void 0 ? void 0 : globalConfig.priceSymbol) === null || _c === void 0 ? void 0 : _c.fontFamily) !== null && _d !== void 0 ? _d : style === null || style === void 0 ? void 0 : style['fontFamily-en']) !== null && _e !== void 0 ? _e : 'inherit'}">${currency}</span>`;
90
113
  text = (0, tool_1.setFontForText)(text, style);
91
114
  if ((priceSymbol === null || priceSymbol === void 0 ? void 0 : priceSymbol.currencyPosition) && (priceSymbol === null || priceSymbol === void 0 ? void 0 : priceSymbol.currencyPosition) !== 'none') {
92
115
  text = (priceSymbol === null || priceSymbol === void 0 ? void 0 : priceSymbol.currencyPosition) === 'left' ? currency + text : text + currency;
@@ -16,4 +16,5 @@ declare function splitUrlParams(urlParams: string): string[] | undefined;
16
16
  declare function deleteCookie(name: string, path?: string, domain?: string): void;
17
17
  declare function setCookie(name: string, value: string, days?: number, path?: string, domain?: string, secure?: boolean, sameSite?: string): void;
18
18
  declare function getUrlParamByKey(key: string): any;
19
+ export declare function getCurrencySymbol(currencyCode: string): string;
19
20
  export { uuid, getIndexByblockType, getBrowserInfo, getDevice, getSystem, getCookie, getScreenReader, splitUrlParams, deleteCookie, setCookie, getUrlParamByKey };
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getUrlParamByKey = exports.setCookie = exports.deleteCookie = exports.splitUrlParams = exports.getScreenReader = exports.getCookie = exports.getSystem = exports.getDevice = exports.getBrowserInfo = exports.getIndexByblockType = exports.uuid = exports.setFontForText = exports.getUid = exports.generateRandomString = void 0;
3
+ exports.getUrlParamByKey = exports.setCookie = exports.deleteCookie = exports.splitUrlParams = exports.getScreenReader = exports.getCookie = exports.getSystem = exports.getDevice = exports.getBrowserInfo = exports.getIndexByblockType = exports.uuid = exports.getCurrencySymbol = exports.setFontForText = exports.getUid = exports.generateRandomString = void 0;
4
4
  const uuid_1 = require("uuid");
5
5
  function uuid(len, radix) {
6
6
  const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
@@ -250,3 +250,47 @@ function getUrlParamByKey(key) {
250
250
  return (_b = params[key]) !== null && _b !== void 0 ? _b : '';
251
251
  }
252
252
  exports.getUrlParamByKey = getUrlParamByKey;
253
+ function getCurrencySymbol(currencyCode) {
254
+ const currencySymbolMap = {
255
+ USD: '$',
256
+ EUR: '€',
257
+ GBP: '£',
258
+ JPY: '¥',
259
+ CNY: '¥',
260
+ KRW: '₩',
261
+ INR: '₹',
262
+ RUB: '₽',
263
+ BRL: 'R$',
264
+ CAD: 'CA$',
265
+ AUD: 'A$',
266
+ CHF: 'CHF',
267
+ SEK: 'kr',
268
+ NOK: 'kr',
269
+ DKK: 'kr',
270
+ PLN: 'zł',
271
+ THB: '฿',
272
+ IDR: 'Rp',
273
+ MYR: 'RM',
274
+ PHP: '₱',
275
+ SGD: 'S$',
276
+ HKD: 'HK$',
277
+ TWD: 'NT$',
278
+ NZD: 'NZ$',
279
+ MXN: 'MX$',
280
+ ZAR: 'R',
281
+ TRY: '₺',
282
+ AED: 'AED',
283
+ SAR: 'SAR',
284
+ ILS: '₪',
285
+ ARS: 'AR$',
286
+ CLP: 'CL$',
287
+ COP: 'CO$',
288
+ VND: '₫',
289
+ EGP: 'E£',
290
+ NGN: '₦',
291
+ PKR: '₨',
292
+ BDT: '৳',
293
+ };
294
+ return currencySymbolMap[currencyCode.toUpperCase()] || currencyCode;
295
+ }
296
+ exports.getCurrencySymbol = getCurrencySymbol;