pb-sxp-ui 1.20.26 → 1.20.27

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 (42) hide show
  1. package/dist/index.cjs +292 -395
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.css +355 -291
  4. package/dist/index.js +292 -395
  5. package/dist/index.js.map +1 -1
  6. package/dist/index.min.cjs +6 -6
  7. package/dist/index.min.cjs.map +1 -1
  8. package/dist/index.min.js +6 -6
  9. package/dist/index.min.js.map +1 -1
  10. package/dist/pb-ui.js +292 -395
  11. package/dist/pb-ui.js.map +1 -1
  12. package/dist/pb-ui.min.js +6 -6
  13. package/dist/pb-ui.min.js.map +1 -1
  14. package/es/core/components/StructurePage/index.d.ts +4 -0
  15. package/es/core/components/StructurePage/index.js +8 -1
  16. package/es/core/components/SxpPageRender/Modal/index.d.ts +1 -0
  17. package/es/core/components/SxpPageRender/Modal/index.js +3 -3
  18. package/es/core/components/SxpPageRender/index.d.ts +1 -0
  19. package/es/core/components/SxpPageRender/typing.d.ts +1 -0
  20. package/es/materials/sxp/popup/AddToCart/index.d.ts +1 -27
  21. package/es/materials/sxp/popup/AddToCart/index.js +117 -173
  22. package/es/materials/sxp/popup/AddToCart/index.new.d.ts +8 -0
  23. package/es/materials/sxp/popup/AddToCart/index.new.js +174 -0
  24. package/es/materials/sxp/popup/AddToCart/index.old.d.ts +33 -0
  25. package/es/materials/sxp/popup/AddToCart/index.old.js +299 -0
  26. package/es/materials/sxp/popup/AddToCart/material.js +1 -54
  27. package/es/materials/sxp/popup/CommodityDetailDiroNew/index.js +48 -53
  28. package/lib/core/components/StructurePage/index.d.ts +4 -0
  29. package/lib/core/components/StructurePage/index.js +8 -1
  30. package/lib/core/components/SxpPageRender/Modal/index.d.ts +1 -0
  31. package/lib/core/components/SxpPageRender/Modal/index.js +3 -3
  32. package/lib/core/components/SxpPageRender/index.d.ts +1 -0
  33. package/lib/core/components/SxpPageRender/typing.d.ts +1 -0
  34. package/lib/materials/sxp/popup/AddToCart/index.d.ts +1 -27
  35. package/lib/materials/sxp/popup/AddToCart/index.js +115 -171
  36. package/lib/materials/sxp/popup/AddToCart/index.new.d.ts +8 -0
  37. package/lib/materials/sxp/popup/AddToCart/index.new.js +176 -0
  38. package/lib/materials/sxp/popup/AddToCart/index.old.d.ts +33 -0
  39. package/lib/materials/sxp/popup/AddToCart/index.old.js +301 -0
  40. package/lib/materials/sxp/popup/AddToCart/material.js +1 -54
  41. package/lib/materials/sxp/popup/CommodityDetailDiroNew/index.js +48 -53
  42. package/package.json +1 -1
@@ -0,0 +1,301 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const react_1 = tslib_1.__importStar(require("react"));
5
+ const hooks_1 = require("../../../../core/hooks");
6
+ const useEventReport_1 = require("../../../../core/hooks/useEventReport");
7
+ const tool_1 = require("../../../../core/utils/tool");
8
+ require("./index.less");
9
+ const AddToCartPopup = (_a) => {
10
+ var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q;
11
+ var { style, isActive = true, index, shopifyDomain = '', storefrontAccessToken = '', variantStyles = {}, buttonStyle = {}, quantityStyle = {}, texts = {}, popupBg = {} } = _a, props = tslib_1.__rest(_a, ["style", "isActive", "index", "shopifyDomain", "storefrontAccessToken", "variantStyles", "buttonStyle", "quantityStyle", "texts", "popupBg"]);
12
+ const { sxpParameter, popupDetailData, isPreview, bffFbReport, globalConfig } = (0, hooks_1.useSxpDataSource)();
13
+ const { jumpToWeb } = (0, useEventReport_1.useEventReport)();
14
+ const curTimeRef = (0, react_1.useRef)(null);
15
+ const [productData, setProductData] = (0, react_1.useState)(null);
16
+ const [selectedOptions, setSelectedOptions] = (0, react_1.useState)({});
17
+ const [selectedVariant, setSelectedVariant] = (0, react_1.useState)(null);
18
+ const [quantity, setQuantity] = (0, react_1.useState)(1);
19
+ const [loading, setLoading] = (0, react_1.useState)(true);
20
+ const [error, setError] = (0, react_1.useState)(null);
21
+ const data = popupDetailData;
22
+ const product = (_f = (_c = (_b = data === null || data === void 0 ? void 0 : data.video) === null || _b === void 0 ? void 0 : _b.bindProduct) !== null && _c !== void 0 ? _c : (_e = (_d = data === null || data === void 0 ? void 0 : data.video) === null || _d === void 0 ? void 0 : _d.bindProducts) === null || _e === void 0 ? void 0 : _e[0]) !== null && _f !== void 0 ? _f : data === null || data === void 0 ? void 0 : data.product;
23
+ const cta = product === null || product === void 0 ? void 0 : product.bindCta;
24
+ const position = (_h = (_g = popupDetailData === null || popupDetailData === void 0 ? void 0 : popupDetailData.index) !== null && _g !== void 0 ? _g : index) !== null && _h !== void 0 ? _h : 0;
25
+ console.log('[AddToCartPopup] 组件挂载,数据:', {
26
+ popupDetailData,
27
+ 'video.bindProduct': (_j = data === null || data === void 0 ? void 0 : data.video) === null || _j === void 0 ? void 0 : _j.bindProduct,
28
+ 'video.bindProducts[0]': (_l = (_k = data === null || data === void 0 ? void 0 : data.video) === null || _k === void 0 ? void 0 : _k.bindProducts) === null || _l === void 0 ? void 0 : _l[0],
29
+ 'data.product': data === null || data === void 0 ? void 0 : data.product,
30
+ product,
31
+ isActive
32
+ });
33
+ const shopifyConfig = window.__SHOPIFY_CONFIG__;
34
+ const finalShopifyDomain = shopifyDomain ||
35
+ (globalConfig === null || globalConfig === void 0 ? void 0 : globalConfig.shopifyDomain) ||
36
+ (shopifyConfig === null || shopifyConfig === void 0 ? void 0 : shopifyConfig.domain) ||
37
+ 'dev-store-749237498237498636.myshopify.com';
38
+ const finalStorefrontToken = storefrontAccessToken ||
39
+ (globalConfig === null || globalConfig === void 0 ? void 0 : globalConfig.storefrontAccessToken) ||
40
+ (shopifyConfig === null || shopifyConfig === void 0 ? void 0 : shopifyConfig.storefrontAccessToken) ||
41
+ '77d894c490f79430ce7bd0a7efdff6b7';
42
+ const productId = (product === null || product === void 0 ? void 0 : product.shopifyId) || (product === null || product === void 0 ? void 0 : product.itemId) || '';
43
+ console.log('[AddToCartPopup] Shopify 配置:', {
44
+ productId,
45
+ finalShopifyDomain,
46
+ hasToken: !!finalStorefrontToken,
47
+ shopifyConfig
48
+ });
49
+ const finalTexts = {
50
+ addToCart: texts.addToCart || 'Add to Cart',
51
+ selectOptions: texts.selectOptions || 'Please select options',
52
+ loading: texts.loading || 'Loading...',
53
+ error: texts.error || 'Failed to load product',
54
+ color: texts.color || 'Color',
55
+ size: texts.size || 'Size',
56
+ material: texts.material || 'Material',
57
+ style: texts.style || 'Style'
58
+ };
59
+ const fetchProductData = (0, react_1.useCallback)(() => tslib_1.__awaiter(void 0, void 0, void 0, function* () {
60
+ var _r;
61
+ if (!productId || !finalShopifyDomain || !finalStorefrontToken) {
62
+ console.log('[AddToCartPopup] 缺少必要配置:', {
63
+ productId,
64
+ shopifyDomain: finalShopifyDomain,
65
+ hasToken: !!finalStorefrontToken
66
+ });
67
+ setLoading(false);
68
+ return;
69
+ }
70
+ console.log('[AddToCartPopup] 开始加载商品数据:', {
71
+ productId,
72
+ shopifyDomain: finalShopifyDomain
73
+ });
74
+ setLoading(true);
75
+ setError(null);
76
+ try {
77
+ const query = `
78
+ query getProduct($id: ID!) {
79
+ product(id: $id) {
80
+ id
81
+ title
82
+ images(first: 10) {
83
+ edges {
84
+ node {
85
+ url
86
+ }
87
+ }
88
+ }
89
+ options {
90
+ name
91
+ values
92
+ }
93
+ variants(first: 100) {
94
+ edges {
95
+ node {
96
+ id
97
+ title
98
+ availableForSale
99
+ price {
100
+ amount
101
+ currencyCode
102
+ }
103
+ image {
104
+ url
105
+ }
106
+ selectedOptions {
107
+ name
108
+ value
109
+ }
110
+ }
111
+ }
112
+ }
113
+ }
114
+ }
115
+ `;
116
+ const formattedProductId = productId.startsWith('gid://')
117
+ ? productId
118
+ : `gid://shopify/Product/${productId}`;
119
+ console.log('[AddToCartPopup] 使用的 Product ID:', formattedProductId);
120
+ const response = yield fetch(`https://${finalShopifyDomain}/api/2024-01/graphql.json`, {
121
+ method: 'POST',
122
+ headers: {
123
+ 'Content-Type': 'application/json',
124
+ 'X-Shopify-Storefront-Access-Token': finalStorefrontToken
125
+ },
126
+ body: JSON.stringify({
127
+ query,
128
+ variables: { id: formattedProductId }
129
+ })
130
+ });
131
+ if (!response.ok) {
132
+ throw new Error(`HTTP ${response.status}`);
133
+ }
134
+ const result = yield response.json();
135
+ if (result.errors) {
136
+ console.error('[AddToCartPopup] GraphQL 错误:', result.errors);
137
+ throw new Error(result.errors[0].message);
138
+ }
139
+ if (!((_r = result.data) === null || _r === void 0 ? void 0 : _r.product)) {
140
+ console.error('[AddToCartPopup] 未找到商品');
141
+ throw new Error('Product not found');
142
+ }
143
+ console.log('[AddToCartPopup] 商品数据加载成功:', result.data.product.title);
144
+ setProductData(result.data.product);
145
+ }
146
+ catch (err) {
147
+ const errorMessage = err instanceof Error ? err.message : finalTexts.error;
148
+ setError(errorMessage);
149
+ console.error('[AddToCartPopup] 加载失败:', err);
150
+ }
151
+ finally {
152
+ setLoading(false);
153
+ }
154
+ }), [productId, finalShopifyDomain, finalStorefrontToken, finalTexts.error]);
155
+ (0, react_1.useEffect)(() => {
156
+ if (isActive) {
157
+ fetchProductData();
158
+ }
159
+ }, [isActive, fetchProductData]);
160
+ (0, react_1.useEffect)(() => {
161
+ if (!productData)
162
+ return;
163
+ const variants = productData.variants.edges.map(edge => edge.node);
164
+ const optionsCount = productData.options.length;
165
+ const selectedCount = Object.keys(selectedOptions).length;
166
+ if (selectedCount === 0 || selectedCount < optionsCount) {
167
+ setSelectedVariant(null);
168
+ return;
169
+ }
170
+ const matchedVariant = variants.find(variant => {
171
+ return variant.selectedOptions.every(option => selectedOptions[option.name] === option.value);
172
+ });
173
+ setSelectedVariant(matchedVariant || null);
174
+ setQuantity(1);
175
+ }, [selectedOptions, productData]);
176
+ const handleOptionSelect = (0, react_1.useCallback)((optionName, value) => {
177
+ setSelectedOptions(prev => {
178
+ const newOptions = Object.assign({}, prev);
179
+ if (newOptions[optionName] === value) {
180
+ delete newOptions[optionName];
181
+ }
182
+ else {
183
+ newOptions[optionName] = value;
184
+ }
185
+ return newOptions;
186
+ });
187
+ }, []);
188
+ const handleQuantityChange = (0, react_1.useCallback)((delta) => {
189
+ setQuantity(prev => {
190
+ var _a;
191
+ const newQuantity = prev + delta;
192
+ const maxQuantity = (_a = selectedVariant === null || selectedVariant === void 0 ? void 0 : selectedVariant.quantityAvailable) !== null && _a !== void 0 ? _a : 999;
193
+ return Math.max(1, Math.min(newQuantity, maxQuantity));
194
+ });
195
+ }, [selectedVariant]);
196
+ const isOptionValueAvailable = (0, react_1.useCallback)((optionName, value) => {
197
+ if (!productData)
198
+ return false;
199
+ const variants = productData.variants.edges.map(edge => edge.node);
200
+ const tempOptions = Object.assign(Object.assign({}, selectedOptions), { [optionName]: value });
201
+ return variants.some(variant => {
202
+ const matches = variant.selectedOptions.every(option => !tempOptions[option.name] || tempOptions[option.name] === option.value);
203
+ const hasStock = variant.quantityAvailable === null || variant.quantityAvailable > 0;
204
+ return matches && variant.availableForSale && hasStock;
205
+ });
206
+ }, [productData, selectedOptions]);
207
+ const handleAddToCart = (0, react_1.useCallback)(() => {
208
+ var _a;
209
+ if (!selectedVariant || quantity === 0)
210
+ return;
211
+ const variantId = selectedVariant.id.split('/').pop();
212
+ const cartUrl = `https://${finalShopifyDomain}/cart/add?id=${variantId}&quantity=${quantity}`;
213
+ console.log('[AddToCartPopup] 加购:', {
214
+ variantId,
215
+ quantity,
216
+ cartUrl
217
+ });
218
+ bffFbReport === null || bffFbReport === void 0 ? void 0 : bffFbReport({
219
+ eventName: 'AddToCart',
220
+ product: product ? [product] : undefined,
221
+ contentType: 'product',
222
+ data,
223
+ position,
224
+ content_id: (_a = product === null || product === void 0 ? void 0 : product.itemId) !== null && _a !== void 0 ? _a : '',
225
+ value: parseFloat(selectedVariant.price.amount) * quantity,
226
+ currency: selectedVariant.price.currencyCode,
227
+ contents: [{
228
+ id: variantId,
229
+ quantity
230
+ }]
231
+ });
232
+ window.location.href = cartUrl;
233
+ }, [selectedVariant, quantity, finalShopifyDomain, bffFbReport, product, data, position]);
234
+ const totalPrice = (0, react_1.useMemo)(() => {
235
+ if (!selectedVariant)
236
+ return null;
237
+ const price = parseFloat(selectedVariant.price.amount);
238
+ const total = price * quantity;
239
+ return total.toFixed(2);
240
+ }, [selectedVariant, quantity]);
241
+ (0, react_1.useEffect)(() => {
242
+ const initTime = () => {
243
+ curTimeRef.current = new Date();
244
+ };
245
+ initTime();
246
+ window.addEventListener('pageshow', initTime);
247
+ return () => {
248
+ window.removeEventListener('pageshow', initTime);
249
+ };
250
+ }, []);
251
+ if (loading) {
252
+ return (react_1.default.createElement("div", { className: "add-to-cart-popup-loading", style: style },
253
+ react_1.default.createElement("div", null, finalTexts.loading)));
254
+ }
255
+ if (error || !productData) {
256
+ return (react_1.default.createElement("div", { className: "add-to-cart-popup-error", style: style },
257
+ react_1.default.createElement("div", null,
258
+ finalTexts.error,
259
+ ": ",
260
+ error || 'Product not found')));
261
+ }
262
+ const mainImage = ((_m = selectedVariant === null || selectedVariant === void 0 ? void 0 : selectedVariant.image) === null || _m === void 0 ? void 0 : _m.url) || ((_o = productData.images.edges[0]) === null || _o === void 0 ? void 0 : _o.node.url) || ((_p = product === null || product === void 0 ? void 0 : product.homePage) === null || _p === void 0 ? void 0 : _p[0]) || '';
263
+ const hasAllOptionsSelected = productData.options.length === Object.keys(selectedOptions).length;
264
+ const isAddToCartDisabled = !selectedVariant || quantity === 0;
265
+ return (react_1.default.createElement("div", Object.assign({ className: "add-to-cart-popup-container", style: style }, props),
266
+ react_1.default.createElement("div", { className: "variant-detail-section" },
267
+ react_1.default.createElement("div", { className: "variant-image-wrapper" },
268
+ react_1.default.createElement("img", { src: mainImage, alt: productData.title, className: "variant-image" })),
269
+ react_1.default.createElement("div", { className: "variant-info-wrapper" },
270
+ react_1.default.createElement("h2", { className: "product-title-text", style: variantStyles.title, dangerouslySetInnerHTML: {
271
+ __html: (0, tool_1.setFontForText)(productData.title, variantStyles.title)
272
+ } }),
273
+ selectedVariant && (react_1.default.createElement(react_1.default.Fragment, null,
274
+ react_1.default.createElement("div", { className: "selected-options-tags" }, selectedVariant.selectedOptions.map(option => (react_1.default.createElement("span", { key: option.name, className: "option-tag", style: variantStyles.selectedOption },
275
+ option.name,
276
+ ": ",
277
+ option.value)))),
278
+ react_1.default.createElement("div", { className: "price-display" },
279
+ react_1.default.createElement("span", { className: "price-value", style: variantStyles.price, dangerouslySetInnerHTML: {
280
+ __html: (0, tool_1.setFontForText)(`${selectedVariant.price.currencyCode} $${totalPrice}`, variantStyles.price)
281
+ } })),
282
+ react_1.default.createElement("div", { className: "quantity-selector-wrapper", style: quantityStyle },
283
+ react_1.default.createElement("button", { className: "quantity-btn quantity-decrease", onClick: () => handleQuantityChange(-1), disabled: quantity <= 1, "aria-label": "Decrease quantity" }, "-"),
284
+ react_1.default.createElement("input", { type: "number", value: quantity, readOnly: true, className: "quantity-input-field", "aria-label": "Quantity" }),
285
+ react_1.default.createElement("button", { className: "quantity-btn quantity-increase", onClick: () => handleQuantityChange(1), disabled: quantity >= ((_q = selectedVariant.quantityAvailable) !== null && _q !== void 0 ? _q : 999), "aria-label": "Increase quantity" }, "+")))),
286
+ !hasAllOptionsSelected && (react_1.default.createElement("div", { className: "no-selection-hint", style: variantStyles.option }, finalTexts.selectOptions)))),
287
+ react_1.default.createElement("div", { className: "variant-options-section" }, productData.options.map(option => (react_1.default.createElement("div", { key: option.name, className: "option-group-wrapper" },
288
+ react_1.default.createElement("h3", { className: "option-group-name", style: variantStyles.option, dangerouslySetInnerHTML: {
289
+ __html: (0, tool_1.setFontForText)(option.name, variantStyles.option)
290
+ } }),
291
+ react_1.default.createElement("div", { className: "option-values-grid" }, option.values.map(value => {
292
+ const isSelected = selectedOptions[option.name] === value;
293
+ const isAvailable = isOptionValueAvailable(option.name, value);
294
+ return (react_1.default.createElement("button", { key: value, className: `option-value-button ${isSelected ? 'selected' : ''} ${!isAvailable ? 'disabled' : ''}`, onClick: () => isAvailable && handleOptionSelect(option.name, value), disabled: !isAvailable, "aria-label": `${option.name}: ${value}`, "aria-pressed": isSelected }, value));
295
+ })))))),
296
+ react_1.default.createElement("button", { className: `add-to-cart-button ${isAddToCartDisabled ? 'disabled' : ''}`, style: buttonStyle, onClick: handleAddToCart, disabled: isAddToCartDisabled, "aria-label": finalTexts.addToCart },
297
+ react_1.default.createElement("span", { dangerouslySetInnerHTML: {
298
+ __html: (0, tool_1.setFontForText)(finalTexts.addToCart, buttonStyle)
299
+ } }))));
300
+ };
301
+ exports.default = AddToCartPopup;
@@ -16,60 +16,7 @@ const AddToCartPopup = (0, create_1.createMaterial)(_1.default, {
16
16
  interactionRender: interactionRender_1.default
17
17
  },
18
18
  defaulSetting: {
19
- props: {
20
- shopifyDomain: '',
21
- storefrontAccessToken: '',
22
- variantStyles: {
23
- title: {
24
- color: '#000',
25
- fontSize: 20,
26
- fontWeight: 600,
27
- marginBottom: 12
28
- },
29
- price: {
30
- color: '#000',
31
- fontSize: 24,
32
- fontWeight: 700,
33
- marginBottom: 16
34
- },
35
- option: {
36
- color: '#111',
37
- fontSize: 16,
38
- fontWeight: 600,
39
- marginBottom: 12
40
- },
41
- selectedOption: {
42
- fontSize: 14,
43
- color: '#374151'
44
- }
45
- },
46
- buttonStyle: {
47
- backgroundColor: '#000',
48
- color: '#fff',
49
- fontSize: 16,
50
- height: 52,
51
- fontWeight: 600,
52
- textAlign: 'center',
53
- textTransform: 'uppercase'
54
- },
55
- quantityStyle: {
56
- gap: 12
57
- },
58
- texts: {
59
- addToCart: 'Add to Cart',
60
- selectOptions: 'Please select options',
61
- loading: 'Loading...',
62
- error: 'Failed to load product',
63
- color: 'Color',
64
- size: 'Size',
65
- material: 'Material',
66
- style: 'Style'
67
- },
68
- popupBg: {
69
- horizontalMargin: 0,
70
- bottomMargin: 0
71
- }
72
- },
19
+ props: {},
73
20
  style: {}
74
21
  },
75
22
  w: 100,
@@ -3,11 +3,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  const css_1 = require("@emotion/css");
5
5
  const react_1 = tslib_1.__importStar(require("react"));
6
- const CommodityGroup_1 = tslib_1.__importDefault(require("../../template/components/CommodityGroup"));
7
- const hooks_1 = require("../../../../core/hooks");
8
- require("./index.less");
9
6
  const modules_1 = require("swiper/modules");
10
7
  const react_2 = require("swiper/react");
8
+ const CommodityGroup_1 = tslib_1.__importDefault(require("../../template/components/CommodityGroup"));
9
+ const AddToCart_1 = tslib_1.__importDefault(require("../AddToCart"));
10
+ const hooks_1 = require("../../../../core/hooks");
11
11
  const Modal_1 = tslib_1.__importDefault(require("../../../../core/components/SxpPageRender/Modal"));
12
12
  const ExpandableText_1 = tslib_1.__importDefault(require("../../../../core/components/SxpPageRender/ExpandableText"));
13
13
  const useEventReport_1 = require("../../../../core/hooks/useEventReport");
@@ -15,18 +15,17 @@ const FormatImage_1 = tslib_1.__importDefault(require("../../../../core/componen
15
15
  const tool_1 = require("../../../../core/utils/tool");
16
16
  const materials_1 = require("../../../../core/utils/materials");
17
17
  const event_1 = tslib_1.__importStar(require("../../../../core/utils/event"));
18
+ require("./index.less");
18
19
  const CommodityDetailDiroNew = (_a) => {
19
- var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4;
20
- var { style, isDefault, rec, viewTime, isPost, bottom_image, tipText, swiper, commodityStyles, buttonStyle, index, commodityGroup, popupBg, iframeIcon, commodityImgRatio, isTel, iframeBgColor, isActive = true } = _a, props = tslib_1.__rest(_a, ["style", "isDefault", "rec", "viewTime", "isPost", "bottom_image", "tipText", "swiper", "commodityStyles", "buttonStyle", "index", "commodityGroup", "popupBg", "iframeIcon", "commodityImgRatio", "isTel", "iframeBgColor", "isActive"]);
21
- const [spread, setSpread] = (0, react_1.useState)(true);
22
- const { sxpParameter, popupCurTimeRef, popupDetailData, isPreview, bffFbReport, checkCommodityIndexRef, globalConfig, ctaEvent } = (0, hooks_1.useSxpDataSource)();
23
- const { jumpToWeb, productView } = (0, useEventReport_1.useEventReport)();
24
- const [stopSlide, setStopSlide] = (0, react_1.useState)(false);
25
- const [isBottom, setIsBottom] = (0, react_1.useState)(false);
26
- const [isTop, setIsTop] = (0, react_1.useState)(true);
20
+ var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5;
21
+ var { style, rec, viewTime, isPost, bottom_image, tipText, swiper, commodityStyles, buttonStyle, index, commodityGroup, popupBg, iframeIcon, commodityImgRatio, iframeBgColor, isActive = true } = _a, props = tslib_1.__rest(_a, ["style", "rec", "viewTime", "isPost", "bottom_image", "tipText", "swiper", "commodityStyles", "buttonStyle", "index", "commodityGroup", "popupBg", "iframeIcon", "commodityImgRatio", "iframeBgColor", "isActive"]);
22
+ const { sxpParameter, popupCurTimeRef, popupDetailData, setPopupDetailData, isPreview, bffFbReport, checkCommodityIndexRef, globalConfig, ctaEvent } = (0, hooks_1.useSxpDataSource)();
23
+ (0, hooks_1.useEditor)();
24
+ const { productView } = (0, useEventReport_1.useEventReport)();
27
25
  const [showModal, setShowModal] = (0, react_1.useState)(false);
28
26
  const curTimeRef = (0, react_1.useRef)(null);
29
27
  const [show3DModal, setShow3DModal] = (0, react_1.useState)(false);
28
+ const [showAddToCart, setShowAddToCart] = (0, react_1.useState)(false);
30
29
  const [checkCommodityIndex, setCheckCommodityIndex] = (0, react_1.useState)((_b = popupDetailData === null || popupDetailData === void 0 ? void 0 : popupDetailData.multiCheckIndex) !== null && _b !== void 0 ? _b : 0);
31
30
  const swiperRef = (0, react_1.useRef)();
32
31
  const [swiperActiveIndex, setSwiperActiveIndex] = (0, react_1.useState)(0);
@@ -43,30 +42,27 @@ const CommodityDetailDiroNew = (_a) => {
43
42
  cta = p === null || p === void 0 ? void 0 : p.bindCta;
44
43
  }
45
44
  const handleLink = (e) => {
46
- if (product === null || product === void 0 ? void 0 : product.link) {
47
- jumpToWeb(e, data, product, cta, position);
48
- if (!isPost) {
49
- productView(data, product, cta, viewTime || curTimeRef.current, position);
50
- }
51
- else {
52
- ctaEvent === null || ctaEvent === void 0 ? void 0 : ctaEvent({
53
- eventSubject: 'clickCta',
54
- eventDescription: 'User clicked the CTA'
55
- }, data, product, position);
56
- bffFbReport === null || bffFbReport === void 0 ? void 0 : bffFbReport({
57
- eventName: 'ClickCTA',
58
- product: product ? [product] : undefined,
59
- contentType: 'product',
60
- data,
61
- position,
62
- cta_text: cta === null || cta === void 0 ? void 0 : cta.enTitle,
63
- cta_action_type: 'open_external_link',
64
- target_content_id: product === null || product === void 0 ? void 0 : product.itemId,
65
- target_url: product.link
66
- });
67
- }
68
- window.location.href = window.getJointUtmLink(product.link);
45
+ e.preventDefault();
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_internal_popup',
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);
69
63
  }
64
+ setPopupDetailData === null || setPopupDetailData === void 0 ? void 0 : setPopupDetailData(Object.assign(Object.assign({}, data), { video: Object.assign(Object.assign({}, data === null || data === void 0 ? void 0 : data.video), { bindProduct: product }), index: position }));
65
+ setShowAddToCart(true);
70
66
  };
71
67
  (0, react_1.useEffect)(() => {
72
68
  var _a, _b;
@@ -87,7 +83,7 @@ const CommodityDetailDiroNew = (_a) => {
87
83
  rec: recData,
88
84
  position
89
85
  });
90
- }, [isActive, bffFbReport, isPost]);
86
+ }, [isActive, bffFbReport, isPost, data, product, position]);
91
87
  (0, react_1.useEffect)(() => {
92
88
  if (!isActive || isPost)
93
89
  return;
@@ -145,9 +141,6 @@ const CommodityDetailDiroNew = (_a) => {
145
141
  });
146
142
  const width = (isPreview ? 375 : (_u = style === null || style === void 0 ? void 0 : style.width) !== null && _u !== void 0 ? _u : window.innerWidth) - ((_v = popupBg === null || popupBg === void 0 ? void 0 : popupBg.horizontalMargin) !== null && _v !== void 0 ? _v : 0) * 2;
147
143
  const height = commodityImgRatio ? width * (commodityImgRatio.h / commodityImgRatio.w) : width;
148
- const handleClickCollapse = () => {
149
- setSpread(!spread);
150
- };
151
144
  const productInfoText = ({ isPost }) => {
152
145
  return (react_1.default.createElement("div", { hidden: !!product && (!(product === null || product === void 0 ? void 0 : product.info) || (product === null || product === void 0 ? void 0 : product.info) === '') },
153
146
  react_1.default.createElement(ExpandableText_1.default, { isPost: isPost, onClick: () => setShowModal(true), className: 'pb-commondityDiroNew-info', style: commodityStyles === null || commodityStyles === void 0 ? void 0 : commodityStyles.info, foldText: tipText === null || tipText === void 0 ? void 0 : tipText.foldText, unfoldText: tipText === null || tipText === void 0 ? void 0 : tipText.unfoldText, text: (product === null || product === void 0 ? void 0 : product.info) ||
@@ -168,13 +161,13 @@ Made in Italy` })));
168
161
  swiperRef.current.swiper.slideTo(0);
169
162
  swiperRef.current.swiper.autoplay.start();
170
163
  }
171
- }, []);
164
+ }, [popupCurTimeRef, checkCommodityIndexRef]);
172
165
  const renderCommodityGroup = (0, react_1.useCallback)(() => {
173
166
  var _a, _b, _c;
174
167
  if (isPost)
175
168
  return;
176
169
  return (react_1.default.createElement(CommodityGroup_1.default, { products: (_a = data === null || data === void 0 ? void 0 : data.video) === null || _a === void 0 ? void 0 : _a.bindProducts, data: commodityGroup, defImg: (_c = (_b = sxpParameter === null || sxpParameter === void 0 ? void 0 : sxpParameter.bottom_image) !== null && _b !== void 0 ? _b : bottom_image) !== null && _c !== void 0 ? _c : '', style: { padding: '0 19px' }, onCLick: handleClick, popupDetailData: popupDetailData, check: checkCommodityIndex }));
177
- }, [checkCommodityIndex]);
170
+ }, [checkCommodityIndex, isPost, (_w = data === null || data === void 0 ? void 0 : data.video) === null || _w === void 0 ? void 0 : _w.bindProducts, commodityGroup, sxpParameter === null || sxpParameter === void 0 ? void 0 : sxpParameter.bottom_image, bottom_image, handleClick, popupDetailData]);
178
171
  const getDotsAlign = (0, react_1.useMemo)(() => {
179
172
  const dotsAlignClass = {
180
173
  left: 'commondityDetail-swiper-clickable-left',
@@ -184,24 +177,24 @@ Made in Italy` })));
184
177
  return dotsAlignClass === null || dotsAlignClass === void 0 ? void 0 : dotsAlignClass[swiper === null || swiper === void 0 ? void 0 : swiper.dotsAlign];
185
178
  }, [swiper === null || swiper === void 0 ? void 0 : swiper.dotsAlign]);
186
179
  const iframeUrl = product === null || product === void 0 ? void 0 : product.remark;
180
+ const isAlly = (0, react_1.useMemo)(() => (0, tool_1.getScreenReader)(), []);
187
181
  const handleMouseEnter = (0, react_1.useCallback)(() => {
188
182
  if (swiperRef.current && swiperRef.current.swiper && isAlly) {
189
183
  swiperRef.current.swiper.autoplay.stop();
190
184
  }
191
- }, []);
185
+ }, [isAlly]);
192
186
  const handleMouseLeave = (0, react_1.useCallback)(() => {
193
187
  if (swiperRef.current && swiperRef.current.swiper && isAlly) {
194
188
  swiperRef.current.swiper.autoplay.start();
195
189
  }
196
- }, []);
190
+ }, [isAlly]);
197
191
  const handleSlideChange = (0, react_1.useCallback)((swiper) => {
198
192
  setSwiperActiveIndex(swiper.activeIndex);
199
193
  }, []);
200
- const isAlly = (0, react_1.useMemo)(() => (0, tool_1.getScreenReader)(), []);
201
194
  return (react_1.default.createElement("div", { className: 'pb-commondityDiroNew' },
202
195
  react_1.default.createElement("div", Object.assign({ className: (0, css_1.css)(Object.assign(Object.assign({}, style), { transform: 'translate3d(0px, 0px, 0px)' })) }, props),
203
196
  react_1.default.createElement("div", { style: { position: 'relative' }, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave },
204
- product && ((_w = product === null || product === void 0 ? void 0 : product.homePage) === null || _w === void 0 ? void 0 : _w.length) > 0 && (react_1.default.createElement(react_2.Swiper, Object.assign({ height: height, modules: [modules_1.Pagination, modules_1.Autoplay, ...(isAlly ? [modules_1.Navigation, modules_1.A11y, modules_1.Mousewheel, modules_1.Keyboard] : [])], pagination: {
197
+ product && ((_x = product === null || product === void 0 ? void 0 : product.homePage) === null || _x === void 0 ? void 0 : _x.length) > 0 && (react_1.default.createElement(react_2.Swiper, Object.assign({ height: height, modules: [modules_1.Pagination, modules_1.Autoplay, ...(isAlly ? [modules_1.Navigation, modules_1.A11y, modules_1.Mousewheel, modules_1.Keyboard] : [])], pagination: {
205
198
  clickable: true,
206
199
  bulletActiveClass: 'swipe-item-active-bullet',
207
200
  clickableClass: getDotsAlign,
@@ -218,7 +211,7 @@ Made in Italy` })));
218
211
  : {}), { loop: true, ref: swiperRef, onSlideChange: handleSlideChange, autoplay: {
219
212
  delay: (swiper === null || swiper === void 0 ? void 0 : swiper.delay) * 1000
220
213
  }, className: (0, css_1.css)(Object.assign(Object.assign({ '.swiper-pagination': {
221
- bottom: (_x = swiper === null || swiper === void 0 ? void 0 : swiper.dotsMarginBottom) !== null && _x !== void 0 ? _x : 0,
214
+ bottom: (_y = swiper === null || swiper === void 0 ? void 0 : swiper.dotsMarginBottom) !== null && _y !== void 0 ? _y : 0,
222
215
  fontSize: '14px'
223
216
  } }, ((swiper === null || swiper === void 0 ? void 0 : swiper.dotsBgColor) && {
224
217
  '.swiper-pagination-bullet': {
@@ -230,7 +223,7 @@ Made in Italy` })));
230
223
  backgroundColor: `${swiper === null || swiper === void 0 ? void 0 : swiper.dotsActiveColor}!important`,
231
224
  opacity: 1
232
225
  }
233
- }))) }), (_y = product === null || product === void 0 ? void 0 : product.homePage) === null || _y === void 0 ? void 0 : _y.map((src, srcKey) => {
226
+ }))) }), (_z = product === null || product === void 0 ? void 0 : product.homePage) === null || _z === void 0 ? void 0 : _z.map((src, srcKey) => {
234
227
  var _a;
235
228
  return (react_1.default.createElement(react_2.SwiperSlide, { key: srcKey, "aria-hidden": srcKey !== swiperActiveIndex },
236
229
  react_1.default.createElement("div", { style: {
@@ -246,7 +239,7 @@ Made in Italy` })));
246
239
  objectPosition: `50% ${(swiper === null || swiper === void 0 ? void 0 : swiper.translateY) ? (swiper === null || swiper === void 0 ? void 0 : swiper.translateY) + 50 : 50}%`
247
240
  }, src: (_a = src !== null && src !== void 0 ? src : sxpParameter === null || sxpParameter === void 0 ? void 0 : sxpParameter.bottom_image) !== null && _a !== void 0 ? _a : bottom_image }))));
248
241
  }))),
249
- !((_z = product === null || product === void 0 ? void 0 : product.homePage) === null || _z === void 0 ? void 0 : _z.length) && (react_1.default.createElement("div", { className: (0, css_1.css)({
242
+ !((_0 = product === null || product === void 0 ? void 0 : product.homePage) === null || _0 === void 0 ? void 0 : _0.length) && (react_1.default.createElement("div", { className: (0, css_1.css)({
250
243
  height,
251
244
  width
252
245
  }) },
@@ -254,7 +247,7 @@ Made in Italy` })));
254
247
  objectFit: 'cover',
255
248
  width: '100%',
256
249
  height: '100%'
257
- }), src: (_0 = sxpParameter === null || sxpParameter === void 0 ? void 0 : sxpParameter.bottom_image) !== null && _0 !== void 0 ? _0 : bottom_image, alt: 'pdp image' }))),
250
+ }), src: (_1 = sxpParameter === null || sxpParameter === void 0 ? void 0 : sxpParameter.bottom_image) !== null && _1 !== void 0 ? _1 : bottom_image, alt: 'pdp image' }))),
258
251
  (iframeUrl || !product) && iframeIcon && (react_1.default.createElement("div", { style: {
259
252
  display: 'flex',
260
253
  alignItems: 'center',
@@ -271,7 +264,7 @@ Made in Italy` })));
271
264
  react_1.default.createElement("div", { className: 'pb-commondityDiroNew-content-top' },
272
265
  react_1.default.createElement("div", { className: 'pb-commondityDiroNew-content-top-left' },
273
266
  react_1.default.createElement("div", { className: 'pb-commondityDiroNew-content-top-left-title', style: getStyle(commodityStyles === null || commodityStyles === void 0 ? void 0 : commodityStyles.title), dangerouslySetInnerHTML: {
274
- __html: (0, tool_1.setFontForText)((_1 = product === null || product === void 0 ? void 0 : product.title) !== null && _1 !== void 0 ? _1 : 'Large Dior Toujours BagLarge', commodityStyles === null || commodityStyles === void 0 ? void 0 : commodityStyles.title)
267
+ __html: (0, tool_1.setFontForText)((_2 = product === null || product === void 0 ? void 0 : product.title) !== null && _2 !== void 0 ? _2 : 'Large Dior Toujours BagLarge', commodityStyles === null || commodityStyles === void 0 ? void 0 : commodityStyles.title)
275
268
  } }),
276
269
  react_1.default.createElement("div", { className: 'pb-commondityDiroNew-content-collection', hidden: !!product && (!(product === null || product === void 0 ? void 0 : product.collection) || (product === null || product === void 0 ? void 0 : product.collection) === ''), style: getStyle(commodityStyles === null || commodityStyles === void 0 ? void 0 : commodityStyles.collection), dangerouslySetInnerHTML: {
277
270
  __html: (0, tool_1.setFontForText)((product === null || product === void 0 ? void 0 : product.collection) || 'Black Macrocannage CalfskinLarge', commodityStyles === null || commodityStyles === void 0 ? void 0 : commodityStyles.collection)
@@ -281,11 +274,11 @@ Made in Italy` })));
281
274
  __html: priceText !== null && priceText !== void 0 ? priceText : ''
282
275
  } }),
283
276
  react_1.default.createElement("div", { className: 'pb-commondityDiroNew-content-top-right-price', hidden: !!product && !(product === null || product === void 0 ? void 0 : product.taxInfo), style: getStyle(commodityStyles === null || commodityStyles === void 0 ? void 0 : commodityStyles.taxInfo), dangerouslySetInnerHTML: {
284
- __html: (0, tool_1.setFontForText)((_2 = product === null || product === void 0 ? void 0 : product.taxInfo) !== null && _2 !== void 0 ? _2 : '税费', commodityStyles === null || commodityStyles === void 0 ? void 0 : commodityStyles.taxInfo)
277
+ __html: (0, tool_1.setFontForText)((_3 = product === null || product === void 0 ? void 0 : product.taxInfo) !== null && _3 !== void 0 ? _3 : '税费', commodityStyles === null || commodityStyles === void 0 ? void 0 : commodityStyles.taxInfo)
285
278
  } }))),
286
- react_1.default.createElement("a", { "aria-label": (_3 = cta === null || cta === void 0 ? void 0 : cta.enTitle) !== null && _3 !== void 0 ? _3 : 'Shop now', role: 'button', tabIndex: 0, onClick: handleLink, className: 'pb-commondityDiroNew-btn', style: buttonStyle },
279
+ react_1.default.createElement("a", { "aria-label": (_4 = cta === null || cta === void 0 ? void 0 : cta.enTitle) !== null && _4 !== void 0 ? _4 : 'Shop now', role: 'button', tabIndex: 0, onClick: handleLink, className: 'pb-commondityDiroNew-btn', style: buttonStyle },
287
280
  react_1.default.createElement("span", { dangerouslySetInnerHTML: {
288
- __html: (0, tool_1.setFontForText)((_4 = cta === null || cta === void 0 ? void 0 : cta.enTitle) !== null && _4 !== void 0 ? _4 : 'Shop now', buttonStyle)
281
+ __html: (0, tool_1.setFontForText)((_5 = cta === null || cta === void 0 ? void 0 : cta.enTitle) !== null && _5 !== void 0 ? _5 : 'Shop now', buttonStyle)
289
282
  } })),
290
283
  productInfoText({ isPost }))),
291
284
  react_1.default.createElement(Modal_1.default, { visible: showModal, onClose: () => setShowModal(false) },
@@ -297,6 +290,8 @@ Made in Italy` })));
297
290
  height: 'calc(100% - 50px)',
298
291
  marginTop: '50px',
299
292
  border: 'none'
300
- } })))));
293
+ } }))),
294
+ showAddToCart && (react_1.default.createElement(Modal_1.default, { visible: showAddToCart, padding: 0, isFullScreen: false, onClose: () => setShowAddToCart(false) },
295
+ react_1.default.createElement(AddToCart_1.default, { isActive: true })))));
301
296
  };
302
297
  exports.default = (0, react_1.memo)(CommodityDetailDiroNew);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pb-sxp-ui",
3
- "version": "1.20.26",
3
+ "version": "1.20.27",
4
4
  "description": "React enterprise-class UI components",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",