@cntrl-site/sdk-nextjs 1.8.21 → 1.8.23

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.
Binary file
@@ -1,34 +1,24 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.SectionImage = void 0;
7
4
  const jsx_runtime_1 = require("react/jsx-runtime");
8
- const react_1 = require("react");
9
- const style_1 = __importDefault(require("styled-jsx/style"));
10
5
  const SectionImage = ({ media, sectionId }) => {
11
- const id = (0, react_1.useId)();
12
6
  const { url, size, position, offsetX } = media;
13
7
  const isContainHeight = size === 'contain-height';
14
8
  const hasOffsetX = offsetX !== null && size === 'contain';
15
- return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { className: `section-image-wrapper-${sectionId}`, children: (0, jsx_runtime_1.jsx)("img", { src: url, className: `image-background-${sectionId}` }) }), (0, jsx_runtime_1.jsx)(style_1.default, { id: id, children: `
16
- .section-image-wrapper-${sectionId} {
17
- position: ${position === 'fixed' ? 'sticky' : 'relative'};
18
- height: ${position === 'fixed' ? '100vh' : '100%'};
19
- top: ${position === 'fixed' ? '100vh' : '0'};
20
- width: 100%;
21
- overflow: hidden;
22
- }
23
- .image-background-${sectionId} {
24
- object-fit: ${isContainHeight ? 'unset' : size !== null && size !== void 0 ? size : 'cover'};
25
- width: ${isContainHeight || hasOffsetX ? 'auto' : '100%'};
26
- transform: ${isContainHeight ? 'translateX(-50%)' : 'none'};
27
- position: relative;
28
- left: ${isContainHeight ? '50%' : (hasOffsetX ? `${offsetX * 100}vw` : '0')};
29
- height: 100%;
30
- ${offsetX ? 'max-width: 100vw;' : ''}
31
- }
32
- ` })] }));
9
+ return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, jsx_runtime_1.jsx)("div", { className: `section-image-wrapper-${sectionId}`, style: {
10
+ position: position === 'fixed' ? 'sticky' : 'relative',
11
+ height: position === 'fixed' ? '100vh' : '100%',
12
+ top: position === 'fixed' ? '100vh' : '0',
13
+ width: '100%',
14
+ overflow: 'hidden'
15
+ }, children: (0, jsx_runtime_1.jsx)("img", { src: url, className: `image-background-${sectionId}`, style: {
16
+ objectFit: isContainHeight ? 'unset' : (size !== null && size !== void 0 ? size : 'cover'),
17
+ width: isContainHeight || hasOffsetX ? 'auto' : '100%',
18
+ transform: isContainHeight ? 'translateX(-50%)' : 'none',
19
+ position: 'relative',
20
+ left: isContainHeight ? '50%' : (hasOffsetX ? `${offsetX * 100}vw` : '0'),
21
+ height: '100%'
22
+ } }) }) }));
33
23
  };
34
24
  exports.SectionImage = SectionImage;
@@ -1,16 +1,13 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.SectionVideo = void 0;
7
4
  const jsx_runtime_1 = require("react/jsx-runtime");
8
5
  const react_1 = require("react");
9
- const style_1 = __importDefault(require("styled-jsx/style"));
10
6
  const SectionVideo = ({ container, sectionId, media }) => {
11
7
  const [video, setVideo] = (0, react_1.useState)(null);
8
+ const [videoWrapper, setVideoWrapper] = (0, react_1.useState)(null);
9
+ const [isVideoWidthOverflow, setIsVideoWidthOverflow] = (0, react_1.useState)(false);
12
10
  const { url, size, position, offsetX, coverUrl, play } = media;
13
- const id = (0, react_1.useId)();
14
11
  const [isPlaying, setIsPlaying] = (0, react_1.useState)(false);
15
12
  const [userPaused, setUserPaused] = (0, react_1.useState)(false);
16
13
  const [isClickedOnCover, setIsClickedOnCover] = (0, react_1.useState)(false);
@@ -43,42 +40,52 @@ const SectionVideo = ({ container, sectionId, media }) => {
43
40
  observer.observe(container);
44
41
  return () => observer.disconnect();
45
42
  }, [container, play, userPaused, isClickedOnCover]);
43
+ (0, react_1.useEffect)(() => {
44
+ if (!video || !videoWrapper)
45
+ return;
46
+ video.addEventListener('loadedmetadata', () => {
47
+ const h = video.videoHeight;
48
+ const w = video.videoWidth;
49
+ const width = (videoWrapper.clientHeight / h) * w;
50
+ if (width > videoWrapper.clientWidth) {
51
+ setIsVideoWidthOverflow(true);
52
+ }
53
+ else {
54
+ setIsVideoWidthOverflow(false);
55
+ }
56
+ });
57
+ }, [video, videoWrapper]);
46
58
  const isContainHeight = size === 'contain-height';
47
59
  const hasOffsetX = offsetX !== null && size === 'contain';
48
- return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)("div", { className: `section-video-wrapper-${sectionId}`, children: [(0, jsx_runtime_1.jsx)("video", { ref: setVideo, autoPlay: play === 'auto', loop: true, style: { opacity: !isPlaying && play === 'on-click' && coverUrl ? 0 : 1 }, controls: false, muted: play === 'auto', playsInline: true, preload: "auto", className: `video-background-${sectionId}`, onPlay: () => setIsPlaying(true), onPause: () => setIsPlaying(false), children: (0, jsx_runtime_1.jsx)("source", { src: `${url}#t=0.001` }) }), (0, jsx_runtime_1.jsx)("div", { className: `video-background-${sectionId}-cover-container`, onClick: handleCoverClick, children: coverUrl && play === 'on-click' && ((0, jsx_runtime_1.jsx)("img", { src: coverUrl, alt: "Video cover", className: `video-background-${sectionId}-cover`, style: { opacity: isPlaying ? 0 : 1 } })) })] }), (0, jsx_runtime_1.jsx)(style_1.default, { id: id, children: `
49
- .section-video-wrapper-${sectionId} {
50
- position: ${position === 'fixed' ? 'sticky' : 'relative'};
51
- height: ${position === 'fixed' ? '100vh' : '100%'};
52
- top: ${position === 'fixed' ? '100vh' : '0'};
53
- width: 100%;
54
- overflow: hidden;
55
- }
56
- .video-background-${sectionId}-cover-container {
57
- position: absolute;
58
- pointer-events: ${play === 'on-click' ? 'auto' : 'none'};
59
- left: 0;
60
- width: 100%;
61
- height: 100%;
62
- top: 0;
63
- }
64
- .video-background-${sectionId}-cover {
65
- position: relative;
66
- left: ${isContainHeight ? '50%' : (hasOffsetX ? `${offsetX * 100}vw` : '0')};
67
- width: ${isContainHeight ? 'auto' : '100%'};
68
- height: 100%;
69
- object-fit: ${isContainHeight ? 'unset' : size !== null && size !== void 0 ? size : 'cover'};
70
- transition: opacity 0.1s ease-in-out;
71
- transform: ${isContainHeight ? 'translateX(-50%)' : 'none'};
72
- ${hasOffsetX ? 'max-width: 100vw;' : ''}
73
- }
74
- .video-background-${sectionId} {
75
- object-fit: ${isContainHeight ? 'unset' : size !== null && size !== void 0 ? size : 'cover'};
76
- width: ${isContainHeight ? 'auto' : '100%'};
77
- height: 100%;
78
- position: relative;
79
- transform: ${isContainHeight ? 'translateX(-50%)' : 'none'};
80
- left: ${isContainHeight ? '50%' : (hasOffsetX ? `${offsetX * 100}vw` : '0')};
81
- }
82
- ` })] }));
60
+ return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: (0, jsx_runtime_1.jsxs)("div", { ref: setVideoWrapper, className: `section-video-wrapper-${sectionId}`, style: {
61
+ position: position === 'fixed' ? 'sticky' : 'relative',
62
+ height: position === 'fixed' ? '100vh' : '100%',
63
+ top: position === 'fixed' ? '100vh' : '0',
64
+ overflow: 'hidden',
65
+ width: '100%'
66
+ }, children: [(0, jsx_runtime_1.jsx)("video", { ref: setVideo, autoPlay: play === 'auto', loop: true, style: {
67
+ opacity: !isPlaying && play === 'on-click' && coverUrl ? 0 : 1,
68
+ objectFit: isContainHeight ? 'cover' : (size !== null && size !== void 0 ? size : 'cover'),
69
+ width: isContainHeight && !isVideoWidthOverflow ? 'auto' : '100%',
70
+ transform: isContainHeight ? 'translateX(-50%)' : 'none',
71
+ left: isContainHeight ? '50%' : (hasOffsetX ? `${offsetX * 100}vw` : '0'),
72
+ height: '100%',
73
+ position: 'relative'
74
+ }, controls: play === 'on-click', muted: play === 'auto', playsInline: true, preload: "auto", className: `video-background-${sectionId}`, onPlay: () => setIsPlaying(true), onPause: () => setIsPlaying(false), children: (0, jsx_runtime_1.jsx)("source", { src: `${url}` }) }), play === 'on-click' && !isPlaying && ((0, jsx_runtime_1.jsx)("div", { className: `video-background-${sectionId}-cover-container`, style: {
75
+ position: 'absolute',
76
+ left: 0,
77
+ width: '100%',
78
+ height: '100%',
79
+ top: 0
80
+ }, onClick: handleCoverClick, children: coverUrl && play === 'on-click' && ((0, jsx_runtime_1.jsx)("img", { src: coverUrl, alt: "Video cover", className: `video-background-${sectionId}-cover`, style: {
81
+ opacity: isPlaying ? 0 : 1,
82
+ left: isContainHeight ? '50%' : (hasOffsetX ? `${offsetX * 100}vw` : '0'),
83
+ width: isContainHeight ? 'auto' : '100%',
84
+ objectFit: isContainHeight ? 'unset' : (size !== null && size !== void 0 ? size : 'cover'),
85
+ transform: isContainHeight ? 'translateX(-50%)' : 'none',
86
+ position: 'relative',
87
+ height: '100%',
88
+ transition: 'opacity 0.1s ease-in-out'
89
+ } })) }))] }) }));
83
90
  };
84
91
  exports.SectionVideo = SectionVideo;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cntrl-site/sdk-nextjs",
3
- "version": "1.8.21",
3
+ "version": "1.8.23",
4
4
  "description": "SDK for Next.js",
5
5
  "author": "arsen@momdesign.nyc",
6
6
  "license": "MIT",
@@ -1,4 +1,4 @@
1
- import { FC, useId } from 'react';
1
+ import { CSSProperties, FC, useId } from 'react';
2
2
  import JSXStyle from 'styled-jsx/style';
3
3
 
4
4
  export type TSectionImage = {
@@ -15,34 +15,34 @@ interface Props {
15
15
  }
16
16
 
17
17
  export const SectionImage: FC<Props> = ({ media, sectionId }) => {
18
- const id = useId();
19
18
  const { url, size, position, offsetX } = media;
20
19
  const isContainHeight = size === 'contain-height';
21
20
  const hasOffsetX = offsetX !== null && size === 'contain';
22
21
  return (
23
22
  <>
24
- <div className={`section-image-wrapper-${sectionId}`}>
25
- <img src={url} className={`image-background-${sectionId}`} />
23
+ <div
24
+ className={`section-image-wrapper-${sectionId}`}
25
+ style={{
26
+ position: position === 'fixed' ? 'sticky' : 'relative',
27
+ height: position === 'fixed' ? '100vh' : '100%',
28
+ top: position === 'fixed' ? '100vh' : '0',
29
+ width: '100%',
30
+ overflow: 'hidden'
31
+ }}
32
+ >
33
+ <img
34
+ src={url}
35
+ className={`image-background-${sectionId}`}
36
+ style={{
37
+ objectFit: isContainHeight ? 'unset' : (size ?? 'cover') as CSSProperties['objectFit'],
38
+ width: isContainHeight || hasOffsetX ? 'auto' : '100%',
39
+ transform: isContainHeight ? 'translateX(-50%)' : 'none',
40
+ position: 'relative',
41
+ left: isContainHeight ? '50%' : (hasOffsetX ? `${offsetX * 100}vw` : '0'),
42
+ height: '100%'
43
+ }}
44
+ />
26
45
  </div>
27
- <JSXStyle id={id}>{`
28
- .section-image-wrapper-${sectionId} {
29
- position: ${position === 'fixed' ? 'sticky' : 'relative'};
30
- height: ${position === 'fixed' ? '100vh' : '100%'};
31
- top: ${position === 'fixed' ? '100vh' : '0'};
32
- width: 100%;
33
- overflow: hidden;
34
- }
35
- .image-background-${sectionId} {
36
- object-fit: ${isContainHeight ? 'unset' : size ?? 'cover'};
37
- width: ${isContainHeight || hasOffsetX ? 'auto' : '100%'};
38
- transform: ${isContainHeight ? 'translateX(-50%)' : 'none'};
39
- position: relative;
40
- left: ${isContainHeight ? '50%' : (hasOffsetX ? `${offsetX * 100}vw` : '0')};
41
- height: 100%;
42
- ${offsetX ? 'max-width: 100vw;' : ''}
43
- }
44
- `}
45
- </JSXStyle>
46
46
  </>
47
47
  );
48
48
  };
@@ -1,4 +1,4 @@
1
- import { FC, useEffect, useId, useRef, useState } from 'react';
1
+ import { CSSProperties, FC, useEffect, useId, useRef, useState } from 'react';
2
2
  import JSXStyle from 'styled-jsx/style';
3
3
 
4
4
  export type TSectionVideo = {
@@ -19,8 +19,9 @@ interface Props {
19
19
 
20
20
  export const SectionVideo: FC<Props> = ({ container, sectionId, media }) => {
21
21
  const [video, setVideo] = useState<HTMLVideoElement | null>(null);
22
+ const [videoWrapper, setVideoWrapper] = useState<HTMLDivElement | null>(null);
23
+ const [isVideoWidthOverflow, setIsVideoWidthOverflow] = useState(false);
22
24
  const { url, size, position, offsetX, coverUrl, play } = media;
23
- const id = useId();
24
25
  const [isPlaying, setIsPlaying] = useState(false);
25
26
  const [userPaused, setUserPaused] = useState(false);
26
27
  const [isClickedOnCover, setIsClickedOnCover] = useState(false);
@@ -53,18 +54,50 @@ export const SectionVideo: FC<Props> = ({ container, sectionId, media }) => {
53
54
  return () => observer.disconnect();
54
55
  }, [container, play, userPaused, isClickedOnCover]);
55
56
 
57
+ useEffect(() => {
58
+ if (!video || !videoWrapper) return;
59
+ video.addEventListener('loadedmetadata', () => {
60
+ const h = video.videoHeight;
61
+ const w = video.videoWidth;
62
+ const width = (videoWrapper.clientHeight / h) * w;
63
+ if (width > videoWrapper.clientWidth) {
64
+ setIsVideoWidthOverflow(true);
65
+ } else {
66
+ setIsVideoWidthOverflow(false);
67
+ }
68
+ });
69
+ }, [video, videoWrapper]);
70
+
56
71
  const isContainHeight = size === 'contain-height';
57
72
  const hasOffsetX = offsetX !== null && size === 'contain';
58
73
 
59
74
  return (
60
75
  <>
61
- <div className={`section-video-wrapper-${sectionId}`}>
76
+ <div
77
+ ref={setVideoWrapper}
78
+ className={`section-video-wrapper-${sectionId}`}
79
+ style={{
80
+ position: position === 'fixed' ? 'sticky' : 'relative',
81
+ height: position === 'fixed' ? '100vh' : '100%',
82
+ top: position === 'fixed' ? '100vh' : '0',
83
+ overflow: 'hidden',
84
+ width: '100%'
85
+ }}
86
+ >
62
87
  <video
63
88
  ref={setVideo}
64
89
  autoPlay={play === 'auto'}
65
90
  loop
66
- style={{ opacity: !isPlaying && play === 'on-click' && coverUrl ? 0 : 1 }}
67
- controls={false}
91
+ style={{
92
+ opacity: !isPlaying && play === 'on-click' && coverUrl ? 0 : 1,
93
+ objectFit: isContainHeight ? 'cover' : (size ?? 'cover') as CSSProperties['objectFit'],
94
+ width: isContainHeight && !isVideoWidthOverflow ? 'auto' : '100%',
95
+ transform: isContainHeight ? 'translateX(-50%)' : 'none',
96
+ left: isContainHeight ? '50%' : (hasOffsetX ? `${offsetX * 100}vw` : '0'),
97
+ height: '100%',
98
+ position: 'relative'
99
+ }}
100
+ controls={play === 'on-click'}
68
101
  muted={play === 'auto'}
69
102
  playsInline
70
103
  preload="auto"
@@ -72,50 +105,40 @@ export const SectionVideo: FC<Props> = ({ container, sectionId, media }) => {
72
105
  onPlay={() => setIsPlaying(true)}
73
106
  onPause={() => setIsPlaying(false)}
74
107
  >
75
- <source src={`${url}#t=0.001`} />
108
+ <source src={`${url}`} />
76
109
  </video>
77
- <div className={`video-background-${sectionId}-cover-container`} onClick={handleCoverClick}>
78
- {coverUrl && play === 'on-click' && (
79
- <img src={coverUrl} alt="Video cover" className={`video-background-${sectionId}-cover`} style={{ opacity: isPlaying ? 0 : 1 }} />
80
- )}
81
- </div>
110
+ {play === 'on-click' && !isPlaying && (
111
+ <div
112
+ className={`video-background-${sectionId}-cover-container`}
113
+ style={{
114
+ position: 'absolute',
115
+ left: 0,
116
+ width: '100%',
117
+ height: '100%',
118
+ top: 0
119
+ }}
120
+ onClick={handleCoverClick}
121
+ >
122
+ {coverUrl && play === 'on-click' && (
123
+ <img
124
+ src={coverUrl}
125
+ alt="Video cover"
126
+ className={`video-background-${sectionId}-cover`}
127
+ style={{
128
+ opacity: isPlaying ? 0 : 1,
129
+ left: isContainHeight ? '50%' : (hasOffsetX ? `${offsetX * 100}vw` : '0'),
130
+ width: isContainHeight ? 'auto' : '100%',
131
+ objectFit: isContainHeight ? 'unset' : (size ?? 'cover') as CSSProperties['objectFit'],
132
+ transform: isContainHeight ? 'translateX(-50%)' : 'none',
133
+ position: 'relative',
134
+ height: '100%',
135
+ transition: 'opacity 0.1s ease-in-out'
136
+ }}
137
+ />
138
+ )}
139
+ </div>
140
+ )}
82
141
  </div>
83
- <JSXStyle id={id}>{`
84
- .section-video-wrapper-${sectionId} {
85
- position: ${position === 'fixed' ? 'sticky' : 'relative'};
86
- height: ${position === 'fixed' ? '100vh' : '100%'};
87
- top: ${position === 'fixed' ? '100vh' : '0'};
88
- width: 100%;
89
- overflow: hidden;
90
- }
91
- .video-background-${sectionId}-cover-container {
92
- position: absolute;
93
- pointer-events: ${play === 'on-click' ? 'auto' : 'none'};
94
- left: 0;
95
- width: 100%;
96
- height: 100%;
97
- top: 0;
98
- }
99
- .video-background-${sectionId}-cover {
100
- position: relative;
101
- left: ${isContainHeight ? '50%' : (hasOffsetX ? `${offsetX * 100}vw` : '0')};
102
- width: ${isContainHeight ? 'auto' : '100%'};
103
- height: 100%;
104
- object-fit: ${isContainHeight ? 'unset' : size ?? 'cover'};
105
- transition: opacity 0.1s ease-in-out;
106
- transform: ${isContainHeight ? 'translateX(-50%)' : 'none'};
107
- ${hasOffsetX ? 'max-width: 100vw;' : ''}
108
- }
109
- .video-background-${sectionId} {
110
- object-fit: ${isContainHeight ? 'unset' : size ?? 'cover'};
111
- width: ${isContainHeight ? 'auto' : '100%'};
112
- height: 100%;
113
- position: relative;
114
- transform: ${isContainHeight ? 'translateX(-50%)' : 'none'};
115
- left: ${isContainHeight ? '50%' : (hasOffsetX ? `${offsetX * 100}vw` : '0')};
116
- }
117
- `}
118
- </JSXStyle>
119
142
  </>
120
143
  );
121
144
  };