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.cjs CHANGED
@@ -2788,7 +2788,7 @@ var index$3 = /*#__PURE__*/Object.freeze({
2788
2788
  StructurePage: StructurePage
2789
2789
  });
2790
2790
 
2791
- var interactionRender$h = [
2791
+ var interactionRender$i = [
2792
2792
  {
2793
2793
  title: '点击事件',
2794
2794
  child: [
@@ -2808,7 +2808,7 @@ var interactionRender$h = [
2808
2808
  * @FilePath: \pb-sxp-ui\src\materials\sxp\popup\AppointForm\settingRender.tsx
2809
2809
  *
2810
2810
  */
2811
- var settingRender$f = [
2811
+ var settingRender$g = [
2812
2812
  {
2813
2813
  title: '弹窗背景',
2814
2814
  child: [
@@ -3245,9 +3245,9 @@ const AppointForm = createMaterial(AppointFormComponent, {
3245
3245
  category: 'popup',
3246
3246
  type: 'AppointForm',
3247
3247
  related: {
3248
- settingRender: settingRender$f,
3248
+ settingRender: settingRender$g,
3249
3249
  bindableProps: [],
3250
- interactionRender: interactionRender$h
3250
+ interactionRender: interactionRender$i
3251
3251
  },
3252
3252
  defaulSetting: {
3253
3253
  name: '表单',
@@ -3270,7 +3270,7 @@ const AppointForm = createMaterial(AppointFormComponent, {
3270
3270
  sort: 2
3271
3271
  });
3272
3272
 
3273
- var settingRender$e = [
3273
+ var settingRender$f = [
3274
3274
  {
3275
3275
  title: '弹窗背景',
3276
3276
  child: [
@@ -3668,6 +3668,22 @@ var settingRender$e = [
3668
3668
  name: ['props', 'enableFixedCloseButton']
3669
3669
  }
3670
3670
  ]
3671
+ },
3672
+ {
3673
+ title: '加购功能',
3674
+ child: [
3675
+ {
3676
+ label: '启用加购弹窗',
3677
+ type: 'Switch',
3678
+ name: ['props', 'enableAddToCart']
3679
+ },
3680
+ {
3681
+ label: '加购弹窗ID',
3682
+ type: 'Input',
3683
+ name: ['props', 'addToCartPopupId'],
3684
+ placeholder: '请输入加购弹窗的ID'
3685
+ }
3686
+ ]
3671
3687
  }
3672
3688
  ];
3673
3689
 
@@ -3687,7 +3703,7 @@ var settingRender$e = [
3687
3703
  * @FilePath: \pb-sxp-ui\src\materials\sxp\cta\AniLink\interactionRender.tsx
3688
3704
  *
3689
3705
  */
3690
- var interactionRender$g = [
3706
+ var interactionRender$h = [
3691
3707
  {
3692
3708
  title: '滑动事件',
3693
3709
  child: [
@@ -11665,8 +11681,8 @@ const getPriceText = ({ product, enableFormattedPrice, globalConfig, isHiddenDef
11665
11681
 
11666
11682
  const CommodityDetail$1 = (_a) => {
11667
11683
  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;
11668
- 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"]);
11669
- const { sxpParameter, popupDetailData, isPreview, bffFbReport, popupCurTimeRef, checkCommodityIndexRef, globalConfig, ctaEvent } = useSxpDataSource();
11684
+ 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"]);
11685
+ const { sxpParameter, popupDetailData, isPreview, bffFbReport, popupCurTimeRef, checkCommodityIndexRef, globalConfig, ctaEvent, setPopupDetailData } = useSxpDataSource();
11670
11686
  const { jumpToWeb, productView } = useEventReport();
11671
11687
  const curTimeRef = React.useRef(null);
11672
11688
  const [showModal, setShowModal] = React.useState(false);
@@ -11687,6 +11703,32 @@ const CommodityDetail$1 = (_a) => {
11687
11703
  cta = p === null || p === void 0 ? void 0 : p.bindCta;
11688
11704
  }
11689
11705
  const handleLink = (e) => {
11706
+ // 如果启用了加购功能且配置了加购弹窗ID,则打开加购弹窗
11707
+ if (enableAddToCart && addToCartPopupId) {
11708
+ // 设置弹窗数据
11709
+ setPopupDetailData === null || setPopupDetailData === void 0 ? void 0 : setPopupDetailData(Object.assign(Object.assign({}, data), { index: position }));
11710
+ // 上报点击事件
11711
+ bffFbReport === null || bffFbReport === void 0 ? void 0 : bffFbReport({
11712
+ eventName: 'ClickCTA',
11713
+ product: product ? [product] : undefined,
11714
+ contentType: 'product',
11715
+ data,
11716
+ position,
11717
+ cta_text: cta === null || cta === void 0 ? void 0 : cta.enTitle,
11718
+ cta_action_type: 'open_internal_popup',
11719
+ target_content_id: product === null || product === void 0 ? void 0 : product.itemId
11720
+ });
11721
+ console.log('[CommodityDetail] 打开加购弹窗:', addToCartPopupId);
11722
+ // 打开加购弹窗
11723
+ if (typeof window !== 'undefined' && window.sxpPopup) {
11724
+ window.sxpPopup(addToCartPopupId);
11725
+ }
11726
+ else {
11727
+ console.warn('[CommodityDetail] sxpPopup 方法不存在');
11728
+ }
11729
+ return;
11730
+ }
11731
+ // 默认行为:跳转到商品链接
11690
11732
  if (product === null || product === void 0 ? void 0 : product.link) {
11691
11733
  jumpToWeb(e, data, product, cta, position);
11692
11734
  if (!isPost) {
@@ -11711,6 +11753,14 @@ const CommodityDetail$1 = (_a) => {
11711
11753
  }
11712
11754
  window.location.href = window.getJointUtmLink(product.link);
11713
11755
  }
11756
+ else {
11757
+ // 如果没有配置链接也没有启用加购功能,给出提示
11758
+ console.warn('[CommodityDetail] 商品未配置跳转链接,且未启用加购功能', {
11759
+ productId: product === null || product === void 0 ? void 0 : product.itemId,
11760
+ enableAddToCart,
11761
+ addToCartPopupId
11762
+ });
11763
+ }
11714
11764
  };
11715
11765
  React.useEffect(() => {
11716
11766
  var _a, _b;
@@ -11958,8 +12008,8 @@ const CommodityDetail = createMaterial(CommodityDetailComponent, {
11958
12008
  category: 'popup',
11959
12009
  type: 'CommodityDetail',
11960
12010
  related: {
11961
- settingRender: settingRender$e,
11962
- interactionRender: interactionRender$g
12011
+ settingRender: settingRender$f,
12012
+ interactionRender: interactionRender$h
11963
12013
  },
11964
12014
  defaulSetting: {
11965
12015
  props: {
@@ -12014,7 +12064,7 @@ const CommodityDetail = createMaterial(CommodityDetailComponent, {
12014
12064
  sort: 1
12015
12065
  });
12016
12066
 
12017
- var interactionRender$f = [
12067
+ var interactionRender$g = [
12018
12068
  {
12019
12069
  title: '点击事件',
12020
12070
  child: [
@@ -12034,7 +12084,7 @@ var interactionRender$f = [
12034
12084
  * @FilePath: \pb-sxp-ui\src\materials\sxp\popup\Prompt\settingRender.tsx
12035
12085
  *
12036
12086
  */
12037
- var settingRender$d = [
12087
+ var settingRender$e = [
12038
12088
  {
12039
12089
  title: '弹窗背景',
12040
12090
  child: [
@@ -12214,9 +12264,9 @@ const Prompt = createMaterial(PromptComponent, {
12214
12264
  category: 'popup',
12215
12265
  type: 'Prompt',
12216
12266
  related: {
12217
- settingRender: settingRender$d,
12267
+ settingRender: settingRender$e,
12218
12268
  bindableProps: [],
12219
- interactionRender: interactionRender$f
12269
+ interactionRender: interactionRender$g
12220
12270
  },
12221
12271
  defaulSetting: {
12222
12272
  props: {
@@ -12239,7 +12289,7 @@ const Prompt = createMaterial(PromptComponent, {
12239
12289
  * @FilePath: \pb-sxp-ui\src\materials\sxp\popup\CommodityDetailDiroNew\settingRender.tsx
12240
12290
  *
12241
12291
  */
12242
- var settingRender$c = [
12292
+ var settingRender$d = [
12243
12293
  {
12244
12294
  title: '弹窗背景',
12245
12295
  child: [
@@ -12972,7 +13022,7 @@ var CommodityDetailDiroNewComponent = React.memo(CommodityDetailDiroNew$1);
12972
13022
  * @FilePath: \pb-sxp-ui\src\materials\sxp\cta\AniLink\interactionRender.tsx
12973
13023
  *
12974
13024
  */
12975
- var interactionRender$e = [
13025
+ var interactionRender$f = [
12976
13026
  {
12977
13027
  title: '滑动事件',
12978
13028
  child: [
@@ -12999,8 +13049,8 @@ const CommodityDetailDiroNew = createMaterial(CommodityDetailDiroNewComponent, {
12999
13049
  category: 'popup',
13000
13050
  type: 'CommodityDetailDiroNew',
13001
13051
  related: {
13002
- settingRender: settingRender$c,
13003
- interactionRender: interactionRender$e
13052
+ settingRender: settingRender$d,
13053
+ interactionRender: interactionRender$f
13004
13054
  },
13005
13055
  defaulSetting: {
13006
13056
  props: {
@@ -13064,7 +13114,7 @@ const CommodityDetailDiroNew = createMaterial(CommodityDetailDiroNewComponent, {
13064
13114
  * @FilePath: \pb-sxp-ui\src\materials\sxp\popup\CommodityList\settingRender.tsx
13065
13115
  *
13066
13116
  */
13067
- var settingRender$b = [
13117
+ var settingRender$c = [
13068
13118
  {
13069
13119
  title: '弹窗背景',
13070
13120
  child: [
@@ -13489,7 +13539,7 @@ var CommodityListComponent = React.memo(CommodityList$1);
13489
13539
  * @FilePath: \pb-sxp-ui\src\materials\sxp\cta\AniLink\interactionRender.tsx
13490
13540
  *
13491
13541
  */
13492
- var interactionRender$d = [
13542
+ var interactionRender$e = [
13493
13543
  {
13494
13544
  title: '点击事件',
13495
13545
  child: [
@@ -13516,8 +13566,8 @@ const CommodityList = createMaterial(CommodityListComponent, {
13516
13566
  category: 'popup',
13517
13567
  type: 'CommodityList',
13518
13568
  related: {
13519
- settingRender: settingRender$b,
13520
- interactionRender: interactionRender$d
13569
+ settingRender: settingRender$c,
13570
+ interactionRender: interactionRender$e
13521
13571
  },
13522
13572
  defaulSetting: {
13523
13573
  props: {
@@ -13565,7 +13615,7 @@ const CommodityList = createMaterial(CommodityListComponent, {
13565
13615
  * @FilePath: \pb-sxp-ui\src\materials\sxp\popup\Iframe\settingRender.tsx
13566
13616
  *
13567
13617
  */
13568
- var settingRender$a = [
13618
+ var settingRender$b = [
13569
13619
  {
13570
13620
  title: '背景样式',
13571
13621
  child: [
@@ -13599,7 +13649,7 @@ const Iframe = createMaterial(IframeComponent, {
13599
13649
  category: 'popup',
13600
13650
  type: 'Iframe',
13601
13651
  related: {
13602
- settingRender: settingRender$a,
13652
+ settingRender: settingRender$b,
13603
13653
  bindableProps: []
13604
13654
  },
13605
13655
  defaulSetting: {
@@ -13619,7 +13669,7 @@ const Iframe = createMaterial(IframeComponent, {
13619
13669
  * @FilePath: \pb-sxp-ui\src\materials\sxp\popup\ConsentDetail\settingRender.tsx
13620
13670
  *
13621
13671
  */
13622
- var settingRender$9 = [
13672
+ var settingRender$a = [
13623
13673
  {
13624
13674
  title: '弹窗文本',
13625
13675
  child: [
@@ -13648,7 +13698,7 @@ const ConsentDetail = createMaterial(ConsentDetail$2, {
13648
13698
  category: 'popup',
13649
13699
  type: 'ConsentDetail',
13650
13700
  related: {
13651
- settingRender: settingRender$9,
13701
+ settingRender: settingRender$a,
13652
13702
  bindableProps: []
13653
13703
  },
13654
13704
  defaulSetting: {
@@ -13660,6 +13710,666 @@ const ConsentDetail = createMaterial(ConsentDetail$2, {
13660
13710
  sort: 7
13661
13711
  });
13662
13712
 
13713
+ var settingRender$9 = [
13714
+ {
13715
+ title: 'Shopify配置',
13716
+ child: [
13717
+ {
13718
+ type: 'Input',
13719
+ label: 'Shopify域名',
13720
+ name: ['props', 'shopifyDomain'],
13721
+ placeholder: 'your-store.myshopify.com'
13722
+ },
13723
+ {
13724
+ type: 'Input',
13725
+ label: 'Storefront Token',
13726
+ name: ['props', 'storefrontAccessToken'],
13727
+ placeholder: 'Storefront Access Token'
13728
+ }
13729
+ ]
13730
+ },
13731
+ {
13732
+ title: '弹窗背景',
13733
+ child: [
13734
+ {
13735
+ type: 'Number',
13736
+ label: '左右边距',
13737
+ name: ['props', 'popupBg', 'horizontalMargin']
13738
+ },
13739
+ {
13740
+ type: 'Number',
13741
+ label: '下边距',
13742
+ name: ['props', 'popupBg', 'bottomMargin']
13743
+ }
13744
+ ]
13745
+ },
13746
+ {
13747
+ title: '商品信息样式',
13748
+ child: [
13749
+ {
13750
+ name: ['props', 'variantStyles'],
13751
+ type: 'SelectLinkage',
13752
+ child: [
13753
+ {
13754
+ label: '字段',
13755
+ type: 'Select',
13756
+ options: [
13757
+ {
13758
+ label: '商品标题',
13759
+ value: 'title'
13760
+ },
13761
+ {
13762
+ label: '价格',
13763
+ value: 'price'
13764
+ },
13765
+ {
13766
+ label: '规格选项',
13767
+ value: 'option'
13768
+ },
13769
+ {
13770
+ label: '已选规格',
13771
+ value: 'selectedOption'
13772
+ }
13773
+ ],
13774
+ name: ['props', 'variantStyles', 'field'],
13775
+ initialValue: 'title'
13776
+ },
13777
+ {
13778
+ type: 'Group',
13779
+ child: [
13780
+ {
13781
+ label: '上边距',
13782
+ type: 'Number',
13783
+ addonAfter: 'px',
13784
+ name: ['marginTop']
13785
+ },
13786
+ {
13787
+ label: '下边距',
13788
+ type: 'Number',
13789
+ addonAfter: 'px',
13790
+ name: ['marginBottom']
13791
+ }
13792
+ ]
13793
+ },
13794
+ {
13795
+ type: 'Group',
13796
+ label: '字体',
13797
+ child: [
13798
+ {
13799
+ type: 'Select',
13800
+ name: ['fontFamily-cn'],
13801
+ bottomText: '中文字体'
13802
+ },
13803
+ {
13804
+ type: 'Select',
13805
+ name: ['fontFamily-en'],
13806
+ bottomText: '英文/其他字体'
13807
+ }
13808
+ ]
13809
+ },
13810
+ {
13811
+ type: 'Group',
13812
+ label: '',
13813
+ child: [
13814
+ {
13815
+ type: 'Color',
13816
+ name: ['color']
13817
+ },
13818
+ {
13819
+ type: 'Number',
13820
+ addonAfter: 'px',
13821
+ name: ['fontSize']
13822
+ }
13823
+ ]
13824
+ },
13825
+ {
13826
+ label: '样式',
13827
+ type: 'TextStyle'
13828
+ },
13829
+ {
13830
+ label: '对齐',
13831
+ type: 'TextAlign'
13832
+ },
13833
+ {
13834
+ label: '间距',
13835
+ type: 'TextSpace'
13836
+ }
13837
+ ]
13838
+ }
13839
+ ]
13840
+ },
13841
+ {
13842
+ title: '加购按钮样式',
13843
+ child: [
13844
+ {
13845
+ label: '英文大小写',
13846
+ type: 'Select',
13847
+ name: ['props', 'buttonStyle', 'textTransform'],
13848
+ options: [
13849
+ {
13850
+ label: '默认',
13851
+ value: 'unset'
13852
+ },
13853
+ {
13854
+ label: '小写',
13855
+ value: 'lowercase'
13856
+ },
13857
+ {
13858
+ label: '大写',
13859
+ value: 'uppercase'
13860
+ }
13861
+ ]
13862
+ },
13863
+ {
13864
+ type: 'Color',
13865
+ label: '背景色',
13866
+ name: ['props', 'buttonStyle', 'backgroundColor'],
13867
+ initialValue: '#000'
13868
+ },
13869
+ {
13870
+ type: 'Group',
13871
+ label: '尺寸',
13872
+ child: [
13873
+ {
13874
+ type: 'Number',
13875
+ name: ['props', 'buttonStyle', 'height'],
13876
+ addonAfter: 'H'
13877
+ }
13878
+ ]
13879
+ },
13880
+ {
13881
+ type: 'Group',
13882
+ label: '圆角',
13883
+ child: [
13884
+ {
13885
+ type: 'Slider',
13886
+ name: ['props', 'buttonStyle', 'borderRadius'],
13887
+ max: 100
13888
+ },
13889
+ {
13890
+ type: 'Number',
13891
+ name: ['props', 'buttonStyle', 'borderRadius'],
13892
+ addonAfter: 'px',
13893
+ max: 100
13894
+ }
13895
+ ]
13896
+ },
13897
+ {
13898
+ type: 'TextMargin',
13899
+ name: ['props', 'buttonStyle']
13900
+ },
13901
+ {
13902
+ type: 'Group',
13903
+ label: '字体',
13904
+ child: [
13905
+ {
13906
+ type: 'Select',
13907
+ name: ['props', 'buttonStyle', 'fontFamily-cn'],
13908
+ bottomText: '中文字体'
13909
+ },
13910
+ {
13911
+ type: 'Select',
13912
+ name: ['props', 'buttonStyle', 'fontFamily-en'],
13913
+ bottomText: '英文/其他字体'
13914
+ }
13915
+ ]
13916
+ },
13917
+ {
13918
+ type: 'Group',
13919
+ label: '',
13920
+ child: [
13921
+ {
13922
+ type: 'Color',
13923
+ name: ['props', 'buttonStyle', 'color'],
13924
+ initialValue: '#fff'
13925
+ },
13926
+ {
13927
+ type: 'Number',
13928
+ name: ['props', 'buttonStyle', 'fontSize'],
13929
+ addonAfter: 'px'
13930
+ }
13931
+ ]
13932
+ },
13933
+ {
13934
+ type: 'TextStyle',
13935
+ name: ['props', 'buttonStyle']
13936
+ },
13937
+ {
13938
+ type: 'TextAlign',
13939
+ name: ['props', 'buttonStyle']
13940
+ },
13941
+ {
13942
+ label: '间距',
13943
+ type: 'TextSpace',
13944
+ name: ['props', 'buttonStyle']
13945
+ }
13946
+ ]
13947
+ },
13948
+ {
13949
+ title: '文案配置',
13950
+ child: [
13951
+ {
13952
+ type: 'Input',
13953
+ label: '加购按钮文案',
13954
+ name: ['props', 'texts', 'addToCart'],
13955
+ placeholder: 'Add to Cart'
13956
+ },
13957
+ {
13958
+ type: 'Input',
13959
+ label: '选择规格提示',
13960
+ name: ['props', 'texts', 'selectOptions'],
13961
+ placeholder: 'Please select options'
13962
+ },
13963
+ {
13964
+ type: 'Input',
13965
+ label: '加载文案',
13966
+ name: ['props', 'texts', 'loading'],
13967
+ placeholder: 'Loading...'
13968
+ },
13969
+ {
13970
+ type: 'Input',
13971
+ label: '错误文案',
13972
+ name: ['props', 'texts', 'error'],
13973
+ placeholder: 'Failed to load product'
13974
+ }
13975
+ ]
13976
+ },
13977
+ {
13978
+ title: '数量选择器',
13979
+ child: [
13980
+ {
13981
+ type: 'Number',
13982
+ label: '按钮间距',
13983
+ name: ['props', 'quantityStyle', 'gap'],
13984
+ addonAfter: 'px',
13985
+ initialValue: 12
13986
+ }
13987
+ ]
13988
+ }
13989
+ ];
13990
+
13991
+ /*
13992
+ * @Author: tao
13993
+ * @Date: 2026-01-12
13994
+ * @Description: Add to Cart 交互配置
13995
+ */
13996
+ var interactionRender$d = () => {
13997
+ return (React.createElement("div", { style: { padding: '20px', color: '#666' } },
13998
+ React.createElement("p", null, "\u52A0\u8D2D\u5546\u54C1\u5F39\u7A97\u4EA4\u4E92\u8BF4\u660E\uFF1A"),
13999
+ React.createElement("ul", { style: { paddingLeft: '20px', lineHeight: '1.8' } },
14000
+ React.createElement("li", null, "\u70B9\u51FB\u5546\u54C1\u8BE6\u60C5\u5F39\u7A97\u7684\"Shop Now\"\u6309\u94AE\u540E\u81EA\u52A8\u5C55\u793A"),
14001
+ React.createElement("li", null, "\u901A\u8FC7Shopify Storefront API\u83B7\u53D6\u5546\u54C1\u89C4\u683C\u548C\u5E93\u5B58\u4FE1\u606F"),
14002
+ React.createElement("li", null, "\u7528\u6237\u9009\u62E9\u89C4\u683C\u540E\u5B9E\u65F6\u663E\u793A\u5BF9\u5E94SKU\u7684\u4EF7\u683C\u548C\u5E93\u5B58"),
14003
+ React.createElement("li", null, "\u70B9\u51FB\"Add to Cart\"\u6309\u94AE\u540E\u8DF3\u8F6C\u81F3Shopify\u8D2D\u7269\u8F66\u9875\u9762"),
14004
+ React.createElement("li", null, "\u65E0\u5E93\u5B58\u6216\u4E0D\u53EF\u552E\u5356\u7684\u89C4\u683C\u81EA\u52A8\u7F6E\u7070\u4E0D\u53EF\u9009"))));
14005
+ };
14006
+
14007
+ const AddToCartPopup$1 = (_a) => {
14008
+ var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
14009
+ 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"]);
14010
+ const { sxpParameter, popupDetailData, isPreview, bffFbReport, globalConfig } = useSxpDataSource();
14011
+ useEventReport();
14012
+ const curTimeRef = React.useRef(null);
14013
+ const [productData, setProductData] = React.useState(null);
14014
+ const [selectedOptions, setSelectedOptions] = React.useState({});
14015
+ const [selectedVariant, setSelectedVariant] = React.useState(null);
14016
+ const [quantity, setQuantity] = React.useState(1);
14017
+ const [loading, setLoading] = React.useState(true);
14018
+ const [error, setError] = React.useState(null);
14019
+ // 获取当前弹窗商品数据(自动从 popupDetailData 获取)
14020
+ const data = popupDetailData;
14021
+ 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];
14022
+ product === null || product === void 0 ? void 0 : product.bindCta;
14023
+ 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;
14024
+ // Shopify配置 - 优先级:props > globalConfig > 默认值
14025
+ const finalShopifyDomain = shopifyDomain || (globalConfig === null || globalConfig === void 0 ? void 0 : globalConfig.shopifyDomain) || 'dev-store-749237498237498636.myshopify.com';
14026
+ const finalStorefrontToken = storefrontAccessToken || (globalConfig === null || globalConfig === void 0 ? void 0 : globalConfig.storefrontAccessToken) || '77d894c490f79430ce7bd0a7efdff6b7';
14027
+ // 自动从商品数据获取 Shopify Product ID
14028
+ const productId = (product === null || product === void 0 ? void 0 : product.itemId) || '';
14029
+ // 文案
14030
+ const finalTexts = {
14031
+ addToCart: texts.addToCart || 'Add to Cart',
14032
+ selectOptions: texts.selectOptions || 'Please select options',
14033
+ loading: texts.loading || 'Loading...',
14034
+ error: texts.error || 'Failed to load product',
14035
+ color: texts.color || 'Color',
14036
+ size: texts.size || 'Size',
14037
+ material: texts.material || 'Material',
14038
+ style: texts.style || 'Style'
14039
+ };
14040
+ // 查询Shopify商品数据
14041
+ const fetchProductData = React.useCallback(() => __awaiter(void 0, void 0, void 0, function* () {
14042
+ var _m;
14043
+ if (!productId || !finalShopifyDomain || !finalStorefrontToken) {
14044
+ console.log('[AddToCartPopup] 缺少必要配置:', {
14045
+ productId,
14046
+ shopifyDomain: finalShopifyDomain,
14047
+ hasToken: !!finalStorefrontToken
14048
+ });
14049
+ setLoading(false);
14050
+ return;
14051
+ }
14052
+ console.log('[AddToCartPopup] 开始加载商品数据:', {
14053
+ productId,
14054
+ shopifyDomain: finalShopifyDomain
14055
+ });
14056
+ setLoading(true);
14057
+ setError(null);
14058
+ try {
14059
+ const query = `
14060
+ query getProduct($id: ID!) {
14061
+ product(id: $id) {
14062
+ id
14063
+ title
14064
+ images(first: 10) {
14065
+ edges {
14066
+ node {
14067
+ url
14068
+ }
14069
+ }
14070
+ }
14071
+ options {
14072
+ name
14073
+ values
14074
+ }
14075
+ variants(first: 100) {
14076
+ edges {
14077
+ node {
14078
+ id
14079
+ title
14080
+ availableForSale
14081
+ quantityAvailable
14082
+ price {
14083
+ amount
14084
+ currencyCode
14085
+ }
14086
+ image {
14087
+ url
14088
+ }
14089
+ selectedOptions {
14090
+ name
14091
+ value
14092
+ }
14093
+ }
14094
+ }
14095
+ }
14096
+ }
14097
+ }
14098
+ `;
14099
+ // 确保 Product ID 格式正确
14100
+ const formattedProductId = productId.startsWith('gid://')
14101
+ ? productId
14102
+ : `gid://shopify/Product/${productId}`;
14103
+ console.log('[AddToCartPopup] 使用的 Product ID:', formattedProductId);
14104
+ const response = yield fetch(`https://${finalShopifyDomain}/api/2024-01/graphql.json`, {
14105
+ method: 'POST',
14106
+ headers: {
14107
+ 'Content-Type': 'application/json',
14108
+ 'X-Shopify-Storefront-Access-Token': finalStorefrontToken
14109
+ },
14110
+ body: JSON.stringify({
14111
+ query,
14112
+ variables: { id: formattedProductId }
14113
+ })
14114
+ });
14115
+ if (!response.ok) {
14116
+ throw new Error(`HTTP ${response.status}`);
14117
+ }
14118
+ const result = yield response.json();
14119
+ if (result.errors) {
14120
+ console.error('[AddToCartPopup] GraphQL 错误:', result.errors);
14121
+ throw new Error(result.errors[0].message);
14122
+ }
14123
+ if (!((_m = result.data) === null || _m === void 0 ? void 0 : _m.product)) {
14124
+ console.error('[AddToCartPopup] 未找到商品');
14125
+ throw new Error('Product not found');
14126
+ }
14127
+ console.log('[AddToCartPopup] 商品数据加载成功:', result.data.product.title);
14128
+ setProductData(result.data.product);
14129
+ }
14130
+ catch (err) {
14131
+ const errorMessage = err instanceof Error ? err.message : finalTexts.error;
14132
+ setError(errorMessage);
14133
+ console.error('[AddToCartPopup] 加载失败:', err);
14134
+ }
14135
+ finally {
14136
+ setLoading(false);
14137
+ }
14138
+ }), [productId, finalShopifyDomain, finalStorefrontToken, finalTexts.error]);
14139
+ React.useEffect(() => {
14140
+ if (isActive) {
14141
+ fetchProductData();
14142
+ }
14143
+ }, [isActive, fetchProductData]);
14144
+ // 根据选中的规格匹配variant
14145
+ React.useEffect(() => {
14146
+ if (!productData)
14147
+ return;
14148
+ const variants = productData.variants.edges.map(edge => edge.node);
14149
+ const optionsCount = productData.options.length;
14150
+ const selectedCount = Object.keys(selectedOptions).length;
14151
+ if (selectedCount === 0 || selectedCount < optionsCount) {
14152
+ setSelectedVariant(null);
14153
+ return;
14154
+ }
14155
+ const matchedVariant = variants.find(variant => {
14156
+ return variant.selectedOptions.every(option => selectedOptions[option.name] === option.value);
14157
+ });
14158
+ setSelectedVariant(matchedVariant || null);
14159
+ setQuantity(1);
14160
+ }, [selectedOptions, productData]);
14161
+ // 处理规格选择
14162
+ const handleOptionSelect = React.useCallback((optionName, value) => {
14163
+ setSelectedOptions(prev => {
14164
+ const newOptions = Object.assign({}, prev);
14165
+ if (newOptions[optionName] === value) {
14166
+ delete newOptions[optionName];
14167
+ }
14168
+ else {
14169
+ newOptions[optionName] = value;
14170
+ }
14171
+ return newOptions;
14172
+ });
14173
+ }, []);
14174
+ // 处理数量变化
14175
+ const handleQuantityChange = React.useCallback((delta) => {
14176
+ setQuantity(prev => {
14177
+ var _a;
14178
+ const newQuantity = prev + delta;
14179
+ const maxQuantity = (_a = selectedVariant === null || selectedVariant === void 0 ? void 0 : selectedVariant.quantityAvailable) !== null && _a !== void 0 ? _a : 999;
14180
+ return Math.max(1, Math.min(newQuantity, maxQuantity));
14181
+ });
14182
+ }, [selectedVariant]);
14183
+ // 检查某个规格值是否可用
14184
+ const isOptionValueAvailable = React.useCallback((optionName, value) => {
14185
+ if (!productData)
14186
+ return false;
14187
+ const variants = productData.variants.edges.map(edge => edge.node);
14188
+ const tempOptions = Object.assign(Object.assign({}, selectedOptions), { [optionName]: value });
14189
+ return variants.some(variant => {
14190
+ const matches = variant.selectedOptions.every(option => !tempOptions[option.name] || tempOptions[option.name] === option.value);
14191
+ const hasStock = variant.quantityAvailable === null || variant.quantityAvailable > 0;
14192
+ return matches && variant.availableForSale && hasStock;
14193
+ });
14194
+ }, [productData, selectedOptions]);
14195
+ // 处理加购
14196
+ const handleAddToCart = React.useCallback(() => {
14197
+ var _a;
14198
+ if (!selectedVariant || quantity === 0)
14199
+ return;
14200
+ const variantId = selectedVariant.id.split('/').pop();
14201
+ const cartUrl = `https://${finalShopifyDomain}/cart/add?id=${variantId}&quantity=${quantity}`;
14202
+ console.log('[AddToCartPopup] 加购:', {
14203
+ variantId,
14204
+ quantity,
14205
+ cartUrl
14206
+ });
14207
+ // 上报事件
14208
+ bffFbReport === null || bffFbReport === void 0 ? void 0 : bffFbReport({
14209
+ eventName: 'AddToCart',
14210
+ product: product ? [product] : undefined,
14211
+ contentType: 'product',
14212
+ data,
14213
+ position,
14214
+ content_id: (_a = product === null || product === void 0 ? void 0 : product.itemId) !== null && _a !== void 0 ? _a : '',
14215
+ value: parseFloat(selectedVariant.price.amount) * quantity,
14216
+ currency: selectedVariant.price.currencyCode,
14217
+ contents: [{
14218
+ id: variantId,
14219
+ quantity
14220
+ }]
14221
+ });
14222
+ // 跳转到Shopify购物车页面
14223
+ window.location.href = cartUrl;
14224
+ }, [selectedVariant, quantity, finalShopifyDomain, bffFbReport, product, data, position]);
14225
+ // 计算总价
14226
+ const totalPrice = React.useMemo(() => {
14227
+ if (!selectedVariant)
14228
+ return null;
14229
+ const price = parseFloat(selectedVariant.price.amount);
14230
+ const total = price * quantity;
14231
+ return total.toFixed(2);
14232
+ }, [selectedVariant, quantity]);
14233
+ // 初始化时间
14234
+ React.useEffect(() => {
14235
+ const initTime = () => {
14236
+ curTimeRef.current = new Date();
14237
+ };
14238
+ initTime();
14239
+ window.addEventListener('pageshow', initTime);
14240
+ return () => {
14241
+ window.removeEventListener('pageshow', initTime);
14242
+ };
14243
+ }, []);
14244
+ // 加载中
14245
+ if (loading) {
14246
+ return (React.createElement("div", { className: "add-to-cart-popup-loading", style: style },
14247
+ React.createElement("div", null, finalTexts.loading)));
14248
+ }
14249
+ // 错误状态
14250
+ if (error || !productData) {
14251
+ return (React.createElement("div", { className: "add-to-cart-popup-error", style: style },
14252
+ React.createElement("div", null,
14253
+ finalTexts.error,
14254
+ ": ",
14255
+ error || 'Product not found')));
14256
+ }
14257
+ 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]) || '';
14258
+ const hasAllOptionsSelected = productData.options.length === Object.keys(selectedOptions).length;
14259
+ const isAddToCartDisabled = !selectedVariant || quantity === 0;
14260
+ return (React.createElement("div", Object.assign({ className: "add-to-cart-popup-container", style: style }, props),
14261
+ React.createElement("div", { className: "variant-detail-section" },
14262
+ React.createElement("div", { className: "variant-image-wrapper" },
14263
+ React.createElement("img", { src: mainImage, alt: productData.title, className: "variant-image" })),
14264
+ React.createElement("div", { className: "variant-info-wrapper" },
14265
+ React.createElement("h2", { className: "product-title-text", style: variantStyles.title, dangerouslySetInnerHTML: {
14266
+ __html: setFontForText(productData.title, variantStyles.title)
14267
+ } }),
14268
+ selectedVariant && (React.createElement(React.Fragment, null,
14269
+ React.createElement("div", { className: "selected-options-tags" }, selectedVariant.selectedOptions.map(option => (React.createElement("span", { key: option.name, className: "option-tag", style: variantStyles.selectedOption },
14270
+ option.name,
14271
+ ": ",
14272
+ option.value)))),
14273
+ React.createElement("div", { className: "price-display" },
14274
+ React.createElement("span", { className: "price-value", style: variantStyles.price, dangerouslySetInnerHTML: {
14275
+ __html: setFontForText(`${selectedVariant.price.currencyCode} $${totalPrice}`, variantStyles.price)
14276
+ } })),
14277
+ React.createElement("div", { className: "quantity-selector-wrapper", style: quantityStyle },
14278
+ React.createElement("button", { className: "quantity-btn quantity-decrease", onClick: () => handleQuantityChange(-1), disabled: quantity <= 1, "aria-label": "Decrease quantity" }, "-"),
14279
+ React.createElement("input", { type: "number", value: quantity, readOnly: true, className: "quantity-input-field", "aria-label": "Quantity" }),
14280
+ 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" }, "+")))),
14281
+ !hasAllOptionsSelected && (React.createElement("div", { className: "no-selection-hint", style: variantStyles.option }, finalTexts.selectOptions)))),
14282
+ React.createElement("div", { className: "variant-options-section" }, productData.options.map(option => (React.createElement("div", { key: option.name, className: "option-group-wrapper" },
14283
+ React.createElement("h3", { className: "option-group-name", style: variantStyles.option, dangerouslySetInnerHTML: {
14284
+ __html: setFontForText(option.name, variantStyles.option)
14285
+ } }),
14286
+ React.createElement("div", { className: "option-values-grid" }, option.values.map(value => {
14287
+ const isSelected = selectedOptions[option.name] === value;
14288
+ const isAvailable = isOptionValueAvailable(option.name, value);
14289
+ 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));
14290
+ })))))),
14291
+ React.createElement("button", { className: `add-to-cart-button ${isAddToCartDisabled ? 'disabled' : ''}`, style: buttonStyle, onClick: handleAddToCart, disabled: isAddToCartDisabled, "aria-label": finalTexts.addToCart },
14292
+ React.createElement("span", { dangerouslySetInnerHTML: {
14293
+ __html: setFontForText(finalTexts.addToCart, buttonStyle)
14294
+ } }))));
14295
+ };
14296
+
14297
+ /*
14298
+ * @Author: tao
14299
+ * @Date: 2026-01-12
14300
+ * @Description: Add to Cart 弹窗组件物料配置
14301
+ */
14302
+ const AddToCartPopup = createMaterial(AddToCartPopup$1, {
14303
+ displayName: '加购商品',
14304
+ icon: '',
14305
+ category: 'popup',
14306
+ type: 'AddToCartPopup',
14307
+ related: {
14308
+ settingRender: settingRender$9,
14309
+ interactionRender: interactionRender$d
14310
+ },
14311
+ defaulSetting: {
14312
+ props: {
14313
+ shopifyDomain: '',
14314
+ storefrontAccessToken: '',
14315
+ variantStyles: {
14316
+ title: {
14317
+ color: '#000',
14318
+ fontSize: 20,
14319
+ fontWeight: 600,
14320
+ marginBottom: 12
14321
+ },
14322
+ price: {
14323
+ color: '#000',
14324
+ fontSize: 24,
14325
+ fontWeight: 700,
14326
+ marginBottom: 16
14327
+ },
14328
+ option: {
14329
+ color: '#111',
14330
+ fontSize: 16,
14331
+ fontWeight: 600,
14332
+ marginBottom: 12
14333
+ },
14334
+ selectedOption: {
14335
+ fontSize: 14,
14336
+ color: '#374151'
14337
+ }
14338
+ },
14339
+ buttonStyle: {
14340
+ backgroundColor: '#000',
14341
+ color: '#fff',
14342
+ fontSize: 16,
14343
+ height: 52,
14344
+ fontWeight: 600,
14345
+ textAlign: 'center',
14346
+ textTransform: 'uppercase'
14347
+ },
14348
+ quantityStyle: {
14349
+ gap: 12
14350
+ },
14351
+ texts: {
14352
+ addToCart: 'Add to Cart',
14353
+ selectOptions: 'Please select options',
14354
+ loading: 'Loading...',
14355
+ error: 'Failed to load product',
14356
+ color: 'Color',
14357
+ size: 'Size',
14358
+ material: 'Material',
14359
+ style: 'Style'
14360
+ },
14361
+ popupBg: {
14362
+ horizontalMargin: 0,
14363
+ bottomMargin: 0
14364
+ }
14365
+ },
14366
+ style: {}
14367
+ },
14368
+ w: 100,
14369
+ h: 40,
14370
+ sort: 7
14371
+ });
14372
+
13663
14373
  /*
13664
14374
  * @Author: binruan@chatlabs.com
13665
14375
  * @Date: 2024-03-26 16:50:25
@@ -19151,6 +19861,7 @@ const MultiPosts = createMaterial(MultiPosts$2, {
19151
19861
 
19152
19862
  var _materials_ = /*#__PURE__*/Object.freeze({
19153
19863
  __proto__: null,
19864
+ AddToCartPopup: AddToCartPopup,
19154
19865
  AniLink: AniLink,
19155
19866
  AniLinkPopup: AniLinkPopup,
19156
19867
  Appoint: Appoint,