pb-sxp-ui 1.20.18 → 1.20.20

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 (46) hide show
  1. package/dist/index.cjs +737 -26
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.css +291 -0
  4. package/dist/index.js +737 -26
  5. package/dist/index.js.map +1 -1
  6. package/dist/index.min.cjs +44 -5
  7. package/dist/index.min.cjs.map +1 -1
  8. package/dist/index.min.js +44 -5
  9. package/dist/index.min.js.map +1 -1
  10. package/dist/pb-ui.js +737 -26
  11. package/dist/pb-ui.js.map +1 -1
  12. package/dist/pb-ui.min.js +44 -5
  13. package/dist/pb-ui.min.js.map +1 -1
  14. package/es/core/components/SxpPageRender/index.d.ts +2 -0
  15. package/es/core/context/SxpDataSourceProvider.d.ts +1 -1
  16. package/es/materials/sxp/popup/AddToCart/index.d.ts +33 -0
  17. package/es/materials/sxp/popup/AddToCart/index.js +279 -0
  18. package/es/materials/sxp/popup/AddToCart/interactionRender.d.ts +3 -0
  19. package/es/materials/sxp/popup/AddToCart/interactionRender.js +11 -0
  20. package/es/materials/sxp/popup/AddToCart/material.d.ts +2 -0
  21. package/es/materials/sxp/popup/AddToCart/material.js +75 -0
  22. package/es/materials/sxp/popup/AddToCart/settingRender.d.ts +160 -0
  23. package/es/materials/sxp/popup/AddToCart/settingRender.js +277 -0
  24. package/es/materials/sxp/popup/CommodityDetail/index.d.ts +2 -0
  25. package/es/materials/sxp/popup/CommodityDetail/index.js +30 -2
  26. package/es/materials/sxp/popup/CommodityDetail/settingRender.d.ts +13 -0
  27. package/es/materials/sxp/popup/CommodityDetail/settingRender.js +16 -0
  28. package/es/materials/sxp/popup/index.d.ts +1 -0
  29. package/es/materials/sxp/popup/index.js +1 -0
  30. package/lib/core/components/SxpPageRender/index.d.ts +2 -0
  31. package/lib/core/context/SxpDataSourceProvider.d.ts +1 -1
  32. package/lib/materials/sxp/popup/AddToCart/index.d.ts +33 -0
  33. package/lib/materials/sxp/popup/AddToCart/index.js +281 -0
  34. package/lib/materials/sxp/popup/AddToCart/interactionRender.d.ts +3 -0
  35. package/lib/materials/sxp/popup/AddToCart/interactionRender.js +14 -0
  36. package/lib/materials/sxp/popup/AddToCart/material.d.ts +2 -0
  37. package/lib/materials/sxp/popup/AddToCart/material.js +79 -0
  38. package/lib/materials/sxp/popup/AddToCart/settingRender.d.ts +160 -0
  39. package/lib/materials/sxp/popup/AddToCart/settingRender.js +279 -0
  40. package/lib/materials/sxp/popup/CommodityDetail/index.d.ts +2 -0
  41. package/lib/materials/sxp/popup/CommodityDetail/index.js +30 -2
  42. package/lib/materials/sxp/popup/CommodityDetail/settingRender.d.ts +13 -0
  43. package/lib/materials/sxp/popup/CommodityDetail/settingRender.js +16 -0
  44. package/lib/materials/sxp/popup/index.d.ts +1 -0
  45. package/lib/materials/sxp/popup/index.js +1 -0
  46. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -2766,7 +2766,7 @@ var index$3 = /*#__PURE__*/Object.freeze({
2766
2766
  StructurePage: StructurePage
2767
2767
  });
2768
2768
 
2769
- var interactionRender$h = [
2769
+ var interactionRender$i = [
2770
2770
  {
2771
2771
  title: '点击事件',
2772
2772
  child: [
@@ -2786,7 +2786,7 @@ var interactionRender$h = [
2786
2786
  * @FilePath: \pb-sxp-ui\src\materials\sxp\popup\AppointForm\settingRender.tsx
2787
2787
  *
2788
2788
  */
2789
- var settingRender$f = [
2789
+ var settingRender$g = [
2790
2790
  {
2791
2791
  title: '弹窗背景',
2792
2792
  child: [
@@ -3223,9 +3223,9 @@ const AppointForm = createMaterial(AppointFormComponent, {
3223
3223
  category: 'popup',
3224
3224
  type: 'AppointForm',
3225
3225
  related: {
3226
- settingRender: settingRender$f,
3226
+ settingRender: settingRender$g,
3227
3227
  bindableProps: [],
3228
- interactionRender: interactionRender$h
3228
+ interactionRender: interactionRender$i
3229
3229
  },
3230
3230
  defaulSetting: {
3231
3231
  name: '表单',
@@ -3248,7 +3248,7 @@ const AppointForm = createMaterial(AppointFormComponent, {
3248
3248
  sort: 2
3249
3249
  });
3250
3250
 
3251
- var settingRender$e = [
3251
+ var settingRender$f = [
3252
3252
  {
3253
3253
  title: '弹窗背景',
3254
3254
  child: [
@@ -3646,6 +3646,22 @@ var settingRender$e = [
3646
3646
  name: ['props', 'enableFixedCloseButton']
3647
3647
  }
3648
3648
  ]
3649
+ },
3650
+ {
3651
+ title: '加购功能',
3652
+ child: [
3653
+ {
3654
+ label: '启用加购弹窗',
3655
+ type: 'Switch',
3656
+ name: ['props', 'enableAddToCart']
3657
+ },
3658
+ {
3659
+ label: '加购弹窗ID',
3660
+ type: 'Input',
3661
+ name: ['props', 'addToCartPopupId'],
3662
+ placeholder: '请输入加购弹窗的ID'
3663
+ }
3664
+ ]
3649
3665
  }
3650
3666
  ];
3651
3667
 
@@ -3665,7 +3681,7 @@ var settingRender$e = [
3665
3681
  * @FilePath: \pb-sxp-ui\src\materials\sxp\cta\AniLink\interactionRender.tsx
3666
3682
  *
3667
3683
  */
3668
- var interactionRender$g = [
3684
+ var interactionRender$h = [
3669
3685
  {
3670
3686
  title: '滑动事件',
3671
3687
  child: [
@@ -11643,8 +11659,8 @@ const getPriceText = ({ product, enableFormattedPrice, globalConfig, isHiddenDef
11643
11659
 
11644
11660
  const CommodityDetail$1 = (_a) => {
11645
11661
  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;
11646
- var { content, style, bgImg, onClick, schema, isDefault, bottom_image, tipText, isPost, viewTime, rec, swiper, commodityStyles, buttonStyle, index, commodityGroup, popupBg, iframeIcon, commodityImgRatio, isTel, iframeBgColor, isActive = true } = _a, props = __rest(_a, ["content", "style", "bgImg", "onClick", "schema", "isDefault", "bottom_image", "tipText", "isPost", "viewTime", "rec", "swiper", "commodityStyles", "buttonStyle", "index", "commodityGroup", "popupBg", "iframeIcon", "commodityImgRatio", "isTel", "iframeBgColor", "isActive"]);
11647
- const { sxpParameter, popupDetailData, isPreview, bffFbReport, popupCurTimeRef, checkCommodityIndexRef, globalConfig, ctaEvent } = useSxpDataSource();
11662
+ var { content, style, bgImg, onClick, schema, isDefault, bottom_image, tipText, isPost, viewTime, rec, swiper, commodityStyles, buttonStyle, index, commodityGroup, popupBg, iframeIcon, commodityImgRatio, isTel, iframeBgColor, isActive = true, enableAddToCart = false, addToCartPopupId = '' } = _a, props = __rest(_a, ["content", "style", "bgImg", "onClick", "schema", "isDefault", "bottom_image", "tipText", "isPost", "viewTime", "rec", "swiper", "commodityStyles", "buttonStyle", "index", "commodityGroup", "popupBg", "iframeIcon", "commodityImgRatio", "isTel", "iframeBgColor", "isActive", "enableAddToCart", "addToCartPopupId"]);
11663
+ const { sxpParameter, popupDetailData, isPreview, bffFbReport, popupCurTimeRef, checkCommodityIndexRef, globalConfig, ctaEvent, setPopupDetailData } = useSxpDataSource();
11648
11664
  const { jumpToWeb, productView } = useEventReport();
11649
11665
  const curTimeRef = useRef(null);
11650
11666
  const [showModal, setShowModal] = useState(false);
@@ -11665,6 +11681,32 @@ const CommodityDetail$1 = (_a) => {
11665
11681
  cta = p === null || p === void 0 ? void 0 : p.bindCta;
11666
11682
  }
11667
11683
  const handleLink = (e) => {
11684
+ // 如果启用了加购功能且配置了加购弹窗ID,则打开加购弹窗
11685
+ if (enableAddToCart && addToCartPopupId) {
11686
+ // 设置弹窗数据
11687
+ setPopupDetailData === null || setPopupDetailData === void 0 ? void 0 : setPopupDetailData(Object.assign(Object.assign({}, data), { index: position }));
11688
+ // 上报点击事件
11689
+ bffFbReport === null || bffFbReport === void 0 ? void 0 : bffFbReport({
11690
+ eventName: 'ClickCTA',
11691
+ product: product ? [product] : undefined,
11692
+ contentType: 'product',
11693
+ data,
11694
+ position,
11695
+ cta_text: cta === null || cta === void 0 ? void 0 : cta.enTitle,
11696
+ cta_action_type: 'open_internal_popup',
11697
+ target_content_id: product === null || product === void 0 ? void 0 : product.itemId
11698
+ });
11699
+ console.log('[CommodityDetail] 打开加购弹窗:', addToCartPopupId);
11700
+ // 打开加购弹窗
11701
+ if (typeof window !== 'undefined' && window.sxpPopup) {
11702
+ window.sxpPopup(addToCartPopupId);
11703
+ }
11704
+ else {
11705
+ console.warn('[CommodityDetail] sxpPopup 方法不存在');
11706
+ }
11707
+ return;
11708
+ }
11709
+ // 默认行为:跳转到商品链接
11668
11710
  if (product === null || product === void 0 ? void 0 : product.link) {
11669
11711
  jumpToWeb(e, data, product, cta, position);
11670
11712
  if (!isPost) {
@@ -11689,6 +11731,14 @@ const CommodityDetail$1 = (_a) => {
11689
11731
  }
11690
11732
  window.location.href = window.getJointUtmLink(product.link);
11691
11733
  }
11734
+ else {
11735
+ // 如果没有配置链接也没有启用加购功能,给出提示
11736
+ console.warn('[CommodityDetail] 商品未配置跳转链接,且未启用加购功能', {
11737
+ productId: product === null || product === void 0 ? void 0 : product.itemId,
11738
+ enableAddToCart,
11739
+ addToCartPopupId
11740
+ });
11741
+ }
11692
11742
  };
11693
11743
  useEffect(() => {
11694
11744
  var _a, _b;
@@ -11936,8 +11986,8 @@ const CommodityDetail = createMaterial(CommodityDetailComponent, {
11936
11986
  category: 'popup',
11937
11987
  type: 'CommodityDetail',
11938
11988
  related: {
11939
- settingRender: settingRender$e,
11940
- interactionRender: interactionRender$g
11989
+ settingRender: settingRender$f,
11990
+ interactionRender: interactionRender$h
11941
11991
  },
11942
11992
  defaulSetting: {
11943
11993
  props: {
@@ -11992,7 +12042,7 @@ const CommodityDetail = createMaterial(CommodityDetailComponent, {
11992
12042
  sort: 1
11993
12043
  });
11994
12044
 
11995
- var interactionRender$f = [
12045
+ var interactionRender$g = [
11996
12046
  {
11997
12047
  title: '点击事件',
11998
12048
  child: [
@@ -12012,7 +12062,7 @@ var interactionRender$f = [
12012
12062
  * @FilePath: \pb-sxp-ui\src\materials\sxp\popup\Prompt\settingRender.tsx
12013
12063
  *
12014
12064
  */
12015
- var settingRender$d = [
12065
+ var settingRender$e = [
12016
12066
  {
12017
12067
  title: '弹窗背景',
12018
12068
  child: [
@@ -12192,9 +12242,9 @@ const Prompt = createMaterial(PromptComponent, {
12192
12242
  category: 'popup',
12193
12243
  type: 'Prompt',
12194
12244
  related: {
12195
- settingRender: settingRender$d,
12245
+ settingRender: settingRender$e,
12196
12246
  bindableProps: [],
12197
- interactionRender: interactionRender$f
12247
+ interactionRender: interactionRender$g
12198
12248
  },
12199
12249
  defaulSetting: {
12200
12250
  props: {
@@ -12217,7 +12267,7 @@ const Prompt = createMaterial(PromptComponent, {
12217
12267
  * @FilePath: \pb-sxp-ui\src\materials\sxp\popup\CommodityDetailDiroNew\settingRender.tsx
12218
12268
  *
12219
12269
  */
12220
- var settingRender$c = [
12270
+ var settingRender$d = [
12221
12271
  {
12222
12272
  title: '弹窗背景',
12223
12273
  child: [
@@ -12950,7 +13000,7 @@ var CommodityDetailDiroNewComponent = memo(CommodityDetailDiroNew$1);
12950
13000
  * @FilePath: \pb-sxp-ui\src\materials\sxp\cta\AniLink\interactionRender.tsx
12951
13001
  *
12952
13002
  */
12953
- var interactionRender$e = [
13003
+ var interactionRender$f = [
12954
13004
  {
12955
13005
  title: '滑动事件',
12956
13006
  child: [
@@ -12977,8 +13027,8 @@ const CommodityDetailDiroNew = createMaterial(CommodityDetailDiroNewComponent, {
12977
13027
  category: 'popup',
12978
13028
  type: 'CommodityDetailDiroNew',
12979
13029
  related: {
12980
- settingRender: settingRender$c,
12981
- interactionRender: interactionRender$e
13030
+ settingRender: settingRender$d,
13031
+ interactionRender: interactionRender$f
12982
13032
  },
12983
13033
  defaulSetting: {
12984
13034
  props: {
@@ -13042,7 +13092,7 @@ const CommodityDetailDiroNew = createMaterial(CommodityDetailDiroNewComponent, {
13042
13092
  * @FilePath: \pb-sxp-ui\src\materials\sxp\popup\CommodityList\settingRender.tsx
13043
13093
  *
13044
13094
  */
13045
- var settingRender$b = [
13095
+ var settingRender$c = [
13046
13096
  {
13047
13097
  title: '弹窗背景',
13048
13098
  child: [
@@ -13467,7 +13517,7 @@ var CommodityListComponent = memo(CommodityList$1);
13467
13517
  * @FilePath: \pb-sxp-ui\src\materials\sxp\cta\AniLink\interactionRender.tsx
13468
13518
  *
13469
13519
  */
13470
- var interactionRender$d = [
13520
+ var interactionRender$e = [
13471
13521
  {
13472
13522
  title: '点击事件',
13473
13523
  child: [
@@ -13494,8 +13544,8 @@ const CommodityList = createMaterial(CommodityListComponent, {
13494
13544
  category: 'popup',
13495
13545
  type: 'CommodityList',
13496
13546
  related: {
13497
- settingRender: settingRender$b,
13498
- interactionRender: interactionRender$d
13547
+ settingRender: settingRender$c,
13548
+ interactionRender: interactionRender$e
13499
13549
  },
13500
13550
  defaulSetting: {
13501
13551
  props: {
@@ -13543,7 +13593,7 @@ const CommodityList = createMaterial(CommodityListComponent, {
13543
13593
  * @FilePath: \pb-sxp-ui\src\materials\sxp\popup\Iframe\settingRender.tsx
13544
13594
  *
13545
13595
  */
13546
- var settingRender$a = [
13596
+ var settingRender$b = [
13547
13597
  {
13548
13598
  title: '背景样式',
13549
13599
  child: [
@@ -13577,7 +13627,7 @@ const Iframe = createMaterial(IframeComponent, {
13577
13627
  category: 'popup',
13578
13628
  type: 'Iframe',
13579
13629
  related: {
13580
- settingRender: settingRender$a,
13630
+ settingRender: settingRender$b,
13581
13631
  bindableProps: []
13582
13632
  },
13583
13633
  defaulSetting: {
@@ -13597,7 +13647,7 @@ const Iframe = createMaterial(IframeComponent, {
13597
13647
  * @FilePath: \pb-sxp-ui\src\materials\sxp\popup\ConsentDetail\settingRender.tsx
13598
13648
  *
13599
13649
  */
13600
- var settingRender$9 = [
13650
+ var settingRender$a = [
13601
13651
  {
13602
13652
  title: '弹窗文本',
13603
13653
  child: [
@@ -13626,7 +13676,7 @@ const ConsentDetail = createMaterial(ConsentDetail$2, {
13626
13676
  category: 'popup',
13627
13677
  type: 'ConsentDetail',
13628
13678
  related: {
13629
- settingRender: settingRender$9,
13679
+ settingRender: settingRender$a,
13630
13680
  bindableProps: []
13631
13681
  },
13632
13682
  defaulSetting: {
@@ -13638,6 +13688,666 @@ const ConsentDetail = createMaterial(ConsentDetail$2, {
13638
13688
  sort: 7
13639
13689
  });
13640
13690
 
13691
+ var settingRender$9 = [
13692
+ {
13693
+ title: 'Shopify配置',
13694
+ child: [
13695
+ {
13696
+ type: 'Input',
13697
+ label: 'Shopify域名',
13698
+ name: ['props', 'shopifyDomain'],
13699
+ placeholder: 'your-store.myshopify.com'
13700
+ },
13701
+ {
13702
+ type: 'Input',
13703
+ label: 'Storefront Token',
13704
+ name: ['props', 'storefrontAccessToken'],
13705
+ placeholder: 'Storefront Access Token'
13706
+ }
13707
+ ]
13708
+ },
13709
+ {
13710
+ title: '弹窗背景',
13711
+ child: [
13712
+ {
13713
+ type: 'Number',
13714
+ label: '左右边距',
13715
+ name: ['props', 'popupBg', 'horizontalMargin']
13716
+ },
13717
+ {
13718
+ type: 'Number',
13719
+ label: '下边距',
13720
+ name: ['props', 'popupBg', 'bottomMargin']
13721
+ }
13722
+ ]
13723
+ },
13724
+ {
13725
+ title: '商品信息样式',
13726
+ child: [
13727
+ {
13728
+ name: ['props', 'variantStyles'],
13729
+ type: 'SelectLinkage',
13730
+ child: [
13731
+ {
13732
+ label: '字段',
13733
+ type: 'Select',
13734
+ options: [
13735
+ {
13736
+ label: '商品标题',
13737
+ value: 'title'
13738
+ },
13739
+ {
13740
+ label: '价格',
13741
+ value: 'price'
13742
+ },
13743
+ {
13744
+ label: '规格选项',
13745
+ value: 'option'
13746
+ },
13747
+ {
13748
+ label: '已选规格',
13749
+ value: 'selectedOption'
13750
+ }
13751
+ ],
13752
+ name: ['props', 'variantStyles', 'field'],
13753
+ initialValue: 'title'
13754
+ },
13755
+ {
13756
+ type: 'Group',
13757
+ child: [
13758
+ {
13759
+ label: '上边距',
13760
+ type: 'Number',
13761
+ addonAfter: 'px',
13762
+ name: ['marginTop']
13763
+ },
13764
+ {
13765
+ label: '下边距',
13766
+ type: 'Number',
13767
+ addonAfter: 'px',
13768
+ name: ['marginBottom']
13769
+ }
13770
+ ]
13771
+ },
13772
+ {
13773
+ type: 'Group',
13774
+ label: '字体',
13775
+ child: [
13776
+ {
13777
+ type: 'Select',
13778
+ name: ['fontFamily-cn'],
13779
+ bottomText: '中文字体'
13780
+ },
13781
+ {
13782
+ type: 'Select',
13783
+ name: ['fontFamily-en'],
13784
+ bottomText: '英文/其他字体'
13785
+ }
13786
+ ]
13787
+ },
13788
+ {
13789
+ type: 'Group',
13790
+ label: '',
13791
+ child: [
13792
+ {
13793
+ type: 'Color',
13794
+ name: ['color']
13795
+ },
13796
+ {
13797
+ type: 'Number',
13798
+ addonAfter: 'px',
13799
+ name: ['fontSize']
13800
+ }
13801
+ ]
13802
+ },
13803
+ {
13804
+ label: '样式',
13805
+ type: 'TextStyle'
13806
+ },
13807
+ {
13808
+ label: '对齐',
13809
+ type: 'TextAlign'
13810
+ },
13811
+ {
13812
+ label: '间距',
13813
+ type: 'TextSpace'
13814
+ }
13815
+ ]
13816
+ }
13817
+ ]
13818
+ },
13819
+ {
13820
+ title: '加购按钮样式',
13821
+ child: [
13822
+ {
13823
+ label: '英文大小写',
13824
+ type: 'Select',
13825
+ name: ['props', 'buttonStyle', 'textTransform'],
13826
+ options: [
13827
+ {
13828
+ label: '默认',
13829
+ value: 'unset'
13830
+ },
13831
+ {
13832
+ label: '小写',
13833
+ value: 'lowercase'
13834
+ },
13835
+ {
13836
+ label: '大写',
13837
+ value: 'uppercase'
13838
+ }
13839
+ ]
13840
+ },
13841
+ {
13842
+ type: 'Color',
13843
+ label: '背景色',
13844
+ name: ['props', 'buttonStyle', 'backgroundColor'],
13845
+ initialValue: '#000'
13846
+ },
13847
+ {
13848
+ type: 'Group',
13849
+ label: '尺寸',
13850
+ child: [
13851
+ {
13852
+ type: 'Number',
13853
+ name: ['props', 'buttonStyle', 'height'],
13854
+ addonAfter: 'H'
13855
+ }
13856
+ ]
13857
+ },
13858
+ {
13859
+ type: 'Group',
13860
+ label: '圆角',
13861
+ child: [
13862
+ {
13863
+ type: 'Slider',
13864
+ name: ['props', 'buttonStyle', 'borderRadius'],
13865
+ max: 100
13866
+ },
13867
+ {
13868
+ type: 'Number',
13869
+ name: ['props', 'buttonStyle', 'borderRadius'],
13870
+ addonAfter: 'px',
13871
+ max: 100
13872
+ }
13873
+ ]
13874
+ },
13875
+ {
13876
+ type: 'TextMargin',
13877
+ name: ['props', 'buttonStyle']
13878
+ },
13879
+ {
13880
+ type: 'Group',
13881
+ label: '字体',
13882
+ child: [
13883
+ {
13884
+ type: 'Select',
13885
+ name: ['props', 'buttonStyle', 'fontFamily-cn'],
13886
+ bottomText: '中文字体'
13887
+ },
13888
+ {
13889
+ type: 'Select',
13890
+ name: ['props', 'buttonStyle', 'fontFamily-en'],
13891
+ bottomText: '英文/其他字体'
13892
+ }
13893
+ ]
13894
+ },
13895
+ {
13896
+ type: 'Group',
13897
+ label: '',
13898
+ child: [
13899
+ {
13900
+ type: 'Color',
13901
+ name: ['props', 'buttonStyle', 'color'],
13902
+ initialValue: '#fff'
13903
+ },
13904
+ {
13905
+ type: 'Number',
13906
+ name: ['props', 'buttonStyle', 'fontSize'],
13907
+ addonAfter: 'px'
13908
+ }
13909
+ ]
13910
+ },
13911
+ {
13912
+ type: 'TextStyle',
13913
+ name: ['props', 'buttonStyle']
13914
+ },
13915
+ {
13916
+ type: 'TextAlign',
13917
+ name: ['props', 'buttonStyle']
13918
+ },
13919
+ {
13920
+ label: '间距',
13921
+ type: 'TextSpace',
13922
+ name: ['props', 'buttonStyle']
13923
+ }
13924
+ ]
13925
+ },
13926
+ {
13927
+ title: '文案配置',
13928
+ child: [
13929
+ {
13930
+ type: 'Input',
13931
+ label: '加购按钮文案',
13932
+ name: ['props', 'texts', 'addToCart'],
13933
+ placeholder: 'Add to Cart'
13934
+ },
13935
+ {
13936
+ type: 'Input',
13937
+ label: '选择规格提示',
13938
+ name: ['props', 'texts', 'selectOptions'],
13939
+ placeholder: 'Please select options'
13940
+ },
13941
+ {
13942
+ type: 'Input',
13943
+ label: '加载文案',
13944
+ name: ['props', 'texts', 'loading'],
13945
+ placeholder: 'Loading...'
13946
+ },
13947
+ {
13948
+ type: 'Input',
13949
+ label: '错误文案',
13950
+ name: ['props', 'texts', 'error'],
13951
+ placeholder: 'Failed to load product'
13952
+ }
13953
+ ]
13954
+ },
13955
+ {
13956
+ title: '数量选择器',
13957
+ child: [
13958
+ {
13959
+ type: 'Number',
13960
+ label: '按钮间距',
13961
+ name: ['props', 'quantityStyle', 'gap'],
13962
+ addonAfter: 'px',
13963
+ initialValue: 12
13964
+ }
13965
+ ]
13966
+ }
13967
+ ];
13968
+
13969
+ /*
13970
+ * @Author: tao
13971
+ * @Date: 2026-01-12
13972
+ * @Description: Add to Cart 交互配置
13973
+ */
13974
+ var interactionRender$d = () => {
13975
+ return (React.createElement("div", { style: { padding: '20px', color: '#666' } },
13976
+ React.createElement("p", null, "\u52A0\u8D2D\u5546\u54C1\u5F39\u7A97\u4EA4\u4E92\u8BF4\u660E\uFF1A"),
13977
+ React.createElement("ul", { style: { paddingLeft: '20px', lineHeight: '1.8' } },
13978
+ React.createElement("li", null, "\u70B9\u51FB\u5546\u54C1\u8BE6\u60C5\u5F39\u7A97\u7684\"Shop Now\"\u6309\u94AE\u540E\u81EA\u52A8\u5C55\u793A"),
13979
+ React.createElement("li", null, "\u901A\u8FC7Shopify Storefront API\u83B7\u53D6\u5546\u54C1\u89C4\u683C\u548C\u5E93\u5B58\u4FE1\u606F"),
13980
+ React.createElement("li", null, "\u7528\u6237\u9009\u62E9\u89C4\u683C\u540E\u5B9E\u65F6\u663E\u793A\u5BF9\u5E94SKU\u7684\u4EF7\u683C\u548C\u5E93\u5B58"),
13981
+ React.createElement("li", null, "\u70B9\u51FB\"Add to Cart\"\u6309\u94AE\u540E\u8DF3\u8F6C\u81F3Shopify\u8D2D\u7269\u8F66\u9875\u9762"),
13982
+ React.createElement("li", null, "\u65E0\u5E93\u5B58\u6216\u4E0D\u53EF\u552E\u5356\u7684\u89C4\u683C\u81EA\u52A8\u7F6E\u7070\u4E0D\u53EF\u9009"))));
13983
+ };
13984
+
13985
+ const AddToCartPopup$1 = (_a) => {
13986
+ var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
13987
+ var { style, isActive = true, index, shopifyDomain = '', storefrontAccessToken = '', variantStyles = {}, buttonStyle = {}, quantityStyle = {}, texts = {}, popupBg = {} } = _a, props = __rest(_a, ["style", "isActive", "index", "shopifyDomain", "storefrontAccessToken", "variantStyles", "buttonStyle", "quantityStyle", "texts", "popupBg"]);
13988
+ const { sxpParameter, popupDetailData, isPreview, bffFbReport, globalConfig } = useSxpDataSource();
13989
+ useEventReport();
13990
+ const curTimeRef = useRef(null);
13991
+ const [productData, setProductData] = useState(null);
13992
+ const [selectedOptions, setSelectedOptions] = useState({});
13993
+ const [selectedVariant, setSelectedVariant] = useState(null);
13994
+ const [quantity, setQuantity] = useState(1);
13995
+ const [loading, setLoading] = useState(true);
13996
+ const [error, setError] = useState(null);
13997
+ // 获取当前弹窗商品数据(自动从 popupDetailData 获取)
13998
+ const data = popupDetailData;
13999
+ const product = (_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];
14000
+ product === null || product === void 0 ? void 0 : product.bindCta;
14001
+ const position = (_g = (_f = popupDetailData === null || popupDetailData === void 0 ? void 0 : popupDetailData.index) !== null && _f !== void 0 ? _f : index) !== null && _g !== void 0 ? _g : 0;
14002
+ // Shopify配置 - 优先级:props > globalConfig > 默认值
14003
+ const finalShopifyDomain = shopifyDomain || (globalConfig === null || globalConfig === void 0 ? void 0 : globalConfig.shopifyDomain) || 'dev-store-749237498237498636.myshopify.com';
14004
+ const finalStorefrontToken = storefrontAccessToken || (globalConfig === null || globalConfig === void 0 ? void 0 : globalConfig.storefrontAccessToken) || '77d894c490f79430ce7bd0a7efdff6b7';
14005
+ // 自动从商品数据获取 Shopify Product ID
14006
+ const productId = (product === null || product === void 0 ? void 0 : product.itemId) || '';
14007
+ // 文案
14008
+ const finalTexts = {
14009
+ addToCart: texts.addToCart || 'Add to Cart',
14010
+ selectOptions: texts.selectOptions || 'Please select options',
14011
+ loading: texts.loading || 'Loading...',
14012
+ error: texts.error || 'Failed to load product',
14013
+ color: texts.color || 'Color',
14014
+ size: texts.size || 'Size',
14015
+ material: texts.material || 'Material',
14016
+ style: texts.style || 'Style'
14017
+ };
14018
+ // 查询Shopify商品数据
14019
+ const fetchProductData = useCallback(() => __awaiter(void 0, void 0, void 0, function* () {
14020
+ var _m;
14021
+ if (!productId || !finalShopifyDomain || !finalStorefrontToken) {
14022
+ console.log('[AddToCartPopup] 缺少必要配置:', {
14023
+ productId,
14024
+ shopifyDomain: finalShopifyDomain,
14025
+ hasToken: !!finalStorefrontToken
14026
+ });
14027
+ setLoading(false);
14028
+ return;
14029
+ }
14030
+ console.log('[AddToCartPopup] 开始加载商品数据:', {
14031
+ productId,
14032
+ shopifyDomain: finalShopifyDomain
14033
+ });
14034
+ setLoading(true);
14035
+ setError(null);
14036
+ try {
14037
+ const query = `
14038
+ query getProduct($id: ID!) {
14039
+ product(id: $id) {
14040
+ id
14041
+ title
14042
+ images(first: 10) {
14043
+ edges {
14044
+ node {
14045
+ url
14046
+ }
14047
+ }
14048
+ }
14049
+ options {
14050
+ name
14051
+ values
14052
+ }
14053
+ variants(first: 100) {
14054
+ edges {
14055
+ node {
14056
+ id
14057
+ title
14058
+ availableForSale
14059
+ quantityAvailable
14060
+ price {
14061
+ amount
14062
+ currencyCode
14063
+ }
14064
+ image {
14065
+ url
14066
+ }
14067
+ selectedOptions {
14068
+ name
14069
+ value
14070
+ }
14071
+ }
14072
+ }
14073
+ }
14074
+ }
14075
+ }
14076
+ `;
14077
+ // 确保 Product ID 格式正确
14078
+ const formattedProductId = productId.startsWith('gid://')
14079
+ ? productId
14080
+ : `gid://shopify/Product/${productId}`;
14081
+ console.log('[AddToCartPopup] 使用的 Product ID:', formattedProductId);
14082
+ const response = yield fetch(`https://${finalShopifyDomain}/api/2024-01/graphql.json`, {
14083
+ method: 'POST',
14084
+ headers: {
14085
+ 'Content-Type': 'application/json',
14086
+ 'X-Shopify-Storefront-Access-Token': finalStorefrontToken
14087
+ },
14088
+ body: JSON.stringify({
14089
+ query,
14090
+ variables: { id: formattedProductId }
14091
+ })
14092
+ });
14093
+ if (!response.ok) {
14094
+ throw new Error(`HTTP ${response.status}`);
14095
+ }
14096
+ const result = yield response.json();
14097
+ if (result.errors) {
14098
+ console.error('[AddToCartPopup] GraphQL 错误:', result.errors);
14099
+ throw new Error(result.errors[0].message);
14100
+ }
14101
+ if (!((_m = result.data) === null || _m === void 0 ? void 0 : _m.product)) {
14102
+ console.error('[AddToCartPopup] 未找到商品');
14103
+ throw new Error('Product not found');
14104
+ }
14105
+ console.log('[AddToCartPopup] 商品数据加载成功:', result.data.product.title);
14106
+ setProductData(result.data.product);
14107
+ }
14108
+ catch (err) {
14109
+ const errorMessage = err instanceof Error ? err.message : finalTexts.error;
14110
+ setError(errorMessage);
14111
+ console.error('[AddToCartPopup] 加载失败:', err);
14112
+ }
14113
+ finally {
14114
+ setLoading(false);
14115
+ }
14116
+ }), [productId, finalShopifyDomain, finalStorefrontToken, finalTexts.error]);
14117
+ useEffect(() => {
14118
+ if (isActive) {
14119
+ fetchProductData();
14120
+ }
14121
+ }, [isActive, fetchProductData]);
14122
+ // 根据选中的规格匹配variant
14123
+ useEffect(() => {
14124
+ if (!productData)
14125
+ return;
14126
+ const variants = productData.variants.edges.map(edge => edge.node);
14127
+ const optionsCount = productData.options.length;
14128
+ const selectedCount = Object.keys(selectedOptions).length;
14129
+ if (selectedCount === 0 || selectedCount < optionsCount) {
14130
+ setSelectedVariant(null);
14131
+ return;
14132
+ }
14133
+ const matchedVariant = variants.find(variant => {
14134
+ return variant.selectedOptions.every(option => selectedOptions[option.name] === option.value);
14135
+ });
14136
+ setSelectedVariant(matchedVariant || null);
14137
+ setQuantity(1);
14138
+ }, [selectedOptions, productData]);
14139
+ // 处理规格选择
14140
+ const handleOptionSelect = useCallback((optionName, value) => {
14141
+ setSelectedOptions(prev => {
14142
+ const newOptions = Object.assign({}, prev);
14143
+ if (newOptions[optionName] === value) {
14144
+ delete newOptions[optionName];
14145
+ }
14146
+ else {
14147
+ newOptions[optionName] = value;
14148
+ }
14149
+ return newOptions;
14150
+ });
14151
+ }, []);
14152
+ // 处理数量变化
14153
+ const handleQuantityChange = useCallback((delta) => {
14154
+ setQuantity(prev => {
14155
+ var _a;
14156
+ const newQuantity = prev + delta;
14157
+ const maxQuantity = (_a = selectedVariant === null || selectedVariant === void 0 ? void 0 : selectedVariant.quantityAvailable) !== null && _a !== void 0 ? _a : 999;
14158
+ return Math.max(1, Math.min(newQuantity, maxQuantity));
14159
+ });
14160
+ }, [selectedVariant]);
14161
+ // 检查某个规格值是否可用
14162
+ const isOptionValueAvailable = useCallback((optionName, value) => {
14163
+ if (!productData)
14164
+ return false;
14165
+ const variants = productData.variants.edges.map(edge => edge.node);
14166
+ const tempOptions = Object.assign(Object.assign({}, selectedOptions), { [optionName]: value });
14167
+ return variants.some(variant => {
14168
+ const matches = variant.selectedOptions.every(option => !tempOptions[option.name] || tempOptions[option.name] === option.value);
14169
+ const hasStock = variant.quantityAvailable === null || variant.quantityAvailable > 0;
14170
+ return matches && variant.availableForSale && hasStock;
14171
+ });
14172
+ }, [productData, selectedOptions]);
14173
+ // 处理加购
14174
+ const handleAddToCart = useCallback(() => {
14175
+ var _a;
14176
+ if (!selectedVariant || quantity === 0)
14177
+ return;
14178
+ const variantId = selectedVariant.id.split('/').pop();
14179
+ const cartUrl = `https://${finalShopifyDomain}/cart/add?id=${variantId}&quantity=${quantity}`;
14180
+ console.log('[AddToCartPopup] 加购:', {
14181
+ variantId,
14182
+ quantity,
14183
+ cartUrl
14184
+ });
14185
+ // 上报事件
14186
+ bffFbReport === null || bffFbReport === void 0 ? void 0 : bffFbReport({
14187
+ eventName: 'AddToCart',
14188
+ product: product ? [product] : undefined,
14189
+ contentType: 'product',
14190
+ data,
14191
+ position,
14192
+ content_id: (_a = product === null || product === void 0 ? void 0 : product.itemId) !== null && _a !== void 0 ? _a : '',
14193
+ value: parseFloat(selectedVariant.price.amount) * quantity,
14194
+ currency: selectedVariant.price.currencyCode,
14195
+ contents: [{
14196
+ id: variantId,
14197
+ quantity
14198
+ }]
14199
+ });
14200
+ // 跳转到Shopify购物车页面
14201
+ window.location.href = cartUrl;
14202
+ }, [selectedVariant, quantity, finalShopifyDomain, bffFbReport, product, data, position]);
14203
+ // 计算总价
14204
+ const totalPrice = useMemo(() => {
14205
+ if (!selectedVariant)
14206
+ return null;
14207
+ const price = parseFloat(selectedVariant.price.amount);
14208
+ const total = price * quantity;
14209
+ return total.toFixed(2);
14210
+ }, [selectedVariant, quantity]);
14211
+ // 初始化时间
14212
+ useEffect(() => {
14213
+ const initTime = () => {
14214
+ curTimeRef.current = new Date();
14215
+ };
14216
+ initTime();
14217
+ window.addEventListener('pageshow', initTime);
14218
+ return () => {
14219
+ window.removeEventListener('pageshow', initTime);
14220
+ };
14221
+ }, []);
14222
+ // 加载中
14223
+ if (loading) {
14224
+ return (React.createElement("div", { className: "add-to-cart-popup-loading", style: style },
14225
+ React.createElement("div", null, finalTexts.loading)));
14226
+ }
14227
+ // 错误状态
14228
+ if (error || !productData) {
14229
+ return (React.createElement("div", { className: "add-to-cart-popup-error", style: style },
14230
+ React.createElement("div", null,
14231
+ finalTexts.error,
14232
+ ": ",
14233
+ error || 'Product not found')));
14234
+ }
14235
+ const mainImage = ((_h = selectedVariant === null || selectedVariant === void 0 ? void 0 : selectedVariant.image) === null || _h === void 0 ? void 0 : _h.url) || ((_j = productData.images.edges[0]) === null || _j === void 0 ? void 0 : _j.node.url) || ((_k = product === null || product === void 0 ? void 0 : product.homePage) === null || _k === void 0 ? void 0 : _k[0]) || '';
14236
+ const hasAllOptionsSelected = productData.options.length === Object.keys(selectedOptions).length;
14237
+ const isAddToCartDisabled = !selectedVariant || quantity === 0;
14238
+ return (React.createElement("div", Object.assign({ className: "add-to-cart-popup-container", style: style }, props),
14239
+ React.createElement("div", { className: "variant-detail-section" },
14240
+ React.createElement("div", { className: "variant-image-wrapper" },
14241
+ React.createElement("img", { src: mainImage, alt: productData.title, className: "variant-image" })),
14242
+ React.createElement("div", { className: "variant-info-wrapper" },
14243
+ React.createElement("h2", { className: "product-title-text", style: variantStyles.title, dangerouslySetInnerHTML: {
14244
+ __html: setFontForText(productData.title, variantStyles.title)
14245
+ } }),
14246
+ selectedVariant && (React.createElement(React.Fragment, null,
14247
+ React.createElement("div", { className: "selected-options-tags" }, selectedVariant.selectedOptions.map(option => (React.createElement("span", { key: option.name, className: "option-tag", style: variantStyles.selectedOption },
14248
+ option.name,
14249
+ ": ",
14250
+ option.value)))),
14251
+ React.createElement("div", { className: "price-display" },
14252
+ React.createElement("span", { className: "price-value", style: variantStyles.price, dangerouslySetInnerHTML: {
14253
+ __html: setFontForText(`${selectedVariant.price.currencyCode} $${totalPrice}`, variantStyles.price)
14254
+ } })),
14255
+ React.createElement("div", { className: "quantity-selector-wrapper", style: quantityStyle },
14256
+ React.createElement("button", { className: "quantity-btn quantity-decrease", onClick: () => handleQuantityChange(-1), disabled: quantity <= 1, "aria-label": "Decrease quantity" }, "-"),
14257
+ React.createElement("input", { type: "number", value: quantity, readOnly: true, className: "quantity-input-field", "aria-label": "Quantity" }),
14258
+ React.createElement("button", { className: "quantity-btn quantity-increase", onClick: () => handleQuantityChange(1), disabled: quantity >= ((_l = selectedVariant.quantityAvailable) !== null && _l !== void 0 ? _l : 999), "aria-label": "Increase quantity" }, "+")))),
14259
+ !hasAllOptionsSelected && (React.createElement("div", { className: "no-selection-hint", style: variantStyles.option }, finalTexts.selectOptions)))),
14260
+ React.createElement("div", { className: "variant-options-section" }, productData.options.map(option => (React.createElement("div", { key: option.name, className: "option-group-wrapper" },
14261
+ React.createElement("h3", { className: "option-group-name", style: variantStyles.option, dangerouslySetInnerHTML: {
14262
+ __html: setFontForText(option.name, variantStyles.option)
14263
+ } }),
14264
+ React.createElement("div", { className: "option-values-grid" }, option.values.map(value => {
14265
+ const isSelected = selectedOptions[option.name] === value;
14266
+ const isAvailable = isOptionValueAvailable(option.name, value);
14267
+ return (React.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));
14268
+ })))))),
14269
+ React.createElement("button", { className: `add-to-cart-button ${isAddToCartDisabled ? 'disabled' : ''}`, style: buttonStyle, onClick: handleAddToCart, disabled: isAddToCartDisabled, "aria-label": finalTexts.addToCart },
14270
+ React.createElement("span", { dangerouslySetInnerHTML: {
14271
+ __html: setFontForText(finalTexts.addToCart, buttonStyle)
14272
+ } }))));
14273
+ };
14274
+
14275
+ /*
14276
+ * @Author: tao
14277
+ * @Date: 2026-01-12
14278
+ * @Description: Add to Cart 弹窗组件物料配置
14279
+ */
14280
+ const AddToCartPopup = createMaterial(AddToCartPopup$1, {
14281
+ displayName: '加购商品',
14282
+ icon: '',
14283
+ category: 'popup',
14284
+ type: 'AddToCartPopup',
14285
+ related: {
14286
+ settingRender: settingRender$9,
14287
+ interactionRender: interactionRender$d
14288
+ },
14289
+ defaulSetting: {
14290
+ props: {
14291
+ shopifyDomain: '',
14292
+ storefrontAccessToken: '',
14293
+ variantStyles: {
14294
+ title: {
14295
+ color: '#000',
14296
+ fontSize: 20,
14297
+ fontWeight: 600,
14298
+ marginBottom: 12
14299
+ },
14300
+ price: {
14301
+ color: '#000',
14302
+ fontSize: 24,
14303
+ fontWeight: 700,
14304
+ marginBottom: 16
14305
+ },
14306
+ option: {
14307
+ color: '#111',
14308
+ fontSize: 16,
14309
+ fontWeight: 600,
14310
+ marginBottom: 12
14311
+ },
14312
+ selectedOption: {
14313
+ fontSize: 14,
14314
+ color: '#374151'
14315
+ }
14316
+ },
14317
+ buttonStyle: {
14318
+ backgroundColor: '#000',
14319
+ color: '#fff',
14320
+ fontSize: 16,
14321
+ height: 52,
14322
+ fontWeight: 600,
14323
+ textAlign: 'center',
14324
+ textTransform: 'uppercase'
14325
+ },
14326
+ quantityStyle: {
14327
+ gap: 12
14328
+ },
14329
+ texts: {
14330
+ addToCart: 'Add to Cart',
14331
+ selectOptions: 'Please select options',
14332
+ loading: 'Loading...',
14333
+ error: 'Failed to load product',
14334
+ color: 'Color',
14335
+ size: 'Size',
14336
+ material: 'Material',
14337
+ style: 'Style'
14338
+ },
14339
+ popupBg: {
14340
+ horizontalMargin: 0,
14341
+ bottomMargin: 0
14342
+ }
14343
+ },
14344
+ style: {}
14345
+ },
14346
+ w: 100,
14347
+ h: 40,
14348
+ sort: 7
14349
+ });
14350
+
13641
14351
  /*
13642
14352
  * @Author: binruan@chatlabs.com
13643
14353
  * @Date: 2024-03-26 16:50:25
@@ -19129,6 +19839,7 @@ const MultiPosts = createMaterial(MultiPosts$2, {
19129
19839
 
19130
19840
  var _materials_ = /*#__PURE__*/Object.freeze({
19131
19841
  __proto__: null,
19842
+ AddToCartPopup: AddToCartPopup,
19132
19843
  AniLink: AniLink,
19133
19844
  AniLinkPopup: AniLinkPopup,
19134
19845
  Appoint: Appoint,