@cntrl-site/sdk-nextjs 1.0.19-alpha.7 → 1.0.19-alpha.8
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.
- package/lib/components/Item.js +8 -2
- package/lib/components/LinkWrapper.js +2 -3
- package/lib/components/items/CodeEmbedItem.js +6 -3
- package/lib/components/items/GroupItem.js +6 -3
- package/lib/components/items/ImageItem.js +6 -2
- package/lib/components/items/RectangleItem.js +5 -2
- package/lib/components/items/RichTextItem.js +6 -3
- package/lib/components/items/VideoItem.js +6 -2
- package/lib/components/items/VimeoEmbed.js +5 -2
- package/lib/components/items/YoutubeEmbed.js +5 -2
- package/lib/components/items/useRichTextItem.js +2 -2
- package/lib/utils/RichTextConverter/RichTextConverter.js +2 -2
- package/package.json +1 -1
- package/src/components/Item.tsx +27 -6
- package/src/components/LinkWrapper.tsx +3 -6
- package/src/components/items/CodeEmbedItem.tsx +6 -4
- package/src/components/items/CustomItem.tsx +1 -1
- package/src/components/items/GroupItem.tsx +8 -6
- package/src/components/items/ImageItem.tsx +6 -2
- package/src/components/items/RectangleItem.tsx +6 -3
- package/src/components/items/RichTextItem.tsx +6 -5
- package/src/components/items/VideoItem.tsx +7 -3
- package/src/components/items/VimeoEmbed.tsx +5 -2
- package/src/components/items/YoutubeEmbed.tsx +5 -2
- package/src/components/items/useRichTextItem.ts +2 -2
- package/src/utils/RichTextConverter/RichTextConverter.tsx +2 -12
package/lib/components/Item.js
CHANGED
|
@@ -52,7 +52,7 @@ const RichTextWrapper = ({ isRichText, children }) => {
|
|
|
52
52
|
return ((0, jsx_runtime_1.jsx)("div", { style: { transformOrigin: 'top left', transform: 'scale(var(--layout-deviation))' }, children: children }));
|
|
53
53
|
};
|
|
54
54
|
const noop = () => null;
|
|
55
|
-
const Item = ({ item, sectionId, articleHeight,
|
|
55
|
+
const Item = ({ item, sectionId, articleHeight, isParentVisible = true, isInGroup = false }) => {
|
|
56
56
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
57
57
|
const itemWrapperRef = (0, react_1.useRef)(null);
|
|
58
58
|
const itemInnerRef = (0, react_1.useRef)(null);
|
|
@@ -63,6 +63,7 @@ const Item = ({ item, sectionId, articleHeight, isItemVisible = true, isInGroup
|
|
|
63
63
|
const { layouts } = (0, useCntrlContext_1.useCntrlContext)();
|
|
64
64
|
const layout = (0, useLayoutContext_1.useLayoutContext)();
|
|
65
65
|
const exemplary = (0, useExemplary_1.useExemplary)();
|
|
66
|
+
const [allowPointerEvents, setAllowPointerEvents] = (0, react_1.useState)(isParentVisible);
|
|
66
67
|
const [wrapperHeight, setWrapperHeight] = (0, react_1.useState)(undefined);
|
|
67
68
|
const [itemHeight, setItemHeight] = (0, react_1.useState)(undefined);
|
|
68
69
|
const itemScale = (0, useItemScale_1.useItemScale)(item, sectionId);
|
|
@@ -106,6 +107,11 @@ const Item = ({ item, sectionId, articleHeight, isItemVisible = true, isInGroup
|
|
|
106
107
|
setItemHeight(height);
|
|
107
108
|
setWrapperHeight(wrapperHeight);
|
|
108
109
|
};
|
|
110
|
+
const handleVisibilityChange = (0, react_1.useCallback)((isVisible) => {
|
|
111
|
+
if (!isParentVisible)
|
|
112
|
+
return;
|
|
113
|
+
setAllowPointerEvents(isVisible);
|
|
114
|
+
}, [isParentVisible]);
|
|
109
115
|
(0, react_1.useEffect)(() => {
|
|
110
116
|
isInitialRef.current = false;
|
|
111
117
|
}, []);
|
|
@@ -134,7 +140,7 @@ const Item = ({ item, sectionId, articleHeight, isItemVisible = true, isInGroup
|
|
|
134
140
|
: `${width * 100}vw`
|
|
135
141
|
: 'max-content'}`,
|
|
136
142
|
height: `${sizingAxis.y === 'manual' ? `${height * 100}vw` : 'unset'}`
|
|
137
|
-
} : {})), (scale !== undefined ? { transform: `scale(${scale})`, 'WebkitTransform': `scale(${scale})` } : {})), { transition: (_k = innerStateProps === null || innerStateProps === void 0 ? void 0 : innerStateProps.transition) !== null && _k !== void 0 ? _k : 'none', pointerEvents:
|
|
143
|
+
} : {})), (scale !== undefined ? { transform: `scale(${scale})`, 'WebkitTransform': `scale(${scale})` } : {})), { transition: (_k = innerStateProps === null || innerStateProps === void 0 ? void 0 : innerStateProps.transition) !== null && _k !== void 0 ? _k : 'none', 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: `
|
|
138
144
|
${(0, sdk_1.getLayoutStyles)(layouts, layoutValues, ([area, hidden, sticky, sectionHeight, layoutParams], exemplary) => {
|
|
139
145
|
const sizingAxis = parseSizing(layoutParams.sizing);
|
|
140
146
|
const isScreenBasedBottom = area.positionType === sdk_1.PositionType.ScreenBased && area.anchorSide === sdk_1.AnchorSide.Bottom;
|
|
@@ -2,10 +2,9 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.LinkWrapper = void 0;
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
-
const LinkWrapper = ({ url, children, target
|
|
5
|
+
const LinkWrapper = ({ url, children, target }) => {
|
|
6
6
|
const validUrl = url && buildValidUrl(url);
|
|
7
|
-
|
|
8
|
-
return url ? ((0, jsx_runtime_1.jsx)("a", { href: validUrl, target: target, rel: "noreferrer", style: style, children: children })) : ((0, jsx_runtime_1.jsx)("span", { style: style, children: children }));
|
|
7
|
+
return url ? ((0, jsx_runtime_1.jsx)("a", { href: validUrl, target: target, rel: "noreferrer", children: children })) : ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: children }));
|
|
9
8
|
};
|
|
10
9
|
exports.LinkWrapper = LinkWrapper;
|
|
11
10
|
function buildValidUrl(url) {
|
|
@@ -24,7 +24,7 @@ const stylesMap = {
|
|
|
24
24
|
[sdk_1.AreaAnchor.BottomCenter]: { justifyContent: 'center', alignItems: 'flex-end' },
|
|
25
25
|
[sdk_1.AreaAnchor.BottomRight]: { justifyContent: 'flex-end', alignItems: 'flex-end' }
|
|
26
26
|
};
|
|
27
|
-
const CodeEmbedItem = ({ item, sectionId, onResize, interactionCtrl }) => {
|
|
27
|
+
const CodeEmbedItem = ({ 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)();
|
|
30
30
|
const { layouts } = (0, useCntrlContext_1.useCntrlContext)();
|
|
@@ -61,8 +61,11 @@ const CodeEmbedItem = ({ item, sectionId, onResize, interactionCtrl }) => {
|
|
|
61
61
|
return;
|
|
62
62
|
iframe.srcdoc = item.commonParams.html;
|
|
63
63
|
}, [item.commonParams.html, item.commonParams.iframe, ref]);
|
|
64
|
-
const isInteractive =
|
|
65
|
-
|
|
64
|
+
const isInteractive = opacity !== 0;
|
|
65
|
+
(0, react_1.useEffect)(() => {
|
|
66
|
+
onVisibilityChange === null || onVisibilityChange === void 0 ? void 0 : onVisibilityChange(isInteractive);
|
|
67
|
+
}, [isInteractive, onVisibilityChange]);
|
|
68
|
+
return ((0, jsx_runtime_1.jsxs)(LinkWrapper_1.LinkWrapper, { url: (_g = item.link) === null || _g === void 0 ? void 0 : _g.url, target: (_h = item.link) === null || _h === void 0 ? void 0 : _h.target, children: [(0, jsx_runtime_1.jsx)("div", { className: `embed-wrapper-${item.id}`, style: Object.assign(Object.assign(Object.assign(Object.assign({}, (angle !== undefined ? { transform: `rotate(${angle}deg)` } : {})), (blur !== undefined ? { filter: `blur(${blur * 100}vw)` } : {})), (opacity !== undefined ? { opacity } : {})), { transition: (_j = stateParams === null || stateParams === void 0 ? void 0 : stateParams.transition) !== null && _j !== void 0 ? _j : 'none' }), ref: setRef, children: item.commonParams.iframe ? ((0, jsx_runtime_1.jsx)("iframe", { "data-embed": item.id, className: `embed-${item.id}`, style: Object.assign(Object.assign({}, pos), { border: 'unset' }) })) : ((0, jsx_runtime_1.jsx)("div", { className: `embed-${item.id}`, style: Object.assign({}, pos), dangerouslySetInnerHTML: { __html: html } })) }), (0, jsx_runtime_1.jsx)(style_1.default, { id: id, children: `
|
|
66
69
|
.embed-wrapper-${item.id} {
|
|
67
70
|
position: absolute;
|
|
68
71
|
width: 100%;
|
|
@@ -15,7 +15,7 @@ const useCntrlContext_1 = require("../../provider/useCntrlContext");
|
|
|
15
15
|
const useItemAngle_1 = require("../useItemAngle");
|
|
16
16
|
const useGroupItem_1 = require("./useGroupItem");
|
|
17
17
|
const getStyleFromItemStateAndParams_1 = require("../../utils/getStyleFromItemStateAndParams");
|
|
18
|
-
const GroupItem = ({ item, sectionId, onResize, articleHeight, interactionCtrl }) => {
|
|
18
|
+
const GroupItem = ({ item, sectionId, onResize, articleHeight, interactionCtrl, onVisibilityChange }) => {
|
|
19
19
|
var _a, _b, _c, _d, _e;
|
|
20
20
|
const id = (0, react_1.useId)();
|
|
21
21
|
const { items } = item;
|
|
@@ -28,8 +28,11 @@ const GroupItem = ({ item, sectionId, onResize, articleHeight, interactionCtrl }
|
|
|
28
28
|
const stateParams = interactionCtrl === null || interactionCtrl === void 0 ? void 0 : interactionCtrl.getState(['opacity', 'angle']);
|
|
29
29
|
const angle = (0, getStyleFromItemStateAndParams_1.getStyleFromItemStateAndParams)((_a = stateParams === null || stateParams === void 0 ? void 0 : stateParams.styles) === null || _a === void 0 ? void 0 : _a.angle, itemAngle);
|
|
30
30
|
const opacity = (0, getStyleFromItemStateAndParams_1.getStyleFromItemStateAndParams)((_b = stateParams === null || stateParams === void 0 ? void 0 : stateParams.styles) === null || _b === void 0 ? void 0 : _b.opacity, itemOpacity);
|
|
31
|
-
const
|
|
32
|
-
|
|
31
|
+
const isInteractive = opacity !== 0;
|
|
32
|
+
(0, react_1.useEffect)(() => {
|
|
33
|
+
onVisibilityChange === null || onVisibilityChange === void 0 ? void 0 : onVisibilityChange(isInteractive);
|
|
34
|
+
}, [isInteractive, onVisibilityChange]);
|
|
35
|
+
return ((0, jsx_runtime_1.jsx)(LinkWrapper_1.LinkWrapper, { url: (_c = item.link) === null || _c === void 0 ? void 0 : _c.url, target: (_d = item.link) === null || _d === void 0 ? void 0 : _d.target, children: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { className: `group-${item.id}`, ref: setRef, style: Object.assign(Object.assign(Object.assign({}, (opacity !== undefined ? { opacity } : {})), (angle !== undefined ? { transform: `rotate(${angle}deg)` } : {})), { transition: (_e = stateParams === null || stateParams === void 0 ? void 0 : stateParams.transition) !== null && _e !== void 0 ? _e : 'none' }), children: items && items.map(item => ((0, jsx_runtime_1.jsx)(Item_1.Item, { item: item, sectionId: sectionId, articleHeight: articleHeight, isParentVisible: isInteractive, isInGroup: true }, item.id))) }), (0, jsx_runtime_1.jsx)(style_1.default, { id: id, children: `
|
|
33
36
|
.group-${item.id} {
|
|
34
37
|
position: absolute;
|
|
35
38
|
width: 100%;
|
|
@@ -26,7 +26,7 @@ uniform vec2 u_patternDimensions;
|
|
|
26
26
|
uniform float u_time;
|
|
27
27
|
uniform vec2 u_cursor;
|
|
28
28
|
varying vec2 v_texCoord;`;
|
|
29
|
-
const ImageItem = ({ item, sectionId, onResize, interactionCtrl }) => {
|
|
29
|
+
const ImageItem = ({ item, sectionId, onResize, interactionCtrl, onVisibilityChange }) => {
|
|
30
30
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
31
31
|
const id = (0, react_1.useId)();
|
|
32
32
|
const { layouts } = (0, useCntrlContext_1.useCntrlContext)();
|
|
@@ -76,7 +76,11 @@ const ImageItem = ({ item, sectionId, onResize, interactionCtrl }) => {
|
|
|
76
76
|
const opacity = (0, getStyleFromItemStateAndParams_1.getStyleFromItemStateAndParams)((_h = wrapperStateParams === null || wrapperStateParams === void 0 ? void 0 : wrapperStateParams.styles) === null || _h === void 0 ? void 0 : _h.opacity, itemOpacity);
|
|
77
77
|
const blur = (0, getStyleFromItemStateAndParams_1.getStyleFromItemStateAndParams)((_j = wrapperStateParams === null || wrapperStateParams === void 0 ? void 0 : wrapperStateParams.styles) === null || _j === void 0 ? void 0 : _j.blur, itemBlur);
|
|
78
78
|
const inlineStyles = Object.assign(Object.assign(Object.assign(Object.assign({}, (borderColor ? { borderColor: `${borderColor.fmt('rgba')}` } : {})), (radius !== undefined ? { borderRadius: `${radius * 100}vw` } : {})), (strokeWidth !== undefined ? { borderWidth: `${strokeWidth * 100}vw` } : {})), { transition: (_k = imgStateParams === null || imgStateParams === void 0 ? void 0 : imgStateParams.transition) !== null && _k !== void 0 ? _k : 'none' });
|
|
79
|
-
|
|
79
|
+
const isInteractive = opacity !== 0;
|
|
80
|
+
(0, react_1.useEffect)(() => {
|
|
81
|
+
onVisibilityChange === null || onVisibilityChange === void 0 ? void 0 : onVisibilityChange(isInteractive);
|
|
82
|
+
}, [isInteractive, onVisibilityChange]);
|
|
83
|
+
return ((0, jsx_runtime_1.jsx)(LinkWrapper_1.LinkWrapper, { url: (_l = item.link) === null || _l === void 0 ? void 0 : _l.url, target: (_m = item.link) === null || _m === void 0 ? void 0 : _m.target, children: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { className: `image-wrapper-${item.id}`, ref: setWrapperRef, 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: (_o = wrapperStateParams === null || wrapperStateParams === void 0 ? void 0 : wrapperStateParams.transition) !== null && _o !== void 0 ? _o : 'none' }), children: hasGLEffect && isFXAllowed ? ((0, jsx_runtime_1.jsx)("canvas", { style: inlineStyles, ref: fxCanvas, className: `img-canvas image-${item.id}`, width: rectWidth, height: rectHeight })) : ((0, jsx_runtime_1.jsx)("img", { alt: "", className: `image image-${item.id}`, style: inlineStyles, src: item.commonParams.url })) }), (0, jsx_runtime_1.jsx)(style_1.default, { id: id, children: `
|
|
80
84
|
.image-wrapper-${item.id} {
|
|
81
85
|
position: absolute;
|
|
82
86
|
width: 100%;
|
|
@@ -15,7 +15,7 @@ const useItemAngle_1 = require("../useItemAngle");
|
|
|
15
15
|
const useCntrlContext_1 = require("../../provider/useCntrlContext");
|
|
16
16
|
const useRegisterResize_1 = require("../../common/useRegisterResize");
|
|
17
17
|
const getStyleFromItemStateAndParams_1 = require("../../utils/getStyleFromItemStateAndParams");
|
|
18
|
-
const RectangleItem = ({ item, sectionId, onResize, interactionCtrl }) => {
|
|
18
|
+
const RectangleItem = ({ item, sectionId, onResize, interactionCtrl, onVisibilityChange }) => {
|
|
19
19
|
var _a, _b, _c, _d;
|
|
20
20
|
const id = (0, react_1.useId)();
|
|
21
21
|
const { layouts } = (0, useCntrlContext_1.useCntrlContext)();
|
|
@@ -41,7 +41,10 @@ const RectangleItem = ({ item, sectionId, onResize, interactionCtrl }) => {
|
|
|
41
41
|
const blur = (0, getStyleFromItemStateAndParams_1.getStyleFromItemStateAndParams)(styles === null || styles === void 0 ? void 0 : styles.blur, itemBlur);
|
|
42
42
|
const backdropFilterValue = backdropBlur ? `blur(${backdropBlur * 100}vw)` : undefined;
|
|
43
43
|
const isInteractive = (backgroundColor === null || backgroundColor === void 0 ? void 0 : backgroundColor.getAlpha()) !== 0 || (strokeWidth !== 0 && (borderColor === null || borderColor === void 0 ? void 0 : borderColor.getAlpha()) !== 0);
|
|
44
|
-
|
|
44
|
+
(0, react_1.useEffect)(() => {
|
|
45
|
+
onVisibilityChange === null || onVisibilityChange === void 0 ? void 0 : onVisibilityChange(isInteractive);
|
|
46
|
+
}, [isInteractive, onVisibilityChange]);
|
|
47
|
+
return ((0, jsx_runtime_1.jsx)(LinkWrapper_1.LinkWrapper, { url: (_b = item.link) === null || _b === void 0 ? void 0 : _b.url, target: (_c = item.link) === null || _c === void 0 ? void 0 : _c.target, children: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { className: `rectangle-${item.id}`, ref: setRef, style: Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (backgroundColor ? { backgroundColor: `${backgroundColor.fmt('rgba')}` } : {})), (borderColor ? { borderColor: `${borderColor.fmt('rgba')}` } : {})), (radius !== undefined ? { borderRadius: `${radius * 100}vw` } : {})), (strokeWidth !== undefined ? { borderWidth: `${strokeWidth * 100}vw` } : {})), (angle !== undefined ? { transform: `rotate(${angle}deg)` } : {})), (blur !== undefined ? { filter: `blur(${blur * 100}vw)` } : {})), (backdropFilterValue !== undefined
|
|
45
48
|
? { backdropFilter: backdropFilterValue, WebkitBackdropFilter: backdropFilterValue }
|
|
46
49
|
: {})), { transition: (_d = stateParams === null || stateParams === void 0 ? void 0 : stateParams.transition) !== null && _d !== void 0 ? _d : 'none' }) }), (0, jsx_runtime_1.jsx)(style_1.default, { id: id, children: `
|
|
47
50
|
.rectangle-${item.id} {
|
|
@@ -18,7 +18,7 @@ const useExemplary_1 = require("../../common/useExemplary");
|
|
|
18
18
|
const useItemAngle_1 = require("../useItemAngle");
|
|
19
19
|
const getStyleFromItemStateAndParams_1 = require("../../utils/getStyleFromItemStateAndParams");
|
|
20
20
|
const useCurrentLayout_1 = require("../../common/useCurrentLayout");
|
|
21
|
-
const RichTextItem = ({ item, sectionId, onResize, interactionCtrl }) => {
|
|
21
|
+
const RichTextItem = ({ item, sectionId, onResize, interactionCtrl, onVisibilityChange }) => {
|
|
22
22
|
var _a, _b, _c, _d;
|
|
23
23
|
const id = (0, react_1.useId)();
|
|
24
24
|
const [ref, setRef] = (0, react_1.useState)(null);
|
|
@@ -49,8 +49,11 @@ const RichTextItem = ({ item, sectionId, onResize, interactionCtrl }) => {
|
|
|
49
49
|
return alpha > 0;
|
|
50
50
|
});
|
|
51
51
|
const isInteractive = colorAlpha !== 0 || hasVisibleRangeColors;
|
|
52
|
-
const [content, styles] = (0, useRichTextItem_1.useRichTextItem)(item
|
|
53
|
-
|
|
52
|
+
const [content, styles] = (0, useRichTextItem_1.useRichTextItem)(item);
|
|
53
|
+
(0, react_1.useEffect)(() => {
|
|
54
|
+
onVisibilityChange === null || onVisibilityChange === void 0 ? void 0 : onVisibilityChange(isInteractive);
|
|
55
|
+
}, [isInteractive, onVisibilityChange]);
|
|
56
|
+
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { ref: setRef, className: `rich-text-wrapper-${item.id}`, style: Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (blur !== undefined ? { filter: `blur(${blur * 100}vw)` } : {})), (textColor ? { color: `${textColor.fmt('rgba')}` } : {})), (angle !== undefined ? { transform: `rotate(${angle}deg)` } : {})), (letterSpacing !== undefined ? { letterSpacing: `${letterSpacing * exemplary}px` } : {})), (wordSpacing !== undefined ? { wordSpacing: `${wordSpacing * exemplary}px` } : {})), (fontSize !== undefined ? { fontSize: `${Math.round(fontSize * exemplary)}px` } : {})), (lineHeight !== undefined ? { lineHeight: `${lineHeight * exemplary}px` } : {})), { transition }), children: content }), (0, jsx_runtime_1.jsxs)(style_1.default, { id: id, children: [styles, `${(0, sdk_1.getLayoutStyles)(layouts, layoutValues, ([area, layoutParams]) => {
|
|
54
57
|
const color = color_1.CntrlColor.parse(layoutParams.color);
|
|
55
58
|
return (`
|
|
56
59
|
.rich-text-wrapper-${item.id} {
|
|
@@ -17,7 +17,7 @@ const useRegisterResize_1 = require("../../common/useRegisterResize");
|
|
|
17
17
|
const useLayoutContext_1 = require("../useLayoutContext");
|
|
18
18
|
const ScrollPlaybackVideo_1 = require("../ScrollPlaybackVideo");
|
|
19
19
|
const getStyleFromItemStateAndParams_1 = require("../../utils/getStyleFromItemStateAndParams");
|
|
20
|
-
const VideoItem = ({ item, sectionId, onResize, interactionCtrl }) => {
|
|
20
|
+
const VideoItem = ({ item, sectionId, onResize, interactionCtrl, onVisibilityChange }) => {
|
|
21
21
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
22
22
|
const id = (0, react_1.useId)();
|
|
23
23
|
const { layouts } = (0, useCntrlContext_1.useCntrlContext)();
|
|
@@ -43,7 +43,11 @@ const VideoItem = ({ item, sectionId, onResize, interactionCtrl }) => {
|
|
|
43
43
|
const radius = (0, getStyleFromItemStateAndParams_1.getStyleFromItemStateAndParams)((_f = wrapperStateParams === null || wrapperStateParams === void 0 ? void 0 : wrapperStateParams.styles) === null || _f === void 0 ? void 0 : _f.radius, itemRadius);
|
|
44
44
|
(0, useRegisterResize_1.useRegisterResize)(ref, onResize);
|
|
45
45
|
const inlineStyles = Object.assign(Object.assign(Object.assign(Object.assign({}, (radius !== undefined ? { borderRadius: `${radius * 100}vw` } : {})), (strokeWidth !== undefined ? { borderWidth: `${strokeWidth * 100}vw` } : {})), (borderColor ? { borderColor: `${borderColor.toCss()}` } : {})), { transition: (_g = videoStateParams === null || videoStateParams === void 0 ? void 0 : videoStateParams.transition) !== null && _g !== void 0 ? _g : 'none' });
|
|
46
|
-
|
|
46
|
+
const isInteractive = opacity !== 0;
|
|
47
|
+
(0, react_1.useEffect)(() => {
|
|
48
|
+
onVisibilityChange === null || onVisibilityChange === void 0 ? void 0 : onVisibilityChange(isInteractive);
|
|
49
|
+
}, [isInteractive, onVisibilityChange]);
|
|
50
|
+
return ((0, jsx_runtime_1.jsxs)(LinkWrapper_1.LinkWrapper, { url: (_h = item.link) === null || _h === void 0 ? void 0 : _h.url, target: (_j = item.link) === null || _j === void 0 ? void 0 : _j.target, children: [(0, jsx_runtime_1.jsx)("div", { className: `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: (_k = wrapperStateParams === null || wrapperStateParams === void 0 ? void 0 : wrapperStateParams.transition) !== null && _k !== void 0 ? _k : 'none' }), children: hasScrollPlayback ? ((0, jsx_runtime_1.jsx)(ScrollPlaybackVideo_1.ScrollPlaybackVideo, { sectionId: sectionId, src: item.commonParams.url, playbackParams: scrollPlayback, style: inlineStyles, className: `video video-playback-wrapper video-${item.id}` })) : ((0, jsx_runtime_1.jsx)("video", { poster: (_l = item.commonParams.coverUrl) !== null && _l !== void 0 ? _l : '', ref: videoRef, autoPlay: true, muted: true, loop: true, playsInline: true, className: `video video-${item.id}`, style: inlineStyles, children: (0, jsx_runtime_1.jsx)("source", { src: item.commonParams.url }) })) }), (0, jsx_runtime_1.jsx)(style_1.default, { id: id, children: `
|
|
47
51
|
.video-wrapper-${item.id} {
|
|
48
52
|
position: absolute;
|
|
49
53
|
overflow: hidden;
|
|
@@ -15,7 +15,7 @@ const sdk_1 = require("@cntrl-site/sdk");
|
|
|
15
15
|
const useCntrlContext_1 = require("../../provider/useCntrlContext");
|
|
16
16
|
const useRegisterResize_1 = require("../../common/useRegisterResize");
|
|
17
17
|
const getStyleFromItemStateAndParams_1 = require("../../utils/getStyleFromItemStateAndParams");
|
|
18
|
-
const VimeoEmbedItem = ({ item, sectionId, onResize, interactionCtrl }) => {
|
|
18
|
+
const VimeoEmbedItem = ({ item, sectionId, onResize, interactionCtrl, onVisibilityChange }) => {
|
|
19
19
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
20
20
|
const id = (0, react_1.useId)();
|
|
21
21
|
const { layouts } = (0, useCntrlContext_1.useCntrlContext)();
|
|
@@ -68,7 +68,10 @@ const VimeoEmbedItem = ({ item, sectionId, onResize, interactionCtrl }) => {
|
|
|
68
68
|
setIsCoverVisible(false);
|
|
69
69
|
};
|
|
70
70
|
const isInteractive = opacity !== 0;
|
|
71
|
-
|
|
71
|
+
(0, react_1.useEffect)(() => {
|
|
72
|
+
onVisibilityChange === null || onVisibilityChange === void 0 ? void 0 : onVisibilityChange(isInteractive);
|
|
73
|
+
}, [isInteractive, onVisibilityChange]);
|
|
74
|
+
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: () => {
|
|
72
75
|
if (!vimeoPlayer || play !== 'on-hover')
|
|
73
76
|
return;
|
|
74
77
|
vimeoPlayer.play();
|
|
@@ -16,7 +16,7 @@ const useCntrlContext_1 = require("../../provider/useCntrlContext");
|
|
|
16
16
|
const useYouTubeIframeApi_1 = require("../../utils/Youtube/useYouTubeIframeApi");
|
|
17
17
|
const useRegisterResize_1 = require("../../common/useRegisterResize");
|
|
18
18
|
const getStyleFromItemStateAndParams_1 = require("../../utils/getStyleFromItemStateAndParams");
|
|
19
|
-
const YoutubeEmbedItem = ({ item, sectionId, onResize, interactionCtrl }) => {
|
|
19
|
+
const YoutubeEmbedItem = ({ item, sectionId, onResize, interactionCtrl, onVisibilityChange }) => {
|
|
20
20
|
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
21
21
|
const id = (0, react_1.useId)();
|
|
22
22
|
const { layouts } = (0, useCntrlContext_1.useCntrlContext)();
|
|
@@ -36,6 +36,9 @@ const YoutubeEmbedItem = ({ item, sectionId, onResize, interactionCtrl }) => {
|
|
|
36
36
|
const opacity = (0, getStyleFromItemStateAndParams_1.getStyleFromItemStateAndParams)((_c = wrapperStateParams === null || wrapperStateParams === void 0 ? void 0 : wrapperStateParams.styles) === null || _c === void 0 ? void 0 : _c.opacity, itemOpacity);
|
|
37
37
|
const radius = (0, getStyleFromItemStateAndParams_1.getStyleFromItemStateAndParams)((_d = frameStateParams === null || frameStateParams === void 0 ? void 0 : frameStateParams.styles) === null || _d === void 0 ? void 0 : _d.radius, itemRadius);
|
|
38
38
|
const isInteractive = opacity !== 0;
|
|
39
|
+
(0, react_1.useEffect)(() => {
|
|
40
|
+
onVisibilityChange === null || onVisibilityChange === void 0 ? void 0 : onVisibilityChange(isInteractive);
|
|
41
|
+
}, [isInteractive, onVisibilityChange]);
|
|
39
42
|
(0, useRegisterResize_1.useRegisterResize)(div, onResize);
|
|
40
43
|
(0, react_1.useEffect)(() => {
|
|
41
44
|
const newUrl = new URL(url);
|
|
@@ -87,7 +90,7 @@ const YoutubeEmbedItem = ({ item, sectionId, onResize, interactionCtrl }) => {
|
|
|
87
90
|
setIsCoverVisible(true);
|
|
88
91
|
}
|
|
89
92
|
}, []);
|
|
90
|
-
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,
|
|
93
|
+
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-youtube-video-wrapper-${item.id}`, onMouseEnter: () => {
|
|
91
94
|
if (!player || play !== 'on-hover')
|
|
92
95
|
return;
|
|
93
96
|
player.playVideo();
|
|
@@ -4,9 +4,9 @@ exports.useRichTextItem = void 0;
|
|
|
4
4
|
const RichTextConverter_1 = require("../../utils/RichTextConverter/RichTextConverter");
|
|
5
5
|
const useCntrlContext_1 = require("../../provider/useCntrlContext");
|
|
6
6
|
const richTextConverter = new RichTextConverter_1.RichTextConverter();
|
|
7
|
-
const useRichTextItem = (item
|
|
7
|
+
const useRichTextItem = (item) => {
|
|
8
8
|
const { layouts } = (0, useCntrlContext_1.useCntrlContext)();
|
|
9
|
-
const [content, styles] = richTextConverter.toHtml(item, layouts
|
|
9
|
+
const [content, styles] = richTextConverter.toHtml(item, layouts);
|
|
10
10
|
return [content, styles];
|
|
11
11
|
};
|
|
12
12
|
exports.useRichTextItem = useRichTextItem;
|
|
@@ -12,7 +12,7 @@ exports.FontStyles = {
|
|
|
12
12
|
'italic': { 'font-style': 'italic' }
|
|
13
13
|
};
|
|
14
14
|
class RichTextConverter {
|
|
15
|
-
toHtml(richText, layouts
|
|
15
|
+
toHtml(richText, layouts) {
|
|
16
16
|
var _a, _b, _c;
|
|
17
17
|
const { text, blocks = [] } = richText.commonParams;
|
|
18
18
|
const root = [];
|
|
@@ -91,7 +91,7 @@ class RichTextConverter {
|
|
|
91
91
|
offset = entity.end;
|
|
92
92
|
}
|
|
93
93
|
if (entity.link) {
|
|
94
|
-
kids.push((0, jsx_runtime_1.jsx)(LinkWrapper_1.LinkWrapper, { url: entity.link, target: entity.target,
|
|
94
|
+
kids.push((0, jsx_runtime_1.jsx)(LinkWrapper_1.LinkWrapper, { url: entity.link, target: entity.target, children: entityKids }, entity.start));
|
|
95
95
|
continue;
|
|
96
96
|
}
|
|
97
97
|
kids.push(...entityKids);
|
package/package.json
CHANGED
package/src/components/Item.tsx
CHANGED
|
@@ -1,4 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
ComponentType,
|
|
3
|
+
FC,
|
|
4
|
+
PropsWithChildren,
|
|
5
|
+
useCallback,
|
|
6
|
+
useContext,
|
|
7
|
+
useEffect,
|
|
8
|
+
useId,
|
|
9
|
+
useMemo,
|
|
10
|
+
useRef,
|
|
11
|
+
useState
|
|
12
|
+
} from 'react';
|
|
2
13
|
import JSXStyle from 'styled-jsx/style';
|
|
3
14
|
import {
|
|
4
15
|
AnchorSide,
|
|
@@ -36,15 +47,18 @@ import { useItemInteractionCtrl } from '../interactions/useItemInteractionCtrl';
|
|
|
36
47
|
export interface ItemProps<I extends ItemAny> {
|
|
37
48
|
item: I;
|
|
38
49
|
sectionId: string;
|
|
39
|
-
onResize?: (height: number) => void;
|
|
40
50
|
articleHeight: number;
|
|
51
|
+
onResize?: (height: number) => void;
|
|
41
52
|
interactionCtrl?: ReturnType<typeof useItemInteractionCtrl>;
|
|
53
|
+
onVisibilityChange: (isVisible: boolean) => void;
|
|
42
54
|
}
|
|
43
55
|
|
|
44
|
-
export interface ItemWrapperProps
|
|
56
|
+
export interface ItemWrapperProps {
|
|
57
|
+
item: ItemAny;
|
|
58
|
+
sectionId: string;
|
|
45
59
|
articleHeight: number;
|
|
46
60
|
isInGroup?: boolean;
|
|
47
|
-
|
|
61
|
+
isParentVisible?: boolean;
|
|
48
62
|
}
|
|
49
63
|
|
|
50
64
|
const itemsMap: Record<ArticleItemType, ComponentType<ItemProps<any>>> = {
|
|
@@ -79,7 +93,7 @@ const RichTextWrapper: FC<PropsWithChildren<RTWrapperProps>> = ({ isRichText, ch
|
|
|
79
93
|
|
|
80
94
|
const noop = () => null;
|
|
81
95
|
|
|
82
|
-
export const Item: FC<ItemWrapperProps> = ({ item, sectionId, articleHeight,
|
|
96
|
+
export const Item: FC<ItemWrapperProps> = ({ item, sectionId, articleHeight, isParentVisible = true, isInGroup = false }) => {
|
|
83
97
|
const itemWrapperRef = useRef<HTMLDivElement | null>(null);
|
|
84
98
|
const itemInnerRef = useRef<HTMLDivElement | null>(null);
|
|
85
99
|
const rectObserver = useContext(ArticleRectContext);
|
|
@@ -89,6 +103,7 @@ export const Item: FC<ItemWrapperProps> = ({ item, sectionId, articleHeight, isI
|
|
|
89
103
|
const { layouts } = useCntrlContext();
|
|
90
104
|
const layout = useLayoutContext();
|
|
91
105
|
const exemplary = useExemplary();
|
|
106
|
+
const [allowPointerEvents, setAllowPointerEvents] = useState<boolean>(isParentVisible);
|
|
92
107
|
const [wrapperHeight, setWrapperHeight] = useState<undefined | number>(undefined);
|
|
93
108
|
const [itemHeight, setItemHeight] = useState<undefined | number>(undefined);
|
|
94
109
|
const itemScale = useItemScale(item, sectionId);
|
|
@@ -133,6 +148,11 @@ export const Item: FC<ItemWrapperProps> = ({ item, sectionId, articleHeight, isI
|
|
|
133
148
|
setWrapperHeight(wrapperHeight);
|
|
134
149
|
};
|
|
135
150
|
|
|
151
|
+
const handleVisibilityChange = useCallback((isVisible: boolean) => {
|
|
152
|
+
if (!isParentVisible) return;
|
|
153
|
+
setAllowPointerEvents(isVisible);
|
|
154
|
+
}, [isParentVisible]);
|
|
155
|
+
|
|
136
156
|
useEffect(() => {
|
|
137
157
|
isInitialRef.current = false;
|
|
138
158
|
}, []);
|
|
@@ -189,7 +209,7 @@ export const Item: FC<ItemWrapperProps> = ({ item, sectionId, articleHeight, isI
|
|
|
189
209
|
height: `${sizingAxis.y === 'manual' ? `${height * 100}vw` : 'unset'}` } : {}),
|
|
190
210
|
...(scale !== undefined ? { transform: `scale(${scale})`, 'WebkitTransform': `scale(${scale})` } : {}),
|
|
191
211
|
transition: innerStateProps?.transition ?? 'none',
|
|
192
|
-
pointerEvents:
|
|
212
|
+
pointerEvents: allowPointerEvents ? 'auto' : 'none'
|
|
193
213
|
}}
|
|
194
214
|
>
|
|
195
215
|
<ItemComponent
|
|
@@ -198,6 +218,7 @@ export const Item: FC<ItemWrapperProps> = ({ item, sectionId, articleHeight, isI
|
|
|
198
218
|
onResize={handleItemResize}
|
|
199
219
|
articleHeight={articleHeight}
|
|
200
220
|
interactionCtrl={interactionCtrl}
|
|
221
|
+
onVisibilityChange={handleVisibilityChange}
|
|
201
222
|
/>
|
|
202
223
|
</div>
|
|
203
224
|
</RichTextWrapper>
|
|
@@ -1,26 +1,23 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, { ReactElement, ReactNode } from 'react';
|
|
2
2
|
|
|
3
3
|
interface Props {
|
|
4
4
|
url?: string;
|
|
5
5
|
children: ReactElement | ReactNode[];
|
|
6
6
|
target?: string;
|
|
7
|
-
isInteractive?: boolean;
|
|
8
7
|
}
|
|
9
8
|
|
|
10
|
-
export const LinkWrapper: React.FC<Props> = ({ url, children, target
|
|
9
|
+
export const LinkWrapper: React.FC<Props> = ({ url, children, target }) => {
|
|
11
10
|
const validUrl = url && buildValidUrl(url);
|
|
12
|
-
const style: CSSProperties = { pointerEvents: isInteractive ? 'unset' : 'none' };
|
|
13
11
|
return url ? (
|
|
14
12
|
<a
|
|
15
13
|
href={validUrl}
|
|
16
14
|
target={target}
|
|
17
15
|
rel="noreferrer"
|
|
18
|
-
style={style}
|
|
19
16
|
>
|
|
20
17
|
{children}
|
|
21
18
|
</a>
|
|
22
19
|
) : (
|
|
23
|
-
|
|
20
|
+
<>{children}</>
|
|
24
21
|
);
|
|
25
22
|
};
|
|
26
23
|
|
|
@@ -20,7 +20,7 @@ const stylesMap = {
|
|
|
20
20
|
[AreaAnchor.BottomRight]: { justifyContent: 'flex-end', alignItems: 'flex-end' }
|
|
21
21
|
};
|
|
22
22
|
|
|
23
|
-
export const CodeEmbedItem: FC<ItemProps<TCodeEmbedItem>> = ({ item, sectionId, onResize, interactionCtrl }) => {
|
|
23
|
+
export const CodeEmbedItem: FC<ItemProps<TCodeEmbedItem>> = ({ item, sectionId, onResize, interactionCtrl, onVisibilityChange }) => {
|
|
24
24
|
const id = useId();
|
|
25
25
|
const { layouts } = useCntrlContext();
|
|
26
26
|
const { anchor, blur: itemBlur, opacity: itemOpacity } = useCodeEmbedItem(item, sectionId);
|
|
@@ -55,11 +55,13 @@ export const CodeEmbedItem: FC<ItemProps<TCodeEmbedItem>> = ({ item, sectionId,
|
|
|
55
55
|
if (!iframe) return;
|
|
56
56
|
iframe.srcdoc = item.commonParams.html;
|
|
57
57
|
}, [item.commonParams.html, item.commonParams.iframe, ref]);
|
|
58
|
-
|
|
59
|
-
|
|
58
|
+
const isInteractive = opacity !== 0;
|
|
59
|
+
useEffect(() => {
|
|
60
|
+
onVisibilityChange?.(isInteractive);
|
|
61
|
+
}, [isInteractive, onVisibilityChange]);
|
|
60
62
|
|
|
61
63
|
return (
|
|
62
|
-
<LinkWrapper url={item.link?.url} target={item.link?.target}
|
|
64
|
+
<LinkWrapper url={item.link?.url} target={item.link?.target}>
|
|
63
65
|
<div
|
|
64
66
|
className={`embed-wrapper-${item.id}`}
|
|
65
67
|
style={{
|
|
@@ -3,7 +3,7 @@ import { FC, useState } from 'react';
|
|
|
3
3
|
import { useCntrlContext } from '../../provider/useCntrlContext';
|
|
4
4
|
import { ItemProps } from '../Item';
|
|
5
5
|
import JSXStyle from 'styled-jsx/style';
|
|
6
|
-
import { useRegisterResize } from
|
|
6
|
+
import { useRegisterResize } from '../../common/useRegisterResize';
|
|
7
7
|
import { useItemAngle } from '../useItemAngle';
|
|
8
8
|
|
|
9
9
|
export const CustomItem: FC<ItemProps<TCustomItem>> = ({ item, onResize, sectionId, interactionCtrl }) => {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { FC, useId, useState } from 'react';
|
|
1
|
+
import React, { FC, useEffect, useId, useState } from 'react';
|
|
2
2
|
import { Item, ItemProps } from '../Item';
|
|
3
3
|
import JSXStyle from 'styled-jsx/style';
|
|
4
4
|
import { getLayoutStyles, GroupItem as TGroupItem } from '@cntrl-site/sdk';
|
|
@@ -9,7 +9,7 @@ import { useItemAngle } from '../useItemAngle';
|
|
|
9
9
|
import { useGroupItem } from './useGroupItem';
|
|
10
10
|
import { getStyleFromItemStateAndParams } from '../../utils/getStyleFromItemStateAndParams';
|
|
11
11
|
|
|
12
|
-
export const GroupItem: FC<ItemProps<TGroupItem>> = ({ item, sectionId, onResize, articleHeight, interactionCtrl }) => {
|
|
12
|
+
export const GroupItem: FC<ItemProps<TGroupItem>> = ({ item, sectionId, onResize, articleHeight, interactionCtrl, onVisibilityChange }) => {
|
|
13
13
|
const id = useId();
|
|
14
14
|
const { items } = item;
|
|
15
15
|
const itemAngle = useItemAngle(item, sectionId);
|
|
@@ -21,9 +21,12 @@ export const GroupItem: FC<ItemProps<TGroupItem>> = ({ item, sectionId, onResize
|
|
|
21
21
|
const stateParams = interactionCtrl?.getState(['opacity', 'angle']);
|
|
22
22
|
const angle = getStyleFromItemStateAndParams(stateParams?.styles?.angle, itemAngle);
|
|
23
23
|
const opacity = getStyleFromItemStateAndParams(stateParams?.styles?.opacity, itemOpacity);
|
|
24
|
-
const
|
|
24
|
+
const isInteractive = opacity !== 0;
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
onVisibilityChange?.(isInteractive);
|
|
27
|
+
}, [isInteractive, onVisibilityChange]);
|
|
25
28
|
return (
|
|
26
|
-
<LinkWrapper url={item.link?.url} target={item.link?.target}
|
|
29
|
+
<LinkWrapper url={item.link?.url} target={item.link?.target}>
|
|
27
30
|
<>
|
|
28
31
|
<div
|
|
29
32
|
className={`group-${item.id}`}
|
|
@@ -40,8 +43,7 @@ export const GroupItem: FC<ItemProps<TGroupItem>> = ({ item, sectionId, onResize
|
|
|
40
43
|
key={item.id}
|
|
41
44
|
sectionId={sectionId}
|
|
42
45
|
articleHeight={articleHeight}
|
|
43
|
-
|
|
44
|
-
isItemVisible={isVisible}
|
|
46
|
+
isParentVisible={isInteractive}
|
|
45
47
|
isInGroup
|
|
46
48
|
/>
|
|
47
49
|
))}
|
|
@@ -22,7 +22,7 @@ uniform float u_time;
|
|
|
22
22
|
uniform vec2 u_cursor;
|
|
23
23
|
varying vec2 v_texCoord;`;
|
|
24
24
|
|
|
25
|
-
export const ImageItem: FC<ItemProps<TImageItem>> = ({ item, sectionId, onResize, interactionCtrl }) => {
|
|
25
|
+
export const ImageItem: FC<ItemProps<TImageItem>> = ({ item, sectionId, onResize, interactionCtrl, onVisibilityChange }) => {
|
|
26
26
|
const id = useId();
|
|
27
27
|
const { layouts } = useCntrlContext();
|
|
28
28
|
const layoutId = useLayoutContext();
|
|
@@ -88,8 +88,12 @@ export const ImageItem: FC<ItemProps<TImageItem>> = ({ item, sectionId, onResize
|
|
|
88
88
|
...(strokeWidth !== undefined ? { borderWidth: `${strokeWidth * 100}vw` } : {}),
|
|
89
89
|
transition: imgStateParams?.transition ?? 'none'
|
|
90
90
|
};
|
|
91
|
+
const isInteractive = opacity !== 0;
|
|
92
|
+
useEffect(() => {
|
|
93
|
+
onVisibilityChange?.(isInteractive);
|
|
94
|
+
}, [isInteractive, onVisibilityChange]);
|
|
91
95
|
return (
|
|
92
|
-
<LinkWrapper url={item.link?.url} target={item.link?.target}
|
|
96
|
+
<LinkWrapper url={item.link?.url} target={item.link?.target}>
|
|
93
97
|
<>
|
|
94
98
|
<div
|
|
95
99
|
className={`image-wrapper-${item.id}`}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FC, useId, useMemo, useState } from 'react';
|
|
1
|
+
import { FC, useEffect, useId, useMemo, useState } from 'react';
|
|
2
2
|
import JSXStyle from 'styled-jsx/style';
|
|
3
3
|
import { CntrlColor } from '@cntrl-site/color';
|
|
4
4
|
import { RectangleItem as TRectangleItem, getLayoutStyles } from '@cntrl-site/sdk';
|
|
@@ -10,7 +10,7 @@ import { useCntrlContext } from '../../provider/useCntrlContext';
|
|
|
10
10
|
import { useRegisterResize } from "../../common/useRegisterResize";
|
|
11
11
|
import { getStyleFromItemStateAndParams } from '../../utils/getStyleFromItemStateAndParams';
|
|
12
12
|
|
|
13
|
-
export const RectangleItem: FC<ItemProps<TRectangleItem>> = ({ item, sectionId, onResize, interactionCtrl }) => {
|
|
13
|
+
export const RectangleItem: FC<ItemProps<TRectangleItem>> = ({ item, sectionId, onResize, interactionCtrl, onVisibilityChange }) => {
|
|
14
14
|
const id = useId();
|
|
15
15
|
const { layouts } = useCntrlContext();
|
|
16
16
|
const {
|
|
@@ -42,9 +42,12 @@ export const RectangleItem: FC<ItemProps<TRectangleItem>> = ({ item, sectionId,
|
|
|
42
42
|
const blur = getStyleFromItemStateAndParams(styles?.blur, itemBlur);
|
|
43
43
|
const backdropFilterValue = backdropBlur ? `blur(${backdropBlur * 100}vw)`: undefined;
|
|
44
44
|
const isInteractive = backgroundColor?.getAlpha() !== 0 || (strokeWidth !== 0 && borderColor?.getAlpha() !== 0);
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
onVisibilityChange?.(isInteractive);
|
|
47
|
+
}, [isInteractive, onVisibilityChange]);
|
|
45
48
|
|
|
46
49
|
return (
|
|
47
|
-
<LinkWrapper url={item.link?.url} target={item.link?.target}
|
|
50
|
+
<LinkWrapper url={item.link?.url} target={item.link?.target}>
|
|
48
51
|
<>
|
|
49
52
|
<div
|
|
50
53
|
className={`rectangle-${item.id}`}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FC, useId, useMemo, useState } from 'react';
|
|
1
|
+
import { FC, useEffect, useId, useMemo, useState } from 'react';
|
|
2
2
|
import { CntrlColor } from '@cntrl-site/color';
|
|
3
3
|
import { getLayoutStyles, RichTextItem as TRichTextItem } from '@cntrl-site/sdk';
|
|
4
4
|
import JSXStyle from 'styled-jsx/style';
|
|
@@ -13,7 +13,7 @@ import { useItemAngle } from '../useItemAngle';
|
|
|
13
13
|
import { getStyleFromItemStateAndParams } from '../../utils/getStyleFromItemStateAndParams';
|
|
14
14
|
import { useCurrentLayout } from '../../common/useCurrentLayout';
|
|
15
15
|
|
|
16
|
-
export const RichTextItem: FC<ItemProps<TRichTextItem>> = ({ item, sectionId, onResize, interactionCtrl }) => {
|
|
16
|
+
export const RichTextItem: FC<ItemProps<TRichTextItem>> = ({ item, sectionId, onResize, interactionCtrl, onVisibilityChange }) => {
|
|
17
17
|
const id = useId();
|
|
18
18
|
const [ref, setRef] = useState<HTMLDivElement | null>(null);
|
|
19
19
|
const { layouts } = useCntrlContext();
|
|
@@ -49,7 +49,10 @@ export const RichTextItem: FC<ItemProps<TRichTextItem>> = ({ item, sectionId, on
|
|
|
49
49
|
return alpha > 0;
|
|
50
50
|
});
|
|
51
51
|
const isInteractive = colorAlpha !== 0 || hasVisibleRangeColors;
|
|
52
|
-
const [content, styles] = useRichTextItem(item
|
|
52
|
+
const [content, styles] = useRichTextItem(item);
|
|
53
|
+
useEffect(() => {
|
|
54
|
+
onVisibilityChange?.(isInteractive);
|
|
55
|
+
}, [isInteractive, onVisibilityChange]);
|
|
53
56
|
|
|
54
57
|
return (
|
|
55
58
|
<>
|
|
@@ -64,8 +67,6 @@ export const RichTextItem: FC<ItemProps<TRichTextItem>> = ({ item, sectionId, on
|
|
|
64
67
|
...(wordSpacing !== undefined ? { wordSpacing: `${wordSpacing * exemplary}px` } : {}),
|
|
65
68
|
...(fontSize !== undefined ? { fontSize: `${Math.round(fontSize * exemplary)}px` } : {}),
|
|
66
69
|
...(lineHeight !== undefined ? { lineHeight: `${lineHeight * exemplary}px` } : {}),
|
|
67
|
-
pointerEvents: isInteractive ? 'unset' : 'none',
|
|
68
|
-
userSelect: isInteractive ? 'unset' : 'none',
|
|
69
70
|
transition
|
|
70
71
|
}}
|
|
71
72
|
>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FC, useId, useMemo, useRef, useState } from 'react';
|
|
1
|
+
import { FC, useEffect, useId, useMemo, useRef, useState } from 'react';
|
|
2
2
|
import JSXStyle from 'styled-jsx/style';
|
|
3
3
|
import { CntrlColor } from '@cntrl-site/color';
|
|
4
4
|
import { getLayoutStyles, VideoItem as TVideoItem } from '@cntrl-site/sdk';
|
|
@@ -12,7 +12,7 @@ import { useLayoutContext } from '../useLayoutContext';
|
|
|
12
12
|
import { ScrollPlaybackVideo } from '../ScrollPlaybackVideo';
|
|
13
13
|
import { getStyleFromItemStateAndParams } from '../../utils/getStyleFromItemStateAndParams';
|
|
14
14
|
|
|
15
|
-
export const VideoItem: FC<ItemProps<TVideoItem>> = ({ item, sectionId, onResize, interactionCtrl }) => {
|
|
15
|
+
export const VideoItem: FC<ItemProps<TVideoItem>> = ({ item, sectionId, onResize, interactionCtrl, onVisibilityChange }) => {
|
|
16
16
|
const id = useId();
|
|
17
17
|
const { layouts } = useCntrlContext();
|
|
18
18
|
const {
|
|
@@ -47,9 +47,13 @@ export const VideoItem: FC<ItemProps<TVideoItem>> = ({ item, sectionId, onResize
|
|
|
47
47
|
...(borderColor ? { borderColor: `${borderColor.toCss()}` } : {}),
|
|
48
48
|
transition: videoStateParams?.transition ?? 'none'
|
|
49
49
|
};
|
|
50
|
+
const isInteractive = opacity !== 0;
|
|
51
|
+
useEffect(() => {
|
|
52
|
+
onVisibilityChange?.(isInteractive);
|
|
53
|
+
}, [isInteractive, onVisibilityChange]);
|
|
50
54
|
|
|
51
55
|
return (
|
|
52
|
-
<LinkWrapper url={item.link?.url} target={item.link?.target}
|
|
56
|
+
<LinkWrapper url={item.link?.url} target={item.link?.target}>
|
|
53
57
|
<div
|
|
54
58
|
className={`video-wrapper-${item.id}`}
|
|
55
59
|
ref={setRef}
|
|
@@ -10,7 +10,7 @@ import { useCntrlContext } from '../../provider/useCntrlContext';
|
|
|
10
10
|
import { useRegisterResize } from "../../common/useRegisterResize";
|
|
11
11
|
import { getStyleFromItemStateAndParams } from '../../utils/getStyleFromItemStateAndParams';
|
|
12
12
|
|
|
13
|
-
export const VimeoEmbedItem: FC<ItemProps<TVimeoEmbedItem>> = ({ item, sectionId, onResize, interactionCtrl }) => {
|
|
13
|
+
export const VimeoEmbedItem: FC<ItemProps<TVimeoEmbedItem>> = ({ item, sectionId, onResize, interactionCtrl, onVisibilityChange }) => {
|
|
14
14
|
const id = useId();
|
|
15
15
|
const { layouts } = useCntrlContext();
|
|
16
16
|
const {
|
|
@@ -67,9 +67,12 @@ export const VimeoEmbedItem: FC<ItemProps<TVimeoEmbedItem>> = ({ item, sectionId
|
|
|
67
67
|
setIsCoverVisible(false);
|
|
68
68
|
};
|
|
69
69
|
const isInteractive = opacity !== 0;
|
|
70
|
+
useEffect(() => {
|
|
71
|
+
onVisibilityChange?.(isInteractive);
|
|
72
|
+
}, [isInteractive, onVisibilityChange]);
|
|
70
73
|
|
|
71
74
|
return (
|
|
72
|
-
<LinkWrapper url={item.link?.url} target={item.link?.target}
|
|
75
|
+
<LinkWrapper url={item.link?.url} target={item.link?.target}>
|
|
73
76
|
<div
|
|
74
77
|
className={`embed-video-wrapper-${item.id}`}
|
|
75
78
|
ref={setRef}
|
|
@@ -12,7 +12,7 @@ import { YTPlayer } from '../../utils/Youtube/YoutubeIframeApi';
|
|
|
12
12
|
import { useRegisterResize } from "../../common/useRegisterResize";
|
|
13
13
|
import { getStyleFromItemStateAndParams } from '../../utils/getStyleFromItemStateAndParams';
|
|
14
14
|
|
|
15
|
-
export const YoutubeEmbedItem: FC<ItemProps<TYoutubeEmbedItem>> = ({ item, sectionId, onResize, interactionCtrl }) => {
|
|
15
|
+
export const YoutubeEmbedItem: FC<ItemProps<TYoutubeEmbedItem>> = ({ item, sectionId, onResize, interactionCtrl, onVisibilityChange }) => {
|
|
16
16
|
const id = useId();
|
|
17
17
|
const { layouts } = useCntrlContext();
|
|
18
18
|
const { play, controls, url } = item.commonParams;
|
|
@@ -31,6 +31,9 @@ export const YoutubeEmbedItem: FC<ItemProps<TYoutubeEmbedItem>> = ({ item, secti
|
|
|
31
31
|
const opacity = getStyleFromItemStateAndParams(wrapperStateParams?.styles?.opacity, itemOpacity);
|
|
32
32
|
const radius = getStyleFromItemStateAndParams(frameStateParams?.styles?.radius, itemRadius);
|
|
33
33
|
const isInteractive = opacity !== 0;
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
onVisibilityChange?.(isInteractive);
|
|
36
|
+
}, [isInteractive, onVisibilityChange]);
|
|
34
37
|
useRegisterResize(div, onResize);
|
|
35
38
|
useEffect(() => {
|
|
36
39
|
const newUrl = new URL(url);
|
|
@@ -82,7 +85,7 @@ export const YoutubeEmbedItem: FC<ItemProps<TYoutubeEmbedItem>> = ({ item, secti
|
|
|
82
85
|
}, []);
|
|
83
86
|
|
|
84
87
|
return (
|
|
85
|
-
<LinkWrapper url={item.link?.url} target={item.link?.target}
|
|
88
|
+
<LinkWrapper url={item.link?.url} target={item.link?.target}>
|
|
86
89
|
<div
|
|
87
90
|
className={`embed-youtube-video-wrapper-${item.id}`}
|
|
88
91
|
onMouseEnter={() => {
|
|
@@ -5,8 +5,8 @@ import { ReactNode } from 'react';
|
|
|
5
5
|
|
|
6
6
|
const richTextConverter = new RichTextConverter();
|
|
7
7
|
|
|
8
|
-
export const useRichTextItem = (item: RichTextItem
|
|
8
|
+
export const useRichTextItem = (item: RichTextItem): [ReactNode[], string] => {
|
|
9
9
|
const { layouts } = useCntrlContext();
|
|
10
|
-
const [content, styles] = richTextConverter.toHtml(item, layouts
|
|
10
|
+
const [content, styles] = richTextConverter.toHtml(item, layouts);
|
|
11
11
|
return [content, styles];
|
|
12
12
|
};
|
|
@@ -40,8 +40,7 @@ export const FontStyles: Record<string, Record<string, string>> = {
|
|
|
40
40
|
export class RichTextConverter {
|
|
41
41
|
toHtml(
|
|
42
42
|
richText: RichTextItem,
|
|
43
|
-
layouts: Layout[]
|
|
44
|
-
isInteractive: boolean
|
|
43
|
+
layouts: Layout[]
|
|
45
44
|
): [ReactNode[], string] {
|
|
46
45
|
const { text, blocks = [] } = richText.commonParams;
|
|
47
46
|
const root: ReactElement[] = [];
|
|
@@ -123,16 +122,7 @@ export class RichTextConverter {
|
|
|
123
122
|
offset = entity.end;
|
|
124
123
|
}
|
|
125
124
|
if (entity.link) {
|
|
126
|
-
kids.push(
|
|
127
|
-
<LinkWrapper
|
|
128
|
-
key={entity.start}
|
|
129
|
-
url={entity.link}
|
|
130
|
-
target={entity.target}
|
|
131
|
-
isInteractive={isInteractive}
|
|
132
|
-
>
|
|
133
|
-
{entityKids}
|
|
134
|
-
</LinkWrapper>
|
|
135
|
-
);
|
|
125
|
+
kids.push(<LinkWrapper key={entity.start} url={entity.link} target={entity.target}>{entityKids}</LinkWrapper>);
|
|
136
126
|
continue;
|
|
137
127
|
}
|
|
138
128
|
kids.push(...entityKids);
|