@cntrl-site/sdk-nextjs 1.9.54 → 1.9.55-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.
- package/lib/components/ScrollPlaybackVideo.js +5 -3
- package/lib/components/items/ComponentItem/ComponentItem.js +13 -6
- package/lib/components/items/FileItem/VideoItem.js +13 -12
- package/lib/index.js +4 -1
- package/lib/provider/CntrlSdkContext.js +26 -1
- package/lib/utils/evaluateComponentBundle.js +92 -0
- package/package.json +4 -3
- package/src/components/Page.tsx +6 -0
- package/src/components/ScrollPlaybackVideo.tsx +5 -3
- package/src/components/items/ComponentItem/ComponentItem.tsx +12 -2
- package/src/components/items/FileItem/VideoItem.tsx +2 -1
- package/src/index.ts +2 -1
- package/src/provider/CntrlSdkContext.ts +31 -2
- package/src/types/components-utils.d.ts +7 -0
- package/src/utils/evaluateComponentBundle.ts +83 -0
|
@@ -19,12 +19,14 @@ const ScrollPlaybackVideo = ({ sectionId, src, playbackParams, style, className,
|
|
|
19
19
|
(0, react_1.useEffect)(() => {
|
|
20
20
|
if (!playbackParams || !articleRectObserver)
|
|
21
21
|
return;
|
|
22
|
+
const from = playbackParams.from;
|
|
23
|
+
const to = playbackParams.to;
|
|
22
24
|
return articleRectObserver.on('scroll', () => {
|
|
23
25
|
const scrollPos = articleRectObserver.getSectionScroll(sectionId);
|
|
24
|
-
const
|
|
25
|
-
setTime(toFixed(
|
|
26
|
+
const nextTime = (0, rangeMap_1.rangeMap)(scrollPos, from, to, 0, 1, true);
|
|
27
|
+
setTime(toFixed(nextTime));
|
|
26
28
|
});
|
|
27
|
-
}, [playbackParams === null || playbackParams === void 0 ? void 0 : playbackParams.from, playbackParams === null || playbackParams === void 0 ? void 0 : playbackParams.to,
|
|
29
|
+
}, [sectionId, playbackParams === null || playbackParams === void 0 ? void 0 : playbackParams.from, playbackParams === null || playbackParams === void 0 ? void 0 : playbackParams.to, articleRectObserver]);
|
|
28
30
|
const scrollVideoManager = (0, react_1.useMemo)(() => {
|
|
29
31
|
if (!containerElement)
|
|
30
32
|
return null;
|
|
@@ -16,11 +16,13 @@ const getStyleFromItemStateAndParams_1 = require("../../../utils/getStyleFromIte
|
|
|
16
16
|
const useLayoutContext_1 = require("../../useLayoutContext");
|
|
17
17
|
const useItemGeometry_1 = require("../../../ItemGeometry/useItemGeometry");
|
|
18
18
|
const ComponentItem = ({ item, sectionId, onResize, interactionCtrl }) => {
|
|
19
|
-
var _a, _b, _c, _d;
|
|
19
|
+
var _a, _b, _c, _d, _e, _f;
|
|
20
20
|
const sdk = (0, useCntrlContext_1.useCntrlContext)();
|
|
21
21
|
const { layouts } = sdk;
|
|
22
22
|
const itemAngle = (0, useItemAngle_1.useItemAngle)(item, sectionId);
|
|
23
23
|
const layout = (0, useLayoutContext_1.useLayoutContext)();
|
|
24
|
+
const fallbackLayout = (_a = layouts[0]) === null || _a === void 0 ? void 0 : _a.id;
|
|
25
|
+
const effectiveLayout = layout !== null && layout !== void 0 ? layout : fallbackLayout;
|
|
24
26
|
const layoutValues = [item.area, item.layoutParams];
|
|
25
27
|
const component = sdk.getComponent(item.commonParams.componentId);
|
|
26
28
|
const [ref, setRef] = (0, react_1.useState)(null);
|
|
@@ -28,12 +30,17 @@ const ComponentItem = ({ item, sectionId, onResize, interactionCtrl }) => {
|
|
|
28
30
|
(0, useRegisterResize_1.useRegisterResize)(ref, onResize);
|
|
29
31
|
(0, useItemGeometry_1.useItemGeometry)(item.id, ref);
|
|
30
32
|
const stateParams = interactionCtrl === null || interactionCtrl === void 0 ? void 0 : interactionCtrl.getState(['opacity', 'angle', 'blur']);
|
|
31
|
-
const angle = (0, getStyleFromItemStateAndParams_1.getStyleFromItemStateAndParams)((
|
|
32
|
-
const opacity = (0, getStyleFromItemStateAndParams_1.getStyleFromItemStateAndParams)((
|
|
33
|
-
const blur = (0, getStyleFromItemStateAndParams_1.getStyleFromItemStateAndParams)((
|
|
33
|
+
const angle = (0, getStyleFromItemStateAndParams_1.getStyleFromItemStateAndParams)((_b = stateParams === null || stateParams === void 0 ? void 0 : stateParams.styles) === null || _b === void 0 ? void 0 : _b.angle, itemAngle);
|
|
34
|
+
const opacity = (0, getStyleFromItemStateAndParams_1.getStyleFromItemStateAndParams)((_c = stateParams === null || stateParams === void 0 ? void 0 : stateParams.styles) === null || _c === void 0 ? void 0 : _c.opacity, itemOpacity);
|
|
35
|
+
const blur = (0, getStyleFromItemStateAndParams_1.getStyleFromItemStateAndParams)((_d = stateParams === null || stateParams === void 0 ? void 0 : stateParams.styles) === null || _d === void 0 ? void 0 : _d.blur, itemBlur);
|
|
34
36
|
const Element = component ? component.element : undefined;
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
+
const layoutParameters = effectiveLayout ? (_e = item.layoutParams[effectiveLayout]) === null || _e === void 0 ? void 0 : _e.parameters : undefined;
|
|
38
|
+
const commonParameters = item.commonParams.parameters;
|
|
39
|
+
const parameters = layoutParameters ? Object.assign(Object.assign({}, layoutParameters), { settings: Object.assign(Object.assign({}, layoutParameters.settings), commonParameters === null || commonParameters === void 0 ? void 0 : commonParameters.settings) }) : undefined;
|
|
40
|
+
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { className: `custom-component-${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)` } : {})), { willChange: blur !== 0 && blur !== undefined ? 'transform' : 'unset', transition: (_f = stateParams === null || stateParams === void 0 ? void 0 : stateParams.transition) !== null && _f !== void 0 ? _f : 'none' }), children: parameters && Element && ((0, jsx_runtime_1.jsx)(Element, Object.assign({ metadata: {
|
|
41
|
+
itemId: item.id,
|
|
42
|
+
submitUrl: sdk.getSubmitUrl(commonParameters === null || commonParameters === void 0 ? void 0 : commonParameters.pluginConfigId)
|
|
43
|
+
}, portalId: "component-portal", content: item.commonParams.content }, parameters))) }), (0, jsx_runtime_1.jsx)(style_1.default, { id: item.id, children: `
|
|
37
44
|
.custom-component-${item.id} {
|
|
38
45
|
width: 100%;
|
|
39
46
|
height: 100%;
|
|
@@ -22,7 +22,7 @@ const useItemFXData_1 = require("../../../common/useItemFXData");
|
|
|
22
22
|
const getFill_1 = require("../../../utils/getFill");
|
|
23
23
|
const useItemGeometry_1 = require("../../../ItemGeometry/useItemGeometry");
|
|
24
24
|
const VideoItem = ({ item, sectionId, onResize, interactionCtrl, onVisibilityChange }) => {
|
|
25
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
|
|
25
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v;
|
|
26
26
|
const reactId = (0, react_1.useId)();
|
|
27
27
|
const id = `${reactId}-video-${item.id}`;
|
|
28
28
|
const { layouts } = (0, useCntrlContext_1.useCntrlContext)();
|
|
@@ -49,17 +49,18 @@ const VideoItem = ({ item, sectionId, onResize, interactionCtrl, onVisibilityCha
|
|
|
49
49
|
const rectHeight = Math.floor((_c = rect === null || rect === void 0 ? void 0 : rect.height) !== null && _c !== void 0 ? _c : 0);
|
|
50
50
|
const scrollPlayback = layoutParams ? layoutParams.scrollPlayback : null;
|
|
51
51
|
const layoutValues = [item.area, item.layoutParams];
|
|
52
|
-
const
|
|
52
|
+
const isHiddenOnLayout = layoutId ? ((_d = item.hidden[layoutId]) !== null && _d !== void 0 ? _d : false) : false;
|
|
53
|
+
const hasScrollPlayback = scrollPlayback !== null && !isHiddenOnLayout;
|
|
53
54
|
const wrapperStateParams = interactionCtrl === null || interactionCtrl === void 0 ? void 0 : interactionCtrl.getState(['angle', 'opacity', 'blur']);
|
|
54
55
|
const videoStateParams = interactionCtrl === null || interactionCtrl === void 0 ? void 0 : interactionCtrl.getState(['strokeWidth', 'radius', 'strokeFill']);
|
|
55
|
-
const angle = (0, getStyleFromItemStateAndParams_1.getStyleFromItemStateAndParams)((
|
|
56
|
-
const opacity = (0, getStyleFromItemStateAndParams_1.getStyleFromItemStateAndParams)((
|
|
57
|
-
const blur = (0, getStyleFromItemStateAndParams_1.getStyleFromItemStateAndParams)((
|
|
58
|
-
const strokeWidth = (0, getStyleFromItemStateAndParams_1.getStyleFromItemStateAndParams)((
|
|
59
|
-
const radius = (0, getStyleFromItemStateAndParams_1.getStyleFromItemStateAndParams)((
|
|
60
|
-
const strokeFill = (
|
|
56
|
+
const angle = (0, getStyleFromItemStateAndParams_1.getStyleFromItemStateAndParams)((_e = wrapperStateParams === null || wrapperStateParams === void 0 ? void 0 : wrapperStateParams.styles) === null || _e === void 0 ? void 0 : _e.angle, itemAngle);
|
|
57
|
+
const opacity = (0, getStyleFromItemStateAndParams_1.getStyleFromItemStateAndParams)((_f = wrapperStateParams === null || wrapperStateParams === void 0 ? void 0 : wrapperStateParams.styles) === null || _f === void 0 ? void 0 : _f.opacity, itemOpacity);
|
|
58
|
+
const blur = (0, getStyleFromItemStateAndParams_1.getStyleFromItemStateAndParams)((_g = wrapperStateParams === null || wrapperStateParams === void 0 ? void 0 : wrapperStateParams.styles) === null || _g === void 0 ? void 0 : _g.blur, itemBlur);
|
|
59
|
+
const strokeWidth = (0, getStyleFromItemStateAndParams_1.getStyleFromItemStateAndParams)((_h = wrapperStateParams === null || wrapperStateParams === void 0 ? void 0 : wrapperStateParams.styles) === null || _h === void 0 ? void 0 : _h.strokeWidth, itemStrokeWidth);
|
|
60
|
+
const radius = (0, getStyleFromItemStateAndParams_1.getStyleFromItemStateAndParams)((_j = wrapperStateParams === null || wrapperStateParams === void 0 ? void 0 : wrapperStateParams.styles) === null || _j === void 0 ? void 0 : _j.radius, itemRadius);
|
|
61
|
+
const strokeFill = (_m = (0, getStyleFromItemStateAndParams_1.getStyleFromItemStateAndParams)((_l = (_k = videoStateParams === null || videoStateParams === void 0 ? void 0 : videoStateParams.styles) === null || _k === void 0 ? void 0 : _k.strokeFill) === null || _l === void 0 ? void 0 : _l[0], itemStrokeFill === null || itemStrokeFill === void 0 ? void 0 : itemStrokeFill[0])) !== null && _m !== void 0 ? _m : itemStrokeFill === null || itemStrokeFill === void 0 ? void 0 : itemStrokeFill[0];
|
|
61
62
|
const stroke = strokeFill
|
|
62
|
-
? (
|
|
63
|
+
? (_o = (0, getFill_1.getFill)(strokeFill)) !== null && _o !== void 0 ? _o : 'transparent'
|
|
63
64
|
: 'transparent';
|
|
64
65
|
(0, react_1.useEffect)(() => {
|
|
65
66
|
isInitialRef.current = false;
|
|
@@ -76,7 +77,7 @@ const VideoItem = ({ item, sectionId, onResize, interactionCtrl, onVisibilityCha
|
|
|
76
77
|
borderColor: stroke,
|
|
77
78
|
borderRadius: radius !== undefined ? `${radius * 100}vw` : 'inherit',
|
|
78
79
|
borderStyle: 'solid'
|
|
79
|
-
} : {})), { transition: (
|
|
80
|
+
} : {})), { transition: (_p = videoStateParams === null || videoStateParams === void 0 ? void 0 : videoStateParams.transition) !== null && _p !== void 0 ? _p : 'none' });
|
|
80
81
|
const isInteractive = opacity !== 0;
|
|
81
82
|
(0, react_1.useEffect)(() => {
|
|
82
83
|
onVisibilityChange === null || onVisibilityChange === void 0 ? void 0 : onVisibilityChange(isInteractive);
|
|
@@ -99,7 +100,7 @@ const VideoItem = ({ item, sectionId, onResize, interactionCtrl, onVisibilityCha
|
|
|
99
100
|
observer.observe(ref);
|
|
100
101
|
return () => observer.disconnect();
|
|
101
102
|
}, [layoutParams, videoRef, ref, userPaused, isVideoInteracted]);
|
|
102
|
-
return ((0, jsx_runtime_1.jsxs)(LinkWrapper_1.LinkWrapper, { url: (
|
|
103
|
+
return ((0, jsx_runtime_1.jsxs)(LinkWrapper_1.LinkWrapper, { url: (_q = item.link) === null || _q === void 0 ? void 0 : _q.url, target: (_r = item.link) === null || _r === void 0 ? void 0 : _r.target, children: [(0, jsx_runtime_1.jsxs)("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)` } : {})), { willChange: blur !== 0 && blur !== undefined ? 'transform' : 'unset', transition: (_s = wrapperStateParams === null || wrapperStateParams === void 0 ? void 0 : wrapperStateParams.transition) !== null && _s !== void 0 ? _s : '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}`, scrollPlaybackFrameData: item.commonParams.scrollPlaybackFrameData, frameBaseUrl: (_t = item.commonParams.scrollPlaybackFrameData) === null || _t === void 0 ? void 0 : _t.framesUrl })), hasGLEffect && isFXAllowed && ((0, jsx_runtime_1.jsx)("canvas", { style: inlineStyles, ref: fxCanvas, className: `video-canvas video-${item.id}`, width: rectWidth, height: rectHeight })), !hasScrollPlayback && !hasGLEffect && layoutParams && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("video", { poster: (_u = item.commonParams.coverUrl) !== null && _u !== void 0 ? _u : '', ref: setVideoRef, autoPlay: layoutParams.play === 'auto', preload: "auto", onClick: () => {
|
|
103
104
|
setIsVideoInteracted(true);
|
|
104
105
|
}, muted: layoutParams.muted, onPlay: () => {
|
|
105
106
|
setIsVideoPlaying(true);
|
|
@@ -122,7 +123,7 @@ const VideoItem = ({ item, sectionId, onResize, interactionCtrl, onVisibilityCha
|
|
|
122
123
|
return;
|
|
123
124
|
setIsVideoInteracted(true);
|
|
124
125
|
videoRef.play();
|
|
125
|
-
}, src: (
|
|
126
|
+
}, src: (_v = item.commonParams.coverUrl) !== null && _v !== void 0 ? _v : '', className: `video-cover-${item.id}`, onClick: () => {
|
|
126
127
|
if (!videoRef)
|
|
127
128
|
return;
|
|
128
129
|
setIsVideoInteracted(true);
|
package/lib/index.js
CHANGED
|
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.cntrlSdkContext = exports.customSections = exports.customItems = exports.useCntrlContext = exports.CntrlProvider = exports.YoutubeEmbedItem = exports.VimeoEmbedItem = exports.LayoutStyle = exports.VideoItem = exports.RichTextItem = exports.RectangleItem = exports.ImageItem = exports.Item = exports.Section = exports.Article = exports.Head = exports.Page = exports.RichTextConverter = void 0;
|
|
17
|
+
exports.cntrlSdkContext = exports.customSections = exports.customItems = exports.resolveCustomComponents = exports.evaluateComponentBundle = exports.useCntrlContext = exports.CntrlProvider = exports.YoutubeEmbedItem = exports.VimeoEmbedItem = exports.LayoutStyle = exports.VideoItem = exports.RichTextItem = exports.RectangleItem = exports.ImageItem = exports.Item = exports.Section = exports.Article = exports.Head = exports.Page = exports.RichTextConverter = void 0;
|
|
18
18
|
const defaultContext_1 = require("./provider/defaultContext");
|
|
19
19
|
__exportStar(require("@cntrl-site/sdk"), exports);
|
|
20
20
|
var RichTextConverter_1 = require("./utils/RichTextConverter/RichTextConverter");
|
|
@@ -47,6 +47,9 @@ var CntrlProvider_1 = require("./provider/CntrlProvider");
|
|
|
47
47
|
Object.defineProperty(exports, "CntrlProvider", { enumerable: true, get: function () { return CntrlProvider_1.CntrlProvider; } });
|
|
48
48
|
var useCntrlContext_1 = require("./provider/useCntrlContext");
|
|
49
49
|
Object.defineProperty(exports, "useCntrlContext", { enumerable: true, get: function () { return useCntrlContext_1.useCntrlContext; } });
|
|
50
|
+
var evaluateComponentBundle_1 = require("./utils/evaluateComponentBundle");
|
|
51
|
+
Object.defineProperty(exports, "evaluateComponentBundle", { enumerable: true, get: function () { return evaluateComponentBundle_1.evaluateComponentBundle; } });
|
|
52
|
+
Object.defineProperty(exports, "resolveCustomComponents", { enumerable: true, get: function () { return evaluateComponentBundle_1.resolveCustomComponents; } });
|
|
50
53
|
exports.customItems = defaultContext_1.cntrlSdkContext.customItems;
|
|
51
54
|
exports.customSections = defaultContext_1.cntrlSdkContext.customSections;
|
|
52
55
|
exports.cntrlSdkContext = defaultContext_1.cntrlSdkContext;
|
|
@@ -17,6 +17,8 @@ class CntrlSdkContext {
|
|
|
17
17
|
this.customSections = customSections;
|
|
18
18
|
this._layouts = [];
|
|
19
19
|
this._fonts = undefined;
|
|
20
|
+
this._projectId = undefined;
|
|
21
|
+
this._publicApiBase = undefined;
|
|
20
22
|
this.sectionHeightMap = new Map();
|
|
21
23
|
this.components = new Map();
|
|
22
24
|
}
|
|
@@ -34,12 +36,30 @@ class CntrlSdkContext {
|
|
|
34
36
|
return Object.fromEntries(yield Promise.all(resolvers.map(({ name, resolver }) => __awaiter(this, void 0, void 0, function* () { return [name, yield resolver()]; }))));
|
|
35
37
|
});
|
|
36
38
|
}
|
|
37
|
-
init({ project, article }) {
|
|
39
|
+
init({ project, article, customComponents }) {
|
|
40
|
+
this._projectId = project.id;
|
|
38
41
|
this.setLayouts(project.layouts);
|
|
39
42
|
this.setComponents(components_1.components);
|
|
43
|
+
if (customComponents) {
|
|
44
|
+
this.setCustomComponents(customComponents);
|
|
45
|
+
}
|
|
40
46
|
this.setFonts(project.fonts);
|
|
41
47
|
this.setSectionsHeight(article.sections);
|
|
42
48
|
}
|
|
49
|
+
setPublicApiBase(url) {
|
|
50
|
+
this._publicApiBase = url;
|
|
51
|
+
}
|
|
52
|
+
get projectId() {
|
|
53
|
+
return this._projectId;
|
|
54
|
+
}
|
|
55
|
+
get publicApiBase() {
|
|
56
|
+
return this._publicApiBase;
|
|
57
|
+
}
|
|
58
|
+
getSubmitUrl(pluginConfigId) {
|
|
59
|
+
if (!this._publicApiBase || !this._projectId || !pluginConfigId)
|
|
60
|
+
return undefined;
|
|
61
|
+
return `${this._publicApiBase}/projects/${this._projectId}/forms/${pluginConfigId}/submit`;
|
|
62
|
+
}
|
|
43
63
|
setLayouts(layouts) {
|
|
44
64
|
this._layouts = layouts;
|
|
45
65
|
}
|
|
@@ -48,6 +68,11 @@ class CntrlSdkContext {
|
|
|
48
68
|
this.components.set(component.id, component);
|
|
49
69
|
}
|
|
50
70
|
}
|
|
71
|
+
setCustomComponents(customComponents) {
|
|
72
|
+
for (const [id, component] of customComponents) {
|
|
73
|
+
this.components.set(id, component);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
51
76
|
setFonts(fonts) {
|
|
52
77
|
this._fonts = fonts;
|
|
53
78
|
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
exports.resolveCustomComponents = exports.evaluateComponentBundle = void 0;
|
|
30
|
+
const react_1 = __importDefault(require("react"));
|
|
31
|
+
const react_dom_1 = __importDefault(require("react-dom"));
|
|
32
|
+
const jsxRuntime = __importStar(require("react/jsx-runtime"));
|
|
33
|
+
const componentUtils = __importStar(require("@cntrl-site/components/utils"));
|
|
34
|
+
let globalsInitialized = false;
|
|
35
|
+
function ensureGlobals() {
|
|
36
|
+
if (globalsInitialized)
|
|
37
|
+
return;
|
|
38
|
+
globalThis.__CNTRL_REACT__ = react_1.default;
|
|
39
|
+
globalThis.__CNTRL_REACT_DOM__ = react_dom_1.default;
|
|
40
|
+
globalThis.__CNTRL_JSX_RUNTIME__ = jsxRuntime;
|
|
41
|
+
globalThis.__CNTRL_COMPONENT_UTILS__ = componentUtils;
|
|
42
|
+
globalsInitialized = true;
|
|
43
|
+
}
|
|
44
|
+
function transformEsmToEvaluatable(code) {
|
|
45
|
+
let transformed = code;
|
|
46
|
+
let hasDefault = false;
|
|
47
|
+
transformed = transformed.replace(/export\s*\{\s*(\w+)\s+as\s+default\s*\}\s*;?/g, (_, name) => { hasDefault = true; return `var __cntrl_default_export__ = ${name};`; });
|
|
48
|
+
transformed = transformed.replace(/export\s+default\s+/g, () => { hasDefault = true; return 'var __cntrl_default_export__ = '; });
|
|
49
|
+
transformed = transformed.replace(/export\s*\{\s*([^}]*)\}\s*;?/g, (_, names) => {
|
|
50
|
+
if (!hasDefault) {
|
|
51
|
+
const firstName = names.split(',')[0].trim().split(/\s+/)[0];
|
|
52
|
+
if (firstName) {
|
|
53
|
+
hasDefault = true;
|
|
54
|
+
return `var __cntrl_default_export__ = ${firstName};`;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return '';
|
|
58
|
+
});
|
|
59
|
+
return `${transformed}\nreturn __cntrl_default_export__;`;
|
|
60
|
+
}
|
|
61
|
+
function evaluateComponentBundle(bundleCode) {
|
|
62
|
+
ensureGlobals();
|
|
63
|
+
const evaluatable = transformEsmToEvaluatable(bundleCode);
|
|
64
|
+
const fn = new Function(evaluatable);
|
|
65
|
+
return fn();
|
|
66
|
+
}
|
|
67
|
+
exports.evaluateComponentBundle = evaluateComponentBundle;
|
|
68
|
+
const resolvedCache = new Map();
|
|
69
|
+
function resolveCustomComponents(bundles, schemas) {
|
|
70
|
+
var _a;
|
|
71
|
+
const result = new Map();
|
|
72
|
+
for (const [id, code] of Object.entries(bundles)) {
|
|
73
|
+
try {
|
|
74
|
+
let element = resolvedCache.get(id);
|
|
75
|
+
if (!element) {
|
|
76
|
+
element = evaluateComponentBundle(code);
|
|
77
|
+
resolvedCache.set(id, element);
|
|
78
|
+
}
|
|
79
|
+
result.set(id, {
|
|
80
|
+
id,
|
|
81
|
+
name: id,
|
|
82
|
+
element,
|
|
83
|
+
schema: (_a = schemas === null || schemas === void 0 ? void 0 : schemas[id]) !== null && _a !== void 0 ? _a : {}
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
catch (err) {
|
|
87
|
+
console.error(`Failed to evaluate custom component bundle "${id}":`, err);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return result;
|
|
91
|
+
}
|
|
92
|
+
exports.resolveCustomComponents = resolveCustomComponents;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cntrl-site/sdk-nextjs",
|
|
3
|
-
"version": "1.9.
|
|
3
|
+
"version": "1.9.55-2",
|
|
4
4
|
"description": "SDK for Next.js",
|
|
5
5
|
"author": "arsen@momdesign.nyc",
|
|
6
6
|
"license": "MIT",
|
|
@@ -31,9 +31,9 @@
|
|
|
31
31
|
"dependencies": {
|
|
32
32
|
"@antfu/eslint-config": "^3.8.0",
|
|
33
33
|
"@cntrl-site/color": "^1.0.0",
|
|
34
|
-
"@cntrl-site/components": "^0.1.
|
|
34
|
+
"@cntrl-site/components": "^1.0.1-alpha.16",
|
|
35
35
|
"@cntrl-site/effects": "^1.4.0",
|
|
36
|
-
"@cntrl-site/sdk": "^1.
|
|
36
|
+
"@cntrl-site/sdk": "^1.26.1",
|
|
37
37
|
"@types/vimeo__player": "^2.18.0",
|
|
38
38
|
"@vimeo/player": "^2.25.0",
|
|
39
39
|
"html-react-parser": "^3.0.1",
|
|
@@ -48,6 +48,7 @@
|
|
|
48
48
|
"@types/jest": "^29.5.12",
|
|
49
49
|
"@types/node": "^18.11.7",
|
|
50
50
|
"@types/react": "^18.0.15",
|
|
51
|
+
"@types/react-dom": "^18.3.7",
|
|
51
52
|
"cross-env": "^10.1.0",
|
|
52
53
|
"jest": "^29.7.0",
|
|
53
54
|
"jest-environment-jsdom": "^29.7.0",
|
package/src/components/Page.tsx
CHANGED
|
@@ -8,12 +8,18 @@ import { Keyframes } from '../provider/Keyframes';
|
|
|
8
8
|
import { ItemGeometryContext } from '../ItemGeometry/ItemGeometryContext';
|
|
9
9
|
import { ItemGeometryService } from '../ItemGeometry/ItemGeometryService';
|
|
10
10
|
|
|
11
|
+
export interface CustomComponentBundlesData {
|
|
12
|
+
bundles: Record<string, string>;
|
|
13
|
+
schemas: Record<string, Record<string, unknown>>;
|
|
14
|
+
}
|
|
15
|
+
|
|
11
16
|
export interface PageProps {
|
|
12
17
|
article: TArticle;
|
|
13
18
|
project: Project;
|
|
14
19
|
meta: Meta;
|
|
15
20
|
keyframes: KeyframeAny[];
|
|
16
21
|
sectionData: Record<SectionName, any>;
|
|
22
|
+
customComponentBundles?: CustomComponentBundlesData;
|
|
17
23
|
}
|
|
18
24
|
|
|
19
25
|
export const Page: FC<PageProps> = ({ article, project, meta, keyframes, sectionData }) => {
|
|
@@ -28,12 +28,14 @@ export const ScrollPlaybackVideo: FC<Props> = ({ sectionId, src, playbackParams,
|
|
|
28
28
|
|
|
29
29
|
useEffect(() => {
|
|
30
30
|
if (!playbackParams || !articleRectObserver) return;
|
|
31
|
+
const from = playbackParams.from;
|
|
32
|
+
const to = playbackParams.to;
|
|
31
33
|
return articleRectObserver.on('scroll', () => {
|
|
32
34
|
const scrollPos = articleRectObserver.getSectionScroll(sectionId);
|
|
33
|
-
const
|
|
34
|
-
setTime(toFixed(
|
|
35
|
+
const nextTime = rangeMap(scrollPos, from, to, 0, 1, true);
|
|
36
|
+
setTime(toFixed(nextTime));
|
|
35
37
|
});
|
|
36
|
-
}, [playbackParams?.from, playbackParams?.to,
|
|
38
|
+
}, [sectionId, playbackParams?.from, playbackParams?.to, articleRectObserver]);
|
|
37
39
|
|
|
38
40
|
const scrollVideoManager = useMemo<ScrollPlaybackVideoManager | null>(() => {
|
|
39
41
|
if (!containerElement) return null;
|
|
@@ -15,6 +15,8 @@ export const ComponentItem: FC<ItemProps<TComponentItem>> = ({ item, sectionId,
|
|
|
15
15
|
const { layouts } = sdk;
|
|
16
16
|
const itemAngle = useItemAngle(item, sectionId);
|
|
17
17
|
const layout = useLayoutContext();
|
|
18
|
+
const fallbackLayout = layouts[0]?.id;
|
|
19
|
+
const effectiveLayout = layout ?? fallbackLayout;
|
|
18
20
|
const layoutValues: Record<string, any>[] = [item.area, item.layoutParams];
|
|
19
21
|
const component = sdk.getComponent(item.commonParams.componentId);
|
|
20
22
|
const [ref, setRef] = useState<HTMLDivElement | null>(null);
|
|
@@ -26,7 +28,12 @@ export const ComponentItem: FC<ItemProps<TComponentItem>> = ({ item, sectionId,
|
|
|
26
28
|
const opacity = getStyleFromItemStateAndParams(stateParams?.styles?.opacity, itemOpacity);
|
|
27
29
|
const blur = getStyleFromItemStateAndParams(stateParams?.styles?.blur, itemBlur);
|
|
28
30
|
const Element = component ? component.element : undefined;
|
|
29
|
-
const
|
|
31
|
+
const layoutParameters = effectiveLayout ? item.layoutParams[effectiveLayout]?.parameters : undefined;
|
|
32
|
+
const commonParameters = (item.commonParams as any).parameters;
|
|
33
|
+
const parameters = layoutParameters ? {
|
|
34
|
+
...layoutParameters,
|
|
35
|
+
settings: { ...layoutParameters.settings, ...commonParameters?.settings }
|
|
36
|
+
} : undefined;
|
|
30
37
|
|
|
31
38
|
return (
|
|
32
39
|
<>
|
|
@@ -43,7 +50,10 @@ export const ComponentItem: FC<ItemProps<TComponentItem>> = ({ item, sectionId,
|
|
|
43
50
|
>
|
|
44
51
|
{parameters && Element && (
|
|
45
52
|
<Element
|
|
46
|
-
metadata={{
|
|
53
|
+
metadata={{
|
|
54
|
+
itemId: item.id,
|
|
55
|
+
submitUrl: sdk.getSubmitUrl(commonParameters?.pluginConfigId)
|
|
56
|
+
}}
|
|
47
57
|
portalId="component-portal"
|
|
48
58
|
content={item.commonParams.content}
|
|
49
59
|
{...parameters}
|
|
@@ -49,7 +49,8 @@ export const VideoItem: FC<ItemProps<TVideoItem>> = ({ item, sectionId, onResize
|
|
|
49
49
|
const rectHeight = Math.floor(rect?.height ?? 0);
|
|
50
50
|
const scrollPlayback = layoutParams ? layoutParams.scrollPlayback : null;
|
|
51
51
|
const layoutValues: Record<string, any>[] = [item.area, item.layoutParams];
|
|
52
|
-
const
|
|
52
|
+
const isHiddenOnLayout = layoutId ? (item.hidden[layoutId] ?? false) : false;
|
|
53
|
+
const hasScrollPlayback = scrollPlayback !== null && !isHiddenOnLayout;
|
|
53
54
|
const wrapperStateParams = interactionCtrl?.getState<number>(['angle', 'opacity', 'blur']);
|
|
54
55
|
const videoStateParams = interactionCtrl?.getState<any>(['strokeWidth', 'radius', 'strokeFill']);
|
|
55
56
|
const angle = getStyleFromItemStateAndParams(wrapperStateParams?.styles?.angle, itemAngle);
|
package/src/index.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { cntrlSdkContext as sdk } from './provider/defaultContext';
|
|
|
3
3
|
export * from '@cntrl-site/sdk';
|
|
4
4
|
export { RichTextConverter } from './utils/RichTextConverter/RichTextConverter';
|
|
5
5
|
export { Page } from './components/Page';
|
|
6
|
-
export type { PageProps } from './components/Page';
|
|
6
|
+
export type { PageProps, CustomComponentBundlesData } from './components/Page';
|
|
7
7
|
export { CNTRLHead as Head } from './components/Head';
|
|
8
8
|
export { Article } from './components/Article';
|
|
9
9
|
export { Section } from './components/Section/Section';
|
|
@@ -19,6 +19,7 @@ export { YoutubeEmbedItem } from './components/items/EmbedVideoItem/YoutubeEmbed
|
|
|
19
19
|
export { CntrlProvider } from './provider/CntrlProvider';
|
|
20
20
|
export type { CustomItemComponent } from './provider/CustomItemTypes';
|
|
21
21
|
export { useCntrlContext } from './provider/useCntrlContext';
|
|
22
|
+
export { evaluateComponentBundle, resolveCustomComponents } from './utils/evaluateComponentBundle';
|
|
22
23
|
export const customItems = sdk.customItems;
|
|
23
24
|
export const customSections = sdk.customSections;
|
|
24
25
|
export const cntrlSdkContext = sdk;
|
|
@@ -2,16 +2,18 @@ import { CustomItemRegistry } from './CustomItemRegistry';
|
|
|
2
2
|
import { Article, Section, Layout, Project, SectionHeight } from '@cntrl-site/sdk';
|
|
3
3
|
import { components, Component as TComponent } from '@cntrl-site/components';
|
|
4
4
|
import { CustomSectionRegistry } from './CustomSectionRegistry';
|
|
5
|
-
import { Component } from 'react';
|
|
6
5
|
|
|
7
6
|
interface SdkContextInitProps {
|
|
8
7
|
project: Project;
|
|
9
8
|
article: Article;
|
|
9
|
+
customComponents?: Map<string, TComponent>;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
export class CntrlSdkContext {
|
|
13
13
|
private _layouts: Layout[] = [];
|
|
14
14
|
private _fonts?: Project['fonts'] = undefined;
|
|
15
|
+
private _projectId?: string = undefined;
|
|
16
|
+
private _publicApiBase?: string = undefined;
|
|
15
17
|
private sectionHeightMap: Map<string, Record<string, SectionHeight>> = new Map();
|
|
16
18
|
private components: Map<string, TComponent> = new Map();
|
|
17
19
|
|
|
@@ -34,13 +36,34 @@ export class CntrlSdkContext {
|
|
|
34
36
|
);
|
|
35
37
|
}
|
|
36
38
|
|
|
37
|
-
init({ project, article }: SdkContextInitProps) {
|
|
39
|
+
init({ project, article, customComponents }: SdkContextInitProps) {
|
|
40
|
+
this._projectId = project.id;
|
|
38
41
|
this.setLayouts(project.layouts);
|
|
39
42
|
this.setComponents(components);
|
|
43
|
+
if (customComponents) {
|
|
44
|
+
this.setCustomComponents(customComponents);
|
|
45
|
+
}
|
|
40
46
|
this.setFonts(project.fonts);
|
|
41
47
|
this.setSectionsHeight(article.sections);
|
|
42
48
|
}
|
|
43
49
|
|
|
50
|
+
setPublicApiBase(url: string) {
|
|
51
|
+
this._publicApiBase = url;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
get projectId(): string | undefined {
|
|
55
|
+
return this._projectId;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
get publicApiBase(): string | undefined {
|
|
59
|
+
return this._publicApiBase;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
getSubmitUrl(pluginConfigId: string | undefined): string | undefined {
|
|
63
|
+
if (!this._publicApiBase || !this._projectId || !pluginConfigId) return undefined;
|
|
64
|
+
return `${this._publicApiBase}/projects/${this._projectId}/forms/${pluginConfigId}/submit`;
|
|
65
|
+
}
|
|
66
|
+
|
|
44
67
|
setLayouts(layouts: Layout[]) {
|
|
45
68
|
this._layouts = layouts;
|
|
46
69
|
}
|
|
@@ -51,6 +74,12 @@ export class CntrlSdkContext {
|
|
|
51
74
|
}
|
|
52
75
|
}
|
|
53
76
|
|
|
77
|
+
setCustomComponents(customComponents: Map<string, TComponent>) {
|
|
78
|
+
for (const [id, component] of customComponents) {
|
|
79
|
+
this.components.set(id, component);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
54
83
|
private setFonts(fonts: Project['fonts']) {
|
|
55
84
|
this._fonts = fonts;
|
|
56
85
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
declare module '@cntrl-site/components/utils' {
|
|
2
|
+
export function scalingValue(value: number, isEditor?: boolean): string;
|
|
3
|
+
export function useScopedStyles(): { prefix: string; cls: (name: string) => string };
|
|
4
|
+
export function getColorAlpha(color: string): number;
|
|
5
|
+
export function getPositionStyles(position: any): Record<string, any>;
|
|
6
|
+
export function getImageRect(rect: any): Record<string, any>;
|
|
7
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import ReactDOM from 'react-dom';
|
|
3
|
+
import * as jsxRuntime from 'react/jsx-runtime';
|
|
4
|
+
import { Component as TComponent } from '@cntrl-site/components';
|
|
5
|
+
import * as componentUtils from '@cntrl-site/components/utils';
|
|
6
|
+
|
|
7
|
+
let globalsInitialized = false;
|
|
8
|
+
|
|
9
|
+
function ensureGlobals() {
|
|
10
|
+
if (globalsInitialized) return;
|
|
11
|
+
(globalThis as any).__CNTRL_REACT__ = React;
|
|
12
|
+
(globalThis as any).__CNTRL_REACT_DOM__ = ReactDOM;
|
|
13
|
+
(globalThis as any).__CNTRL_JSX_RUNTIME__ = jsxRuntime;
|
|
14
|
+
(globalThis as any).__CNTRL_COMPONENT_UTILS__ = componentUtils;
|
|
15
|
+
globalsInitialized = true;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
function transformEsmToEvaluatable(code: string): string {
|
|
19
|
+
let transformed = code;
|
|
20
|
+
let hasDefault = false;
|
|
21
|
+
|
|
22
|
+
transformed = transformed.replace(
|
|
23
|
+
/export\s*\{\s*(\w+)\s+as\s+default\s*\}\s*;?/g,
|
|
24
|
+
(_, name) => { hasDefault = true; return `var __cntrl_default_export__ = ${name};`; }
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
transformed = transformed.replace(
|
|
28
|
+
/export\s+default\s+/g,
|
|
29
|
+
() => { hasDefault = true; return 'var __cntrl_default_export__ = '; }
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
transformed = transformed.replace(
|
|
33
|
+
/export\s*\{\s*([^}]*)\}\s*;?/g,
|
|
34
|
+
(_, names) => {
|
|
35
|
+
if (!hasDefault) {
|
|
36
|
+
const firstName = names.split(',')[0].trim().split(/\s+/)[0];
|
|
37
|
+
if (firstName) {
|
|
38
|
+
hasDefault = true;
|
|
39
|
+
return `var __cntrl_default_export__ = ${firstName};`;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return '';
|
|
43
|
+
}
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
return `${transformed}\nreturn __cntrl_default_export__;`;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function evaluateComponentBundle(
|
|
50
|
+
bundleCode: string
|
|
51
|
+
): (props: any) => React.ReactElement {
|
|
52
|
+
ensureGlobals();
|
|
53
|
+
const evaluatable = transformEsmToEvaluatable(bundleCode);
|
|
54
|
+
const fn = new Function(evaluatable);
|
|
55
|
+
return fn();
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const resolvedCache = new Map<string, (props: any) => React.ReactElement>();
|
|
59
|
+
|
|
60
|
+
export function resolveCustomComponents(
|
|
61
|
+
bundles: Record<string, string>,
|
|
62
|
+
schemas?: Record<string, Record<string, unknown>>
|
|
63
|
+
): Map<string, TComponent> {
|
|
64
|
+
const result = new Map<string, TComponent>();
|
|
65
|
+
for (const [id, code] of Object.entries(bundles)) {
|
|
66
|
+
try {
|
|
67
|
+
let element = resolvedCache.get(id);
|
|
68
|
+
if (!element) {
|
|
69
|
+
element = evaluateComponentBundle(code);
|
|
70
|
+
resolvedCache.set(id, element);
|
|
71
|
+
}
|
|
72
|
+
result.set(id, {
|
|
73
|
+
id,
|
|
74
|
+
name: id,
|
|
75
|
+
element,
|
|
76
|
+
schema: schemas?.[id] ?? {}
|
|
77
|
+
} as TComponent);
|
|
78
|
+
} catch (err) {
|
|
79
|
+
console.error(`Failed to evaluate custom component bundle "${id}":`, err);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return result;
|
|
83
|
+
}
|