@cntrl-site/sdk-nextjs 1.0.19-alpha.0 → 1.0.19-alpha.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/Item.js +5 -3
- package/lib/components/items/CodeEmbedItem.js +2 -0
- package/lib/components/items/CustomItem.js +2 -0
- package/lib/components/items/GroupItem.js +2 -0
- package/lib/components/items/ImageItem.js +9 -4
- package/lib/components/items/RectangleItem.js +2 -0
- package/lib/components/items/RichTextItem.js +2 -0
- package/lib/components/items/VideoItem.js +3 -0
- package/lib/components/items/VimeoEmbed.js +3 -0
- package/lib/components/items/YoutubeEmbed.js +5 -1
- package/lib/components/useStatesTransitions.js +89 -0
- package/lib/utils/StateStyles/StateStyles.js +28 -18
- package/package.json +2 -2
- package/src/components/Item.tsx +5 -2
- package/src/components/items/CodeEmbedItem.tsx +2 -0
- package/src/components/items/CustomItem.tsx +2 -0
- package/src/components/items/GroupItem.tsx +2 -0
- package/src/components/items/ImageItem.tsx +10 -4
- package/src/components/items/RectangleItem.tsx +2 -0
- package/src/components/items/RichTextItem.tsx +2 -0
- package/src/components/items/VideoItem.tsx +3 -0
- package/src/components/items/VimeoEmbed.tsx +3 -0
- package/src/components/items/YoutubeEmbed.tsx +5 -1
- package/src/components/useStatesTransitions.ts +95 -0
- package/src/utils/StateStyles/StateStyles.ts +34 -21
- package/src/utils/getStatesCSS.ts +7 -4
package/lib/components/Item.js
CHANGED
|
@@ -33,6 +33,7 @@ const KeyframesContext_1 = require("../provider/KeyframesContext");
|
|
|
33
33
|
const InteractionsContext_1 = require("../provider/InteractionsContext");
|
|
34
34
|
const getStatesCSS_1 = require("../utils/getStatesCSS");
|
|
35
35
|
const useStatesClassNames_1 = require("./useStatesClassNames");
|
|
36
|
+
const useStatesTransitions_1 = require("./useStatesTransitions");
|
|
36
37
|
const itemsMap = {
|
|
37
38
|
[sdk_1.ArticleItemType.Rectangle]: RectangleItem_1.RectangleItem,
|
|
38
39
|
[sdk_1.ArticleItemType.Image]: ImageItem_1.ImageItem,
|
|
@@ -56,6 +57,7 @@ const RichTextWrapper = ({ isRichText, children }) => {
|
|
|
56
57
|
const noop = () => null;
|
|
57
58
|
const Item = ({ item, sectionId, articleHeight, isInGroup = false }) => {
|
|
58
59
|
const itemWrapperRef = (0, react_1.useRef)(null);
|
|
60
|
+
const itemInnerRef = (0, react_1.useRef)(null);
|
|
59
61
|
const rectObserver = (0, react_1.useContext)(ArticleRectContext_1.ArticleRectContext);
|
|
60
62
|
const keyframesRepo = (0, react_1.useContext)(KeyframesContext_1.KeyframesContext);
|
|
61
63
|
const id = (0, react_1.useId)();
|
|
@@ -107,11 +109,13 @@ const Item = ({ item, sectionId, articleHeight, isInGroup = false }) => {
|
|
|
107
109
|
const isRichText = isItemType(item, sdk_1.ArticleItemType.RichText);
|
|
108
110
|
const innerStatesClassNames = (0, useStatesClassNames_1.useStatesClassNames)(item.id, item.state, 'item-inner');
|
|
109
111
|
const wrapperStatesClassNames = (0, useStatesClassNames_1.useStatesClassNames)(item.id, item.state, 'item-wrapper');
|
|
112
|
+
(0, useStatesTransitions_1.useStatesTransitions)(itemWrapperRef.current, item.state, ['top', 'left']);
|
|
113
|
+
(0, useStatesTransitions_1.useStatesTransitions)(itemInnerRef.current, item.state, ['width', 'height', 'scale']);
|
|
110
114
|
return ((0, jsx_runtime_1.jsxs)("div", { className: `item-wrapper-${item.id} ${wrapperStatesClassNames}`, ref: itemWrapperRef, style: Object.assign(Object.assign(Object.assign(Object.assign({}, (position ? { top: position.top } : {})), (position ? { left: position.left } : {})), (position ? { bottom: position.bottom } : {})), (wrapperHeight !== undefined ? { height: `${wrapperHeight * 100}vw` } : {})), children: [(0, jsx_runtime_1.jsx)("div", { suppressHydrationWarning: true, className: `item-${item.id}`, style: {
|
|
111
115
|
opacity: (keyframes.length !== 0 && !layout) ? 0 : 1,
|
|
112
116
|
top: `${stickyTop * 100}vw`,
|
|
113
117
|
height: isRichText && itemHeight ? `${itemHeight * 100}vw` : 'unset',
|
|
114
|
-
}, children: (0, jsx_runtime_1.jsx)(RichTextWrapper, { isRichText: isRichText, children: (0, jsx_runtime_1.jsx)("div", { className: `item-${item.id}-inner ${innerStatesClassNames}`, onClick: () => {
|
|
118
|
+
}, children: (0, jsx_runtime_1.jsx)(RichTextWrapper, { isRichText: isRichText, children: (0, jsx_runtime_1.jsx)("div", { className: `item-${item.id}-inner ${innerStatesClassNames}`, ref: itemInnerRef, onClick: () => {
|
|
115
119
|
const trigger = getItemTrigger(item.id, 'click');
|
|
116
120
|
if (!trigger)
|
|
117
121
|
return;
|
|
@@ -157,7 +161,6 @@ const Item = ({ item, sectionId, articleHeight, isInGroup = false }) => {
|
|
|
157
161
|
height: ${sizingAxis.y === 'manual' ? `${area.height * 100}vw` : 'unset'};
|
|
158
162
|
transform-origin: ${ScaleAnchorMap_1.ScaleAnchorMap[scaleAnchor]};
|
|
159
163
|
transform: scale(${area.scale});
|
|
160
|
-
transition: all 0.2s ease;
|
|
161
164
|
}
|
|
162
165
|
.item-wrapper-${item.id} {
|
|
163
166
|
position: ${area.positionType === sdk_1.PositionType.ScreenBased ? 'fixed' : 'absolute'};
|
|
@@ -167,7 +170,6 @@ const Item = ({ item, sectionId, articleHeight, isInGroup = false }) => {
|
|
|
167
170
|
bottom: ${isScreenBasedBottom ? `${-area.top * 100}vw` : 'unset'};
|
|
168
171
|
top: ${isScreenBasedBottom ? 'unset' : (0, getItemTopStyle_1.getItemTopStyle)(area.top, area.anchorSide)};
|
|
169
172
|
left: ${area.left * 100}vw;
|
|
170
|
-
transition: all 0.2s ease;
|
|
171
173
|
}
|
|
172
174
|
${statesWrapperCSS}
|
|
173
175
|
${statesInnerCSS}
|
|
@@ -15,6 +15,7 @@ const LinkWrapper_1 = require("../LinkWrapper");
|
|
|
15
15
|
const useCodeEmbedItem_1 = require("./useCodeEmbedItem");
|
|
16
16
|
const getStatesCSS_1 = require("../../utils/getStatesCSS");
|
|
17
17
|
const useStatesClassNames_1 = require("../useStatesClassNames");
|
|
18
|
+
const useStatesTransitions_1 = require("../useStatesTransitions");
|
|
18
19
|
const stylesMap = {
|
|
19
20
|
[sdk_1.AreaAnchor.TopLeft]: {},
|
|
20
21
|
[sdk_1.AreaAnchor.TopCenter]: { justifyContent: 'center' },
|
|
@@ -38,6 +39,7 @@ const CodeEmbedItem = ({ item, sectionId, onResize }) => {
|
|
|
38
39
|
const pos = stylesMap[anchor];
|
|
39
40
|
const layoutValues = [item.area, item.layoutParams, item.state];
|
|
40
41
|
const statesClassNames = (0, useStatesClassNames_1.useStatesClassNames)(item.id, item.state, 'embed-wrapper');
|
|
42
|
+
(0, useStatesTransitions_1.useStatesTransitions)(ref, item.state, ['angle', 'blur', 'opacity']);
|
|
41
43
|
(0, react_1.useEffect)(() => {
|
|
42
44
|
if (!ref)
|
|
43
45
|
return;
|
|
@@ -13,6 +13,7 @@ const useRegisterResize_1 = require("../../common/useRegisterResize");
|
|
|
13
13
|
const useItemAngle_1 = require("../useItemAngle");
|
|
14
14
|
const useStatesClassNames_1 = require("../useStatesClassNames");
|
|
15
15
|
const getStatesCSS_1 = require("../../utils/getStatesCSS");
|
|
16
|
+
const useStatesTransitions_1 = require("../useStatesTransitions");
|
|
16
17
|
const CustomItem = ({ item, onResize, sectionId }) => {
|
|
17
18
|
const sdk = (0, useCntrlContext_1.useCntrlContext)();
|
|
18
19
|
const { layouts } = (0, useCntrlContext_1.useCntrlContext)();
|
|
@@ -22,6 +23,7 @@ const CustomItem = ({ item, onResize, sectionId }) => {
|
|
|
22
23
|
const [ref, setRef] = (0, react_1.useState)(null);
|
|
23
24
|
(0, useRegisterResize_1.useRegisterResize)(ref, onResize);
|
|
24
25
|
const statesClassNames = (0, useStatesClassNames_1.useStatesClassNames)(item.id, item.state, 'custom-component');
|
|
26
|
+
(0, useStatesTransitions_1.useStatesTransitions)(ref, item.state, ['angle']);
|
|
25
27
|
if (!component)
|
|
26
28
|
return null;
|
|
27
29
|
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { className: `custom-component-${item.id} ${statesClassNames}`, ref: setRef, style: Object.assign({}, (angle !== undefined ? { transform: `rotate(${angle}deg)` } : {})), children: component({}) }), (0, jsx_runtime_1.jsx)(style_1.default, { id: item.id, children: `${(0, sdk_1.getLayoutStyles)(layouts, layoutValues, ([area, stateParams]) => {
|
|
@@ -16,6 +16,7 @@ const useItemAngle_1 = require("../useItemAngle");
|
|
|
16
16
|
const useGroupItem_1 = require("./useGroupItem");
|
|
17
17
|
const useStatesClassNames_1 = require("../useStatesClassNames");
|
|
18
18
|
const getStatesCSS_1 = require("../../utils/getStatesCSS");
|
|
19
|
+
const useStatesTransitions_1 = require("../useStatesTransitions");
|
|
19
20
|
const GroupItem = ({ item, sectionId, onResize, articleHeight }) => {
|
|
20
21
|
var _a, _b;
|
|
21
22
|
const id = (0, react_1.useId)();
|
|
@@ -27,6 +28,7 @@ const GroupItem = ({ item, sectionId, onResize, articleHeight }) => {
|
|
|
27
28
|
const statesClassNames = (0, useStatesClassNames_1.useStatesClassNames)(item.id, item.state, 'group');
|
|
28
29
|
const [ref, setRef] = (0, react_1.useState)(null);
|
|
29
30
|
(0, useRegisterResize_1.useRegisterResize)(ref, onResize);
|
|
31
|
+
(0, useStatesTransitions_1.useStatesTransitions)(ref, item.state, ['opacity', 'angle']);
|
|
30
32
|
return ((0, jsx_runtime_1.jsx)(LinkWrapper_1.LinkWrapper, { url: (_a = item.link) === null || _a === void 0 ? void 0 : _a.url, target: (_b = item.link) === null || _b === void 0 ? void 0 : _b.target, children: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { className: `group-${item.id} ${statesClassNames}`, ref: setRef, style: Object.assign(Object.assign({}, (opacity !== undefined ? { opacity } : {})), (angle !== undefined ? { transform: `rotate(${angle}deg)` } : {})), children: items && items.map(item => ((0, jsx_runtime_1.jsx)(Item_1.Item, { item: item, sectionId: sectionId, articleHeight: articleHeight, isInGroup: true }, item.id))) }), (0, jsx_runtime_1.jsx)(style_1.default, { id: id, children: `
|
|
31
33
|
.group-${item.id} {
|
|
32
34
|
position: absolute;
|
|
@@ -19,6 +19,7 @@ const useElementRect_1 = require("../../utils/useElementRect");
|
|
|
19
19
|
const useLayoutContext_1 = require("../useLayoutContext");
|
|
20
20
|
const useStatesClassNames_1 = require("../useStatesClassNames");
|
|
21
21
|
const getStatesCSS_1 = require("../../utils/getStatesCSS");
|
|
22
|
+
const useStatesTransitions_1 = require("../useStatesTransitions");
|
|
22
23
|
const baseVariables = `precision mediump float;
|
|
23
24
|
uniform sampler2D u_image;
|
|
24
25
|
uniform sampler2D u_pattern;
|
|
@@ -35,8 +36,9 @@ const ImageItem = ({ item, sectionId, onResize }) => {
|
|
|
35
36
|
const { radius, strokeWidth, opacity, strokeColor, blur } = (0, useFileItem_1.useFileItem)(item, sectionId);
|
|
36
37
|
const angle = (0, useItemAngle_1.useItemAngle)(item, sectionId);
|
|
37
38
|
const borderColor = (0, react_1.useMemo)(() => strokeColor ? color_1.CntrlColor.parse(strokeColor) : undefined, [strokeColor]);
|
|
38
|
-
const [
|
|
39
|
-
(0,
|
|
39
|
+
const [wrapperRef, setWrapperRef] = (0, react_1.useState)(null);
|
|
40
|
+
const [imgRef, setImgRef] = (0, react_1.useState)(null);
|
|
41
|
+
(0, useRegisterResize_1.useRegisterResize)(wrapperRef, onResize);
|
|
40
42
|
const { url, hasGLEffect, fragmentShader, FXControls, FXCursor } = item.commonParams;
|
|
41
43
|
const fxCanvas = (0, react_1.useRef)(null);
|
|
42
44
|
const isInitialRef = (0, react_1.useRef)(true);
|
|
@@ -55,6 +57,9 @@ const ImageItem = ({ item, sectionId, onResize }) => {
|
|
|
55
57
|
const height = area && exemplary ? area.height * exemplary : 0;
|
|
56
58
|
const statesWrapperClassNames = (0, useStatesClassNames_1.useStatesClassNames)(item.id, item.state, 'image-wrapper');
|
|
57
59
|
const statesImgClassNames = (0, useStatesClassNames_1.useStatesClassNames)(item.id, item.state, 'image');
|
|
60
|
+
(0, useStatesTransitions_1.useStatesTransitions)(wrapperRef, item.state, ['angle', 'opacity', 'blur']);
|
|
61
|
+
(0, useStatesTransitions_1.useStatesTransitions)(imgRef, item.state, ['strokeWidth', 'radius', 'strokeColor']);
|
|
62
|
+
(0, useStatesTransitions_1.useStatesTransitions)(fxCanvas.current, item.state, ['strokeWidth', 'radius', 'strokeColor']);
|
|
58
63
|
(0, react_1.useEffect)(() => {
|
|
59
64
|
isInitialRef.current = false;
|
|
60
65
|
}, []);
|
|
@@ -64,11 +69,11 @@ const ImageItem = ({ item, sectionId, onResize }) => {
|
|
|
64
69
|
cursor: FXCursor,
|
|
65
70
|
controls: controlValues
|
|
66
71
|
}, width, height);
|
|
67
|
-
const rect = (0, useElementRect_1.useElementRect)(
|
|
72
|
+
const rect = (0, useElementRect_1.useElementRect)(wrapperRef);
|
|
68
73
|
const rectWidth = Math.floor((_b = rect === null || rect === void 0 ? void 0 : rect.width) !== null && _b !== void 0 ? _b : 0);
|
|
69
74
|
const rectHeight = Math.floor((_c = rect === null || rect === void 0 ? void 0 : rect.height) !== null && _c !== void 0 ? _c : 0);
|
|
70
75
|
const inlineStyles = Object.assign(Object.assign(Object.assign({}, (borderColor ? { borderColor: `${borderColor.fmt('rgba')}` } : {})), (radius !== undefined ? { borderRadius: `${radius * 100}vw` } : {})), (strokeWidth !== undefined ? { borderWidth: `${strokeWidth * 100}vw` } : {}));
|
|
71
|
-
return ((0, jsx_runtime_1.jsx)(LinkWrapper_1.LinkWrapper, { url: (_d = item.link) === null || _d === void 0 ? void 0 : _d.url, target: (_e = item.link) === null || _e === void 0 ? void 0 : _e.target, children: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { className: `image-wrapper-${item.id} ${statesWrapperClassNames}`, ref:
|
|
76
|
+
return ((0, jsx_runtime_1.jsx)(LinkWrapper_1.LinkWrapper, { url: (_d = item.link) === null || _d === void 0 ? void 0 : _d.url, target: (_e = item.link) === null || _e === void 0 ? void 0 : _e.target, children: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { className: `image-wrapper-${item.id} ${statesWrapperClassNames}`, ref: setWrapperRef, style: Object.assign(Object.assign(Object.assign({}, (opacity !== undefined ? { opacity } : {})), (angle !== undefined ? { transform: `rotate(${angle}deg)` } : {})), (blur !== undefined ? { filter: `blur(${blur * 100}vw)` } : {})), children: hasGLEffect && isFXAllowed ? ((0, jsx_runtime_1.jsx)("canvas", { style: inlineStyles, ref: fxCanvas, className: `img-canvas image-${item.id} ${statesImgClassNames}`, width: rectWidth, height: rectHeight })) : ((0, jsx_runtime_1.jsx)("img", { alt: "", className: `image image-${item.id} ${statesImgClassNames}`, style: inlineStyles, ref: setImgRef, src: item.commonParams.url })) }), (0, jsx_runtime_1.jsx)(style_1.default, { id: id, children: `
|
|
72
77
|
.image-wrapper-${item.id} {
|
|
73
78
|
position: absolute;
|
|
74
79
|
width: 100%;
|
|
@@ -16,6 +16,7 @@ const useCntrlContext_1 = require("../../provider/useCntrlContext");
|
|
|
16
16
|
const useRegisterResize_1 = require("../../common/useRegisterResize");
|
|
17
17
|
const getStatesCSS_1 = require("../../utils/getStatesCSS");
|
|
18
18
|
const useStatesClassNames_1 = require("../useStatesClassNames");
|
|
19
|
+
const useStatesTransitions_1 = require("../useStatesTransitions");
|
|
19
20
|
const RectangleItem = ({ item, sectionId, onResize }) => {
|
|
20
21
|
var _a, _b;
|
|
21
22
|
const id = (0, react_1.useId)();
|
|
@@ -29,6 +30,7 @@ const RectangleItem = ({ item, sectionId, onResize }) => {
|
|
|
29
30
|
const statesClassNames = (0, useStatesClassNames_1.useStatesClassNames)(item.id, item.state, 'rectangle');
|
|
30
31
|
(0, useRegisterResize_1.useRegisterResize)(ref, onResize);
|
|
31
32
|
const backdropFilterValue = backdropBlur ? `blur(${backdropBlur * 100}vw)` : undefined;
|
|
33
|
+
(0, useStatesTransitions_1.useStatesTransitions)(ref, item.state, ['angle', 'fillColor', 'strokeWidth', 'radius', 'strokeColor', 'blur', 'backdropBlur']);
|
|
32
34
|
return ((0, jsx_runtime_1.jsx)(LinkWrapper_1.LinkWrapper, { url: (_a = item.link) === null || _a === void 0 ? void 0 : _a.url, target: (_b = item.link) === null || _b === void 0 ? void 0 : _b.target, children: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { className: `rectangle-${item.id} ${statesClassNames}`, ref: setRef, style: 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
|
|
33
35
|
? { backdropFilter: backdropFilterValue, WebkitBackdropFilter: backdropFilterValue }
|
|
34
36
|
: {})) }), (0, jsx_runtime_1.jsx)(style_1.default, { id: id, children: `
|
|
@@ -18,6 +18,7 @@ const useExemplary_1 = require("../../common/useExemplary");
|
|
|
18
18
|
const useItemAngle_1 = require("../useItemAngle");
|
|
19
19
|
const useStatesClassNames_1 = require("../useStatesClassNames");
|
|
20
20
|
const getStatesCSS_1 = require("../../utils/getStatesCSS");
|
|
21
|
+
const useStatesTransitions_1 = require("../useStatesTransitions");
|
|
21
22
|
const RichTextItem = ({ item, sectionId, onResize }) => {
|
|
22
23
|
const [content, styles] = (0, useRichTextItem_1.useRichTextItem)(item);
|
|
23
24
|
const id = (0, react_1.useId)();
|
|
@@ -30,6 +31,7 @@ const RichTextItem = ({ item, sectionId, onResize }) => {
|
|
|
30
31
|
const exemplary = (0, useExemplary_1.useExemplary)();
|
|
31
32
|
const stateClassNames = (0, useStatesClassNames_1.useStatesClassNames)(item.id, item.state, 'rich-text-wrapper');
|
|
32
33
|
(0, useRegisterResize_1.useRegisterResize)(ref, onResize);
|
|
34
|
+
(0, useStatesTransitions_1.useStatesTransitions)(ref, item.state, ['angle', 'blur', 'letterSpacing', 'wordSpacing', 'color']);
|
|
33
35
|
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} ${stateClassNames}`, style: 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` } : {})), children: content }), (0, jsx_runtime_1.jsxs)(style_1.default, { id: id, children: [styles, `${(0, sdk_1.getLayoutStyles)(layouts, layoutValues, ([area, layoutParams, states]) => {
|
|
34
36
|
const color = color_1.CntrlColor.parse(layoutParams.color);
|
|
35
37
|
const statesCSS = (0, getStatesCSS_1.getStatesCSS)(item.id, 'rich-text-wrapper', ['angle', 'blur', 'letterSpacing', 'wordSpacing', 'color'], states);
|
|
@@ -18,6 +18,7 @@ const useLayoutContext_1 = require("../useLayoutContext");
|
|
|
18
18
|
const ScrollPlaybackVideo_1 = require("../ScrollPlaybackVideo");
|
|
19
19
|
const useStatesClassNames_1 = require("../useStatesClassNames");
|
|
20
20
|
const getStatesCSS_1 = require("../../utils/getStatesCSS");
|
|
21
|
+
const useStatesTransitions_1 = require("../useStatesTransitions");
|
|
21
22
|
const VideoItem = ({ item, sectionId, onResize }) => {
|
|
22
23
|
var _a, _b, _c;
|
|
23
24
|
const id = (0, react_1.useId)();
|
|
@@ -33,6 +34,8 @@ const VideoItem = ({ item, sectionId, onResize }) => {
|
|
|
33
34
|
const statesWrapperClassNames = (0, useStatesClassNames_1.useStatesClassNames)(item.id, item.state, 'video-wrapper');
|
|
34
35
|
const statesVideoClassNames = (0, useStatesClassNames_1.useStatesClassNames)(item.id, item.state, 'video');
|
|
35
36
|
const hasScrollPlayback = scrollPlayback !== null;
|
|
37
|
+
(0, useStatesTransitions_1.useStatesTransitions)(ref, item.state, ['angle', 'opacity', 'blur']);
|
|
38
|
+
(0, useStatesTransitions_1.useStatesTransitions)(videoRef.current, item.state, ['strokeWidth', 'radius', 'strokeColor']);
|
|
36
39
|
(0, useRegisterResize_1.useRegisterResize)(ref, onResize);
|
|
37
40
|
const inlineStyles = Object.assign(Object.assign(Object.assign({}, (radius !== undefined ? { borderRadius: `${radius * 100}vw` } : {})), (strokeWidth !== undefined ? { borderWidth: `${strokeWidth * 100}vw` } : {})), (borderColor ? { borderColor: `${borderColor.toCss()}` } : {}));
|
|
38
41
|
return ((0, jsx_runtime_1.jsxs)(LinkWrapper_1.LinkWrapper, { url: (_a = item.link) === null || _a === void 0 ? void 0 : _a.url, target: (_b = item.link) === null || _b === void 0 ? void 0 : _b.target, children: [(0, jsx_runtime_1.jsx)("div", { className: `video-wrapper-${item.id} ${statesWrapperClassNames}`, ref: setRef, style: Object.assign(Object.assign(Object.assign({}, (opacity !== undefined ? { opacity } : {})), (angle !== undefined ? { transform: `rotate(${angle}deg)` } : {})), (blur !== undefined ? { filter: `blur(${blur * 100}vw)` } : {})), 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} ${statesWrapperClassNames}` })) : ((0, jsx_runtime_1.jsx)("video", { poster: (_c = item.commonParams.coverUrl) !== null && _c !== void 0 ? _c : '', ref: videoRef, autoPlay: true, muted: true, loop: true, playsInline: true, className: `video video-${item.id} ${statesVideoClassNames}`, style: inlineStyles, children: (0, jsx_runtime_1.jsx)("source", { src: item.commonParams.url }) })) }), (0, jsx_runtime_1.jsx)(style_1.default, { id: id, children: `
|
|
@@ -16,6 +16,7 @@ const useCntrlContext_1 = require("../../provider/useCntrlContext");
|
|
|
16
16
|
const useRegisterResize_1 = require("../../common/useRegisterResize");
|
|
17
17
|
const useStatesClassNames_1 = require("../useStatesClassNames");
|
|
18
18
|
const getStatesCSS_1 = require("../../utils/getStatesCSS");
|
|
19
|
+
const useStatesTransitions_1 = require("../useStatesTransitions");
|
|
19
20
|
const VimeoEmbedItem = ({ item, sectionId, onResize }) => {
|
|
20
21
|
var _a, _b, _c;
|
|
21
22
|
const id = (0, react_1.useId)();
|
|
@@ -32,6 +33,8 @@ const VimeoEmbedItem = ({ item, sectionId, onResize }) => {
|
|
|
32
33
|
const wrapperClassNames = (0, useStatesClassNames_1.useStatesClassNames)(item.id, item.state, 'embed-video-wrapper');
|
|
33
34
|
const videoClassNames = (0, useStatesClassNames_1.useStatesClassNames)(item.id, item.state, 'embed-video');
|
|
34
35
|
(0, useRegisterResize_1.useRegisterResize)(ref, onResize);
|
|
36
|
+
(0, useStatesTransitions_1.useStatesTransitions)(ref, item.state, ['angle', 'blur', 'opacity']);
|
|
37
|
+
(0, useStatesTransitions_1.useStatesTransitions)(iframeRef, item.state, ['radius']);
|
|
35
38
|
const getValidVimeoUrl = (url) => {
|
|
36
39
|
const validURL = new URL(url);
|
|
37
40
|
validURL.searchParams.append('controls', String(controls));
|
|
@@ -17,6 +17,7 @@ const useYouTubeIframeApi_1 = require("../../utils/Youtube/useYouTubeIframeApi")
|
|
|
17
17
|
const useRegisterResize_1 = require("../../common/useRegisterResize");
|
|
18
18
|
const useStatesClassNames_1 = require("../useStatesClassNames");
|
|
19
19
|
const getStatesCSS_1 = require("../../utils/getStatesCSS");
|
|
20
|
+
const useStatesTransitions_1 = require("../useStatesTransitions");
|
|
20
21
|
const YoutubeEmbedItem = ({ item, sectionId, onResize }) => {
|
|
21
22
|
var _a, _b, _c;
|
|
22
23
|
const id = (0, react_1.useId)();
|
|
@@ -26,6 +27,7 @@ const YoutubeEmbedItem = ({ item, sectionId, onResize }) => {
|
|
|
26
27
|
const angle = (0, useItemAngle_1.useItemAngle)(item, sectionId);
|
|
27
28
|
const YT = (0, useYouTubeIframeApi_1.useYouTubeIframeApi)();
|
|
28
29
|
const [div, setDiv] = (0, react_1.useState)(null);
|
|
30
|
+
const [wrapperRef, setWrapperRef] = (0, react_1.useState)(null);
|
|
29
31
|
const [player, setPlayer] = (0, react_1.useState)(undefined);
|
|
30
32
|
const [isCoverVisible, setIsCoverVisible] = (0, react_1.useState)(false);
|
|
31
33
|
const [imgRef, setImgRef] = (0, react_1.useState)(null);
|
|
@@ -33,6 +35,8 @@ const YoutubeEmbedItem = ({ item, sectionId, onResize }) => {
|
|
|
33
35
|
const wrapperClassNames = (0, useStatesClassNames_1.useStatesClassNames)(item.id, item.state, 'embed-youtube-video-wrapper');
|
|
34
36
|
const embedClassNames = (0, useStatesClassNames_1.useStatesClassNames)(item.id, item.state, 'embed');
|
|
35
37
|
(0, useRegisterResize_1.useRegisterResize)(div, onResize);
|
|
38
|
+
(0, useStatesTransitions_1.useStatesTransitions)(wrapperRef, item.state, ['angle', 'blur', 'opacity']);
|
|
39
|
+
(0, useStatesTransitions_1.useStatesTransitions)(div, item.state, ['radius']);
|
|
36
40
|
(0, react_1.useEffect)(() => {
|
|
37
41
|
const newUrl = new URL(url);
|
|
38
42
|
const videoId = (0, getValidYoutubeUrl_1.getYoutubeId)(newUrl);
|
|
@@ -83,7 +87,7 @@ const YoutubeEmbedItem = ({ item, sectionId, onResize }) => {
|
|
|
83
87
|
setIsCoverVisible(true);
|
|
84
88
|
}
|
|
85
89
|
}, []);
|
|
86
|
-
return ((0, jsx_runtime_1.jsxs)(LinkWrapper_1.LinkWrapper, { url: (_a = item.link) === null || _a === void 0 ? void 0 : _a.url, target: (_b = item.link) === null || _b === void 0 ? void 0 : _b.target, children: [(0, jsx_runtime_1.jsxs)("div", { className: `embed-youtube-video-wrapper-${item.id} ${wrapperClassNames}`, onMouseEnter: () => {
|
|
90
|
+
return ((0, jsx_runtime_1.jsxs)(LinkWrapper_1.LinkWrapper, { url: (_a = item.link) === null || _a === void 0 ? void 0 : _a.url, target: (_b = item.link) === null || _b === void 0 ? void 0 : _b.target, children: [(0, jsx_runtime_1.jsxs)("div", { ref: setWrapperRef, className: `embed-youtube-video-wrapper-${item.id} ${wrapperClassNames}`, onMouseEnter: () => {
|
|
87
91
|
if (!player || play !== 'on-hover')
|
|
88
92
|
return;
|
|
89
93
|
player.playVideo();
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useStatesTransitions = void 0;
|
|
4
|
+
const react_1 = require("react");
|
|
5
|
+
const InteractionsContext_1 = require("../provider/InteractionsContext");
|
|
6
|
+
const useCurrentLayout_1 = require("../common/useCurrentLayout");
|
|
7
|
+
function useStatesTransitions(el, state, values) {
|
|
8
|
+
const { interactionsStatesMap } = (0, react_1.useContext)(InteractionsContext_1.InteractionsContext);
|
|
9
|
+
const { layoutId } = (0, useCurrentLayout_1.useCurrentLayout)();
|
|
10
|
+
const activeStates = Object.values(interactionsStatesMap);
|
|
11
|
+
const statesForLayout = (0, react_1.useMemo)(() => layoutId ? state[layoutId] : {}, [state, layoutId]);
|
|
12
|
+
const itemStatesIds = statesForLayout ? Object.keys(statesForLayout) : [];
|
|
13
|
+
const itemActiveStateId = activeStates.find((stateId) => itemStatesIds.includes(stateId));
|
|
14
|
+
(0, react_1.useEffect)(() => {
|
|
15
|
+
if (!itemActiveStateId || !el)
|
|
16
|
+
return;
|
|
17
|
+
const state = statesForLayout[itemActiveStateId];
|
|
18
|
+
const transitionStr = getTransition(state, 'in', values);
|
|
19
|
+
const slowestProp = getSlowestProperty(state, 'in', values);
|
|
20
|
+
if (!transitionStr)
|
|
21
|
+
return;
|
|
22
|
+
el.style.transition = transitionStr;
|
|
23
|
+
el.ontransitionend = (e) => {
|
|
24
|
+
e.stopPropagation();
|
|
25
|
+
if (e.target !== el || e.propertyName !== slowestProp)
|
|
26
|
+
return;
|
|
27
|
+
el.style.transition = 'none';
|
|
28
|
+
};
|
|
29
|
+
return () => {
|
|
30
|
+
const transitionStr = getTransition(state, 'out', values);
|
|
31
|
+
const slowestProp = getSlowestProperty(state, 'out', values);
|
|
32
|
+
if (!transitionStr)
|
|
33
|
+
return;
|
|
34
|
+
el.style.transition = transitionStr;
|
|
35
|
+
el.ontransitionend = (e) => {
|
|
36
|
+
e.stopPropagation();
|
|
37
|
+
if (e.target !== el || e.propertyName !== slowestProp)
|
|
38
|
+
return;
|
|
39
|
+
el.style.transition = 'none';
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
}, [itemActiveStateId, statesForLayout, el]);
|
|
43
|
+
}
|
|
44
|
+
exports.useStatesTransitions = useStatesTransitions;
|
|
45
|
+
const CSSPropertyNameMap = {
|
|
46
|
+
'width': 'width',
|
|
47
|
+
'height': 'height',
|
|
48
|
+
'top': 'top',
|
|
49
|
+
'left': 'left',
|
|
50
|
+
'scale': 'transform',
|
|
51
|
+
'angle': 'transform',
|
|
52
|
+
'opacity': 'opacity',
|
|
53
|
+
'radius': 'border-radius',
|
|
54
|
+
'strokeWidth': 'border-width',
|
|
55
|
+
'strokeColor': 'border-color',
|
|
56
|
+
'fillColor': 'background-color',
|
|
57
|
+
'blur': 'filter',
|
|
58
|
+
'backdropBlur': 'backdrop-filter',
|
|
59
|
+
'letterSpacing': 'letter-spacing',
|
|
60
|
+
'wordSpacing': 'word-spacing',
|
|
61
|
+
'color': 'color'
|
|
62
|
+
};
|
|
63
|
+
function getTransition(state, direction, values) {
|
|
64
|
+
return Object.entries(state)
|
|
65
|
+
.filter(([key]) => values.includes(key))
|
|
66
|
+
.map(([key, params]) => {
|
|
67
|
+
const cssKey = CSSPropertyNameMap[key];
|
|
68
|
+
if (!cssKey) {
|
|
69
|
+
throw new Error(`Cannot translate "${key}" to a CSS property.`);
|
|
70
|
+
}
|
|
71
|
+
return `${cssKey} ${params[direction].duration}ms ${params[direction].timing} ${params[direction].delay}ms`;
|
|
72
|
+
}, [])
|
|
73
|
+
.join(', ');
|
|
74
|
+
}
|
|
75
|
+
function getSlowestProperty(state, direction, values) {
|
|
76
|
+
const mappedEntries = Object.entries(state)
|
|
77
|
+
.filter(([key]) => values.includes(key))
|
|
78
|
+
.map(([key, params]) => {
|
|
79
|
+
const transitionParams = params[direction];
|
|
80
|
+
return {
|
|
81
|
+
key,
|
|
82
|
+
time: transitionParams.duration + transitionParams.delay
|
|
83
|
+
};
|
|
84
|
+
});
|
|
85
|
+
if (mappedEntries.length === 0)
|
|
86
|
+
return '';
|
|
87
|
+
const { key } = mappedEntries.reduce((slowest, current) => current.time > slowest.time ? current : slowest);
|
|
88
|
+
return CSSPropertyNameMap[key];
|
|
89
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.getTransitions = exports.getStateStyles = void 0;
|
|
4
4
|
const color_1 = require("@cntrl-site/color");
|
|
5
5
|
const getItemTopStyle_1 = require("../getItemTopStyle");
|
|
6
6
|
const stateTransformationMap = {
|
|
@@ -39,41 +39,51 @@ const CSSPropertyNameMap = {
|
|
|
39
39
|
'wordSpacing': 'word-spacing',
|
|
40
40
|
'color': 'color'
|
|
41
41
|
};
|
|
42
|
-
function
|
|
42
|
+
function getStateStyles(values, state, anchorSide) {
|
|
43
43
|
if (!state)
|
|
44
|
-
return '
|
|
45
|
-
const
|
|
44
|
+
return '';
|
|
45
|
+
const stateValues = values.reduce((acc, valueName) => {
|
|
46
|
+
// @ts-ignore
|
|
46
47
|
if (valueName in state && state[valueName] !== undefined) {
|
|
47
|
-
// @ts-ignore
|
|
48
|
+
// @ts-ignore
|
|
48
49
|
const stateProperties = state[valueName];
|
|
50
|
+
const getter = stateTransformationMap[valueName];
|
|
49
51
|
return [
|
|
50
52
|
...acc,
|
|
51
|
-
|
|
53
|
+
getter(stateProperties.value, anchorSide)
|
|
52
54
|
];
|
|
53
55
|
}
|
|
54
56
|
return acc;
|
|
55
57
|
}, []);
|
|
56
|
-
if (!
|
|
57
|
-
return '
|
|
58
|
-
|
|
58
|
+
if (!stateValues.length)
|
|
59
|
+
return '';
|
|
60
|
+
// @ts-ignore
|
|
61
|
+
const transitionStr = getTransitions(values, state);
|
|
62
|
+
stateValues.push(`transition: ${transitionStr};`);
|
|
63
|
+
return stateValues.join('\n');
|
|
59
64
|
}
|
|
60
|
-
exports.
|
|
61
|
-
function
|
|
65
|
+
exports.getStateStyles = getStateStyles;
|
|
66
|
+
function getTransitions(values, state) {
|
|
62
67
|
if (!state)
|
|
63
|
-
return '';
|
|
64
|
-
const
|
|
68
|
+
return 'unset';
|
|
69
|
+
const transitionValues = values.reduce((acc, valueName) => {
|
|
70
|
+
// @ts-ignore TODO
|
|
65
71
|
if (valueName in state && state[valueName] !== undefined) {
|
|
66
72
|
// @ts-ignore TODO
|
|
67
73
|
const stateProperties = state[valueName];
|
|
68
74
|
return [
|
|
69
75
|
...acc,
|
|
70
|
-
|
|
76
|
+
// @ts-ignore
|
|
77
|
+
`${CSSPropertyNameMap[valueName]} ${stateProperties.duration}ms ${stateProperties.timing} ${stateProperties.delay}ms`
|
|
71
78
|
];
|
|
72
79
|
}
|
|
73
80
|
return acc;
|
|
74
81
|
}, []);
|
|
75
|
-
if (!
|
|
76
|
-
return '';
|
|
77
|
-
return
|
|
82
|
+
if (!transitionValues.length)
|
|
83
|
+
return 'unset';
|
|
84
|
+
return transitionValues.join(', ');
|
|
78
85
|
}
|
|
79
|
-
exports.
|
|
86
|
+
exports.getTransitions = getTransitions;
|
|
87
|
+
// export function getStateTransitions<T extends ArticleItemType>(
|
|
88
|
+
//
|
|
89
|
+
// )
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cntrl-site/sdk-nextjs",
|
|
3
|
-
"version": "1.0.19-alpha.
|
|
3
|
+
"version": "1.0.19-alpha.2",
|
|
4
4
|
"description": "SDK for Next.js",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "src/index.ts",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"@cntrl-site/color": "^1.0.0",
|
|
25
25
|
"@cntrl-site/effects": "^1.2.0",
|
|
26
|
-
"@cntrl-site/sdk": "^1.12.4-alpha.
|
|
26
|
+
"@cntrl-site/sdk": "^1.12.4-alpha.8",
|
|
27
27
|
"@types/vimeo__player": "^2.18.0",
|
|
28
28
|
"@vimeo/player": "^2.20.1",
|
|
29
29
|
"html-react-parser": "^3.0.1",
|
package/src/components/Item.tsx
CHANGED
|
@@ -34,6 +34,7 @@ import { KeyframesContext } from '../provider/KeyframesContext';
|
|
|
34
34
|
import { InteractionsContext } from '../provider/InteractionsContext';
|
|
35
35
|
import { getStatesCSS } from '../utils/getStatesCSS';
|
|
36
36
|
import { useStatesClassNames } from './useStatesClassNames';
|
|
37
|
+
import { useStatesTransitions } from './useStatesTransitions';
|
|
37
38
|
|
|
38
39
|
export interface ItemProps<I extends ItemAny> {
|
|
39
40
|
item: I;
|
|
@@ -81,6 +82,7 @@ const noop = () => null;
|
|
|
81
82
|
|
|
82
83
|
export const Item: FC<ItemWrapperProps> = ({ item, sectionId, articleHeight, isInGroup = false }) => {
|
|
83
84
|
const itemWrapperRef = useRef<HTMLDivElement | null>(null);
|
|
85
|
+
const itemInnerRef = useRef<HTMLDivElement | null>(null);
|
|
84
86
|
const rectObserver = useContext(ArticleRectContext);
|
|
85
87
|
const keyframesRepo = useContext(KeyframesContext);
|
|
86
88
|
const id = useId();
|
|
@@ -134,6 +136,8 @@ export const Item: FC<ItemWrapperProps> = ({ item, sectionId, articleHeight, isI
|
|
|
134
136
|
const isRichText = isItemType(item, ArticleItemType.RichText);
|
|
135
137
|
const innerStatesClassNames = useStatesClassNames(item.id, item.state, 'item-inner');
|
|
136
138
|
const wrapperStatesClassNames = useStatesClassNames(item.id, item.state, 'item-wrapper');
|
|
139
|
+
useStatesTransitions(itemWrapperRef.current, item.state, ['top', 'left']);
|
|
140
|
+
useStatesTransitions(itemInnerRef.current, item.state, ['width', 'height', 'scale']);
|
|
137
141
|
return (
|
|
138
142
|
<div
|
|
139
143
|
className={`item-wrapper-${item.id} ${wrapperStatesClassNames}`}
|
|
@@ -157,6 +161,7 @@ export const Item: FC<ItemWrapperProps> = ({ item, sectionId, articleHeight, isI
|
|
|
157
161
|
<RichTextWrapper isRichText={isRichText}>
|
|
158
162
|
<div
|
|
159
163
|
className={`item-${item.id}-inner ${innerStatesClassNames}`}
|
|
164
|
+
ref={itemInnerRef}
|
|
160
165
|
onClick={() => {
|
|
161
166
|
const trigger = getItemTrigger(item.id, 'click');
|
|
162
167
|
if (!trigger) return;
|
|
@@ -211,7 +216,6 @@ export const Item: FC<ItemWrapperProps> = ({ item, sectionId, articleHeight, isI
|
|
|
211
216
|
height: ${sizingAxis.y === 'manual' ? `${area.height * 100}vw` : 'unset'};
|
|
212
217
|
transform-origin: ${ScaleAnchorMap[scaleAnchor]};
|
|
213
218
|
transform: scale(${area.scale});
|
|
214
|
-
transition: all 0.2s ease;
|
|
215
219
|
}
|
|
216
220
|
.item-wrapper-${item.id} {
|
|
217
221
|
position: ${area.positionType === PositionType.ScreenBased ? 'fixed': 'absolute'};
|
|
@@ -221,7 +225,6 @@ export const Item: FC<ItemWrapperProps> = ({ item, sectionId, articleHeight, isI
|
|
|
221
225
|
bottom: ${isScreenBasedBottom ? `${-area.top * 100}vw` : 'unset'};
|
|
222
226
|
top: ${isScreenBasedBottom ? 'unset' : getItemTopStyle(area.top, area.anchorSide)};
|
|
223
227
|
left: ${area.left * 100}vw;
|
|
224
|
-
transition: all 0.2s ease;
|
|
225
228
|
}
|
|
226
229
|
${statesWrapperCSS}
|
|
227
230
|
${statesInnerCSS}
|
|
@@ -9,6 +9,7 @@ import { LinkWrapper } from '../LinkWrapper';
|
|
|
9
9
|
import { useCodeEmbedItem } from './useCodeEmbedItem';
|
|
10
10
|
import { getStatesCSS } from '../../utils/getStatesCSS';
|
|
11
11
|
import { useStatesClassNames } from '../useStatesClassNames';
|
|
12
|
+
import { useStatesTransitions } from '../useStatesTransitions';
|
|
12
13
|
|
|
13
14
|
const stylesMap = {
|
|
14
15
|
[AreaAnchor.TopLeft]: {},
|
|
@@ -33,6 +34,7 @@ export const CodeEmbedItem: FC<ItemProps<TCodeEmbedItem>> = ({ item, sectionId,
|
|
|
33
34
|
const pos = stylesMap[anchor];
|
|
34
35
|
const layoutValues: Record<string, any>[] = [item.area, item.layoutParams, item.state];
|
|
35
36
|
const statesClassNames = useStatesClassNames(item.id, item.state, 'embed-wrapper');
|
|
37
|
+
useStatesTransitions(ref!, item.state, ['angle', 'blur', 'opacity']);
|
|
36
38
|
|
|
37
39
|
useEffect(() => {
|
|
38
40
|
if (!ref) return;
|
|
@@ -7,6 +7,7 @@ import { useRegisterResize } from "../../common/useRegisterResize";
|
|
|
7
7
|
import { useItemAngle } from '../useItemAngle';
|
|
8
8
|
import { useStatesClassNames } from '../useStatesClassNames';
|
|
9
9
|
import { getStatesCSS } from '../../utils/getStatesCSS';
|
|
10
|
+
import { useStatesTransitions } from '../useStatesTransitions';
|
|
10
11
|
|
|
11
12
|
export const CustomItem: FC<ItemProps<TCustomItem>> = ({ item, onResize, sectionId }) => {
|
|
12
13
|
const sdk = useCntrlContext();
|
|
@@ -17,6 +18,7 @@ export const CustomItem: FC<ItemProps<TCustomItem>> = ({ item, onResize, section
|
|
|
17
18
|
const [ref, setRef] = useState<HTMLDivElement | null>(null);
|
|
18
19
|
useRegisterResize(ref, onResize);
|
|
19
20
|
const statesClassNames = useStatesClassNames(item.id, item.state, 'custom-component');
|
|
21
|
+
useStatesTransitions(ref, item.state, ['angle'])
|
|
20
22
|
if (!component) return null;
|
|
21
23
|
return (
|
|
22
24
|
<>
|
|
@@ -9,6 +9,7 @@ import { useItemAngle } from '../useItemAngle';
|
|
|
9
9
|
import { useGroupItem } from './useGroupItem';
|
|
10
10
|
import { useStatesClassNames } from '../useStatesClassNames';
|
|
11
11
|
import { getStatesCSS } from '../../utils/getStatesCSS';
|
|
12
|
+
import { useStatesTransitions } from '../useStatesTransitions';
|
|
12
13
|
|
|
13
14
|
export const GroupItem: FC<ItemProps<TGroupItem>> = ({ item, sectionId, onResize, articleHeight }) => {
|
|
14
15
|
const id = useId();
|
|
@@ -20,6 +21,7 @@ export const GroupItem: FC<ItemProps<TGroupItem>> = ({ item, sectionId, onResize
|
|
|
20
21
|
const statesClassNames = useStatesClassNames(item.id, item.state, 'group');
|
|
21
22
|
const [ref, setRef] = useState<HTMLDivElement | null>(null);
|
|
22
23
|
useRegisterResize(ref, onResize);
|
|
24
|
+
useStatesTransitions(ref!, item.state, ['opacity', 'angle'])
|
|
23
25
|
|
|
24
26
|
return (
|
|
25
27
|
<LinkWrapper url={item.link?.url} target={item.link?.target}>
|
|
@@ -13,6 +13,7 @@ import { useElementRect } from '../../utils/useElementRect';
|
|
|
13
13
|
import { useLayoutContext } from '../useLayoutContext';
|
|
14
14
|
import { useStatesClassNames } from '../useStatesClassNames';
|
|
15
15
|
import { getStatesCSS } from '../../utils/getStatesCSS';
|
|
16
|
+
import { useStatesTransitions } from '../useStatesTransitions';
|
|
16
17
|
|
|
17
18
|
const baseVariables = `precision mediump float;
|
|
18
19
|
uniform sampler2D u_image;
|
|
@@ -30,8 +31,9 @@ export const ImageItem: FC<ItemProps<TImageItem>> = ({ item, sectionId, onResize
|
|
|
30
31
|
const { radius, strokeWidth, opacity, strokeColor, blur } = useFileItem(item, sectionId);
|
|
31
32
|
const angle = useItemAngle(item, sectionId);
|
|
32
33
|
const borderColor = useMemo(() => strokeColor ? CntrlColor.parse(strokeColor) : undefined, [strokeColor]);
|
|
33
|
-
const [
|
|
34
|
-
|
|
34
|
+
const [wrapperRef, setWrapperRef] = useState<HTMLDivElement | null>(null);
|
|
35
|
+
const [imgRef, setImgRef] = useState<HTMLImageElement | HTMLCanvasElement | null>(null);
|
|
36
|
+
useRegisterResize(wrapperRef, onResize);
|
|
35
37
|
const { url, hasGLEffect, fragmentShader, FXControls, FXCursor } = item.commonParams;
|
|
36
38
|
const fxCanvas = useRef<HTMLCanvasElement | null>(null);
|
|
37
39
|
const isInitialRef = useRef(true);
|
|
@@ -50,6 +52,9 @@ export const ImageItem: FC<ItemProps<TImageItem>> = ({ item, sectionId, onResize
|
|
|
50
52
|
const height = area && exemplary ? area.height * exemplary : 0;
|
|
51
53
|
const statesWrapperClassNames = useStatesClassNames(item.id, item.state, 'image-wrapper');
|
|
52
54
|
const statesImgClassNames = useStatesClassNames(item.id, item.state, 'image');
|
|
55
|
+
useStatesTransitions(wrapperRef, item.state, ['angle', 'opacity', 'blur']);
|
|
56
|
+
useStatesTransitions(imgRef, item.state, ['strokeWidth', 'radius', 'strokeColor']);
|
|
57
|
+
useStatesTransitions(fxCanvas.current, item.state, ['strokeWidth', 'radius', 'strokeColor']);
|
|
53
58
|
useEffect(() => {
|
|
54
59
|
isInitialRef.current = false;
|
|
55
60
|
}, []);
|
|
@@ -65,7 +70,7 @@ export const ImageItem: FC<ItemProps<TImageItem>> = ({ item, sectionId, onResize
|
|
|
65
70
|
width,
|
|
66
71
|
height
|
|
67
72
|
);
|
|
68
|
-
const rect = useElementRect(
|
|
73
|
+
const rect = useElementRect(wrapperRef);
|
|
69
74
|
const rectWidth = Math.floor(rect?.width ?? 0);
|
|
70
75
|
const rectHeight = Math.floor(rect?.height ?? 0);
|
|
71
76
|
const inlineStyles = {
|
|
@@ -78,7 +83,7 @@ export const ImageItem: FC<ItemProps<TImageItem>> = ({ item, sectionId, onResize
|
|
|
78
83
|
<>
|
|
79
84
|
<div
|
|
80
85
|
className={`image-wrapper-${item.id} ${statesWrapperClassNames}`}
|
|
81
|
-
ref={
|
|
86
|
+
ref={setWrapperRef}
|
|
82
87
|
style={{
|
|
83
88
|
...(opacity !== undefined ? { opacity } : {}),
|
|
84
89
|
...(angle !== undefined ? { transform: `rotate(${angle}deg)` } : {}),
|
|
@@ -98,6 +103,7 @@ export const ImageItem: FC<ItemProps<TImageItem>> = ({ item, sectionId, onResize
|
|
|
98
103
|
alt=""
|
|
99
104
|
className={`image image-${item.id} ${statesImgClassNames}`}
|
|
100
105
|
style={inlineStyles}
|
|
106
|
+
ref={setImgRef}
|
|
101
107
|
src={item.commonParams.url}
|
|
102
108
|
/>
|
|
103
109
|
)}
|
|
@@ -10,6 +10,7 @@ import { useCntrlContext } from '../../provider/useCntrlContext';
|
|
|
10
10
|
import { useRegisterResize } from "../../common/useRegisterResize";
|
|
11
11
|
import { getStatesCSS } from '../../utils/getStatesCSS';
|
|
12
12
|
import { useStatesClassNames } from '../useStatesClassNames';
|
|
13
|
+
import { useStatesTransitions } from '../useStatesTransitions';
|
|
13
14
|
|
|
14
15
|
export const RectangleItem: FC<ItemProps<TRectangleItem>> = ({ item, sectionId, onResize }) => {
|
|
15
16
|
const id = useId();
|
|
@@ -23,6 +24,7 @@ export const RectangleItem: FC<ItemProps<TRectangleItem>> = ({ item, sectionId,
|
|
|
23
24
|
const statesClassNames = useStatesClassNames(item.id, item.state, 'rectangle');
|
|
24
25
|
useRegisterResize(ref, onResize);
|
|
25
26
|
const backdropFilterValue = backdropBlur ? `blur(${backdropBlur * 100}vw)`: undefined;
|
|
27
|
+
useStatesTransitions(ref, item.state, ['angle', 'fillColor', 'strokeWidth', 'radius', 'strokeColor', 'blur', 'backdropBlur']);
|
|
26
28
|
|
|
27
29
|
return (
|
|
28
30
|
<LinkWrapper url={item.link?.url} target={item.link?.target}>
|
|
@@ -12,6 +12,7 @@ import { useExemplary } from '../../common/useExemplary';
|
|
|
12
12
|
import { useItemAngle } from '../useItemAngle';
|
|
13
13
|
import { useStatesClassNames } from '../useStatesClassNames';
|
|
14
14
|
import { getStatesCSS } from '../../utils/getStatesCSS';
|
|
15
|
+
import { useStatesTransitions } from '../useStatesTransitions';
|
|
15
16
|
|
|
16
17
|
export const RichTextItem: FC<ItemProps<TRichTextItem>> = ({ item, sectionId, onResize }) => {
|
|
17
18
|
const [content, styles] = useRichTextItem(item);
|
|
@@ -25,6 +26,7 @@ export const RichTextItem: FC<ItemProps<TRichTextItem>> = ({ item, sectionId, on
|
|
|
25
26
|
const exemplary = useExemplary();
|
|
26
27
|
const stateClassNames = useStatesClassNames(item.id, item.state, 'rich-text-wrapper');
|
|
27
28
|
useRegisterResize(ref, onResize);
|
|
29
|
+
useStatesTransitions(ref, item.state, ['angle', 'blur', 'letterSpacing', 'wordSpacing', 'color']);
|
|
28
30
|
|
|
29
31
|
return (
|
|
30
32
|
<>
|
|
@@ -12,6 +12,7 @@ import { useLayoutContext } from '../useLayoutContext';
|
|
|
12
12
|
import { ScrollPlaybackVideo } from '../ScrollPlaybackVideo';
|
|
13
13
|
import { useStatesClassNames } from '../useStatesClassNames';
|
|
14
14
|
import { getStatesCSS } from '../../utils/getStatesCSS';
|
|
15
|
+
import { useStatesTransitions } from '../useStatesTransitions';
|
|
15
16
|
|
|
16
17
|
export const VideoItem: FC<ItemProps<TVideoItem>> = ({ item, sectionId, onResize }) => {
|
|
17
18
|
const id = useId();
|
|
@@ -27,6 +28,8 @@ export const VideoItem: FC<ItemProps<TVideoItem>> = ({ item, sectionId, onResize
|
|
|
27
28
|
const statesWrapperClassNames = useStatesClassNames(item.id, item.state, 'video-wrapper');
|
|
28
29
|
const statesVideoClassNames = useStatesClassNames(item.id, item.state, 'video');
|
|
29
30
|
const hasScrollPlayback = scrollPlayback !== null;
|
|
31
|
+
useStatesTransitions(ref, item.state, ['angle', 'opacity', 'blur']);
|
|
32
|
+
useStatesTransitions(videoRef.current, item.state, ['strokeWidth', 'radius', 'strokeColor']);
|
|
30
33
|
useRegisterResize(ref, onResize);
|
|
31
34
|
const inlineStyles = {
|
|
32
35
|
...(radius !== undefined ? { borderRadius: `${radius * 100}vw` } : {}),
|
|
@@ -10,6 +10,7 @@ import { useCntrlContext } from '../../provider/useCntrlContext';
|
|
|
10
10
|
import { useRegisterResize } from "../../common/useRegisterResize";
|
|
11
11
|
import { useStatesClassNames } from '../useStatesClassNames';
|
|
12
12
|
import { getStatesCSS } from '../../utils/getStatesCSS';
|
|
13
|
+
import { useStatesTransitions } from '../useStatesTransitions';
|
|
13
14
|
|
|
14
15
|
export const VimeoEmbedItem: FC<ItemProps<TVimeoEmbedItem>> = ({ item, sectionId, onResize }) => {
|
|
15
16
|
const id = useId();
|
|
@@ -26,6 +27,8 @@ export const VimeoEmbedItem: FC<ItemProps<TVimeoEmbedItem>> = ({ item, sectionId
|
|
|
26
27
|
const wrapperClassNames = useStatesClassNames(item.id, item.state, 'embed-video-wrapper');
|
|
27
28
|
const videoClassNames = useStatesClassNames(item.id, item.state, 'embed-video');
|
|
28
29
|
useRegisterResize(ref, onResize);
|
|
30
|
+
useStatesTransitions(ref, item.state, ['angle', 'blur', 'opacity']);
|
|
31
|
+
useStatesTransitions(iframeRef, item.state, ['radius']);
|
|
29
32
|
const getValidVimeoUrl = (url: string): string => {
|
|
30
33
|
const validURL = new URL(url);
|
|
31
34
|
validURL.searchParams.append('controls', String(controls));
|
|
@@ -12,6 +12,7 @@ import { YTPlayer } from '../../utils/Youtube/YoutubeIframeApi';
|
|
|
12
12
|
import { useRegisterResize } from "../../common/useRegisterResize";
|
|
13
13
|
import { useStatesClassNames } from '../useStatesClassNames';
|
|
14
14
|
import { getStatesCSS } from '../../utils/getStatesCSS';
|
|
15
|
+
import { useStatesTransitions } from '../useStatesTransitions';
|
|
15
16
|
|
|
16
17
|
export const YoutubeEmbedItem: FC<ItemProps<TYoutubeEmbedItem>> = ({ item, sectionId, onResize }) => {
|
|
17
18
|
const id = useId();
|
|
@@ -21,6 +22,7 @@ export const YoutubeEmbedItem: FC<ItemProps<TYoutubeEmbedItem>> = ({ item, secti
|
|
|
21
22
|
const angle = useItemAngle(item, sectionId);
|
|
22
23
|
const YT = useYouTubeIframeApi();
|
|
23
24
|
const [div, setDiv] = useState<HTMLDivElement | null>(null);
|
|
25
|
+
const [wrapperRef, setWrapperRef] = useState<HTMLDivElement | null>(null);
|
|
24
26
|
const [player, setPlayer] = useState<YTPlayer | undefined>(undefined);
|
|
25
27
|
const [isCoverVisible, setIsCoverVisible] = useState(false);
|
|
26
28
|
const [imgRef, setImgRef] = useState<HTMLImageElement | null>(null);
|
|
@@ -28,7 +30,8 @@ export const YoutubeEmbedItem: FC<ItemProps<TYoutubeEmbedItem>> = ({ item, secti
|
|
|
28
30
|
const wrapperClassNames = useStatesClassNames(item.id, item.state, 'embed-youtube-video-wrapper');
|
|
29
31
|
const embedClassNames = useStatesClassNames(item.id, item.state, 'embed');
|
|
30
32
|
useRegisterResize(div, onResize);
|
|
31
|
-
|
|
33
|
+
useStatesTransitions(wrapperRef, item.state, ['angle', 'blur', 'opacity']);
|
|
34
|
+
useStatesTransitions(div, item.state, ['radius']);
|
|
32
35
|
useEffect(() => {
|
|
33
36
|
const newUrl = new URL(url);
|
|
34
37
|
const videoId = getYoutubeId(newUrl);
|
|
@@ -81,6 +84,7 @@ export const YoutubeEmbedItem: FC<ItemProps<TYoutubeEmbedItem>> = ({ item, secti
|
|
|
81
84
|
return (
|
|
82
85
|
<LinkWrapper url={item.link?.url} target={item.link?.target}>
|
|
83
86
|
<div
|
|
87
|
+
ref={setWrapperRef}
|
|
84
88
|
className={`embed-youtube-video-wrapper-${item.id} ${wrapperClassNames}`}
|
|
85
89
|
onMouseEnter={() => {
|
|
86
90
|
if (!player || play !== 'on-hover') return;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { ArticleItemType, ItemState, ItemStateParams, ItemStatesMap } from '@cntrl-site/sdk';
|
|
2
|
+
import { useContext, useEffect, useMemo } from 'react';
|
|
3
|
+
import { InteractionsContext } from '../provider/InteractionsContext';
|
|
4
|
+
import { useCurrentLayout } from '../common/useCurrentLayout';
|
|
5
|
+
|
|
6
|
+
type AllKeys<T> = T extends any ? keyof T : never;
|
|
7
|
+
type StatePropertyKey = AllKeys<ItemStatesMap[keyof ItemStatesMap]>;
|
|
8
|
+
|
|
9
|
+
export function useStatesTransitions(
|
|
10
|
+
el: HTMLElement | null,
|
|
11
|
+
state: ItemState<ArticleItemType>,
|
|
12
|
+
values: StatePropertyKey[]
|
|
13
|
+
) {
|
|
14
|
+
const { interactionsStatesMap } = useContext(InteractionsContext);
|
|
15
|
+
const { layoutId } = useCurrentLayout();
|
|
16
|
+
const activeStates = Object.values(interactionsStatesMap);
|
|
17
|
+
const statesForLayout = useMemo(() => layoutId ? state[layoutId] : {}, [state, layoutId]);
|
|
18
|
+
const itemStatesIds = statesForLayout ? Object.keys(statesForLayout) : [];
|
|
19
|
+
const itemActiveStateId = activeStates.find((stateId) => itemStatesIds.includes(stateId));
|
|
20
|
+
useEffect(() => {
|
|
21
|
+
if (!itemActiveStateId || !el) return;
|
|
22
|
+
const state = statesForLayout[itemActiveStateId];
|
|
23
|
+
const transitionStr = getTransition(state, 'in', values);
|
|
24
|
+
const slowestProp = getSlowestProperty(state, 'in', values);
|
|
25
|
+
if (!transitionStr) return;
|
|
26
|
+
el.style.transition = transitionStr;
|
|
27
|
+
el.ontransitionend = (e) => {
|
|
28
|
+
e.stopPropagation();
|
|
29
|
+
if (e.target !== el || e.propertyName !== slowestProp) return;
|
|
30
|
+
el.style.transition = 'none';
|
|
31
|
+
};
|
|
32
|
+
return () => {
|
|
33
|
+
const transitionStr = getTransition(state, 'out', values);
|
|
34
|
+
const slowestProp = getSlowestProperty(state, 'out', values);
|
|
35
|
+
if (!transitionStr) return;
|
|
36
|
+
el.style.transition = transitionStr;
|
|
37
|
+
el.ontransitionend = (e) => {
|
|
38
|
+
e.stopPropagation();
|
|
39
|
+
if (e.target !== el || e.propertyName !== slowestProp) return;
|
|
40
|
+
el.style.transition = 'none';
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
}, [itemActiveStateId, statesForLayout, el]);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const CSSPropertyNameMap: Record<keyof ItemState<ArticleItemType>, string> = {
|
|
47
|
+
'width': 'width',
|
|
48
|
+
'height': 'height',
|
|
49
|
+
'top': 'top',
|
|
50
|
+
'left': 'left',
|
|
51
|
+
'scale': 'transform',
|
|
52
|
+
'angle': 'transform',
|
|
53
|
+
'opacity': 'opacity',
|
|
54
|
+
'radius': 'border-radius',
|
|
55
|
+
'strokeWidth': 'border-width',
|
|
56
|
+
'strokeColor': 'border-color',
|
|
57
|
+
'fillColor': 'background-color',
|
|
58
|
+
'blur': 'filter',
|
|
59
|
+
'backdropBlur': 'backdrop-filter',
|
|
60
|
+
'letterSpacing': 'letter-spacing',
|
|
61
|
+
'wordSpacing': 'word-spacing',
|
|
62
|
+
'color': 'color'
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
function getTransition(
|
|
66
|
+
state: ItemStateParams,
|
|
67
|
+
direction: 'in' | 'out',
|
|
68
|
+
values: string[]
|
|
69
|
+
) {
|
|
70
|
+
return Object.entries(state)
|
|
71
|
+
.filter(([key]) => values.includes(key))
|
|
72
|
+
.map(([key, params]) => {
|
|
73
|
+
const cssKey = CSSPropertyNameMap[key];
|
|
74
|
+
if (!cssKey) {
|
|
75
|
+
throw new Error(`Cannot translate "${key}" to a CSS property.`);
|
|
76
|
+
}
|
|
77
|
+
return `${cssKey} ${params[direction].duration}ms ${params[direction].timing} ${params[direction].delay}ms`;
|
|
78
|
+
}, [])
|
|
79
|
+
.join(', ');
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function getSlowestProperty(state: ItemStateParams, direction: 'in' | 'out', values: string[]): string {
|
|
83
|
+
const mappedEntries = Object.entries(state)
|
|
84
|
+
.filter(([key]) => values.includes(key))
|
|
85
|
+
.map(([key, params]) => {
|
|
86
|
+
const transitionParams = params[direction];
|
|
87
|
+
return {
|
|
88
|
+
key,
|
|
89
|
+
time: transitionParams.duration + transitionParams.delay
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
if (mappedEntries.length === 0) return '';
|
|
93
|
+
const { key } = mappedEntries.reduce((slowest, current) => current.time > slowest.time ? current : slowest);
|
|
94
|
+
return CSSPropertyNameMap[key];
|
|
95
|
+
}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { StateParams, ArticleItemType, AnchorSide, ItemState } from '@cntrl-site/sdk';
|
|
1
|
+
import { StateParams, ArticleItemType, AnchorSide, ItemState, ItemStatesMap } from '@cntrl-site/sdk';
|
|
2
2
|
import { CntrlColor } from '@cntrl-site/color';
|
|
3
3
|
import { getItemTopStyle } from '../getItemTopStyle';
|
|
4
4
|
|
|
5
|
-
type UnionToIntersection<U> = (U extends any ? (arg: U) => void : never) extends (arg: infer I) => void ? I : never;
|
|
6
5
|
type StateParamsGetter = (value: any, anchorSide?: AnchorSide) => string;
|
|
6
|
+
type AllKeys<T> = T extends any ? keyof T : never;
|
|
7
|
+
type StatePropertyKey = AllKeys<ItemStatesMap[keyof ItemStatesMap]>;
|
|
7
8
|
|
|
8
|
-
const stateTransformationMap: Record<
|
|
9
|
+
const stateTransformationMap: Record<StatePropertyKey, StateParamsGetter> = {
|
|
9
10
|
'width': (width: number) => `width: ${width * 100}vw !important;`,
|
|
10
11
|
'height': (height: number) => `height: ${height * 100}vw !important;`,
|
|
11
12
|
'top': (top: number, anchorSide?: AnchorSide) => `top: ${getItemTopStyle(top, anchorSide)} !important;`,
|
|
@@ -43,44 +44,56 @@ const CSSPropertyNameMap: Record<keyof ItemState<ArticleItemType>, string> = {
|
|
|
43
44
|
'color': 'color'
|
|
44
45
|
};
|
|
45
46
|
|
|
46
|
-
export function
|
|
47
|
-
values: Array<
|
|
48
|
-
state?:
|
|
47
|
+
export function getStateStyles<T extends ArticleItemType>(
|
|
48
|
+
values: Array<StatePropertyKey>,
|
|
49
|
+
state?: ItemStatesMap[T],
|
|
50
|
+
anchorSide?: AnchorSide
|
|
49
51
|
): string {
|
|
50
|
-
if (!state) return '
|
|
51
|
-
|
|
52
|
+
if (!state) return '';
|
|
53
|
+
|
|
54
|
+
const stateValues = values.reduce<string[]>((acc, valueName) => {
|
|
55
|
+
// @ts-ignore
|
|
52
56
|
if (valueName in state && state[valueName] !== undefined) {
|
|
53
|
-
// @ts-ignore
|
|
57
|
+
// @ts-ignore
|
|
54
58
|
const stateProperties = state[valueName] as StateParams<string | number>;
|
|
59
|
+
const getter = stateTransformationMap[valueName] as StateParamsGetter;
|
|
55
60
|
return [
|
|
56
61
|
...acc,
|
|
57
|
-
|
|
62
|
+
getter(stateProperties.value, anchorSide)
|
|
58
63
|
];
|
|
59
64
|
}
|
|
60
65
|
return acc;
|
|
61
66
|
}, []);
|
|
62
|
-
|
|
63
|
-
|
|
67
|
+
|
|
68
|
+
if (!stateValues.length) return '';
|
|
69
|
+
// @ts-ignore
|
|
70
|
+
const transitionStr = getTransitions(values, state);
|
|
71
|
+
stateValues.push(`transition: ${transitionStr};`);
|
|
72
|
+
return stateValues.join('\n');
|
|
64
73
|
}
|
|
65
74
|
|
|
66
|
-
export function
|
|
67
|
-
values: Array<
|
|
68
|
-
state?:
|
|
69
|
-
anchorSide?: AnchorSide
|
|
75
|
+
export function getTransitions<T extends ArticleItemType>(
|
|
76
|
+
values: Array<StatePropertyKey>,
|
|
77
|
+
state?: ItemStatesMap[T]
|
|
70
78
|
): string {
|
|
71
|
-
if (!state) return '';
|
|
72
|
-
const
|
|
79
|
+
if (!state) return 'unset';
|
|
80
|
+
const transitionValues = values.reduce<string[]>((acc, valueName) => {
|
|
81
|
+
// @ts-ignore TODO
|
|
73
82
|
if (valueName in state && state[valueName] !== undefined) {
|
|
74
83
|
// @ts-ignore TODO
|
|
75
84
|
const stateProperties = state[valueName] as StateParams<string | number>;
|
|
76
85
|
return [
|
|
77
86
|
...acc,
|
|
78
|
-
|
|
87
|
+
// @ts-ignore
|
|
88
|
+
`${CSSPropertyNameMap[valueName]} ${stateProperties!.duration}ms ${stateProperties!.timing} ${stateProperties!.delay}ms`
|
|
79
89
|
];
|
|
80
90
|
}
|
|
81
91
|
return acc;
|
|
82
92
|
}, []);
|
|
83
|
-
if (!
|
|
84
|
-
return
|
|
93
|
+
if (!transitionValues.length) return 'unset';
|
|
94
|
+
return transitionValues.join(', ');
|
|
85
95
|
}
|
|
86
96
|
|
|
97
|
+
// export function getStateTransitions<T extends ArticleItemType>(
|
|
98
|
+
//
|
|
99
|
+
// )
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
import { AnchorSide, ArticleItemType,
|
|
1
|
+
import { AnchorSide, ArticleItemType, ItemStatesMap } from '@cntrl-site/sdk';
|
|
2
2
|
import { getStateStyles } from './StateStyles/StateStyles';
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
type AllKeys<T> = T extends any ? keyof T : never;
|
|
5
|
+
type StatePropertyKey = AllKeys<ItemStatesMap[keyof ItemStatesMap]>;
|
|
6
|
+
|
|
7
|
+
export function getStatesCSS<T extends ArticleItemType>(
|
|
5
8
|
itemId: string,
|
|
6
9
|
classNamePrefix: string,
|
|
7
|
-
keys: Array<
|
|
8
|
-
states: Record<string,
|
|
10
|
+
keys: Array<StatePropertyKey>,
|
|
11
|
+
states: Record<string, ItemStatesMap[T]> | undefined,
|
|
9
12
|
anchorSide?: AnchorSide
|
|
10
13
|
) {
|
|
11
14
|
return states
|