pb-sxp-ui 1.0.20 → 1.0.22

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 (39) hide show
  1. package/dist/index.cjs +75 -45
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.js +75 -45
  4. package/dist/index.js.map +1 -1
  5. package/dist/index.min.cjs +4 -3
  6. package/dist/index.min.cjs.map +1 -1
  7. package/dist/index.min.js +4 -3
  8. package/dist/index.min.js.map +1 -1
  9. package/dist/pb-ui.js +75 -45
  10. package/dist/pb-ui.js.map +1 -1
  11. package/dist/pb-ui.min.js +4 -3
  12. package/dist/pb-ui.min.js.map +1 -1
  13. package/es/core/components/SxpPageRender/FormatImage.d.ts +13 -0
  14. package/es/core/components/SxpPageRender/FormatImage.js +22 -0
  15. package/es/core/components/SxpPageRender/PictureGroup/Picture.js +25 -27
  16. package/es/core/components/SxpPageRender/VideoWidget/index.js +2 -1
  17. package/es/core/components/SxpPageRender/WaterFall/List.js +9 -7
  18. package/es/materials/sxp/popup/CommodityDetail/index.js +2 -1
  19. package/es/materials/sxp/popup/CommodityDetailDiro/index.js +2 -1
  20. package/es/materials/sxp/popup/CommodityDetailDiroNew/index.js +2 -1
  21. package/es/materials/sxp/template/Commodity/index.js +2 -1
  22. package/es/materials/sxp/template/CommodityDiro/index.js +2 -1
  23. package/es/materials/sxp/template/CommodityDiroNew/index.js +2 -1
  24. package/es/materials/sxp/template/Link/index.js +2 -1
  25. package/es/materials/sxp/template/components/Img.js +3 -1
  26. package/lib/core/components/SxpPageRender/FormatImage.d.ts +13 -0
  27. package/lib/core/components/SxpPageRender/FormatImage.js +25 -0
  28. package/lib/core/components/SxpPageRender/PictureGroup/Picture.js +24 -26
  29. package/lib/core/components/SxpPageRender/VideoWidget/index.js +2 -1
  30. package/lib/core/components/SxpPageRender/WaterFall/List.js +9 -7
  31. package/lib/materials/sxp/popup/CommodityDetail/index.js +2 -1
  32. package/lib/materials/sxp/popup/CommodityDetailDiro/index.js +2 -1
  33. package/lib/materials/sxp/popup/CommodityDetailDiroNew/index.js +2 -1
  34. package/lib/materials/sxp/template/Commodity/index.js +2 -1
  35. package/lib/materials/sxp/template/CommodityDiro/index.js +2 -1
  36. package/lib/materials/sxp/template/CommodityDiroNew/index.js +2 -1
  37. package/lib/materials/sxp/template/Link/index.js +2 -1
  38. package/lib/materials/sxp/template/components/Img.js +3 -1
  39. package/package.json +1 -1
@@ -0,0 +1,13 @@
1
+ import React, { CSSProperties } from 'react';
2
+ interface IFormatImageProps {
3
+ src?: string;
4
+ onLoad?: (e: any) => void;
5
+ style?: CSSProperties;
6
+ className?: any;
7
+ loading?: 'eager' | 'lazy';
8
+ }
9
+ interface IFormatImageRefProps {
10
+ setSrc: (v: string) => void;
11
+ }
12
+ declare const _default: React.MemoExoticComponent<React.ForwardRefExoticComponent<IFormatImageProps & React.RefAttributes<IFormatImageRefProps>>>;
13
+ export default _default;
@@ -0,0 +1,22 @@
1
+ import React, { forwardRef, memo, useImperativeHandle, useState } from 'react';
2
+ const FormatImage = forwardRef((props, ref) => {
3
+ const { src, onLoad, style, className, loading } = props;
4
+ const [imgSrc, setImgSrc] = useState(src);
5
+ useImperativeHandle(ref, () => ({
6
+ setSrc: (v) => {
7
+ setImgSrc(v);
8
+ }
9
+ }));
10
+ if (imgSrc === '' || !imgSrc)
11
+ return null;
12
+ return (imgSrc === null || imgSrc === void 0 ? void 0 : imgSrc.includes('.avif')) ? (React.createElement("picture", null,
13
+ React.createElement("source", { type: 'image/avif', srcSet: imgSrc }),
14
+ React.createElement("source", { type: 'image/webp', srcSet: `${imgSrc}?imageMogr2/format/webp` }),
15
+ React.createElement("source", { type: 'image/jpeg', srcSet: `${imgSrc}?imageMogr2/format/jpg` }),
16
+ React.createElement("img", { className: className, src: imgSrc, style: style, loading: loading, onLoad: (e) => {
17
+ onLoad === null || onLoad === void 0 ? void 0 : onLoad(e.target);
18
+ } }))) : (React.createElement("img", { className: className, src: imgSrc, style: style, loading: loading, onLoad: (e) => {
19
+ onLoad === null || onLoad === void 0 ? void 0 : onLoad(e.target);
20
+ } }));
21
+ });
22
+ export default memo(FormatImage);
@@ -1,31 +1,30 @@
1
- import React, { useCallback, useEffect, useState } from 'react';
1
+ import React, { useCallback, useState } from 'react';
2
+ import FormatImage from '../FormatImage';
2
3
  import { useSxpDataSource } from '../../../../core/hooks';
3
4
  const Picture = (props) => {
4
5
  const { src, height, width } = props;
5
6
  const [blur, setBlur] = useState(false);
6
7
  const { sxpParameter } = useSxpDataSource();
7
- useEffect(() => {
8
- if (src === '' || !src)
9
- return;
10
- const img = new Image();
11
- img.src = `${src}?imageMogr2/format/jpg`;
12
- img.onload = () => {
13
- const aspectRatio = img.height / img.width;
14
- const targetAspectRatio = 16 / 9;
15
- const tolerance = 0.05;
16
- if (Math.abs(aspectRatio - targetAspectRatio) > tolerance) {
17
- setBlur(true);
18
- }
19
- };
20
- }, [src]);
8
+ const onLoad = (img) => {
9
+ const aspectRatio = img.height / img.width;
10
+ const targetAspectRatio = 16 / 9;
11
+ const tolerance = 0.05;
12
+ if (Math.abs(aspectRatio - targetAspectRatio) > tolerance) {
13
+ setBlur(true);
14
+ }
15
+ };
21
16
  const getImg = useCallback((src, style) => {
22
17
  if (src === '' || !src)
23
18
  return;
24
- return (src === null || src === void 0 ? void 0 : src.indexOf('.avif')) !== -1 ? (React.createElement("picture", null,
19
+ return (src === null || src === void 0 ? void 0 : src.includes('.avif')) ? (React.createElement("picture", null,
25
20
  React.createElement("source", { type: 'image/avif', srcSet: src }),
26
21
  React.createElement("source", { type: 'image/webp', srcSet: `${src}?imageMogr2/format/webp` }),
27
22
  React.createElement("source", { type: 'image/jpeg', srcSet: `${src}?imageMogr2/format/jpg` }),
28
- React.createElement("img", { loading: 'lazy', src: src, style: style }))) : (React.createElement("img", { loading: 'lazy', src: src, style: style }));
23
+ React.createElement("img", { src: src, style: style, onLoad: (e) => {
24
+ onLoad(e.target);
25
+ } }))) : (React.createElement("img", { src: src, style: style, onLoad: (e) => {
26
+ onLoad(e.target);
27
+ } }));
29
28
  }, []);
30
29
  return (React.createElement("div", { style: {
31
30
  overflow: 'hidden',
@@ -33,15 +32,14 @@ const Picture = (props) => {
33
32
  width: '100%',
34
33
  position: 'relative'
35
34
  } },
36
- getImg(src !== null && src !== void 0 ? src : sxpParameter === null || sxpParameter === void 0 ? void 0 : sxpParameter.placeholder_image, {
37
- height: '100%',
38
- width: '100%',
39
- objectFit: 'cover',
40
- filter: blur ? 'blur(10px)' : 'none',
41
- transform: blur ? 'scale(1.2)' : 'none'
42
- }),
43
- blur &&
44
- getImg(src, {
35
+ React.createElement(FormatImage, { src: src, style: {
36
+ height: '100%',
37
+ width: '100%',
38
+ objectFit: 'cover',
39
+ filter: blur ? 'blur(10px)' : 'none',
40
+ transform: blur ? 'scale(1.2)' : 'none'
41
+ }, onLoad: onLoad }),
42
+ blur && (React.createElement(FormatImage, { src: src, style: {
45
43
  width: '100%',
46
44
  objectFit: 'contain',
47
45
  position: 'absolute',
@@ -49,6 +47,6 @@ const Picture = (props) => {
49
47
  transform: 'translateY(-50%)',
50
48
  left: 0,
51
49
  right: 0
52
- })));
50
+ } }))));
53
51
  };
54
52
  export default Picture;
@@ -212,7 +212,8 @@ const VideoWidget = ({ rec, index, height, data, muted, activeIndex }) => {
212
212
  width: '100%',
213
213
  height
214
214
  } },
215
- React.createElement("video", { id: `pb-video-${index}`, className: 'clc-pb-video', ref: videoRef, muted: true, controls: false, playsInline: true, preload: 'auto', onPause: onPause, onEnded: handleVideoStart }),
215
+ React.createElement("video", { id: `pb-video-${index}`, className: 'clc-pb-video', ref: videoRef, poster: sxpParameter === null || sxpParameter === void 0 ? void 0 : sxpParameter.placeholder_image, muted: true, controls: false, playsInline: true, preload: 'auto', onPause: onPause, onEnded: handleVideoStart }),
216
+ renderPoster,
216
217
  React.createElement("img", { hidden: !isPauseVideo, className: 'clc-pb-video-pause', src: PAUSE_ICON })));
217
218
  };
218
219
  export default memo(VideoWidget);
@@ -1,6 +1,7 @@
1
1
  import { __rest } from "tslib";
2
2
  import React, { useState, useEffect, useMemo, useRef, useCallback } from 'react';
3
3
  import './List.less';
4
+ import FormatImage from '../FormatImage';
4
5
  import previewData from './preview.json';
5
6
  import { useSxpDataSource } from '../../../../core/hooks';
6
7
  const WaterfallFlowItem = (props) => {
@@ -8,6 +9,7 @@ const WaterfallFlowItem = (props) => {
8
9
  const { swiperRef, setRtcList, setOpenHashtag, bffEventReport, sxpParameter } = useSxpDataSource();
9
10
  const [showVideo, setShowVideo] = useState(false);
10
11
  const imgDom = useRef(null);
12
+ const ref = useRef(null);
11
13
  const videoDom = useRef(null);
12
14
  const canvasRef = useRef(null);
13
15
  const [firstFrameSrc, setFirstFrameSrc] = useState('');
@@ -49,20 +51,20 @@ const WaterfallFlowItem = (props) => {
49
51
  const observer = new IntersectionObserver((entries) => {
50
52
  entries.forEach((entry) => {
51
53
  if (entry.isIntersecting) {
52
- if (imgDom.current === null || src === '') {
54
+ if (ref.current === null || src === '') {
53
55
  return;
54
56
  }
55
57
  if (showVideo && firstFrameSrc) {
56
- imgDom.current.src = firstFrameSrc;
58
+ imgDom.current.setSrc(firstFrameSrc);
57
59
  }
58
60
  else {
59
- imgDom.current.src = src;
61
+ imgDom.current.setSrc(src);
60
62
  }
61
- observer.unobserve(imgDom.current);
63
+ observer.unobserve(ref.current);
62
64
  }
63
65
  });
64
66
  });
65
- observer.observe(imgDom.current);
67
+ observer.observe(ref.current);
66
68
  return () => {
67
69
  observer.disconnect();
68
70
  };
@@ -104,12 +106,12 @@ const WaterfallFlowItem = (props) => {
104
106
  setOpenHashtag === null || setOpenHashtag === void 0 ? void 0 : setOpenHashtag(false);
105
107
  }, 0);
106
108
  };
107
- return (React.createElement("div", { className: 'list-content-listItem', key: index, onClick: handleClickToDetail, style: { marginBottom: space } },
109
+ return (React.createElement("div", { ref: ref, className: 'list-content-listItem', key: index, onClick: handleClickToDetail, style: { marginBottom: space } },
108
110
  React.createElement("div", { className: 'list-content-listItem-picture' },
109
111
  showVideo && (React.createElement("div", { style: { display: 'none' } },
110
112
  React.createElement("video", { ref: videoDom, crossOrigin: 'anonymous', className: 'list-content-listItem-picture-img' }),
111
113
  React.createElement("canvas", { ref: canvasRef }))),
112
- React.createElement("img", { className: 'list-content-listItem-picture-img', loading: 'lazy', ref: imgDom })),
114
+ React.createElement(FormatImage, { loading: 'lazy', className: 'list-content-listItem-picture-img', ref: imgDom })),
113
115
  React.createElement("div", { className: 'list-content-listItem-info' },
114
116
  React.createElement("div", { className: `${'list-content-listItem-info-title'} ${priceText ? 'list-content-listItem-info-nowrap' : ''}`, style: textStyles === null || textStyles === void 0 ? void 0 : textStyles.title }, title && title),
115
117
  React.createElement("div", { className: 'list-content-listItem-info-price', style: textStyles === null || textStyles === void 0 ? void 0 : textStyles.price, hidden: !priceText }, priceText))));
@@ -8,6 +8,7 @@ import { Swiper, SwiperSlide } from 'swiper/react';
8
8
  import { useEventReport } from '../../../../core/hooks/useEventReport';
9
9
  import Modal from '../../../../core/components/SxpPageRender/Modal';
10
10
  import ExpandableText from '../../../../core/components/SxpPageRender/ExpandableText';
11
+ import FormatImage from '../../../../core/components/SxpPageRender/FormatImage';
11
12
  const CommodityDetail = (_a) => {
12
13
  var _b, _c, _d, _e, _f, _g, _h, _j;
13
14
  var { content, style, bgImg, onClick, schema, isDefault, bottom_image, tipText, isPost, viewTime, rec, swiper, commodityStyles, buttonStyle, index } = _a, props = __rest(_a, ["content", "style", "bgImg", "onClick", "schema", "isDefault", "bottom_image", "tipText", "isPost", "viewTime", "rec", "swiper", "commodityStyles", "buttonStyle", "index"]);
@@ -85,7 +86,7 @@ const CommodityDetail = (_a) => {
85
86
  width,
86
87
  height: width
87
88
  } },
88
- React.createElement("img", { src: src, style: { height: '100%', width: '100%', objectFit: 'cover' } }))));
89
+ React.createElement(FormatImage, { style: { height: '100%', width: '100%', objectFit: 'cover', display: 'block' }, src: src }))));
89
90
  }))),
90
91
  !((_h = product === null || product === void 0 ? void 0 : product.homePage) === null || _h === void 0 ? void 0 : _h.length) && (React.createElement("div", { className: css({
91
92
  position: 'relative',
@@ -7,6 +7,7 @@ import { Autoplay, Pagination } from 'swiper/modules';
7
7
  import { Swiper, SwiperSlide } from 'swiper/react';
8
8
  import arrow from './arrow.png';
9
9
  import { useEventReport } from '../../../../core/hooks/useEventReport';
10
+ import FormatImage from '../../../../core/components/SxpPageRender/FormatImage';
10
11
  const CommodityDetailDiro = (_a) => {
11
12
  var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
12
13
  var { style, isDefault, rec, viewTime, isPost, bottom_image, index } = _a, props = __rest(_a, ["style", "isDefault", "rec", "viewTime", "isPost", "bottom_image", "index"]);
@@ -127,7 +128,7 @@ const CommodityDetailDiro = (_a) => {
127
128
  width,
128
129
  height: width
129
130
  } },
130
- React.createElement("img", { src: src, style: { height: '100%', width: '100%', objectFit: 'cover' } }))));
131
+ React.createElement(FormatImage, { style: { height: '100%', width: '100%', objectFit: 'cover', display: 'block' }, src: src }))));
131
132
  }))),
132
133
  !((_h = product === null || product === void 0 ? void 0 : product.homePage) === null || _h === void 0 ? void 0 : _h.length) && (React.createElement("div", { className: css({
133
134
  position: 'relative',
@@ -8,6 +8,7 @@ import { Swiper, SwiperSlide } from 'swiper/react';
8
8
  import Modal from '../../../../core/components/SxpPageRender/Modal';
9
9
  import ExpandableText from '../../../../core/components/SxpPageRender/ExpandableText';
10
10
  import { useEventReport } from '../../../../core/hooks/useEventReport';
11
+ import FormatImage from '../../../../core/components/SxpPageRender/FormatImage';
11
12
  const CommodityDetailDiroNew = (_a) => {
12
13
  var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
13
14
  var { style, isDefault, rec, viewTime, isPost, bottom_image, tipText, swiper, commodityStyles, buttonStyle, index } = _a, props = __rest(_a, ["style", "isDefault", "rec", "viewTime", "isPost", "bottom_image", "tipText", "swiper", "commodityStyles", "buttonStyle", "index"]);
@@ -103,7 +104,7 @@ Made in Italy` })));
103
104
  width,
104
105
  height: width
105
106
  } },
106
- React.createElement("img", { src: src, style: { height: '100%', width: '100%', objectFit: 'cover' } }))));
107
+ React.createElement(FormatImage, { style: { height: '100%', width: '100%', objectFit: 'cover', display: 'block' }, src: src }))));
107
108
  }))),
108
109
  !((_h = product === null || product === void 0 ? void 0 : product.homePage) === null || _h === void 0 ? void 0 : _h.length) && (React.createElement("div", { className: css({
109
110
  position: 'relative',
@@ -4,6 +4,7 @@ import React, { memo } from 'react';
4
4
  import EventProvider from '../components/EventProvider';
5
5
  import styles from './index.module.less';
6
6
  import { useSxpDataSource } from '../../../../core/hooks';
7
+ import FormatImage from '../../../../core/components/SxpPageRender/FormatImage';
7
8
  const Commodity = (_a) => {
8
9
  var _b, _c, _d, _e, _f, _g, _h;
9
10
  var { content, style, bgImg, recData, bottom_image, ctaTempStyles, isExternalLink } = _a, props = __rest(_a, ["content", "style", "bgImg", "recData", "bottom_image", "ctaTempStyles", "isExternalLink"]);
@@ -12,7 +13,7 @@ const Commodity = (_a) => {
12
13
  const src = (_e = (_d = (_c = product === null || product === void 0 ? void 0 : product.homePage) === null || _c === void 0 ? void 0 : _c[0]) !== null && _d !== void 0 ? _d : sxpParameter === null || sxpParameter === void 0 ? void 0 : sxpParameter.bottom_image) !== null && _e !== void 0 ? _e : bottom_image;
13
14
  return (React.createElement(EventProvider, Object.assign({ isExternalLink: isExternalLink, rec: recData, className: css(Object.assign({}, style)), style: { display: 'flex' } }, props),
14
15
  React.createElement("div", { className: css(Object.assign({ overflow: 'hidden', flexShrink: 0, backgroundColor: '#f2f2f2' }, ctaTempStyles === null || ctaTempStyles === void 0 ? void 0 : ctaTempStyles.img)) },
15
- React.createElement("img", { className: css({ width: '100%', objectFit: 'cover', height: '100%' }), src: src, hidden: !src, alt: '' })),
16
+ React.createElement(FormatImage, { className: css({ width: '100%', objectFit: 'cover', height: '100%', display: 'block' }), src: src })),
16
17
  React.createElement("div", { className: css({
17
18
  color: '#fff',
18
19
  display: 'flex',
@@ -4,6 +4,7 @@ import React, { memo } from 'react';
4
4
  import EventProvider from '../components/EventProvider';
5
5
  import styles from './index.module.less';
6
6
  import { useSxpDataSource } from '../../../../core/hooks';
7
+ import FormatImage from '../../../../core/components/SxpPageRender/FormatImage';
7
8
  const CommodityDiro = (_a) => {
8
9
  var _b, _c, _d, _e, _f, _g, _h;
9
10
  var { content, style, bgImg, recData, bottom_image, ctaTempStyles, isExternalLink } = _a, props = __rest(_a, ["content", "style", "bgImg", "recData", "bottom_image", "ctaTempStyles", "isExternalLink"]);
@@ -12,7 +13,7 @@ const CommodityDiro = (_a) => {
12
13
  const src = (_e = (_d = (_c = product === null || product === void 0 ? void 0 : product.homePage) === null || _c === void 0 ? void 0 : _c[0]) !== null && _d !== void 0 ? _d : sxpParameter === null || sxpParameter === void 0 ? void 0 : sxpParameter.bottom_image) !== null && _e !== void 0 ? _e : bottom_image;
13
14
  return (React.createElement(EventProvider, Object.assign({ isExternalLink: isExternalLink, rec: recData, className: css(Object.assign({}, style)), style: { display: 'flex' } }, props),
14
15
  React.createElement("div", { className: css(Object.assign({ overflow: 'hidden', flexShrink: 0, backgroundColor: '#f2f2f2' }, ctaTempStyles === null || ctaTempStyles === void 0 ? void 0 : ctaTempStyles.img)) },
15
- React.createElement("img", { className: css({ width: '100%', objectFit: 'cover', height: '100%' }), src: src, hidden: !src, alt: '' })),
16
+ React.createElement(FormatImage, { className: css({ width: '100%', objectFit: 'cover', height: '100%', display: 'block' }), src: src })),
16
17
  React.createElement("div", { className: css({
17
18
  color: '#fff',
18
19
  display: 'flex',
@@ -4,6 +4,7 @@ import React, { memo } from 'react';
4
4
  import EventProvider from '../components/EventProvider';
5
5
  import styles from './index.module.less';
6
6
  import { useSxpDataSource } from '../../../../core/hooks';
7
+ import FormatImage from '../../../../core/components/SxpPageRender/FormatImage';
7
8
  const CommodityDiroNew = (_a) => {
8
9
  var _b, _c, _d, _e, _f, _g, _h;
9
10
  var { content, style, bgImg, recData, bottom_image, ctaTempStyles, isExternalLink } = _a, props = __rest(_a, ["content", "style", "bgImg", "recData", "bottom_image", "ctaTempStyles", "isExternalLink"]);
@@ -12,7 +13,7 @@ const CommodityDiroNew = (_a) => {
12
13
  const src = (_e = (_d = (_c = product === null || product === void 0 ? void 0 : product.homePage) === null || _c === void 0 ? void 0 : _c[0]) !== null && _d !== void 0 ? _d : sxpParameter === null || sxpParameter === void 0 ? void 0 : sxpParameter.bottom_image) !== null && _e !== void 0 ? _e : bottom_image;
13
14
  return (React.createElement(EventProvider, Object.assign({ isExternalLink: isExternalLink, rec: recData, className: css(Object.assign({}, style)), style: { display: 'flex' } }, props),
14
15
  React.createElement("div", { className: css(Object.assign({ overflow: 'hidden', flexShrink: 0, backgroundColor: '#f2f2f2' }, ctaTempStyles === null || ctaTempStyles === void 0 ? void 0 : ctaTempStyles.img)) },
15
- React.createElement("img", { className: css({ width: '100%', objectFit: 'cover', height: '100%' }), src: src, hidden: !src, alt: '' })),
16
+ React.createElement(FormatImage, { className: css({ width: '100%', objectFit: 'cover', height: '100%', display: 'block' }), src: src })),
16
17
  React.createElement("div", { className: css({
17
18
  color: '#fff',
18
19
  display: 'flex',
@@ -5,6 +5,7 @@ import EventProvider from '../components/EventProvider';
5
5
  import styles from './index.module.less';
6
6
  import { useSxpDataSource } from '../../../../core/hooks';
7
7
  import { useEventReport } from '../../../../core/hooks/useEventReport';
8
+ import FormatImage from '../../../../core/components/SxpPageRender/FormatImage';
8
9
  const Link = (_a) => {
9
10
  var _b, _c, _d, _e, _f;
10
11
  var { content, style, bgImg, recData, bottom_image, ctaTempStyles, index } = _a, props = __rest(_a, ["content", "style", "bgImg", "recData", "bottom_image", "ctaTempStyles", "index"]);
@@ -20,7 +21,7 @@ const Link = (_a) => {
20
21
  };
21
22
  return (React.createElement(EventProvider, Object.assign({ index: index, rec: recData, className: css(Object.assign({ alignItems: 'center' }, style)), style: { display: 'flex' } }, props, { onClick: handleTo }),
22
23
  React.createElement("div", { className: css(Object.assign({ backgroundColor: '#f2f2f2', overflow: 'hidden', flexShrink: 0 }, ctaTempStyles === null || ctaTempStyles === void 0 ? void 0 : ctaTempStyles.img)) },
23
- React.createElement("img", { className: css({ width: '100%', objectFit: 'cover', height: '100%' }), src: (_e = (_d = cta === null || cta === void 0 ? void 0 : cta.icon) !== null && _d !== void 0 ? _d : sxpParameter === null || sxpParameter === void 0 ? void 0 : sxpParameter.bottom_image) !== null && _e !== void 0 ? _e : bottom_image, alt: '' })),
24
+ React.createElement(FormatImage, { className: css({ width: '100%', objectFit: 'cover', height: '100%', display: 'block' }), src: (_e = (_d = cta === null || cta === void 0 ? void 0 : cta.icon) !== null && _d !== void 0 ? _d : sxpParameter === null || sxpParameter === void 0 ? void 0 : sxpParameter.bottom_image) !== null && _e !== void 0 ? _e : bottom_image })),
24
25
  React.createElement("div", { className: css({
25
26
  display: 'flex',
26
27
  alignItems: 'center',
@@ -2,6 +2,7 @@ import { css } from '@emotion/css';
2
2
  import React, { memo, useEffect, useRef } from 'react';
3
3
  import useOnScreen from '../../../../core/hooks/useOnScreen';
4
4
  import { useSxpDataSource } from '../../../../core/hooks';
5
+ import FormatImage from '../../../../core/components/SxpPageRender/FormatImage';
5
6
  const Img = ({ src, rec, item, index }) => {
6
7
  const ref = useRef(null);
7
8
  const isOnScreen = useOnScreen(ref);
@@ -14,6 +15,7 @@ const Img = ({ src, rec, item, index }) => {
14
15
  }, rec, item, index);
15
16
  }
16
17
  }, [isOnScreen, src, ref, rec, ctaEvent, item, index]);
17
- return (React.createElement("img", { ref: ref, hidden: !src, className: css({ width: '100%', objectFit: 'cover', height: '100%' }), src: src, alt: '' }));
18
+ return (React.createElement("div", { ref: ref, hidden: !src },
19
+ React.createElement(FormatImage, { className: css({ width: '100%', objectFit: 'cover', height: '100%', display: 'block' }), src: src })));
18
20
  };
19
21
  export default memo(Img);
@@ -0,0 +1,13 @@
1
+ import React, { CSSProperties } from 'react';
2
+ interface IFormatImageProps {
3
+ src?: string;
4
+ onLoad?: (e: any) => void;
5
+ style?: CSSProperties;
6
+ className?: any;
7
+ loading?: 'eager' | 'lazy';
8
+ }
9
+ interface IFormatImageRefProps {
10
+ setSrc: (v: string) => void;
11
+ }
12
+ declare const _default: React.MemoExoticComponent<React.ForwardRefExoticComponent<IFormatImageProps & React.RefAttributes<IFormatImageRefProps>>>;
13
+ export default _default;
@@ -0,0 +1,25 @@
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 FormatImage = (0, react_1.forwardRef)((props, ref) => {
6
+ const { src, onLoad, style, className, loading } = props;
7
+ const [imgSrc, setImgSrc] = (0, react_1.useState)(src);
8
+ (0, react_1.useImperativeHandle)(ref, () => ({
9
+ setSrc: (v) => {
10
+ setImgSrc(v);
11
+ }
12
+ }));
13
+ if (imgSrc === '' || !imgSrc)
14
+ return null;
15
+ return (imgSrc === null || imgSrc === void 0 ? void 0 : imgSrc.includes('.avif')) ? (react_1.default.createElement("picture", null,
16
+ react_1.default.createElement("source", { type: 'image/avif', srcSet: imgSrc }),
17
+ react_1.default.createElement("source", { type: 'image/webp', srcSet: `${imgSrc}?imageMogr2/format/webp` }),
18
+ react_1.default.createElement("source", { type: 'image/jpeg', srcSet: `${imgSrc}?imageMogr2/format/jpg` }),
19
+ react_1.default.createElement("img", { className: className, src: imgSrc, style: style, loading: loading, onLoad: (e) => {
20
+ onLoad === null || onLoad === void 0 ? void 0 : onLoad(e.target);
21
+ } }))) : (react_1.default.createElement("img", { className: className, src: imgSrc, style: style, loading: loading, onLoad: (e) => {
22
+ onLoad === null || onLoad === void 0 ? void 0 : onLoad(e.target);
23
+ } }));
24
+ });
25
+ exports.default = (0, react_1.memo)(FormatImage);
@@ -2,33 +2,32 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  const react_1 = tslib_1.__importStar(require("react"));
5
+ const FormatImage_1 = tslib_1.__importDefault(require("../FormatImage"));
5
6
  const hooks_1 = require("../../../../core/hooks");
6
7
  const Picture = (props) => {
7
8
  const { src, height, width } = props;
8
9
  const [blur, setBlur] = (0, react_1.useState)(false);
9
10
  const { sxpParameter } = (0, hooks_1.useSxpDataSource)();
10
- (0, react_1.useEffect)(() => {
11
- if (src === '' || !src)
12
- return;
13
- const img = new Image();
14
- img.src = `${src}?imageMogr2/format/jpg`;
15
- img.onload = () => {
16
- const aspectRatio = img.height / img.width;
17
- const targetAspectRatio = 16 / 9;
18
- const tolerance = 0.05;
19
- if (Math.abs(aspectRatio - targetAspectRatio) > tolerance) {
20
- setBlur(true);
21
- }
22
- };
23
- }, [src]);
11
+ const onLoad = (img) => {
12
+ const aspectRatio = img.height / img.width;
13
+ const targetAspectRatio = 16 / 9;
14
+ const tolerance = 0.05;
15
+ if (Math.abs(aspectRatio - targetAspectRatio) > tolerance) {
16
+ setBlur(true);
17
+ }
18
+ };
24
19
  const getImg = (0, react_1.useCallback)((src, style) => {
25
20
  if (src === '' || !src)
26
21
  return;
27
- return (src === null || src === void 0 ? void 0 : src.indexOf('.avif')) !== -1 ? (react_1.default.createElement("picture", null,
22
+ return (src === null || src === void 0 ? void 0 : src.includes('.avif')) ? (react_1.default.createElement("picture", null,
28
23
  react_1.default.createElement("source", { type: 'image/avif', srcSet: src }),
29
24
  react_1.default.createElement("source", { type: 'image/webp', srcSet: `${src}?imageMogr2/format/webp` }),
30
25
  react_1.default.createElement("source", { type: 'image/jpeg', srcSet: `${src}?imageMogr2/format/jpg` }),
31
- react_1.default.createElement("img", { loading: 'lazy', src: src, style: style }))) : (react_1.default.createElement("img", { loading: 'lazy', src: src, style: style }));
26
+ react_1.default.createElement("img", { src: src, style: style, onLoad: (e) => {
27
+ onLoad(e.target);
28
+ } }))) : (react_1.default.createElement("img", { src: src, style: style, onLoad: (e) => {
29
+ onLoad(e.target);
30
+ } }));
32
31
  }, []);
33
32
  return (react_1.default.createElement("div", { style: {
34
33
  overflow: 'hidden',
@@ -36,15 +35,14 @@ const Picture = (props) => {
36
35
  width: '100%',
37
36
  position: 'relative'
38
37
  } },
39
- getImg(src !== null && src !== void 0 ? src : sxpParameter === null || sxpParameter === void 0 ? void 0 : sxpParameter.placeholder_image, {
40
- height: '100%',
41
- width: '100%',
42
- objectFit: 'cover',
43
- filter: blur ? 'blur(10px)' : 'none',
44
- transform: blur ? 'scale(1.2)' : 'none'
45
- }),
46
- blur &&
47
- getImg(src, {
38
+ react_1.default.createElement(FormatImage_1.default, { src: src, style: {
39
+ height: '100%',
40
+ width: '100%',
41
+ objectFit: 'cover',
42
+ filter: blur ? 'blur(10px)' : 'none',
43
+ transform: blur ? 'scale(1.2)' : 'none'
44
+ }, onLoad: onLoad }),
45
+ blur && (react_1.default.createElement(FormatImage_1.default, { src: src, style: {
48
46
  width: '100%',
49
47
  objectFit: 'contain',
50
48
  position: 'absolute',
@@ -52,6 +50,6 @@ const Picture = (props) => {
52
50
  transform: 'translateY(-50%)',
53
51
  left: 0,
54
52
  right: 0
55
- })));
53
+ } }))));
56
54
  };
57
55
  exports.default = Picture;
@@ -215,7 +215,8 @@ const VideoWidget = ({ rec, index, height, data, muted, activeIndex }) => {
215
215
  width: '100%',
216
216
  height
217
217
  } },
218
- react_1.default.createElement("video", { id: `pb-video-${index}`, className: 'clc-pb-video', ref: videoRef, muted: true, controls: false, playsInline: true, preload: 'auto', onPause: onPause, onEnded: handleVideoStart }),
218
+ react_1.default.createElement("video", { id: `pb-video-${index}`, className: 'clc-pb-video', ref: videoRef, poster: sxpParameter === null || sxpParameter === void 0 ? void 0 : sxpParameter.placeholder_image, muted: true, controls: false, playsInline: true, preload: 'auto', onPause: onPause, onEnded: handleVideoStart }),
219
+ renderPoster,
219
220
  react_1.default.createElement("img", { hidden: !isPauseVideo, className: 'clc-pb-video-pause', src: PAUSE_ICON })));
220
221
  };
221
222
  exports.default = (0, react_1.memo)(VideoWidget);
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const tslib_1 = require("tslib");
4
4
  const react_1 = tslib_1.__importStar(require("react"));
5
5
  require("./List.less");
6
+ const FormatImage_1 = tslib_1.__importDefault(require("../FormatImage"));
6
7
  const preview_json_1 = tslib_1.__importDefault(require("./preview.json"));
7
8
  const hooks_1 = require("../../../../core/hooks");
8
9
  const WaterfallFlowItem = (props) => {
@@ -10,6 +11,7 @@ const WaterfallFlowItem = (props) => {
10
11
  const { swiperRef, setRtcList, setOpenHashtag, bffEventReport, sxpParameter } = (0, hooks_1.useSxpDataSource)();
11
12
  const [showVideo, setShowVideo] = (0, react_1.useState)(false);
12
13
  const imgDom = (0, react_1.useRef)(null);
14
+ const ref = (0, react_1.useRef)(null);
13
15
  const videoDom = (0, react_1.useRef)(null);
14
16
  const canvasRef = (0, react_1.useRef)(null);
15
17
  const [firstFrameSrc, setFirstFrameSrc] = (0, react_1.useState)('');
@@ -51,20 +53,20 @@ const WaterfallFlowItem = (props) => {
51
53
  const observer = new IntersectionObserver((entries) => {
52
54
  entries.forEach((entry) => {
53
55
  if (entry.isIntersecting) {
54
- if (imgDom.current === null || src === '') {
56
+ if (ref.current === null || src === '') {
55
57
  return;
56
58
  }
57
59
  if (showVideo && firstFrameSrc) {
58
- imgDom.current.src = firstFrameSrc;
60
+ imgDom.current.setSrc(firstFrameSrc);
59
61
  }
60
62
  else {
61
- imgDom.current.src = src;
63
+ imgDom.current.setSrc(src);
62
64
  }
63
- observer.unobserve(imgDom.current);
65
+ observer.unobserve(ref.current);
64
66
  }
65
67
  });
66
68
  });
67
- observer.observe(imgDom.current);
69
+ observer.observe(ref.current);
68
70
  return () => {
69
71
  observer.disconnect();
70
72
  };
@@ -106,12 +108,12 @@ const WaterfallFlowItem = (props) => {
106
108
  setOpenHashtag === null || setOpenHashtag === void 0 ? void 0 : setOpenHashtag(false);
107
109
  }, 0);
108
110
  };
109
- return (react_1.default.createElement("div", { className: 'list-content-listItem', key: index, onClick: handleClickToDetail, style: { marginBottom: space } },
111
+ return (react_1.default.createElement("div", { ref: ref, className: 'list-content-listItem', key: index, onClick: handleClickToDetail, style: { marginBottom: space } },
110
112
  react_1.default.createElement("div", { className: 'list-content-listItem-picture' },
111
113
  showVideo && (react_1.default.createElement("div", { style: { display: 'none' } },
112
114
  react_1.default.createElement("video", { ref: videoDom, crossOrigin: 'anonymous', className: 'list-content-listItem-picture-img' }),
113
115
  react_1.default.createElement("canvas", { ref: canvasRef }))),
114
- react_1.default.createElement("img", { className: 'list-content-listItem-picture-img', loading: 'lazy', ref: imgDom })),
116
+ react_1.default.createElement(FormatImage_1.default, { loading: 'lazy', className: 'list-content-listItem-picture-img', ref: imgDom })),
115
117
  react_1.default.createElement("div", { className: 'list-content-listItem-info' },
116
118
  react_1.default.createElement("div", { className: `${'list-content-listItem-info-title'} ${priceText ? 'list-content-listItem-info-nowrap' : ''}`, style: textStyles === null || textStyles === void 0 ? void 0 : textStyles.title }, title && title),
117
119
  react_1.default.createElement("div", { className: 'list-content-listItem-info-price', style: textStyles === null || textStyles === void 0 ? void 0 : textStyles.price, hidden: !priceText }, priceText))));
@@ -10,6 +10,7 @@ const react_2 = require("swiper/react");
10
10
  const useEventReport_1 = require("../../../../core/hooks/useEventReport");
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
+ const FormatImage_1 = tslib_1.__importDefault(require("../../../../core/components/SxpPageRender/FormatImage"));
13
14
  const CommodityDetail = (_a) => {
14
15
  var _b, _c, _d, _e, _f, _g, _h, _j;
15
16
  var { content, style, bgImg, onClick, schema, isDefault, bottom_image, tipText, isPost, viewTime, rec, swiper, commodityStyles, buttonStyle, index } = _a, props = tslib_1.__rest(_a, ["content", "style", "bgImg", "onClick", "schema", "isDefault", "bottom_image", "tipText", "isPost", "viewTime", "rec", "swiper", "commodityStyles", "buttonStyle", "index"]);
@@ -87,7 +88,7 @@ const CommodityDetail = (_a) => {
87
88
  width,
88
89
  height: width
89
90
  } },
90
- react_1.default.createElement("img", { src: src, style: { height: '100%', width: '100%', objectFit: 'cover' } }))));
91
+ react_1.default.createElement(FormatImage_1.default, { style: { height: '100%', width: '100%', objectFit: 'cover', display: 'block' }, src: src }))));
91
92
  }))),
92
93
  !((_h = product === null || product === void 0 ? void 0 : product.homePage) === null || _h === void 0 ? void 0 : _h.length) && (react_1.default.createElement("div", { className: (0, css_1.css)({
93
94
  position: 'relative',
@@ -9,6 +9,7 @@ const modules_1 = require("swiper/modules");
9
9
  const react_2 = require("swiper/react");
10
10
  const arrow_png_1 = tslib_1.__importDefault(require("./arrow.png"));
11
11
  const useEventReport_1 = require("../../../../core/hooks/useEventReport");
12
+ const FormatImage_1 = tslib_1.__importDefault(require("../../../../core/components/SxpPageRender/FormatImage"));
12
13
  const CommodityDetailDiro = (_a) => {
13
14
  var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
14
15
  var { style, isDefault, rec, viewTime, isPost, bottom_image, index } = _a, props = tslib_1.__rest(_a, ["style", "isDefault", "rec", "viewTime", "isPost", "bottom_image", "index"]);
@@ -129,7 +130,7 @@ const CommodityDetailDiro = (_a) => {
129
130
  width,
130
131
  height: width
131
132
  } },
132
- react_1.default.createElement("img", { src: src, style: { height: '100%', width: '100%', objectFit: 'cover' } }))));
133
+ react_1.default.createElement(FormatImage_1.default, { style: { height: '100%', width: '100%', objectFit: 'cover', display: 'block' }, src: src }))));
133
134
  }))),
134
135
  !((_h = product === null || product === void 0 ? void 0 : product.homePage) === null || _h === void 0 ? void 0 : _h.length) && (react_1.default.createElement("div", { className: (0, css_1.css)({
135
136
  position: 'relative',
@@ -10,6 +10,7 @@ const react_2 = require("swiper/react");
10
10
  const Modal_1 = tslib_1.__importDefault(require("../../../../core/components/SxpPageRender/Modal"));
11
11
  const ExpandableText_1 = tslib_1.__importDefault(require("../../../../core/components/SxpPageRender/ExpandableText"));
12
12
  const useEventReport_1 = require("../../../../core/hooks/useEventReport");
13
+ const FormatImage_1 = tslib_1.__importDefault(require("../../../../core/components/SxpPageRender/FormatImage"));
13
14
  const CommodityDetailDiroNew = (_a) => {
14
15
  var _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
15
16
  var { style, isDefault, rec, viewTime, isPost, bottom_image, tipText, swiper, commodityStyles, buttonStyle, index } = _a, props = tslib_1.__rest(_a, ["style", "isDefault", "rec", "viewTime", "isPost", "bottom_image", "tipText", "swiper", "commodityStyles", "buttonStyle", "index"]);
@@ -105,7 +106,7 @@ Made in Italy` })));
105
106
  width,
106
107
  height: width
107
108
  } },
108
- react_1.default.createElement("img", { src: src, style: { height: '100%', width: '100%', objectFit: 'cover' } }))));
109
+ react_1.default.createElement(FormatImage_1.default, { style: { height: '100%', width: '100%', objectFit: 'cover', display: 'block' }, src: src }))));
109
110
  }))),
110
111
  !((_h = product === null || product === void 0 ? void 0 : product.homePage) === null || _h === void 0 ? void 0 : _h.length) && (react_1.default.createElement("div", { className: (0, css_1.css)({
111
112
  position: 'relative',
@@ -6,6 +6,7 @@ const react_1 = tslib_1.__importStar(require("react"));
6
6
  const EventProvider_1 = tslib_1.__importDefault(require("../components/EventProvider"));
7
7
  const index_module_less_1 = tslib_1.__importDefault(require("./index.module.less"));
8
8
  const hooks_1 = require("../../../../core/hooks");
9
+ const FormatImage_1 = tslib_1.__importDefault(require("../../../../core/components/SxpPageRender/FormatImage"));
9
10
  const Commodity = (_a) => {
10
11
  var _b, _c, _d, _e, _f, _g, _h;
11
12
  var { content, style, bgImg, recData, bottom_image, ctaTempStyles, isExternalLink } = _a, props = tslib_1.__rest(_a, ["content", "style", "bgImg", "recData", "bottom_image", "ctaTempStyles", "isExternalLink"]);
@@ -14,7 +15,7 @@ const Commodity = (_a) => {
14
15
  const src = (_e = (_d = (_c = product === null || product === void 0 ? void 0 : product.homePage) === null || _c === void 0 ? void 0 : _c[0]) !== null && _d !== void 0 ? _d : sxpParameter === null || sxpParameter === void 0 ? void 0 : sxpParameter.bottom_image) !== null && _e !== void 0 ? _e : bottom_image;
15
16
  return (react_1.default.createElement(EventProvider_1.default, Object.assign({ isExternalLink: isExternalLink, rec: recData, className: (0, css_1.css)(Object.assign({}, style)), style: { display: 'flex' } }, props),
16
17
  react_1.default.createElement("div", { className: (0, css_1.css)(Object.assign({ overflow: 'hidden', flexShrink: 0, backgroundColor: '#f2f2f2' }, ctaTempStyles === null || ctaTempStyles === void 0 ? void 0 : ctaTempStyles.img)) },
17
- react_1.default.createElement("img", { className: (0, css_1.css)({ width: '100%', objectFit: 'cover', height: '100%' }), src: src, hidden: !src, alt: '' })),
18
+ react_1.default.createElement(FormatImage_1.default, { className: (0, css_1.css)({ width: '100%', objectFit: 'cover', height: '100%', display: 'block' }), src: src })),
18
19
  react_1.default.createElement("div", { className: (0, css_1.css)({
19
20
  color: '#fff',
20
21
  display: 'flex',