pb-sxp-ui 1.0.25 → 1.0.26

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.
@@ -1,15 +1,16 @@
1
- import React, { forwardRef, memo, useImperativeHandle, useState } from 'react';
1
+ import React, { forwardRef, memo, useEffect, useImperativeHandle, useState } from 'react';
2
2
  const FormatImage = forwardRef((props, ref) => {
3
3
  const { src, onLoad, style, className, loading } = props;
4
- const [imgSrc, setImgSrc] = useState(src);
4
+ const [imgSrc, setImgSrc] = useState();
5
5
  useImperativeHandle(ref, () => ({
6
6
  setSrc: (v) => {
7
7
  setImgSrc(v);
8
8
  }
9
9
  }));
10
- if (imgSrc === '' || !imgSrc)
11
- return null;
12
- return (imgSrc === null || imgSrc === void 0 ? void 0 : imgSrc.includes('.avif')) ? (React.createElement("picture", null,
10
+ useEffect(() => {
11
+ setImgSrc(src);
12
+ }, [src]);
13
+ return (React.createElement(React.Fragment, null, (imgSrc === null || imgSrc === void 0 ? void 0 : imgSrc.includes('.avif')) ? (React.createElement("picture", null,
13
14
  React.createElement("source", { type: 'image/avif', srcSet: imgSrc }),
14
15
  React.createElement("source", { type: 'image/webp', srcSet: `${imgSrc}?imageMogr2/format/webp` }),
15
16
  React.createElement("source", { type: 'image/jpeg', srcSet: `${imgSrc}?imageMogr2/format/jpg` }),
@@ -17,6 +18,6 @@ const FormatImage = forwardRef((props, ref) => {
17
18
  onLoad === null || onLoad === void 0 ? void 0 : onLoad(e.target);
18
19
  } }))) : (React.createElement("img", { className: className, src: imgSrc, style: style, loading: loading, onLoad: (e) => {
19
20
  onLoad === null || onLoad === void 0 ? void 0 : onLoad(e.target);
20
- } }));
21
+ } }))));
21
22
  });
22
23
  export default memo(FormatImage);
@@ -12,6 +12,8 @@ const VideoWidget = ({ rec, index, height, data, muted, activeIndex, videoPostCo
12
12
  const [isLoadFinish, setIsLoadFinish] = useState(false);
13
13
  const [isFirstPlay, setIsFirstPlay] = useState(true);
14
14
  const { isActive } = useSwiperSlide();
15
+ const canvasRef = useRef(null);
16
+ const [firstFrameSrc, setFirstFrameSrc] = useState('');
15
17
  useEffect(() => {
16
18
  if (!videoRef.current)
17
19
  return;
@@ -105,8 +107,24 @@ const VideoWidget = ({ rec, index, height, data, muted, activeIndex, videoPostCo
105
107
  });
106
108
  }
107
109
  }, [data, index, bffEventReport]);
110
+ const handLoadeddata = useCallback(() => {
111
+ const video = videoRef === null || videoRef === void 0 ? void 0 : videoRef.current;
112
+ if (!video)
113
+ return;
114
+ const canvas = canvasRef === null || canvasRef === void 0 ? void 0 : canvasRef.current;
115
+ if (!canvas)
116
+ return;
117
+ const ctx = canvas.getContext('2d');
118
+ const targetWidth = window === null || window === void 0 ? void 0 : window.innerWidth;
119
+ const targetHeight = window === null || window === void 0 ? void 0 : window.innerHeight;
120
+ canvas.height = targetHeight;
121
+ canvas.width = targetWidth;
122
+ ctx === null || ctx === void 0 ? void 0 : ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
123
+ setFirstFrameSrc(canvas.toDataURL());
124
+ canvas.remove();
125
+ }, []);
108
126
  useEffect(() => {
109
- var _a, _b;
127
+ var _a, _b, _c;
110
128
  if (!videoRef.current)
111
129
  return;
112
130
  setIsPauseVideo(false);
@@ -118,12 +136,14 @@ const VideoWidget = ({ rec, index, height, data, muted, activeIndex, videoPostCo
118
136
  }
119
137
  (_a = videoRef.current) === null || _a === void 0 ? void 0 : _a.addEventListener('canplay', handleLoadedMetadata);
120
138
  (_b = videoRef.current) === null || _b === void 0 ? void 0 : _b.addEventListener('playing', handlePlaying);
139
+ (_c = videoRef.current) === null || _c === void 0 ? void 0 : _c.addEventListener('loadeddata', handLoadeddata);
121
140
  return () => {
122
- var _a, _b;
141
+ var _a, _b, _c;
123
142
  (_a = videoRef.current) === null || _a === void 0 ? void 0 : _a.removeEventListener('canplay', handleLoadedMetadata);
124
143
  (_b = videoRef.current) === null || _b === void 0 ? void 0 : _b.removeEventListener('playing', handlePlaying);
144
+ (_c = videoRef.current) === null || _c === void 0 ? void 0 : _c.removeEventListener('loadeddata', handLoadeddata);
125
145
  };
126
- }, [handleLoadedMetadata, handlePlaying, rec.video]);
146
+ }, [handleLoadedMetadata, handlePlaying, rec.video, handLoadeddata]);
127
147
  useEffect(() => {
128
148
  var _a;
129
149
  if (!(videoRef === null || videoRef === void 0 ? void 0 : videoRef.current) || !isLoadFinish)
@@ -186,21 +206,27 @@ const VideoWidget = ({ rec, index, height, data, muted, activeIndex, videoPostCo
186
206
  ? `translateY(-${50 + ((_a = videoPostConfig === null || videoPostConfig === void 0 ? void 0 : videoPostConfig.offsetTop) !== null && _a !== void 0 ? _a : 0)}%)`
187
207
  : 'translateY(-50%)';
188
208
  }, [videoPostConfig]);
209
+ const blurBgSrc = useMemo(() => {
210
+ var _a;
211
+ return ((_a = rec === null || rec === void 0 ? void 0 : rec.video) === null || _a === void 0 ? void 0 : _a.cover) || firstFrameSrc;
212
+ }, [firstFrameSrc, rec]);
189
213
  if (!rec.video) {
190
214
  return null;
191
215
  }
192
216
  return (React.createElement(React.Fragment, null, blur ? (React.createElement("div", { className: 'video-container', key: rec.video.itemId, onClick: handleClickVideo(), style: {
193
217
  position: 'relative',
194
218
  width: '100%',
195
- height
219
+ height,
220
+ overflow: 'hidden'
196
221
  } },
197
- React.createElement(FormatImage, { src: sxpParameter === null || sxpParameter === void 0 ? void 0 : sxpParameter.placeholder_image, style: {
222
+ React.createElement(FormatImage, { src: blurBgSrc, style: {
198
223
  height: '100%',
199
224
  width: '100%',
200
225
  objectFit: 'cover',
201
226
  filter: blur ? 'blur(10px)' : 'none',
202
227
  transform: blur ? 'scale(1.2)' : 'none'
203
228
  } }),
229
+ React.createElement("canvas", { ref: canvasRef, style: { display: 'none' } }),
204
230
  React.createElement("div", { style: {
205
231
  position: 'absolute',
206
232
  width: '100%',
@@ -211,7 +237,7 @@ const VideoWidget = ({ rec, index, height, data, muted, activeIndex, videoPostCo
211
237
  right: 0
212
238
  } },
213
239
  React.createElement("div", { style: { position: 'relative' } },
214
- 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, style: {
240
+ React.createElement("video", { id: `pb-video-${index}`, className: 'clc-pb-video', ref: videoRef, crossOrigin: 'anonymous', poster: sxpParameter === null || sxpParameter === void 0 ? void 0 : sxpParameter.placeholder_image, muted: true, controls: false, playsInline: true, preload: 'auto', onPause: onPause, onEnded: handleVideoStart, style: {
215
241
  width: '100%',
216
242
  height: 'auto',
217
243
  objectFit: 'contain'
@@ -220,9 +246,10 @@ const VideoWidget = ({ rec, index, height, data, muted, activeIndex, videoPostCo
220
246
  React.createElement("img", { hidden: !isPauseVideo, className: 'clc-pb-video-pause', src: PAUSE_ICON }))))) : (React.createElement("div", { className: 'video-container', key: rec.video.itemId, onClick: handleClickVideo(), style: {
221
247
  position: 'relative',
222
248
  width: '100%',
223
- height
249
+ height,
250
+ overflow: 'hidden'
224
251
  } },
225
- 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 }),
252
+ React.createElement("video", { id: `pb-video-${index}`, className: 'clc-pb-video', ref: videoRef, crossOrigin: 'anonymous', poster: sxpParameter === null || sxpParameter === void 0 ? void 0 : sxpParameter.placeholder_image, muted: true, controls: false, playsInline: true, preload: 'auto', onPause: onPause, onEnded: handleVideoStart }),
226
253
  renderPoster,
227
254
  React.createElement("img", { hidden: !isPauseVideo, className: 'clc-pb-video-pause', src: PAUSE_ICON })))));
228
255
  };
@@ -4,15 +4,16 @@ const tslib_1 = require("tslib");
4
4
  const react_1 = tslib_1.__importStar(require("react"));
5
5
  const FormatImage = (0, react_1.forwardRef)((props, ref) => {
6
6
  const { src, onLoad, style, className, loading } = props;
7
- const [imgSrc, setImgSrc] = (0, react_1.useState)(src);
7
+ const [imgSrc, setImgSrc] = (0, react_1.useState)();
8
8
  (0, react_1.useImperativeHandle)(ref, () => ({
9
9
  setSrc: (v) => {
10
10
  setImgSrc(v);
11
11
  }
12
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,
13
+ (0, react_1.useEffect)(() => {
14
+ setImgSrc(src);
15
+ }, [src]);
16
+ return (react_1.default.createElement(react_1.default.Fragment, null, (imgSrc === null || imgSrc === void 0 ? void 0 : imgSrc.includes('.avif')) ? (react_1.default.createElement("picture", null,
16
17
  react_1.default.createElement("source", { type: 'image/avif', srcSet: imgSrc }),
17
18
  react_1.default.createElement("source", { type: 'image/webp', srcSet: `${imgSrc}?imageMogr2/format/webp` }),
18
19
  react_1.default.createElement("source", { type: 'image/jpeg', srcSet: `${imgSrc}?imageMogr2/format/jpg` }),
@@ -20,6 +21,6 @@ const FormatImage = (0, react_1.forwardRef)((props, ref) => {
20
21
  onLoad === null || onLoad === void 0 ? void 0 : onLoad(e.target);
21
22
  } }))) : (react_1.default.createElement("img", { className: className, src: imgSrc, style: style, loading: loading, onLoad: (e) => {
22
23
  onLoad === null || onLoad === void 0 ? void 0 : onLoad(e.target);
23
- } }));
24
+ } }))));
24
25
  });
25
26
  exports.default = (0, react_1.memo)(FormatImage);
@@ -15,6 +15,8 @@ const VideoWidget = ({ rec, index, height, data, muted, activeIndex, videoPostCo
15
15
  const [isLoadFinish, setIsLoadFinish] = (0, react_1.useState)(false);
16
16
  const [isFirstPlay, setIsFirstPlay] = (0, react_1.useState)(true);
17
17
  const { isActive } = (0, react_2.useSwiperSlide)();
18
+ const canvasRef = (0, react_1.useRef)(null);
19
+ const [firstFrameSrc, setFirstFrameSrc] = (0, react_1.useState)('');
18
20
  (0, react_1.useEffect)(() => {
19
21
  if (!videoRef.current)
20
22
  return;
@@ -108,8 +110,24 @@ const VideoWidget = ({ rec, index, height, data, muted, activeIndex, videoPostCo
108
110
  });
109
111
  }
110
112
  }, [data, index, bffEventReport]);
113
+ const handLoadeddata = (0, react_1.useCallback)(() => {
114
+ const video = videoRef === null || videoRef === void 0 ? void 0 : videoRef.current;
115
+ if (!video)
116
+ return;
117
+ const canvas = canvasRef === null || canvasRef === void 0 ? void 0 : canvasRef.current;
118
+ if (!canvas)
119
+ return;
120
+ const ctx = canvas.getContext('2d');
121
+ const targetWidth = window === null || window === void 0 ? void 0 : window.innerWidth;
122
+ const targetHeight = window === null || window === void 0 ? void 0 : window.innerHeight;
123
+ canvas.height = targetHeight;
124
+ canvas.width = targetWidth;
125
+ ctx === null || ctx === void 0 ? void 0 : ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
126
+ setFirstFrameSrc(canvas.toDataURL());
127
+ canvas.remove();
128
+ }, []);
111
129
  (0, react_1.useEffect)(() => {
112
- var _a, _b;
130
+ var _a, _b, _c;
113
131
  if (!videoRef.current)
114
132
  return;
115
133
  setIsPauseVideo(false);
@@ -121,12 +139,14 @@ const VideoWidget = ({ rec, index, height, data, muted, activeIndex, videoPostCo
121
139
  }
122
140
  (_a = videoRef.current) === null || _a === void 0 ? void 0 : _a.addEventListener('canplay', handleLoadedMetadata);
123
141
  (_b = videoRef.current) === null || _b === void 0 ? void 0 : _b.addEventListener('playing', handlePlaying);
142
+ (_c = videoRef.current) === null || _c === void 0 ? void 0 : _c.addEventListener('loadeddata', handLoadeddata);
124
143
  return () => {
125
- var _a, _b;
144
+ var _a, _b, _c;
126
145
  (_a = videoRef.current) === null || _a === void 0 ? void 0 : _a.removeEventListener('canplay', handleLoadedMetadata);
127
146
  (_b = videoRef.current) === null || _b === void 0 ? void 0 : _b.removeEventListener('playing', handlePlaying);
147
+ (_c = videoRef.current) === null || _c === void 0 ? void 0 : _c.removeEventListener('loadeddata', handLoadeddata);
128
148
  };
129
- }, [handleLoadedMetadata, handlePlaying, rec.video]);
149
+ }, [handleLoadedMetadata, handlePlaying, rec.video, handLoadeddata]);
130
150
  (0, react_1.useEffect)(() => {
131
151
  var _a;
132
152
  if (!(videoRef === null || videoRef === void 0 ? void 0 : videoRef.current) || !isLoadFinish)
@@ -189,21 +209,27 @@ const VideoWidget = ({ rec, index, height, data, muted, activeIndex, videoPostCo
189
209
  ? `translateY(-${50 + ((_a = videoPostConfig === null || videoPostConfig === void 0 ? void 0 : videoPostConfig.offsetTop) !== null && _a !== void 0 ? _a : 0)}%)`
190
210
  : 'translateY(-50%)';
191
211
  }, [videoPostConfig]);
212
+ const blurBgSrc = (0, react_1.useMemo)(() => {
213
+ var _a;
214
+ return ((_a = rec === null || rec === void 0 ? void 0 : rec.video) === null || _a === void 0 ? void 0 : _a.cover) || firstFrameSrc;
215
+ }, [firstFrameSrc, rec]);
192
216
  if (!rec.video) {
193
217
  return null;
194
218
  }
195
219
  return (react_1.default.createElement(react_1.default.Fragment, null, blur ? (react_1.default.createElement("div", { className: 'video-container', key: rec.video.itemId, onClick: handleClickVideo(), style: {
196
220
  position: 'relative',
197
221
  width: '100%',
198
- height
222
+ height,
223
+ overflow: 'hidden'
199
224
  } },
200
- react_1.default.createElement(FormatImage_1.default, { src: sxpParameter === null || sxpParameter === void 0 ? void 0 : sxpParameter.placeholder_image, style: {
225
+ react_1.default.createElement(FormatImage_1.default, { src: blurBgSrc, style: {
201
226
  height: '100%',
202
227
  width: '100%',
203
228
  objectFit: 'cover',
204
229
  filter: blur ? 'blur(10px)' : 'none',
205
230
  transform: blur ? 'scale(1.2)' : 'none'
206
231
  } }),
232
+ react_1.default.createElement("canvas", { ref: canvasRef, style: { display: 'none' } }),
207
233
  react_1.default.createElement("div", { style: {
208
234
  position: 'absolute',
209
235
  width: '100%',
@@ -214,7 +240,7 @@ const VideoWidget = ({ rec, index, height, data, muted, activeIndex, videoPostCo
214
240
  right: 0
215
241
  } },
216
242
  react_1.default.createElement("div", { style: { position: 'relative' } },
217
- 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, style: {
243
+ react_1.default.createElement("video", { id: `pb-video-${index}`, className: 'clc-pb-video', ref: videoRef, crossOrigin: 'anonymous', poster: sxpParameter === null || sxpParameter === void 0 ? void 0 : sxpParameter.placeholder_image, muted: true, controls: false, playsInline: true, preload: 'auto', onPause: onPause, onEnded: handleVideoStart, style: {
218
244
  width: '100%',
219
245
  height: 'auto',
220
246
  objectFit: 'contain'
@@ -223,9 +249,10 @@ const VideoWidget = ({ rec, index, height, data, muted, activeIndex, videoPostCo
223
249
  react_1.default.createElement("img", { hidden: !isPauseVideo, className: 'clc-pb-video-pause', src: PAUSE_ICON }))))) : (react_1.default.createElement("div", { className: 'video-container', key: rec.video.itemId, onClick: handleClickVideo(), style: {
224
250
  position: 'relative',
225
251
  width: '100%',
226
- height
252
+ height,
253
+ overflow: 'hidden'
227
254
  } },
228
- 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 }),
255
+ react_1.default.createElement("video", { id: `pb-video-${index}`, className: 'clc-pb-video', ref: videoRef, crossOrigin: 'anonymous', poster: sxpParameter === null || sxpParameter === void 0 ? void 0 : sxpParameter.placeholder_image, muted: true, controls: false, playsInline: true, preload: 'auto', onPause: onPause, onEnded: handleVideoStart }),
229
256
  renderPoster,
230
257
  react_1.default.createElement("img", { hidden: !isPauseVideo, className: 'clc-pb-video-pause', src: PAUSE_ICON })))));
231
258
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pb-sxp-ui",
3
- "version": "1.0.25",
3
+ "version": "1.0.26",
4
4
  "description": "React enterprise-class UI components",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",