@cntrl-site/sdk-nextjs 1.2.0 → 1.2.2

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.
@@ -0,0 +1,5 @@
1
+ <component name="ProjectCodeStyleConfiguration">
2
+ <state>
3
+ <option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
4
+ </state>
5
+ </component>
@@ -0,0 +1,15 @@
1
+ <component name="InspectionProjectProfileManager">
2
+ <profile version="1.0">
3
+ <option name="myName" value="Project Default" />
4
+ <inspection_tool class="HtmlUnknownAttribute" enabled="true" level="WARNING" enabled_by_default="true">
5
+ <option name="myValues">
6
+ <value>
7
+ <list size="1">
8
+ <item index="0" class="java.lang.String" itemvalue="jsx" />
9
+ </list>
10
+ </value>
11
+ </option>
12
+ <option name="myCustomValuesEnabled" value="true" />
13
+ </inspection_tool>
14
+ </profile>
15
+ </component>
@@ -0,0 +1,18 @@
1
+ import antfu from '@antfu/eslint-config';
2
+
3
+ export default antfu(
4
+ {
5
+ ignores: [],
6
+ },
7
+ {
8
+ rules: {
9
+ 'import/order': 'off',
10
+ 'style/semi': 'off',
11
+ 'antfu/if-newline': 'off',
12
+ 'style/comma-dangle': 'off',
13
+ 'style/member-delimiter-style': 'off',
14
+ 'semi': ['error', 'always'],
15
+ 'no-alert': 'off',
16
+ },
17
+ },
18
+ );
@@ -11,8 +11,6 @@ const useLayoutContext_1 = require("../../useLayoutContext");
11
11
  const useExemplary_1 = require("../../../common/useExemplary");
12
12
  const useItemScale_1 = require("../useItemScale");
13
13
  const useItemInteractionCtrl_1 = require("../../../interactions/useItemInteractionCtrl");
14
- const useItemPosition_1 = require("../useItemPosition");
15
- const useItemDimensions_1 = require("../useItemDimensions");
16
14
  const sdk_1 = require("@cntrl-site/sdk");
17
15
  const style_1 = __importDefault(require("styled-jsx/style"));
18
16
  const ScaleAnchorMap_1 = require("../../../utils/ScaleAnchorMap");
@@ -20,55 +18,50 @@ const isItemType_1 = require("../../../utils/isItemType");
20
18
  const RichTextWrapper_1 = require("../RichTextWrapper");
21
19
  const itemsMap_1 = require("../itemsMap");
22
20
  const getCompoundBondaryStyles_1 = require("../../../utils/getCompoundBondaryStyles");
21
+ const useItemTriggers_1 = require("../useItemTriggers");
22
+ const useSizing_1 = require("../useSizing");
23
+ const useItemPointerEvents_1 = require("../useItemPointerEvents");
24
+ const useItemArea_1 = require("../useItemArea");
23
25
  const noop = () => null;
24
26
  const CompoundChild = ({ item, sectionId, isParentVisible = true }) => {
25
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
27
+ var _a, _b, _c, _d, _e, _f, _g, _h;
26
28
  const id = (0, react_1.useId)();
27
29
  const { layouts } = (0, useCntrlContext_1.useCntrlContext)();
28
30
  const layout = (0, useLayoutContext_1.useLayoutContext)();
29
31
  const exemplary = (0, useExemplary_1.useExemplary)();
30
- const [allowPointerEvents, setAllowPointerEvents] = (0, react_1.useState)(isParentVisible);
32
+ const { handleVisibilityChange, allowPointerEvents } = (0, useItemPointerEvents_1.useItemPointerEvents)(isParentVisible);
31
33
  const itemScale = (0, useItemScale_1.useItemScale)(item, sectionId);
32
34
  const interactionCtrl = (0, useItemInteractionCtrl_1.useItemInteractionCtrl)(item.id);
33
- const wrapperStateProps = interactionCtrl === null || interactionCtrl === void 0 ? void 0 : interactionCtrl.getState(['top', 'left']);
34
- const innerStateProps = interactionCtrl === null || interactionCtrl === void 0 ? void 0 : interactionCtrl.getState(['width', 'height', 'scale']);
35
- const position = (0, useItemPosition_1.useItemPosition)(item, sectionId, {
36
- top: (_a = wrapperStateProps === null || wrapperStateProps === void 0 ? void 0 : wrapperStateProps.styles) === null || _a === void 0 ? void 0 : _a.top,
37
- left: (_b = wrapperStateProps === null || wrapperStateProps === void 0 ? void 0 : wrapperStateProps.styles) === null || _b === void 0 ? void 0 : _b.left,
38
- });
35
+ const triggers = (0, useItemTriggers_1.useItemTriggers)(interactionCtrl);
36
+ const stateProps = interactionCtrl === null || interactionCtrl === void 0 ? void 0 : interactionCtrl.getState(['top', 'left', 'width', 'height', 'scale']);
39
37
  const compoundSettings = layout && item.compoundSettings ? item.compoundSettings[layout] : undefined;
40
- const dimensions = (0, useItemDimensions_1.useItemDimensions)(item, sectionId);
38
+ const { width, height, top, left } = (0, useItemArea_1.useItemArea)(item, sectionId, {
39
+ top: (_a = stateProps === null || stateProps === void 0 ? void 0 : stateProps.styles) === null || _a === void 0 ? void 0 : _a.top,
40
+ left: (_b = stateProps === null || stateProps === void 0 ? void 0 : stateProps.styles) === null || _b === void 0 ? void 0 : _b.left,
41
+ width: (_c = stateProps === null || stateProps === void 0 ? void 0 : stateProps.styles) === null || _c === void 0 ? void 0 : _c.width,
42
+ height: (_d = stateProps === null || stateProps === void 0 ? void 0 : stateProps.styles) === null || _d === void 0 ? void 0 : _d.height
43
+ });
41
44
  const isInitialRef = (0, react_1.useRef)(true);
42
- const sizing = layout && (0, isItemType_1.isItemType)(item, sdk_1.ArticleItemType.RichText)
43
- ? item.layoutParams[layout].sizing
44
- : undefined;
45
- const sizingAxis = parseSizing(sizing);
45
+ const sizingAxis = (0, useSizing_1.useSizing)(item);
46
46
  const ItemComponent = itemsMap_1.itemsMap[item.type] || noop;
47
- const handleVisibilityChange = (0, react_1.useCallback)((isVisible) => {
48
- if (!isParentVisible)
49
- return;
50
- setAllowPointerEvents(isVisible);
51
- }, [isParentVisible]);
52
47
  (0, react_1.useEffect)(() => {
53
48
  isInitialRef.current = false;
54
49
  }, []);
55
50
  const transformOrigin = compoundSettings ? ScaleAnchorMap_1.ScaleAnchorMap[compoundSettings.positionAnchor] : 'top left';
56
51
  const isRichText = (0, isItemType_1.isItemType)(item, sdk_1.ArticleItemType.RichText);
57
- const width = ((_d = (_c = innerStateProps === null || innerStateProps === void 0 ? void 0 : innerStateProps.styles) === null || _c === void 0 ? void 0 : _c.width) !== null && _d !== void 0 ? _d : dimensions === null || dimensions === void 0 ? void 0 : dimensions.width);
58
- const height = ((_f = (_e = innerStateProps === null || innerStateProps === void 0 ? void 0 : innerStateProps.styles) === null || _e === void 0 ? void 0 : _e.height) !== null && _f !== void 0 ? _f : dimensions === null || dimensions === void 0 ? void 0 : dimensions.height);
59
- const scale = (_h = (_g = innerStateProps === null || innerStateProps === void 0 ? void 0 : innerStateProps.styles) === null || _g === void 0 ? void 0 : _g.scale) !== null && _h !== void 0 ? _h : itemScale;
60
- const hasClickTriggers = (_j = interactionCtrl === null || interactionCtrl === void 0 ? void 0 : interactionCtrl.getHasTrigger(item.id, 'click')) !== null && _j !== void 0 ? _j : false;
52
+ const scale = (_f = (_e = stateProps === null || stateProps === void 0 ? void 0 : stateProps.styles) === null || _e === void 0 ? void 0 : _e.scale) !== null && _f !== void 0 ? _f : itemScale;
53
+ const hasClickTriggers = (_g = interactionCtrl === null || interactionCtrl === void 0 ? void 0 : interactionCtrl.getHasTrigger(item.id, 'click')) !== null && _g !== void 0 ? _g : false;
61
54
  if (!item.compoundSettings)
62
55
  return null;
63
56
  const layoutValues = [item.area, item.hidden, item.compoundSettings];
64
57
  if (item.layoutParams) {
65
58
  layoutValues.push(item.layoutParams);
66
59
  }
67
- return ((0, jsx_runtime_1.jsxs)("div", { className: `item-${item.id}`, onTransitionEnd: (e) => {
60
+ return ((0, jsx_runtime_1.jsxs)("div", Object.assign({ className: `item-${item.id}`, onTransitionEnd: (e) => {
68
61
  var _a;
69
62
  e.stopPropagation();
70
63
  (_a = interactionCtrl === null || interactionCtrl === void 0 ? void 0 : interactionCtrl.handleTransitionEnd) === null || _a === void 0 ? void 0 : _a.call(interactionCtrl, e.propertyName);
71
- }, style: Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (position && compoundSettings ? { top: (0, getCompoundBondaryStyles_1.getCompoundTop)(compoundSettings, position.top) } : {})), (position && compoundSettings ? { left: (0, getCompoundBondaryStyles_1.getCompoundLeft)(compoundSettings, position.left) } : {})), (width && compoundSettings
64
+ }, style: Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (top && compoundSettings ? { top: (0, getCompoundBondaryStyles_1.getCompoundTop)(compoundSettings, top) } : {})), (left && compoundSettings ? { left: (0, getCompoundBondaryStyles_1.getCompoundLeft)(compoundSettings, left) } : {})), (width && compoundSettings
72
65
  ? { width: `${sizingAxis.x === 'manual'
73
66
  ? (0, getCompoundBondaryStyles_1.getCompoundWidth)(compoundSettings, width, isRichText, exemplary)
74
67
  : 'max-content'}` }
@@ -76,15 +69,9 @@ const CompoundChild = ({ item, sectionId, isParentVisible = true }) => {
76
69
  ? { height: `${sizingAxis.y === 'manual'
77
70
  ? (0, getCompoundBondaryStyles_1.getCompoundHeight)(compoundSettings, height)
78
71
  : 'unset'}` }
79
- : {})), (scale && compoundSettings ? { transform: `scale(${scale}) ${(0, getCompoundBondaryStyles_1.getCompoundTransform)(compoundSettings)}` } : {})), { transition: (_k = innerStateProps === null || innerStateProps === void 0 ? void 0 : innerStateProps.transition) !== null && _k !== void 0 ? _k : 'none', cursor: hasClickTriggers ? 'pointer' : 'unset', pointerEvents: allowPointerEvents ? 'auto' : 'none' }), onClick: () => {
80
- interactionCtrl === null || interactionCtrl === void 0 ? void 0 : interactionCtrl.sendTrigger('click');
81
- }, onMouseEnter: () => {
82
- interactionCtrl === null || interactionCtrl === void 0 ? void 0 : interactionCtrl.sendTrigger('hover-in');
83
- }, onMouseLeave: () => {
84
- interactionCtrl === null || interactionCtrl === void 0 ? void 0 : interactionCtrl.sendTrigger('hover-out');
85
- }, children: [(0, jsx_runtime_1.jsx)(RichTextWrapper_1.RichTextWrapper, { isRichText: isRichText, transformOrigin: transformOrigin, children: (0, jsx_runtime_1.jsx)(ItemComponent, { item: item, sectionId: sectionId, interactionCtrl: interactionCtrl, onVisibilityChange: handleVisibilityChange }) }), (0, jsx_runtime_1.jsx)(style_1.default, { id: id, children: `
72
+ : {})), (scale && compoundSettings ? { transform: `scale(${scale}) ${(0, getCompoundBondaryStyles_1.getCompoundTransform)(compoundSettings)}` } : {})), { transition: (_h = stateProps === null || stateProps === void 0 ? void 0 : stateProps.transition) !== null && _h !== void 0 ? _h : 'none', cursor: hasClickTriggers ? 'pointer' : 'unset', pointerEvents: allowPointerEvents ? 'auto' : 'none' }) }, triggers, { children: [(0, jsx_runtime_1.jsx)(RichTextWrapper_1.RichTextWrapper, { isRichText: isRichText, transformOrigin: transformOrigin, children: (0, jsx_runtime_1.jsx)(ItemComponent, { item: item, sectionId: sectionId, interactionCtrl: interactionCtrl, onVisibilityChange: handleVisibilityChange }) }), (0, jsx_runtime_1.jsx)(style_1.default, { id: id, children: `
86
73
  ${(0, sdk_1.getLayoutStyles)(layouts, layoutValues, ([area, hidden, compoundSettings, layoutParams]) => {
87
- const sizingAxis = parseSizing(layoutParams.sizing);
74
+ const sizingAxis = (0, useSizing_1.parseSizing)(layoutParams.sizing);
88
75
  const scaleAnchor = area.scaleAnchor;
89
76
  return (`
90
77
  .item-${item.id} {
@@ -103,13 +90,6 @@ const CompoundChild = ({ item, sectionId, isParentVisible = true }) => {
103
90
  }
104
91
  `);
105
92
  })}
106
- ` })] }));
93
+ ` })] })));
107
94
  };
108
95
  exports.CompoundChild = CompoundChild;
109
- function parseSizing(sizing = 'manual') {
110
- const axisSizing = sizing.split(' ');
111
- return {
112
- y: axisSizing[0],
113
- x: axisSizing[1] ? axisSizing[1] : axisSizing[0]
114
- };
115
- }
@@ -14,16 +14,16 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
14
14
  Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.VimeoEmbedItem = void 0;
16
16
  const jsx_runtime_1 = require("react/jsx-runtime");
17
- const react_1 = require("react");
17
+ const sdk_1 = require("@cntrl-site/sdk");
18
18
  const player_1 = __importDefault(require("@vimeo/player"));
19
+ const react_1 = require("react");
19
20
  const style_1 = __importDefault(require("styled-jsx/style"));
20
- const LinkWrapper_1 = require("../LinkWrapper");
21
- const useEmbedVideoItem_1 = require("./useEmbedVideoItem");
22
21
  const useItemAngle_1 = require("../useItemAngle");
23
- const sdk_1 = require("@cntrl-site/sdk");
24
22
  const useCntrlContext_1 = require("../../../provider/useCntrlContext");
25
23
  const useRegisterResize_1 = require("../../../common/useRegisterResize");
26
24
  const getStyleFromItemStateAndParams_1 = require("../../../utils/getStyleFromItemStateAndParams");
25
+ const useEmbedVideoItem_1 = require("./useEmbedVideoItem");
26
+ const LinkWrapper_1 = require("../LinkWrapper");
27
27
  const VimeoEmbedItem = ({ item, sectionId, onResize, interactionCtrl, onVisibilityChange }) => {
28
28
  var _a, _b, _c, _d, _e, _f, _g, _h, _j;
29
29
  const id = (0, react_1.useId)();
@@ -48,7 +48,7 @@ const VimeoEmbedItem = ({ item, sectionId, onResize, interactionCtrl, onVisibili
48
48
  const validURL = new URL(url);
49
49
  validURL.searchParams.append('controls', String(controls));
50
50
  validURL.searchParams.append('autoplay', String(play === 'auto'));
51
- validURL.searchParams.append('muted', String(play !== 'on-click' ? true : muted));
51
+ validURL.searchParams.append('muted', String(muted));
52
52
  validURL.searchParams.append('loop', String(loop));
53
53
  validURL.searchParams.append('pip', String(pictureInPicture));
54
54
  validURL.searchParams.append('title', '0');
@@ -61,7 +61,7 @@ const VimeoEmbedItem = ({ item, sectionId, onResize, interactionCtrl, onVisibili
61
61
  (0, react_1.useEffect)(() => {
62
62
  if (!vimeoPlayer || !imgRef)
63
63
  return;
64
- if (play === 'on-click' && !controls) {
64
+ if (play === 'on-click') {
65
65
  setIsCoverVisible(true);
66
66
  }
67
67
  vimeoPlayer.on('pause', (e) => {
@@ -69,6 +69,9 @@ const VimeoEmbedItem = ({ item, sectionId, onResize, interactionCtrl, onVisibili
69
69
  setIsCoverVisible(true);
70
70
  }
71
71
  });
72
+ vimeoPlayer.on('ended', () => {
73
+ setIsCoverVisible(true);
74
+ });
72
75
  }, [vimeoPlayer, imgRef]);
73
76
  const handleClick = () => __awaiter(void 0, void 0, void 0, function* () {
74
77
  if (!vimeoPlayer)
@@ -91,7 +94,10 @@ const VimeoEmbedItem = ({ item, sectionId, onResize, interactionCtrl, onVisibili
91
94
  const isInteractive = opacity !== 0;
92
95
  (0, react_1.useEffect)(() => {
93
96
  onVisibilityChange === null || onVisibilityChange === void 0 ? void 0 : onVisibilityChange(isInteractive);
94
- }, [isInteractive, onVisibilityChange]);
97
+ if (!isInteractive && vimeoPlayer) {
98
+ vimeoPlayer.pause();
99
+ }
100
+ }, [isInteractive, onVisibilityChange, vimeoPlayer]);
95
101
  return ((0, jsx_runtime_1.jsxs)(LinkWrapper_1.LinkWrapper, { url: (_e = item.link) === null || _e === void 0 ? void 0 : _e.url, target: (_f = item.link) === null || _f === void 0 ? void 0 : _f.target, children: [(0, jsx_runtime_1.jsxs)("div", { className: `embed-video-wrapper-${item.id}`, ref: setRef, style: Object.assign(Object.assign(Object.assign(Object.assign({}, (opacity !== undefined ? { opacity } : {})), (angle !== undefined ? { transform: `rotate(${angle}deg)` } : {})), (blur !== undefined ? { filter: `blur(${blur * 100}vw)` } : {})), { transition: (_g = wrapperStateParams === null || wrapperStateParams === void 0 ? void 0 : wrapperStateParams.transition) !== null && _g !== void 0 ? _g : 'none' }), onMouseEnter: () => {
96
102
  if (!vimeoPlayer || play !== 'on-hover')
97
103
  return;
@@ -109,13 +115,13 @@ const VimeoEmbedItem = ({ item, sectionId, onResize, interactionCtrl, onVisibili
109
115
  width: '100%',
110
116
  top: '0',
111
117
  left: '0'
112
- }, alt: "Cover img" })), (!item.commonParams.controls && play === 'on-click') && ((0, jsx_runtime_1.jsx)("div", { onClick: handleClick, style: {
118
+ }, alt: "Cover img" })), (!item.commonParams.controls && (play === 'on-click' || play === 'auto')) && ((0, jsx_runtime_1.jsx)("div", { onClick: handleClick, style: {
113
119
  position: 'absolute',
114
120
  height: '100%',
115
121
  width: '100%',
116
122
  top: '0',
117
123
  left: '0'
118
- } })), (0, jsx_runtime_1.jsx)("iframe", { ref: setIframeRef, className: `embed-video`, src: validUrl || '', allow: "autoplay; fullscreen; picture-in-picture;", allowFullScreen: true, style: Object.assign(Object.assign({}, (radius !== undefined ? { borderRadius: `${radius * 100}vw` } : {})), { transition: (_j = frameStateParams === null || frameStateParams === void 0 ? void 0 : frameStateParams.transition) !== null && _j !== void 0 ? _j : 'none' }) })] }), (0, jsx_runtime_1.jsx)(style_1.default, { id: id, children: `
124
+ } })), (0, jsx_runtime_1.jsx)("iframe", { ref: setIframeRef, className: "embed-video", src: validUrl || '', allow: "autoplay; fullscreen; picture-in-picture;", allowFullScreen: true, style: Object.assign(Object.assign({}, (radius !== undefined ? { borderRadius: `${radius * 100}vw` } : {})), { transition: (_j = frameStateParams === null || frameStateParams === void 0 ? void 0 : frameStateParams.transition) !== null && _j !== void 0 ? _j : 'none' }) })] }), (0, jsx_runtime_1.jsx)(style_1.default, { id: id, children: `
119
125
  .embed-video-wrapper-${item.id} {
120
126
  position: absolute;
121
127
  width: 100%;
@@ -9,8 +9,6 @@ const react_1 = require("react");
9
9
  const style_1 = __importDefault(require("styled-jsx/style"));
10
10
  const sdk_1 = require("@cntrl-site/sdk");
11
11
  const useCntrlContext_1 = require("../../provider/useCntrlContext");
12
- const useItemPosition_1 = require("./useItemPosition");
13
- const useItemDimensions_1 = require("./useItemDimensions");
14
12
  const useItemScale_1 = require("./useItemScale");
15
13
  const ScaleAnchorMap_1 = require("../../utils/ScaleAnchorMap");
16
14
  const useSectionHeightMap_1 = require("../Section/useSectionHeightMap");
@@ -25,13 +23,17 @@ const useItemInteractionCtrl_1 = require("../../interactions/useItemInteractionC
25
23
  const isItemType_1 = require("../../utils/isItemType");
26
24
  const RichTextWrapper_1 = require("./RichTextWrapper");
27
25
  const itemsMap_1 = require("./itemsMap");
26
+ const useItemTriggers_1 = require("./useItemTriggers");
27
+ const useSizing_1 = require("./useSizing");
28
+ const useItemPointerEvents_1 = require("./useItemPointerEvents");
29
+ const useItemArea_1 = require("./useItemArea");
28
30
  const stickyFix = `
29
31
  -webkit-transform: translate3d(0, 0, 0);
30
32
  transform: translate3d(0, 0, 0);
31
33
  `;
32
34
  const noop = () => null;
33
35
  const Item = ({ item, sectionId, articleHeight, isParentVisible = true, isInGroup = false }) => {
34
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
36
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
35
37
  const itemWrapperRef = (0, react_1.useRef)(null);
36
38
  const itemInnerRef = (0, react_1.useRef)(null);
37
39
  const rectObserver = (0, react_1.useContext)(ArticleRectContext_1.ArticleRectContext);
@@ -41,31 +43,29 @@ const Item = ({ item, sectionId, articleHeight, isParentVisible = true, isInGrou
41
43
  const { layouts } = (0, useCntrlContext_1.useCntrlContext)();
42
44
  const layout = (0, useLayoutContext_1.useLayoutContext)();
43
45
  const exemplary = (0, useExemplary_1.useExemplary)();
44
- const [allowPointerEvents, setAllowPointerEvents] = (0, react_1.useState)(isParentVisible);
46
+ const { handleVisibilityChange, allowPointerEvents } = (0, useItemPointerEvents_1.useItemPointerEvents)(isParentVisible);
45
47
  const [wrapperHeight, setWrapperHeight] = (0, react_1.useState)(undefined);
46
48
  const [itemHeight, setItemHeight] = (0, react_1.useState)(undefined);
47
49
  const itemScale = (0, useItemScale_1.useItemScale)(item, sectionId);
48
50
  const interactionCtrl = (0, useItemInteractionCtrl_1.useItemInteractionCtrl)(item.id);
51
+ const triggers = (0, useItemTriggers_1.useItemTriggers)(interactionCtrl);
49
52
  const wrapperStateProps = interactionCtrl === null || interactionCtrl === void 0 ? void 0 : interactionCtrl.getState(['top', 'left']);
50
- const innerStateProps = interactionCtrl === null || interactionCtrl === void 0 ? void 0 : interactionCtrl.getState(['width', 'height', 'scale']);
51
- const position = (0, useItemPosition_1.useItemPosition)(item, sectionId, {
53
+ const innerStateProps = interactionCtrl === null || interactionCtrl === void 0 ? void 0 : interactionCtrl.getState(['width', 'height', 'scale', 'top', 'left']);
54
+ const { width, height, top, left } = (0, useItemArea_1.useItemArea)(item, sectionId, {
52
55
  top: (_a = wrapperStateProps === null || wrapperStateProps === void 0 ? void 0 : wrapperStateProps.styles) === null || _a === void 0 ? void 0 : _a.top,
53
56
  left: (_b = wrapperStateProps === null || wrapperStateProps === void 0 ? void 0 : wrapperStateProps.styles) === null || _b === void 0 ? void 0 : _b.left,
57
+ width: (_c = innerStateProps === null || innerStateProps === void 0 ? void 0 : innerStateProps.styles) === null || _c === void 0 ? void 0 : _c.width,
58
+ height: (_d = innerStateProps === null || innerStateProps === void 0 ? void 0 : innerStateProps.styles) === null || _d === void 0 ? void 0 : _d.height
54
59
  });
55
60
  const sectionHeight = (0, useSectionHeightMap_1.useSectionHeightData)(sectionId);
56
61
  const stickyTop = (0, useStickyItemTop_1.useStickyItemTop)(item, sectionHeight, sectionId);
57
- const dimensions = (0, useItemDimensions_1.useItemDimensions)(item, sectionId);
58
62
  const layoutValues = [item.area, item.hidden];
59
- const isInitialRef = (0, react_1.useRef)(true);
60
63
  layoutValues.push(item.sticky);
61
64
  layoutValues.push(sectionHeight);
62
65
  if (item.layoutParams) {
63
66
  layoutValues.push(item.layoutParams);
64
67
  }
65
- const sizing = layout && (0, isItemType_1.isItemType)(item, sdk_1.ArticleItemType.RichText)
66
- ? item.layoutParams[layout].sizing
67
- : undefined;
68
- const sizingAxis = parseSizing(sizing);
68
+ const sizingAxis = (0, useSizing_1.useSizing)(item);
69
69
  const ItemComponent = itemsMap_1.itemsMap[item.type] || noop;
70
70
  const sectionTop = rectObserver ? rectObserver.getSectionTop(sectionId) : 0;
71
71
  const handleItemResize = (height) => {
@@ -85,46 +85,30 @@ const Item = ({ item, sectionId, articleHeight, isParentVisible = true, isInGrou
85
85
  setItemHeight(height);
86
86
  setWrapperHeight(wrapperHeight);
87
87
  };
88
- const handleVisibilityChange = (0, react_1.useCallback)((isVisible) => {
89
- if (!isParentVisible)
90
- return;
91
- setAllowPointerEvents(isVisible);
92
- }, [isParentVisible]);
93
- (0, react_1.useEffect)(() => {
94
- isInitialRef.current = false;
95
- }, []);
96
88
  const isRichText = (0, isItemType_1.isItemType)(item, sdk_1.ArticleItemType.RichText);
97
- const width = ((_d = (_c = innerStateProps === null || innerStateProps === void 0 ? void 0 : innerStateProps.styles) === null || _c === void 0 ? void 0 : _c.width) !== null && _d !== void 0 ? _d : dimensions === null || dimensions === void 0 ? void 0 : dimensions.width);
98
- const height = ((_f = (_e = innerStateProps === null || innerStateProps === void 0 ? void 0 : innerStateProps.styles) === null || _e === void 0 ? void 0 : _e.height) !== null && _f !== void 0 ? _f : dimensions === null || dimensions === void 0 ? void 0 : dimensions.height);
99
89
  const anchorSide = layout ? item.area[layout].anchorSide : sdk_1.AnchorSide.Top;
100
90
  const positionType = layout ? item.area[layout].positionType : sdk_1.PositionType.ScreenBased;
101
91
  const isScreenBasedBottom = positionType === sdk_1.PositionType.ScreenBased && anchorSide === sdk_1.AnchorSide.Bottom;
102
- const scale = (_h = (_g = innerStateProps === null || innerStateProps === void 0 ? void 0 : innerStateProps.styles) === null || _g === void 0 ? void 0 : _g.scale) !== null && _h !== void 0 ? _h : itemScale;
103
- const hasClickTriggers = (_j = interactionCtrl === null || interactionCtrl === void 0 ? void 0 : interactionCtrl.getHasTrigger(item.id, 'click')) !== null && _j !== void 0 ? _j : false;
92
+ const scale = (_f = (_e = innerStateProps === null || innerStateProps === void 0 ? void 0 : innerStateProps.styles) === null || _e === void 0 ? void 0 : _e.scale) !== null && _f !== void 0 ? _f : itemScale;
93
+ const hasClickTriggers = (_g = interactionCtrl === null || interactionCtrl === void 0 ? void 0 : interactionCtrl.getHasTrigger(item.id, 'click')) !== null && _g !== void 0 ? _g : false;
104
94
  return ((0, jsx_runtime_1.jsxs)("div", { className: `item-wrapper-${item.id}`, ref: itemWrapperRef, onTransitionEnd: (e) => {
105
95
  var _a;
106
96
  e.stopPropagation();
107
97
  (_a = interactionCtrl === null || interactionCtrl === void 0 ? void 0 : interactionCtrl.handleTransitionEnd) === null || _a === void 0 ? void 0 : _a.call(interactionCtrl, e.propertyName);
108
- }, style: Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (position ? { top: isScreenBasedBottom ? 'unset' : (0, getItemTopStyle_1.getItemTopStyle)(position.top, anchorSide) } : {})), (position ? { left: `${position.left * 100}vw` } : {})), (position ? { bottom: isScreenBasedBottom ? `${-position.top * 100}vw` : 'unset' } : {})), (wrapperHeight !== undefined ? { height: `${wrapperHeight * 100}vw` } : {})), { transition: (_k = wrapperStateProps === null || wrapperStateProps === void 0 ? void 0 : wrapperStateProps.transition) !== null && _k !== void 0 ? _k : 'none' }), children: [(0, jsx_runtime_1.jsx)("div", { suppressHydrationWarning: true, className: `item-${item.id}`, style: {
98
+ }, style: Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (top ? { top: isScreenBasedBottom ? 'unset' : (0, getItemTopStyle_1.getItemTopStyle)(top, anchorSide) } : {})), (left ? { left: `${left * 100}vw` } : {})), (top ? { bottom: isScreenBasedBottom ? `${-top * 100}vw` : 'unset' } : {})), (wrapperHeight !== undefined ? { height: `${wrapperHeight * 100}vw` } : {})), { transition: (_h = wrapperStateProps === null || wrapperStateProps === void 0 ? void 0 : wrapperStateProps.transition) !== null && _h !== void 0 ? _h : 'none' }), children: [(0, jsx_runtime_1.jsx)("div", { suppressHydrationWarning: true, className: `item-${item.id}`, style: {
109
99
  opacity: (keyframes.length !== 0 && !layout) ? 0 : 1,
110
100
  top: `${stickyTop * 100}vw`,
111
101
  height: isRichText && itemHeight ? `${itemHeight * 100}vw` : 'unset',
112
- }, children: (0, jsx_runtime_1.jsx)(RichTextWrapper_1.RichTextWrapper, { isRichText: isRichText, children: (0, jsx_runtime_1.jsx)("div", { className: `item-${item.id}-inner`, ref: itemInnerRef, onClick: () => {
113
- interactionCtrl === null || interactionCtrl === void 0 ? void 0 : interactionCtrl.sendTrigger('click');
114
- }, onMouseEnter: () => {
115
- interactionCtrl === null || interactionCtrl === void 0 ? void 0 : interactionCtrl.sendTrigger('hover-in');
116
- }, onMouseLeave: () => {
117
- interactionCtrl === null || interactionCtrl === void 0 ? void 0 : interactionCtrl.sendTrigger('hover-out');
118
- }, style: Object.assign(Object.assign(Object.assign({}, ((width && height) ? {
102
+ }, children: (0, jsx_runtime_1.jsx)(RichTextWrapper_1.RichTextWrapper, { isRichText: isRichText, children: (0, jsx_runtime_1.jsx)("div", Object.assign({ className: `item-${item.id}-inner`, ref: itemInnerRef, style: Object.assign(Object.assign(Object.assign({}, ((width && height) ? {
119
103
  width: `${sizingAxis.x === 'manual'
120
104
  ? isRichText
121
105
  ? `${width * exemplary}px`
122
106
  : `${width * 100}vw`
123
107
  : 'max-content'}`,
124
108
  height: `${sizingAxis.y === 'manual' ? `${height * 100}vw` : 'unset'}`
125
- } : {})), (scale !== undefined ? { transform: `scale(${scale})`, 'WebkitTransform': `scale(${scale})` } : {})), { transition: (_l = innerStateProps === null || innerStateProps === void 0 ? void 0 : innerStateProps.transition) !== null && _l !== void 0 ? _l : 'none', cursor: hasClickTriggers ? 'pointer' : 'unset', pointerEvents: allowPointerEvents ? 'auto' : 'none' }), children: (0, jsx_runtime_1.jsx)(ItemComponent, { item: item, sectionId: sectionId, onResize: handleItemResize, articleHeight: articleHeight, interactionCtrl: interactionCtrl, onVisibilityChange: handleVisibilityChange }) }) }) }), (0, jsx_runtime_1.jsx)(style_1.default, { id: id, children: `
109
+ } : {})), (scale !== undefined ? { transform: `scale(${scale})`, 'WebkitTransform': `scale(${scale})` } : {})), { transition: (_j = innerStateProps === null || innerStateProps === void 0 ? void 0 : innerStateProps.transition) !== null && _j !== void 0 ? _j : 'none', cursor: hasClickTriggers ? 'pointer' : 'unset', pointerEvents: allowPointerEvents ? 'auto' : 'none' }) }, triggers, { children: (0, jsx_runtime_1.jsx)(ItemComponent, { item: item, sectionId: sectionId, onResize: handleItemResize, articleHeight: articleHeight, interactionCtrl: interactionCtrl, onVisibilityChange: handleVisibilityChange }) })) }) }), (0, jsx_runtime_1.jsx)(style_1.default, { id: id, children: `
126
110
  ${(0, sdk_1.getLayoutStyles)(layouts, layoutValues, ([area, hidden, sticky, sectionHeight, layoutParams]) => {
127
- const sizingAxis = parseSizing(layoutParams.sizing);
111
+ const sizingAxis = (0, useSizing_1.parseSizing)(layoutParams.sizing);
128
112
  const isScreenBasedBottom = area.positionType === sdk_1.PositionType.ScreenBased && area.anchorSide === sdk_1.AnchorSide.Bottom;
129
113
  const scaleAnchor = area.scaleAnchor;
130
114
  return (`
@@ -158,10 +142,3 @@ const Item = ({ item, sectionId, articleHeight, isParentVisible = true, isInGrou
158
142
  ` })] }));
159
143
  };
160
144
  exports.Item = Item;
161
- function parseSizing(sizing = 'manual') {
162
- const axisSizing = sizing.split(' ');
163
- return {
164
- y: axisSizing[0],
165
- x: axisSizing[1] ? axisSizing[1] : axisSizing[0]
166
- };
167
- }
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useItemArea = void 0;
4
+ const sdk_1 = require("@cntrl-site/sdk");
5
+ const useLayoutContext_1 = require("../useLayoutContext");
6
+ const useKeyframeValue_1 = require("../../common/useKeyframeValue");
7
+ function useItemArea(item, sectionId, stateValues) {
8
+ var _a, _b, _c, _d;
9
+ const layoutId = (0, useLayoutContext_1.useLayoutContext)();
10
+ const position = (0, useKeyframeValue_1.useKeyframeValue)(item, sdk_1.KeyframeType.Position, (item, layoutId) => {
11
+ if (!layoutId)
12
+ return;
13
+ return item.area[layoutId];
14
+ }, (animator, scroll, value) => value ? animator.getPositions(value, scroll) : undefined, sectionId, [layoutId]);
15
+ const dimensions = (0, useKeyframeValue_1.useKeyframeValue)(item, sdk_1.KeyframeType.Dimensions, (item, layoutId) => layoutId ? item.area[layoutId] : undefined, (animator, scroll, value) => value ? animator.getDimensions(value, scroll) : undefined, sectionId, [layoutId]);
16
+ const width = ((_a = stateValues.width) !== null && _a !== void 0 ? _a : dimensions === null || dimensions === void 0 ? void 0 : dimensions.width);
17
+ const height = ((_b = stateValues.height) !== null && _b !== void 0 ? _b : dimensions === null || dimensions === void 0 ? void 0 : dimensions.height);
18
+ const top = ((_c = stateValues.top) !== null && _c !== void 0 ? _c : position === null || position === void 0 ? void 0 : position.top);
19
+ const left = ((_d = stateValues.left) !== null && _d !== void 0 ? _d : position === null || position === void 0 ? void 0 : position.left);
20
+ return { width, height, top, left };
21
+ }
22
+ exports.useItemArea = useItemArea;
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useItemPointerEvents = void 0;
4
+ const react_1 = require("react");
5
+ function useItemPointerEvents(isParentVisible) {
6
+ const [allowPointerEvents, setAllowPointerEvents] = (0, react_1.useState)(isParentVisible);
7
+ const handleVisibilityChange = (0, react_1.useCallback)((isVisible) => {
8
+ if (!isParentVisible)
9
+ return;
10
+ setAllowPointerEvents(isVisible);
11
+ }, [isParentVisible]);
12
+ return { allowPointerEvents, handleVisibilityChange };
13
+ }
14
+ exports.useItemPointerEvents = useItemPointerEvents;
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useItemTriggers = void 0;
4
+ function useItemTriggers(interactionCtrl) {
5
+ return {
6
+ onClick: () => {
7
+ interactionCtrl === null || interactionCtrl === void 0 ? void 0 : interactionCtrl.sendTrigger('click');
8
+ },
9
+ onMouseEnter: () => {
10
+ interactionCtrl === null || interactionCtrl === void 0 ? void 0 : interactionCtrl.sendTrigger('hover-in');
11
+ },
12
+ onMouseLeave: () => {
13
+ interactionCtrl === null || interactionCtrl === void 0 ? void 0 : interactionCtrl.sendTrigger('hover-out');
14
+ }
15
+ };
16
+ }
17
+ exports.useItemTriggers = useItemTriggers;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseSizing = exports.useSizing = void 0;
4
+ const isItemType_1 = require("../../utils/isItemType");
5
+ const sdk_1 = require("@cntrl-site/sdk");
6
+ const useLayoutContext_1 = require("../useLayoutContext");
7
+ function useSizing(item) {
8
+ const layout = (0, useLayoutContext_1.useLayoutContext)();
9
+ const sizing = layout && (0, isItemType_1.isItemType)(item, sdk_1.ArticleItemType.RichText)
10
+ ? item.layoutParams[layout].sizing
11
+ : undefined;
12
+ const sizingAxis = parseSizing(sizing);
13
+ return sizingAxis;
14
+ }
15
+ exports.useSizing = useSizing;
16
+ function parseSizing(sizing = 'manual') {
17
+ const axisSizing = sizing.split(' ');
18
+ return {
19
+ y: axisSizing[0],
20
+ x: axisSizing[1] ? axisSizing[1] : axisSizing[0]
21
+ };
22
+ }
23
+ exports.parseSizing = parseSizing;
package/package.json CHANGED
@@ -1,7 +1,17 @@
1
1
  {
2
2
  "name": "@cntrl-site/sdk-nextjs",
3
- "version": "1.2.0",
3
+ "version": "1.2.2",
4
4
  "description": "SDK for Next.js",
5
+ "author": "arsen@momdesign.nyc",
6
+ "license": "MIT",
7
+ "homepage": "https://github.com/cntrl-site/sdk-nextjs#readme",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/cntrl-site/sdk-nextjs.git"
11
+ },
12
+ "bugs": {
13
+ "url": "https://github.com/cntrl-site/sdk-nextjs/issues"
14
+ },
5
15
  "main": "lib/index.js",
6
16
  "types": "src/index.ts",
7
17
  "scripts": {
@@ -10,17 +20,15 @@
10
20
  "build": "tsc --project tsconfig.build.json",
11
21
  "prepublishOnly": "NODE_ENV=production npm run build"
12
22
  },
13
- "repository": {
14
- "type": "git",
15
- "url": "git+https://github.com/cntrl-site/sdk-nextjs.git"
16
- },
17
- "author": "arsen@momdesign.nyc",
18
- "license": "MIT",
19
- "bugs": {
20
- "url": "https://github.com/cntrl-site/sdk-nextjs/issues"
23
+ "peerDependencies": {
24
+ "@types/lodash.isequal": "^4.5.6",
25
+ "lodash.isequal": "^4.5.0",
26
+ "next": "^14.2.3",
27
+ "react": "^18.3.1",
28
+ "react-dom": "^18.3.1"
21
29
  },
22
- "homepage": "https://github.com/cntrl-site/sdk-nextjs#readme",
23
30
  "dependencies": {
31
+ "@antfu/eslint-config": "^3.8.0",
24
32
  "@cntrl-site/color": "^1.0.0",
25
33
  "@cntrl-site/effects": "^1.2.0",
26
34
  "@cntrl-site/sdk": "^1.14.0",
@@ -30,13 +38,6 @@
30
38
  "resize-observer-polyfill": "^1.5.1",
31
39
  "styled-jsx": "^5.0.2"
32
40
  },
33
- "peerDependencies": {
34
- "@types/lodash.isequal": "^4.5.6",
35
- "lodash.isequal": "^4.5.0",
36
- "next": "^14.2.3",
37
- "react": "^18.3.1",
38
- "react-dom": "^18.3.1"
39
- },
40
41
  "devDependencies": {
41
42
  "@testing-library/jest-dom": "^6.4.8",
42
43
  "@testing-library/react": "^16.0.0",
@@ -1,18 +1,14 @@
1
1
  import React, {
2
2
  FC,
3
- useCallback,
4
3
  useEffect,
5
4
  useId,
6
5
  useRef,
7
- useState
8
6
  } from 'react';
9
7
  import { useCntrlContext } from '../../../provider/useCntrlContext';
10
8
  import { useLayoutContext } from '../../useLayoutContext';
11
9
  import { useExemplary } from '../../../common/useExemplary';
12
10
  import { useItemScale } from '../useItemScale';
13
11
  import { useItemInteractionCtrl } from '../../../interactions/useItemInteractionCtrl';
14
- import { useItemPosition } from '../useItemPosition';
15
- import { useItemDimensions } from '../useItemDimensions';
16
12
  import { ArticleItemType, getLayoutStyles, ItemAny, AreaAnchor } from '@cntrl-site/sdk';
17
13
  import JSXStyle from 'styled-jsx/style';
18
14
  import { ScaleAnchorMap } from '../../../utils/ScaleAnchorMap';
@@ -25,6 +21,10 @@ import {
25
21
  getCompoundTop, getCompoundTransform,
26
22
  getCompoundWidth
27
23
  } from '../../../utils/getCompoundBondaryStyles';
24
+ import { useItemTriggers } from '../useItemTriggers';
25
+ import { parseSizing, useSizing } from '../useSizing';
26
+ import { useItemPointerEvents } from '../useItemPointerEvents';
27
+ import { useItemArea } from '../useItemArea';
28
28
 
29
29
  interface ChildItemProps {
30
30
  item: ItemAny;
@@ -39,27 +39,21 @@ export const CompoundChild: FC<ChildItemProps> = ({ item, sectionId, isParentVis
39
39
  const { layouts } = useCntrlContext();
40
40
  const layout = useLayoutContext();
41
41
  const exemplary = useExemplary();
42
- const [allowPointerEvents, setAllowPointerEvents] = useState<boolean>(isParentVisible);
42
+ const { handleVisibilityChange, allowPointerEvents } = useItemPointerEvents(isParentVisible);
43
43
  const itemScale = useItemScale(item, sectionId);
44
44
  const interactionCtrl = useItemInteractionCtrl(item.id);
45
- const wrapperStateProps = interactionCtrl?.getState(['top', 'left']);
46
- const innerStateProps = interactionCtrl?.getState(['width', 'height', 'scale']);
47
- const position = useItemPosition(item, sectionId, {
48
- top: wrapperStateProps?.styles?.top as number,
49
- left: wrapperStateProps?.styles?.left as number,
50
- });
45
+ const triggers = useItemTriggers(interactionCtrl);
46
+ const stateProps = interactionCtrl?.getState(['top', 'left', 'width', 'height', 'scale']);
51
47
  const compoundSettings = layout && item.compoundSettings ? item.compoundSettings[layout] : undefined;
52
- const dimensions = useItemDimensions(item, sectionId);
48
+ const { width, height, top, left } = useItemArea(item, sectionId, {
49
+ top: stateProps?.styles?.top as number,
50
+ left: stateProps?.styles?.left as number,
51
+ width: stateProps?.styles?.width as number,
52
+ height: stateProps?.styles?.height as number
53
+ });
53
54
  const isInitialRef = useRef(true);
54
- const sizing = layout && isItemType(item, ArticleItemType.RichText)
55
- ? item.layoutParams[layout].sizing
56
- : undefined;
57
- const sizingAxis = parseSizing(sizing);
55
+ const sizingAxis = useSizing(item);
58
56
  const ItemComponent = itemsMap[item.type] || noop;
59
- const handleVisibilityChange = useCallback((isVisible: boolean) => {
60
- if (!isParentVisible) return;
61
- setAllowPointerEvents(isVisible);
62
- }, [isParentVisible]);
63
57
 
64
58
  useEffect(() => {
65
59
  isInitialRef.current = false;
@@ -67,9 +61,7 @@ export const CompoundChild: FC<ChildItemProps> = ({ item, sectionId, isParentVis
67
61
 
68
62
  const transformOrigin = compoundSettings ? ScaleAnchorMap[compoundSettings.positionAnchor] : 'top left';
69
63
  const isRichText = isItemType(item, ArticleItemType.RichText);
70
- const width = (innerStateProps?.styles?.width ?? dimensions?.width) as number | undefined;
71
- const height = (innerStateProps?.styles?.height ?? dimensions?.height) as number | undefined;
72
- const scale = innerStateProps?.styles?.scale ?? itemScale;
64
+ const scale = stateProps?.styles?.scale ?? itemScale;
73
65
  const hasClickTriggers = interactionCtrl?.getHasTrigger(item.id, 'click') ?? false;
74
66
  if (!item.compoundSettings) return null;
75
67
  const layoutValues: Record<string, any>[] = [item.area, item.hidden, item.compoundSettings];
@@ -84,8 +76,8 @@ export const CompoundChild: FC<ChildItemProps> = ({ item, sectionId, isParentVis
84
76
  interactionCtrl?.handleTransitionEnd?.(e.propertyName);
85
77
  }}
86
78
  style={{
87
- ...(position && compoundSettings ? { top: getCompoundTop(compoundSettings, position.top) } : {}),
88
- ...(position && compoundSettings ? { left: getCompoundLeft(compoundSettings, position.left) } : {}),
79
+ ...(top && compoundSettings ? { top: getCompoundTop(compoundSettings, top) } : {}),
80
+ ...(left && compoundSettings ? { left: getCompoundLeft(compoundSettings, left) } : {}),
89
81
  ...(width && compoundSettings
90
82
  ? { width: `${sizingAxis.x === 'manual'
91
83
  ? getCompoundWidth(compoundSettings, width, isRichText, exemplary)
@@ -97,19 +89,11 @@ export const CompoundChild: FC<ChildItemProps> = ({ item, sectionId, isParentVis
97
89
  : 'unset'}` }
98
90
  : {}),
99
91
  ...(scale && compoundSettings ? { transform: `scale(${scale}) ${getCompoundTransform(compoundSettings)}` } : {}),
100
- transition: innerStateProps?.transition ?? 'none',
92
+ transition: stateProps?.transition ?? 'none',
101
93
  cursor: hasClickTriggers ? 'pointer' : 'unset',
102
94
  pointerEvents: allowPointerEvents ? 'auto' : 'none'
103
95
  }}
104
- onClick={() => {
105
- interactionCtrl?.sendTrigger('click');
106
- }}
107
- onMouseEnter={() => {
108
- interactionCtrl?.sendTrigger('hover-in');
109
- }}
110
- onMouseLeave={() => {
111
- interactionCtrl?.sendTrigger('hover-out');
112
- }}
96
+ {...triggers}
113
97
  >
114
98
  <RichTextWrapper isRichText={isRichText} transformOrigin={transformOrigin}>
115
99
  <ItemComponent
@@ -144,17 +128,3 @@ export const CompoundChild: FC<ChildItemProps> = ({ item, sectionId, isParentVis
144
128
  </div>
145
129
  );
146
130
  };
147
-
148
-
149
- function parseSizing(sizing: string = 'manual'): Axis {
150
- const axisSizing = sizing.split(' ');
151
- return {
152
- y: axisSizing[0],
153
- x: axisSizing[1] ? axisSizing[1] : axisSizing[0]
154
- } as Axis;
155
- }
156
-
157
- interface Axis {
158
- x: 'manual' | 'auto';
159
- y: 'manual' | 'auto';
160
- }
@@ -1,14 +1,16 @@
1
- import { FC, useEffect, useId, useMemo, useState } from 'react';
1
+ import type { VimeoEmbedItem as TVimeoEmbedItem } from '@cntrl-site/sdk';
2
+ import { getLayoutStyles } from '@cntrl-site/sdk';
3
+ import type { FC } from 'react';
4
+ import type { ItemProps } from '../Item';
2
5
  import Player from '@vimeo/player';
6
+ import { useEffect, useId, useMemo, useState } from 'react';
3
7
  import JSXStyle from 'styled-jsx/style';
4
- import { ItemProps } from '../Item';
5
- import { LinkWrapper } from '../LinkWrapper';
6
- import { useEmbedVideoItem } from './useEmbedVideoItem';
7
8
  import { useItemAngle } from '../useItemAngle';
8
- import { getLayoutStyles, VimeoEmbedItem as TVimeoEmbedItem } from '@cntrl-site/sdk';
9
9
  import { useCntrlContext } from '../../../provider/useCntrlContext';
10
10
  import { useRegisterResize } from "../../../common/useRegisterResize";
11
11
  import { getStyleFromItemStateAndParams } from '../../../utils/getStyleFromItemStateAndParams';
12
+ import { useEmbedVideoItem } from './useEmbedVideoItem';
13
+ import { LinkWrapper } from '../LinkWrapper';
12
14
 
13
15
  export const VimeoEmbedItem: FC<ItemProps<TVimeoEmbedItem>> = ({ item, sectionId, onResize, interactionCtrl, onVisibilityChange }) => {
14
16
  const id = useId();
@@ -37,7 +39,7 @@ export const VimeoEmbedItem: FC<ItemProps<TVimeoEmbedItem>> = ({ item, sectionId
37
39
  const validURL = new URL(url);
38
40
  validURL.searchParams.append('controls', String(controls));
39
41
  validURL.searchParams.append('autoplay', String(play === 'auto'));
40
- validURL.searchParams.append('muted', String(play !== 'on-click' ? true : muted));
42
+ validURL.searchParams.append('muted', String(muted));
41
43
  validURL.searchParams.append('loop', String(loop));
42
44
  validURL.searchParams.append('pip', String(pictureInPicture));
43
45
  validURL.searchParams.append('title', '0');
@@ -46,12 +48,12 @@ export const VimeoEmbedItem: FC<ItemProps<TVimeoEmbedItem>> = ({ item, sectionId
46
48
  validURL.searchParams.append('autopause', 'false');
47
49
 
48
50
  return validURL.href;
49
- }
51
+ };
50
52
  const validUrl = getValidVimeoUrl(url);
51
53
 
52
54
  useEffect(() => {
53
55
  if (!vimeoPlayer || !imgRef) return;
54
- if (play === 'on-click' && !controls) {
56
+ if (play === 'on-click') {
55
57
  setIsCoverVisible(true);
56
58
  }
57
59
  vimeoPlayer.on('pause', (e) => {
@@ -59,6 +61,9 @@ export const VimeoEmbedItem: FC<ItemProps<TVimeoEmbedItem>> = ({ item, sectionId
59
61
  setIsCoverVisible(true);
60
62
  }
61
63
  });
64
+ vimeoPlayer.on('ended', () => {
65
+ setIsCoverVisible(true);
66
+ });
62
67
  }, [vimeoPlayer, imgRef]);
63
68
 
64
69
  const handleClick = async () => {
@@ -67,7 +72,8 @@ export const VimeoEmbedItem: FC<ItemProps<TVimeoEmbedItem>> = ({ item, sectionId
67
72
  if (isPaused) {
68
73
  vimeoPlayer.play();
69
74
  setIsCoverVisible(false);
70
- } else {
75
+ }
76
+ else {
71
77
  vimeoPlayer.pause();
72
78
  }
73
79
  };
@@ -77,10 +83,14 @@ export const VimeoEmbedItem: FC<ItemProps<TVimeoEmbedItem>> = ({ item, sectionId
77
83
  vimeoPlayer!.play();
78
84
  setIsCoverVisible(false);
79
85
  };
86
+
80
87
  const isInteractive = opacity !== 0;
81
88
  useEffect(() => {
82
89
  onVisibilityChange?.(isInteractive);
83
- }, [isInteractive, onVisibilityChange]);
90
+ if (!isInteractive && vimeoPlayer) {
91
+ vimeoPlayer.pause();
92
+ }
93
+ }, [isInteractive, onVisibilityChange, vimeoPlayer]);
84
94
 
85
95
  return (
86
96
  <LinkWrapper url={item.link?.url} target={item.link?.target}>
@@ -97,7 +107,7 @@ export const VimeoEmbedItem: FC<ItemProps<TVimeoEmbedItem>> = ({ item, sectionId
97
107
  if (!vimeoPlayer || play !== 'on-hover') return;
98
108
  vimeoPlayer.play();
99
109
  }}
100
- onMouseLeave={() =>{
110
+ onMouseLeave={() => {
101
111
  if (!vimeoPlayer || play !== 'on-hover') return;
102
112
  vimeoPlayer.pause();
103
113
  }}
@@ -121,7 +131,7 @@ export const VimeoEmbedItem: FC<ItemProps<TVimeoEmbedItem>> = ({ item, sectionId
121
131
  />
122
132
  )}
123
133
  {/* ↓ This is necessary to track clicks on an iframe. */}
124
- {(!item.commonParams.controls && play === 'on-click') && (
134
+ {(!item.commonParams.controls && (play === 'on-click' || play === 'auto')) && (
125
135
  <div
126
136
  onClick={handleClick}
127
137
  style={{
@@ -135,17 +145,18 @@ export const VimeoEmbedItem: FC<ItemProps<TVimeoEmbedItem>> = ({ item, sectionId
135
145
  )}
136
146
  <iframe
137
147
  ref={setIframeRef}
138
- className={`embed-video`}
148
+ className="embed-video"
139
149
  src={validUrl || ''}
140
150
  allow="autoplay; fullscreen; picture-in-picture;"
141
151
  allowFullScreen
142
152
  style={{
143
- ...(radius !== undefined ? { borderRadius: `${radius * 100}vw` } : {}),
153
+ ...(radius !== undefined ? { borderRadius: `${radius * 100}vw` } : {}),
144
154
  transition: frameStateParams?.transition ?? 'none'
145
155
  }}
146
156
  />
147
157
  </div>
148
- <JSXStyle id={id}>{`
158
+ <JSXStyle id={id}>
159
+ {`
149
160
  .embed-video-wrapper-${item.id} {
150
161
  position: absolute;
151
162
  width: 100%;
@@ -159,7 +170,7 @@ export const VimeoEmbedItem: FC<ItemProps<TVimeoEmbedItem>> = ({ item, sectionId
159
170
  overflow: hidden;
160
171
  }
161
172
  ${getLayoutStyles(layouts, layoutValues, ([area, layoutParams]) => {
162
- return (`
173
+ return (`
163
174
  .embed-video-wrapper-${item.id} {
164
175
  opacity: ${layoutParams.opacity};
165
176
  transform: rotate(${area.angle}deg);
@@ -169,8 +180,9 @@ export const VimeoEmbedItem: FC<ItemProps<TVimeoEmbedItem>> = ({ item, sectionId
169
180
  border-radius: ${layoutParams.radius * 100}vw;
170
181
  }
171
182
  `);
172
- })}
173
- `}</JSXStyle>
183
+ })}
184
+ `}
185
+ </JSXStyle>
174
186
  </LinkWrapper>
175
187
  );
176
188
  };
@@ -1,8 +1,6 @@
1
1
  import React, {
2
2
  FC,
3
- useCallback,
4
3
  useContext,
5
- useEffect,
6
4
  useId,
7
5
  useMemo,
8
6
  useRef,
@@ -17,8 +15,6 @@ import {
17
15
  PositionType
18
16
  } from '@cntrl-site/sdk';
19
17
  import { useCntrlContext } from '../../provider/useCntrlContext';
20
- import { useItemPosition } from './useItemPosition';
21
- import { useItemDimensions } from './useItemDimensions';
22
18
  import { useItemScale } from './useItemScale';
23
19
  import { ScaleAnchorMap } from '../../utils/ScaleAnchorMap';
24
20
  import { useSectionHeightData } from '../Section/useSectionHeightMap';
@@ -34,6 +30,10 @@ import { useItemInteractionCtrl } from '../../interactions/useItemInteractionCtr
34
30
  import { isItemType } from '../../utils/isItemType';
35
31
  import { RichTextWrapper } from './RichTextWrapper';
36
32
  import { itemsMap } from './itemsMap';
33
+ import { useItemTriggers } from './useItemTriggers';
34
+ import { parseSizing, useSizing } from './useSizing';
35
+ import { useItemPointerEvents } from './useItemPointerEvents';
36
+ import { useItemArea } from './useItemArea';
37
37
 
38
38
  export interface ItemProps<I extends ItemAny> {
39
39
  item: I;
@@ -69,31 +69,29 @@ export const Item: FC<ItemWrapperProps> = ({ item, sectionId, articleHeight, isP
69
69
  const { layouts } = useCntrlContext();
70
70
  const layout = useLayoutContext();
71
71
  const exemplary = useExemplary();
72
- const [allowPointerEvents, setAllowPointerEvents] = useState<boolean>(isParentVisible);
72
+ const { handleVisibilityChange, allowPointerEvents } = useItemPointerEvents(isParentVisible);
73
73
  const [wrapperHeight, setWrapperHeight] = useState<undefined | number>(undefined);
74
74
  const [itemHeight, setItemHeight] = useState<undefined | number>(undefined);
75
75
  const itemScale = useItemScale(item, sectionId);
76
76
  const interactionCtrl = useItemInteractionCtrl(item.id);
77
+ const triggers = useItemTriggers(interactionCtrl);
77
78
  const wrapperStateProps = interactionCtrl?.getState(['top', 'left']);
78
- const innerStateProps = interactionCtrl?.getState(['width', 'height', 'scale']);
79
- const position = useItemPosition(item, sectionId, {
79
+ const innerStateProps = interactionCtrl?.getState(['width', 'height', 'scale', 'top', 'left']);
80
+ const { width, height, top, left } = useItemArea(item, sectionId, {
80
81
  top: wrapperStateProps?.styles?.top as number,
81
82
  left: wrapperStateProps?.styles?.left as number,
83
+ width: innerStateProps?.styles?.width as number,
84
+ height: innerStateProps?.styles?.height as number
82
85
  });
83
86
  const sectionHeight = useSectionHeightData(sectionId);
84
87
  const stickyTop = useStickyItemTop(item, sectionHeight, sectionId);
85
- const dimensions = useItemDimensions(item, sectionId);
86
88
  const layoutValues: Record<string, any>[] = [item.area, item.hidden];
87
- const isInitialRef = useRef(true);
88
89
  layoutValues.push(item.sticky);
89
90
  layoutValues.push(sectionHeight);
90
91
  if (item.layoutParams) {
91
92
  layoutValues.push(item.layoutParams);
92
93
  }
93
- const sizing = layout && isItemType(item, ArticleItemType.RichText)
94
- ? item.layoutParams[layout].sizing
95
- : undefined;
96
- const sizingAxis = parseSizing(sizing);
94
+ const sizingAxis = useSizing(item);
97
95
  const ItemComponent = itemsMap[item.type] || noop;
98
96
  const sectionTop = rectObserver ? rectObserver.getSectionTop(sectionId) : 0;
99
97
 
@@ -114,18 +112,7 @@ export const Item: FC<ItemWrapperProps> = ({ item, sectionId, articleHeight, isP
114
112
  setWrapperHeight(wrapperHeight);
115
113
  };
116
114
 
117
- const handleVisibilityChange = useCallback((isVisible: boolean) => {
118
- if (!isParentVisible) return;
119
- setAllowPointerEvents(isVisible);
120
- }, [isParentVisible]);
121
-
122
- useEffect(() => {
123
- isInitialRef.current = false;
124
- }, []);
125
-
126
115
  const isRichText = isItemType(item, ArticleItemType.RichText);
127
- const width = (innerStateProps?.styles?.width ?? dimensions?.width) as number | undefined;
128
- const height = (innerStateProps?.styles?.height ?? dimensions?.height) as number | undefined;
129
116
  const anchorSide = layout ? item.area[layout].anchorSide : AnchorSide.Top;
130
117
  const positionType = layout ? item.area[layout].positionType : PositionType.ScreenBased;
131
118
  const isScreenBasedBottom = positionType === PositionType.ScreenBased && anchorSide === AnchorSide.Bottom;
@@ -140,9 +127,9 @@ export const Item: FC<ItemWrapperProps> = ({ item, sectionId, articleHeight, isP
140
127
  interactionCtrl?.handleTransitionEnd?.(e.propertyName);
141
128
  }}
142
129
  style={{
143
- ...(position ? { top: isScreenBasedBottom ? 'unset' : getItemTopStyle(position.top, anchorSide) } : {}),
144
- ...(position ? { left: `${position.left * 100}vw` } : {}),
145
- ...(position ? { bottom: isScreenBasedBottom ? `${-position.top * 100}vw` : 'unset' } : {}),
130
+ ...(top ? { top: isScreenBasedBottom ? 'unset' : getItemTopStyle(top, anchorSide) } : {}),
131
+ ...(left ? { left: `${left * 100}vw` } : {}),
132
+ ...(top ? { bottom: isScreenBasedBottom ? `${-top * 100}vw` : 'unset' } : {}),
146
133
  ...(wrapperHeight !== undefined ? { height: `${wrapperHeight * 100}vw` } : {}),
147
134
  transition: wrapperStateProps?.transition ?? 'none'
148
135
  }}
@@ -160,15 +147,6 @@ export const Item: FC<ItemWrapperProps> = ({ item, sectionId, articleHeight, isP
160
147
  <div
161
148
  className={`item-${item.id}-inner`}
162
149
  ref={itemInnerRef}
163
- onClick={() => {
164
- interactionCtrl?.sendTrigger('click');
165
- }}
166
- onMouseEnter={() => {
167
- interactionCtrl?.sendTrigger('hover-in');
168
- }}
169
- onMouseLeave={() => {
170
- interactionCtrl?.sendTrigger('hover-out');
171
- }}
172
150
  style={{
173
151
  ...((width && height) ? {
174
152
  width: `${sizingAxis.x === 'manual'
@@ -182,6 +160,7 @@ export const Item: FC<ItemWrapperProps> = ({ item, sectionId, articleHeight, isP
182
160
  cursor: hasClickTriggers ? 'pointer' : 'unset',
183
161
  pointerEvents: allowPointerEvents ? 'auto' : 'none'
184
162
  }}
163
+ {...triggers}
185
164
  >
186
165
  <ItemComponent
187
166
  item={item}
@@ -231,16 +210,3 @@ export const Item: FC<ItemWrapperProps> = ({ item, sectionId, articleHeight, isP
231
210
  </div>
232
211
  );
233
212
  };
234
-
235
- function parseSizing(sizing: string = 'manual'): Axis {
236
- const axisSizing = sizing.split(' ');
237
- return {
238
- y: axisSizing[0],
239
- x: axisSizing[1] ? axisSizing[1] : axisSizing[0]
240
- } as Axis;
241
- }
242
-
243
- interface Axis {
244
- x: 'manual' | 'auto';
245
- y: 'manual' | 'auto';
246
- }
@@ -0,0 +1,35 @@
1
+ import { ItemAny, KeyframeType } from '@cntrl-site/sdk';
2
+ import { useLayoutContext } from '../useLayoutContext';
3
+ import { useKeyframeValue } from '../../common/useKeyframeValue';
4
+
5
+ export function useItemArea(
6
+ item: ItemAny,
7
+ sectionId: string,
8
+ stateValues: { top?: number; left?: number; width?: number; height?: number }
9
+ ) {
10
+ const layoutId = useLayoutContext();
11
+ const position = useKeyframeValue<{ top: number; left: number } | undefined>(
12
+ item,
13
+ KeyframeType.Position,
14
+ (item, layoutId) => {
15
+ if (!layoutId) return;
16
+ return item.area[layoutId]
17
+ },
18
+ (animator, scroll, value) => value ? animator.getPositions(value, scroll) : undefined,
19
+ sectionId,
20
+ [layoutId]
21
+ );
22
+ const dimensions = useKeyframeValue<{ width: number; height: number } | undefined>(
23
+ item,
24
+ KeyframeType.Dimensions,
25
+ (item, layoutId) => layoutId ? item.area[layoutId] : undefined,
26
+ (animator, scroll, value) => value ? animator.getDimensions(value, scroll) : undefined,
27
+ sectionId,
28
+ [layoutId]
29
+ );
30
+ const width = (stateValues.width ?? dimensions?.width) as number | undefined;
31
+ const height = (stateValues.height ?? dimensions?.height) as number | undefined;
32
+ const top = (stateValues.top ?? position?.top) as number | undefined;
33
+ const left = (stateValues.left ?? position?.left) as number | undefined;
34
+ return { width, height, top, left };
35
+ }
@@ -0,0 +1,10 @@
1
+ import { useCallback, useState } from 'react';
2
+
3
+ export function useItemPointerEvents(isParentVisible: boolean) {
4
+ const [allowPointerEvents, setAllowPointerEvents] = useState<boolean>(isParentVisible);
5
+ const handleVisibilityChange = useCallback((isVisible: boolean) => {
6
+ if (!isParentVisible) return;
7
+ setAllowPointerEvents(isVisible);
8
+ }, [isParentVisible]);
9
+ return { allowPointerEvents, handleVisibilityChange };
10
+ }
@@ -0,0 +1,15 @@
1
+ import { ItemInteractionCtrl } from '../../interactions/types';
2
+
3
+ export function useItemTriggers(interactionCtrl: ItemInteractionCtrl | undefined) {
4
+ return {
5
+ onClick: () => {
6
+ interactionCtrl?.sendTrigger('click');
7
+ },
8
+ onMouseEnter: () => {
9
+ interactionCtrl?.sendTrigger('hover-in');
10
+ },
11
+ onMouseLeave: () => {
12
+ interactionCtrl?.sendTrigger('hover-out');
13
+ }
14
+ };
15
+ }
@@ -0,0 +1,25 @@
1
+ import { isItemType } from '../../utils/isItemType';
2
+ import { ArticleItemType, ItemAny } from '@cntrl-site/sdk';
3
+ import { useLayoutContext } from '../useLayoutContext';
4
+
5
+ export function useSizing(item: ItemAny) {
6
+ const layout = useLayoutContext();
7
+ const sizing = layout && isItemType(item, ArticleItemType.RichText)
8
+ ? item.layoutParams[layout].sizing
9
+ : undefined;
10
+ const sizingAxis = parseSizing(sizing);
11
+ return sizingAxis;
12
+ }
13
+
14
+ export function parseSizing(sizing: string = 'manual'): Axis {
15
+ const axisSizing = sizing.split(' ');
16
+ return {
17
+ y: axisSizing[0],
18
+ x: axisSizing[1] ? axisSizing[1] : axisSizing[0]
19
+ } as Axis;
20
+ }
21
+
22
+ interface Axis {
23
+ x: 'manual' | 'auto';
24
+ y: 'manual' | 'auto';
25
+ }
Binary file
@@ -1,12 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.useItemDimensions = void 0;
4
- const sdk_1 = require("@cntrl-site/sdk");
5
- const useKeyframeValue_1 = require("../../common/useKeyframeValue");
6
- const useLayoutContext_1 = require("../useLayoutContext");
7
- const useItemDimensions = (item, sectionId) => {
8
- const layoutId = (0, useLayoutContext_1.useLayoutContext)();
9
- const dimensions = (0, useKeyframeValue_1.useKeyframeValue)(item, sdk_1.KeyframeType.Dimensions, (item, layoutId) => layoutId ? item.area[layoutId] : undefined, (animator, scroll, value) => value ? animator.getDimensions(value, scroll) : undefined, sectionId, [layoutId]);
10
- return dimensions;
11
- };
12
- exports.useItemDimensions = useItemDimensions;
@@ -1,25 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.useItemPosition = void 0;
4
- const sdk_1 = require("@cntrl-site/sdk");
5
- const useKeyframeValue_1 = require("../../common/useKeyframeValue");
6
- const useLayoutContext_1 = require("../useLayoutContext");
7
- const useItemPosition = (item, sectionId, stateValues) => {
8
- var _a, _b;
9
- const layoutId = (0, useLayoutContext_1.useLayoutContext)();
10
- const position = (0, useKeyframeValue_1.useKeyframeValue)(item, sdk_1.KeyframeType.Position, (item, layoutId) => {
11
- if (!layoutId)
12
- return;
13
- return item.area[layoutId];
14
- }, (animator, scroll, value) => value ? animator.getPositions(value, scroll) : undefined, sectionId, [layoutId]);
15
- // to prevent fixed item (with anchor point bottom) to jump when scroll in safari on mobile
16
- if (!position)
17
- return undefined;
18
- const top = (_a = stateValues === null || stateValues === void 0 ? void 0 : stateValues.top) !== null && _a !== void 0 ? _a : position.top;
19
- const left = (_b = stateValues === null || stateValues === void 0 ? void 0 : stateValues.left) !== null && _b !== void 0 ? _b : position.left;
20
- return position ? {
21
- top,
22
- left
23
- } : undefined;
24
- };
25
- exports.useItemPosition = useItemPosition;
@@ -1,16 +0,0 @@
1
- import { ItemAny, KeyframeType } from '@cntrl-site/sdk';
2
- import { useKeyframeValue } from '../../common/useKeyframeValue';
3
- import { useLayoutContext } from '../useLayoutContext';
4
-
5
- export const useItemDimensions = (item: ItemAny, sectionId: string) => {
6
- const layoutId = useLayoutContext();
7
- const dimensions = useKeyframeValue<{ width: number; height: number } | undefined>(
8
- item,
9
- KeyframeType.Dimensions,
10
- (item, layoutId) => layoutId ? item.area[layoutId] : undefined,
11
- (animator, scroll, value) => value ? animator.getDimensions(value, scroll) : undefined,
12
- sectionId,
13
- [layoutId]
14
- );
15
- return dimensions;
16
- };
@@ -1,34 +0,0 @@
1
- import { AnchorSide, ItemAny, KeyframeType, PositionType } from '@cntrl-site/sdk';
2
- import { useKeyframeValue } from '../../common/useKeyframeValue';
3
- import { getItemTopStyle } from '../../utils/getItemTopStyle';
4
- import { useLayoutContext } from '../useLayoutContext';
5
-
6
- export const useItemPosition = (
7
- item: ItemAny,
8
- sectionId: string,
9
- stateValues: { top?: number; left?: number; }
10
- ) => {
11
- const layoutId = useLayoutContext();
12
- const position = useKeyframeValue<{ top: number; left: number } | undefined>(
13
- item,
14
- KeyframeType.Position,
15
- (item, layoutId) => {
16
- if (!layoutId) return;
17
- return item.area[layoutId]
18
- },
19
- (animator, scroll, value) => value ? animator.getPositions(value, scroll) : undefined,
20
- sectionId,
21
- [layoutId]
22
- );
23
- // to prevent fixed item (with anchor point bottom) to jump when scroll in safari on mobile
24
- if (!position) return undefined;
25
- const top = stateValues?.top ?? position.top;
26
- const left = stateValues?.left ?? position.left;
27
- return position ? {
28
- top,
29
- left
30
- } : undefined;
31
-
32
- };
33
-
34
-