@cntrl-site/sdk-nextjs 1.0.19-alpha.2 → 1.0.19
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/jest.config.js +2 -2
- package/lib/components/Article.js +8 -9
- package/lib/components/Head.js +1 -1
- package/lib/components/Item.js +13 -33
- package/lib/components/items/CodeEmbedItem.js +8 -11
- package/lib/components/items/CustomItem.js +7 -10
- package/lib/components/items/GroupItem.js +8 -11
- package/lib/components/items/ImageItem.js +15 -21
- package/lib/components/items/RectangleItem.js +8 -11
- package/lib/components/items/RichTextItem.js +7 -10
- package/lib/components/items/VideoItem.js +12 -16
- package/lib/components/items/VimeoEmbed.js +15 -19
- package/lib/components/items/YoutubeEmbed.js +13 -18
- package/lib/utils/{StateStyles/StateStyles.js → HoverStyles/HoverStyles.js} +24 -36
- package/package.json +4 -7
- package/src/components/Article.tsx +28 -31
- package/src/components/ArticleWrapper.tsx +2 -1
- package/src/components/Head.tsx +1 -0
- package/src/components/Item.tsx +18 -38
- package/src/components/items/CodeEmbedItem.tsx +9 -12
- package/src/components/items/CustomItem.tsx +9 -12
- package/src/components/items/GroupItem.tsx +9 -12
- package/src/components/items/ImageItem.tsx +19 -26
- package/src/components/items/RectangleItem.tsx +10 -13
- package/src/components/items/RichTextItem.tsx +9 -17
- package/src/components/items/VideoItem.tsx +15 -19
- package/src/components/items/VimeoEmbed.tsx +16 -20
- package/src/components/items/YoutubeEmbed.tsx +16 -20
- package/src/utils/{StateStyles/StateStyles.ts → HoverStyles/HoverStyles.ts} +27 -41
- package/lib/components/useStatesClassNames.js +0 -18
- package/lib/components/useStatesTransitions.js +0 -89
- package/lib/provider/InteractionsContext.js +0 -45
- package/lib/utils/getStatesCSS.js +0 -16
- package/src/components/useStatesClassNames.ts +0 -23
- package/src/components/useStatesTransitions.ts +0 -95
- package/src/provider/InteractionsContext.test.tsx +0 -97
- package/src/provider/InteractionsContext.tsx +0 -65
- package/src/utils/getStatesCSS.ts +0 -24
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
import React, { FC, useId, useState } from 'react';
|
|
2
2
|
import { Item, ItemProps } from '../Item';
|
|
3
3
|
import JSXStyle from 'styled-jsx/style';
|
|
4
|
-
import { getLayoutStyles, GroupItem as TGroupItem } from '@cntrl-site/sdk';
|
|
4
|
+
import { ArticleItemType, getLayoutStyles, GroupItem as TGroupItem } from '@cntrl-site/sdk';
|
|
5
|
+
import { getHoverStyles, getTransitions } from '../../utils/HoverStyles/HoverStyles';
|
|
5
6
|
import { LinkWrapper } from '../LinkWrapper';
|
|
6
7
|
import { useRegisterResize } from '../../common/useRegisterResize';
|
|
7
8
|
import { useCntrlContext } from '../../provider/useCntrlContext';
|
|
8
9
|
import { useItemAngle } from '../useItemAngle';
|
|
9
10
|
import { useGroupItem } from './useGroupItem';
|
|
10
|
-
import { useStatesClassNames } from '../useStatesClassNames';
|
|
11
|
-
import { getStatesCSS } from '../../utils/getStatesCSS';
|
|
12
|
-
import { useStatesTransitions } from '../useStatesTransitions';
|
|
13
11
|
|
|
14
12
|
export const GroupItem: FC<ItemProps<TGroupItem>> = ({ item, sectionId, onResize, articleHeight }) => {
|
|
15
13
|
const id = useId();
|
|
@@ -17,17 +15,15 @@ export const GroupItem: FC<ItemProps<TGroupItem>> = ({ item, sectionId, onResize
|
|
|
17
15
|
const angle = useItemAngle(item, sectionId);
|
|
18
16
|
const { layouts } = useCntrlContext();
|
|
19
17
|
const { opacity } = useGroupItem(item, sectionId);
|
|
20
|
-
const layoutValues: Record<string, any>[] = [item.area, item.layoutParams, item.state];
|
|
21
|
-
const statesClassNames = useStatesClassNames(item.id, item.state, 'group');
|
|
18
|
+
const layoutValues: Record<string, any>[] = [item.area, item.layoutParams, item.state.hover];
|
|
22
19
|
const [ref, setRef] = useState<HTMLDivElement | null>(null);
|
|
23
20
|
useRegisterResize(ref, onResize);
|
|
24
|
-
useStatesTransitions(ref!, item.state, ['opacity', 'angle'])
|
|
25
21
|
|
|
26
22
|
return (
|
|
27
23
|
<LinkWrapper url={item.link?.url} target={item.link?.target}>
|
|
28
24
|
<>
|
|
29
25
|
<div
|
|
30
|
-
className={`group-${item.id}
|
|
26
|
+
className={`group-${item.id}`}
|
|
31
27
|
ref={setRef}
|
|
32
28
|
style={{
|
|
33
29
|
...(opacity !== undefined ? { opacity } : {}),
|
|
@@ -51,15 +47,16 @@ export const GroupItem: FC<ItemProps<TGroupItem>> = ({ item, sectionId, onResize
|
|
|
51
47
|
height: 100%;
|
|
52
48
|
box-sizing: border-box;
|
|
53
49
|
}
|
|
54
|
-
${getLayoutStyles(layouts, layoutValues, ([area, layoutParams,
|
|
55
|
-
const statesCSS = getStatesCSS(item.id, 'group', ['opacity', 'angle'], stateParams);
|
|
50
|
+
${getLayoutStyles(layouts, layoutValues, ([area, layoutParams, hoverParams]) => {
|
|
56
51
|
return (`
|
|
57
52
|
.group-${item.id} {
|
|
58
53
|
opacity: ${layoutParams.opacity};
|
|
59
54
|
transform: rotate(${area.angle}deg);
|
|
60
|
-
transition:
|
|
55
|
+
transition: ${getTransitions<ArticleItemType.Group>(['opacity', 'angle'], hoverParams)};
|
|
56
|
+
}
|
|
57
|
+
.group-${item.id}:hover {
|
|
58
|
+
${getHoverStyles<ArticleItemType.Group>(['opacity', 'angle'], hoverParams)};
|
|
61
59
|
}
|
|
62
|
-
${statesCSS}
|
|
63
60
|
`);
|
|
64
61
|
})}
|
|
65
62
|
`}</JSXStyle>
|
|
@@ -1,19 +1,17 @@
|
|
|
1
1
|
import { FC, useEffect, useId, useMemo, useRef, useState } from 'react';
|
|
2
2
|
import JSXStyle from 'styled-jsx/style';
|
|
3
3
|
import { CntrlColor } from '@cntrl-site/color';
|
|
4
|
-
import { getLayoutStyles, ImageItem as TImageItem } from '@cntrl-site/sdk';
|
|
4
|
+
import { ArticleItemType, getLayoutStyles, ImageItem as TImageItem } from '@cntrl-site/sdk';
|
|
5
5
|
import { ItemProps } from '../Item';
|
|
6
6
|
import { LinkWrapper } from '../LinkWrapper';
|
|
7
7
|
import { useFileItem } from './useFileItem';
|
|
8
8
|
import { useItemAngle } from '../useItemAngle';
|
|
9
9
|
import { useCntrlContext } from '../../provider/useCntrlContext';
|
|
10
|
+
import { getHoverStyles, getTransitions } from '../../utils/HoverStyles/HoverStyles';
|
|
10
11
|
import { useRegisterResize } from "../../common/useRegisterResize";
|
|
11
12
|
import { useImageFx } from '../../utils/effects/useImageFx';
|
|
12
13
|
import { useElementRect } from '../../utils/useElementRect';
|
|
13
14
|
import { useLayoutContext } from '../useLayoutContext';
|
|
14
|
-
import { useStatesClassNames } from '../useStatesClassNames';
|
|
15
|
-
import { getStatesCSS } from '../../utils/getStatesCSS';
|
|
16
|
-
import { useStatesTransitions } from '../useStatesTransitions';
|
|
17
15
|
|
|
18
16
|
const baseVariables = `precision mediump float;
|
|
19
17
|
uniform sampler2D u_image;
|
|
@@ -31,9 +29,8 @@ export const ImageItem: FC<ItemProps<TImageItem>> = ({ item, sectionId, onResize
|
|
|
31
29
|
const { radius, strokeWidth, opacity, strokeColor, blur } = useFileItem(item, sectionId);
|
|
32
30
|
const angle = useItemAngle(item, sectionId);
|
|
33
31
|
const borderColor = useMemo(() => strokeColor ? CntrlColor.parse(strokeColor) : undefined, [strokeColor]);
|
|
34
|
-
const [
|
|
35
|
-
|
|
36
|
-
useRegisterResize(wrapperRef, onResize);
|
|
32
|
+
const [ref, setRef] = useState<HTMLDivElement | null>(null);
|
|
33
|
+
useRegisterResize(ref, onResize);
|
|
37
34
|
const { url, hasGLEffect, fragmentShader, FXControls, FXCursor } = item.commonParams;
|
|
38
35
|
const fxCanvas = useRef<HTMLCanvasElement | null>(null);
|
|
39
36
|
const isInitialRef = useRef(true);
|
|
@@ -44,17 +41,12 @@ export const ImageItem: FC<ItemProps<TImageItem>> = ({ item, sectionId, onResize
|
|
|
44
41
|
acc[control.shaderParam] = control.value;
|
|
45
42
|
return acc;
|
|
46
43
|
}, {});
|
|
47
|
-
const layoutValues: Record<string, any>[] = [item.area, item.layoutParams, item.state];
|
|
44
|
+
const layoutValues: Record<string, any>[] = [item.area, item.layoutParams, item.state.hover];
|
|
48
45
|
const fullShaderCode = `${baseVariables}\n${controlsVariables}\n${fragmentShader}`;
|
|
49
46
|
const area = layoutId ? item.area[layoutId] : null;
|
|
50
47
|
const exemplary = layouts?.find(l => l.id === layoutId)?.exemplary;
|
|
51
48
|
const width = area && exemplary ? area.width * exemplary : 0;
|
|
52
49
|
const height = area && exemplary ? area.height * exemplary : 0;
|
|
53
|
-
const statesWrapperClassNames = useStatesClassNames(item.id, item.state, 'image-wrapper');
|
|
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']);
|
|
58
50
|
useEffect(() => {
|
|
59
51
|
isInitialRef.current = false;
|
|
60
52
|
}, []);
|
|
@@ -70,7 +62,7 @@ export const ImageItem: FC<ItemProps<TImageItem>> = ({ item, sectionId, onResize
|
|
|
70
62
|
width,
|
|
71
63
|
height
|
|
72
64
|
);
|
|
73
|
-
const rect = useElementRect(
|
|
65
|
+
const rect = useElementRect(ref);
|
|
74
66
|
const rectWidth = Math.floor(rect?.width ?? 0);
|
|
75
67
|
const rectHeight = Math.floor(rect?.height ?? 0);
|
|
76
68
|
const inlineStyles = {
|
|
@@ -82,8 +74,8 @@ export const ImageItem: FC<ItemProps<TImageItem>> = ({ item, sectionId, onResize
|
|
|
82
74
|
<LinkWrapper url={item.link?.url} target={item.link?.target}>
|
|
83
75
|
<>
|
|
84
76
|
<div
|
|
85
|
-
className={`image-wrapper-${item.id}
|
|
86
|
-
ref={
|
|
77
|
+
className={`image-wrapper-${item.id}`}
|
|
78
|
+
ref={setRef}
|
|
87
79
|
style={{
|
|
88
80
|
...(opacity !== undefined ? { opacity } : {}),
|
|
89
81
|
...(angle !== undefined ? { transform: `rotate(${angle}deg)` } : {}),
|
|
@@ -94,16 +86,15 @@ export const ImageItem: FC<ItemProps<TImageItem>> = ({ item, sectionId, onResize
|
|
|
94
86
|
<canvas
|
|
95
87
|
style={inlineStyles}
|
|
96
88
|
ref={fxCanvas}
|
|
97
|
-
className={`img-canvas image-${item.id}
|
|
89
|
+
className={`img-canvas image-${item.id}`}
|
|
98
90
|
width={rectWidth}
|
|
99
91
|
height={rectHeight}
|
|
100
92
|
/>
|
|
101
93
|
) : (
|
|
102
94
|
<img
|
|
103
95
|
alt=""
|
|
104
|
-
className={`image image-${item.id}
|
|
96
|
+
className={`image image-${item.id}`}
|
|
105
97
|
style={inlineStyles}
|
|
106
|
-
ref={setImgRef}
|
|
107
98
|
src={item.commonParams.url}
|
|
108
99
|
/>
|
|
109
100
|
)}
|
|
@@ -134,24 +125,26 @@ export const ImageItem: FC<ItemProps<TImageItem>> = ({ item, sectionId, onResize
|
|
|
134
125
|
border-width: 0;
|
|
135
126
|
box-sizing: border-box;
|
|
136
127
|
}
|
|
137
|
-
${getLayoutStyles(layouts, layoutValues, ([area, layoutParams,
|
|
138
|
-
const wrapperStatesCSS = getStatesCSS(item.id, 'image-wrapper', ['angle', 'opacity', 'blur'], stateParams);
|
|
139
|
-
const imgStatesCSS = getStatesCSS(item.id, 'image', ['strokeWidth', 'radius', 'strokeColor'], stateParams);
|
|
128
|
+
${getLayoutStyles(layouts, layoutValues, ([area, layoutParams, hoverParams]) => {
|
|
140
129
|
return (`
|
|
141
130
|
.image-wrapper-${item.id} {
|
|
142
131
|
opacity: ${layoutParams.opacity};
|
|
143
132
|
transform: rotate(${area.angle}deg);
|
|
144
133
|
filter: ${layoutParams.blur !== 0 ? `blur(${layoutParams.blur * 100}vw)` : 'unset'};
|
|
145
|
-
transition:
|
|
134
|
+
transition: ${getTransitions<ArticleItemType.Image>(['angle', 'opacity', 'blur'], hoverParams)};
|
|
135
|
+
}
|
|
136
|
+
.image-wrapper-${item.id}:hover {
|
|
137
|
+
${getHoverStyles<ArticleItemType.Image>(['angle', 'opacity', 'blur'], hoverParams)};
|
|
146
138
|
}
|
|
147
139
|
.image-${item.id} {
|
|
148
140
|
border-color: ${CntrlColor.parse(layoutParams.strokeColor).fmt('rgba')};
|
|
149
141
|
border-radius: ${layoutParams.radius * 100}vw;
|
|
150
142
|
border-width: ${layoutParams.strokeWidth * 100}vw;
|
|
151
|
-
transition:
|
|
143
|
+
transition: ${getTransitions<ArticleItemType.Image>(['strokeWidth', 'radius', 'strokeColor'], hoverParams)};
|
|
144
|
+
}
|
|
145
|
+
.image-wrapper-${item.id}:hover .image, .image-wrapper-${item.id}:hover .img-canvas {
|
|
146
|
+
${getHoverStyles<ArticleItemType.Image>(['strokeWidth', 'radius', 'strokeColor'], hoverParams)};
|
|
152
147
|
}
|
|
153
|
-
${wrapperStatesCSS}
|
|
154
|
-
${imgStatesCSS}
|
|
155
148
|
`);
|
|
156
149
|
})}
|
|
157
150
|
`}</JSXStyle>
|
|
@@ -1,16 +1,14 @@
|
|
|
1
|
-
import { FC, useId, useMemo, useState } from 'react';
|
|
1
|
+
import { FC, useEffect, useId, useMemo, useRef, useState } from 'react';
|
|
2
2
|
import JSXStyle from 'styled-jsx/style';
|
|
3
3
|
import { CntrlColor } from '@cntrl-site/color';
|
|
4
|
-
import { RectangleItem as TRectangleItem, getLayoutStyles } from '@cntrl-site/sdk';
|
|
4
|
+
import { RectangleItem as TRectangleItem, getLayoutStyles, ArticleItemType } from '@cntrl-site/sdk';
|
|
5
5
|
import { ItemProps } from '../Item';
|
|
6
6
|
import { LinkWrapper } from '../LinkWrapper';
|
|
7
7
|
import { useRectangleItem } from './useRectangleItem';
|
|
8
8
|
import { useItemAngle } from '../useItemAngle';
|
|
9
9
|
import { useCntrlContext } from '../../provider/useCntrlContext';
|
|
10
|
+
import { getHoverStyles, getTransitions } from '../../utils/HoverStyles/HoverStyles';
|
|
10
11
|
import { useRegisterResize } from "../../common/useRegisterResize";
|
|
11
|
-
import { getStatesCSS } from '../../utils/getStatesCSS';
|
|
12
|
-
import { useStatesClassNames } from '../useStatesClassNames';
|
|
13
|
-
import { useStatesTransitions } from '../useStatesTransitions';
|
|
14
12
|
|
|
15
13
|
export const RectangleItem: FC<ItemProps<TRectangleItem>> = ({ item, sectionId, onResize }) => {
|
|
16
14
|
const id = useId();
|
|
@@ -19,18 +17,16 @@ export const RectangleItem: FC<ItemProps<TRectangleItem>> = ({ item, sectionId,
|
|
|
19
17
|
const angle = useItemAngle(item, sectionId);
|
|
20
18
|
const backgroundColor = useMemo(() => fillColor ? CntrlColor.parse(fillColor) : undefined, [fillColor]);
|
|
21
19
|
const borderColor = useMemo(() => strokeColor ? CntrlColor.parse(strokeColor) : undefined, [strokeColor]);
|
|
22
|
-
const layoutValues: Record<string, any>[] = [item.area, item.layoutParams, item.state];
|
|
20
|
+
const layoutValues: Record<string, any>[] = [item.area, item.layoutParams, item.state.hover];
|
|
23
21
|
const [ref, setRef] = useState<HTMLDivElement | null>(null);
|
|
24
|
-
const statesClassNames = useStatesClassNames(item.id, item.state, 'rectangle');
|
|
25
22
|
useRegisterResize(ref, onResize);
|
|
26
23
|
const backdropFilterValue = backdropBlur ? `blur(${backdropBlur * 100}vw)`: undefined;
|
|
27
|
-
useStatesTransitions(ref, item.state, ['angle', 'fillColor', 'strokeWidth', 'radius', 'strokeColor', 'blur', 'backdropBlur']);
|
|
28
24
|
|
|
29
25
|
return (
|
|
30
26
|
<LinkWrapper url={item.link?.url} target={item.link?.target}>
|
|
31
27
|
<>
|
|
32
28
|
<div
|
|
33
|
-
className={`rectangle-${item.id}
|
|
29
|
+
className={`rectangle-${item.id}`}
|
|
34
30
|
ref={setRef}
|
|
35
31
|
style={{
|
|
36
32
|
...(backgroundColor ? { backgroundColor : `${backgroundColor.fmt('rgba')}` } : {}),
|
|
@@ -53,8 +49,7 @@ export const RectangleItem: FC<ItemProps<TRectangleItem>> = ({ item, sectionId,
|
|
|
53
49
|
border-style: solid;
|
|
54
50
|
box-sizing: border-box;
|
|
55
51
|
}
|
|
56
|
-
${getLayoutStyles(layouts, layoutValues, ([area, layoutParams,
|
|
57
|
-
const statesCSS = getStatesCSS(item.id, 'rectangle', ['angle', 'fillColor', 'strokeWidth', 'radius', 'strokeColor', 'blur', 'backdropBlur'], states);
|
|
52
|
+
${getLayoutStyles(layouts, layoutValues, ([area, layoutParams, hoverParams]) => {
|
|
58
53
|
return (`
|
|
59
54
|
.rectangle-${item.id} {
|
|
60
55
|
background-color: ${CntrlColor.parse(layoutParams.fillColor).fmt('rgba')};
|
|
@@ -65,9 +60,11 @@ export const RectangleItem: FC<ItemProps<TRectangleItem>> = ({ item, sectionId,
|
|
|
65
60
|
filter: ${layoutParams.blur !== 0 ? `blur(${layoutParams.blur * 100}vw)` : 'unset'};
|
|
66
61
|
backdrop-filter: ${layoutParams.backdropFilter !== 0 ? `blur(${layoutParams.blur * 100}vw)` : 'unset'};
|
|
67
62
|
-webkit-backdrop-filter: ${layoutParams.backdropFilter !== 0 ? `blur(${layoutParams.blur * 100}vw)` : 'unset'};
|
|
68
|
-
transition:
|
|
63
|
+
transition: ${getTransitions<ArticleItemType.Rectangle>(['angle', 'fillColor', 'strokeWidth', 'radius', 'strokeColor', 'blur', 'backdropBlur'], hoverParams)};
|
|
64
|
+
}
|
|
65
|
+
.rectangle-${item.id}:hover {
|
|
66
|
+
${getHoverStyles<ArticleItemType.Rectangle>(['angle', 'fillColor', 'strokeWidth', 'radius', 'strokeColor', 'blur', 'backdropBlur'], hoverParams)};
|
|
69
67
|
}
|
|
70
|
-
${statesCSS}
|
|
71
68
|
`);
|
|
72
69
|
})}
|
|
73
70
|
`}</JSXStyle>
|
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
import { FC, useId, useMemo, useState } from 'react';
|
|
2
2
|
import { CntrlColor } from '@cntrl-site/color';
|
|
3
|
-
import { getLayoutStyles, RichTextItem as TRichTextItem } from '@cntrl-site/sdk';
|
|
3
|
+
import { ArticleItemType, getLayoutStyles, RichTextItem as TRichTextItem } from '@cntrl-site/sdk';
|
|
4
4
|
import JSXStyle from 'styled-jsx/style';
|
|
5
5
|
import { ItemProps } from '../Item';
|
|
6
6
|
import { useRichTextItem } from './useRichTextItem';
|
|
7
7
|
import { useCntrlContext } from '../../provider/useCntrlContext';
|
|
8
|
+
import { getHoverStyles, getTransitions } from '../../utils/HoverStyles/HoverStyles';
|
|
8
9
|
import { useRichTextItemValues } from './useRichTextItemValues';
|
|
9
10
|
import { useRegisterResize } from "../../common/useRegisterResize";
|
|
10
11
|
import { getFontFamilyValue } from '../../utils/getFontFamilyValue';
|
|
11
12
|
import { useExemplary } from '../../common/useExemplary';
|
|
12
13
|
import { useItemAngle } from '../useItemAngle';
|
|
13
|
-
import { useStatesClassNames } from '../useStatesClassNames';
|
|
14
|
-
import { getStatesCSS } from '../../utils/getStatesCSS';
|
|
15
|
-
import { useStatesTransitions } from '../useStatesTransitions';
|
|
16
14
|
|
|
17
15
|
export const RichTextItem: FC<ItemProps<TRichTextItem>> = ({ item, sectionId, onResize }) => {
|
|
18
16
|
const [content, styles] = useRichTextItem(item);
|
|
@@ -22,17 +20,15 @@ export const RichTextItem: FC<ItemProps<TRichTextItem>> = ({ item, sectionId, on
|
|
|
22
20
|
const angle = useItemAngle(item, sectionId);
|
|
23
21
|
const { blur, wordSpacing, letterSpacing, color, fontSize, lineHeight } = useRichTextItemValues(item, sectionId);
|
|
24
22
|
const textColor = useMemo(() => color ? CntrlColor.parse(color) : undefined, [color]);
|
|
25
|
-
const layoutValues: Record<string, any>[] = [item.area, item.layoutParams, item.state];
|
|
23
|
+
const layoutValues: Record<string, any>[] = [item.area, item.layoutParams, item.state.hover];
|
|
26
24
|
const exemplary = useExemplary();
|
|
27
|
-
const stateClassNames = useStatesClassNames(item.id, item.state, 'rich-text-wrapper');
|
|
28
25
|
useRegisterResize(ref, onResize);
|
|
29
|
-
useStatesTransitions(ref, item.state, ['angle', 'blur', 'letterSpacing', 'wordSpacing', 'color']);
|
|
30
26
|
|
|
31
27
|
return (
|
|
32
28
|
<>
|
|
33
29
|
<div
|
|
34
30
|
ref={setRef}
|
|
35
|
-
className={`rich-text-wrapper-${item.id}
|
|
31
|
+
className={`rich-text-wrapper-${item.id}`}
|
|
36
32
|
style={{
|
|
37
33
|
...(blur !== undefined ? { filter: `blur(${blur * 100}vw)` } : {}),
|
|
38
34
|
...(textColor ? { color: `${textColor.fmt('rgba')}` } : {}),
|
|
@@ -47,14 +43,8 @@ export const RichTextItem: FC<ItemProps<TRichTextItem>> = ({ item, sectionId, on
|
|
|
47
43
|
</div>
|
|
48
44
|
<JSXStyle id={id}>
|
|
49
45
|
{styles}
|
|
50
|
-
{`${getLayoutStyles(layouts, layoutValues, ([area, layoutParams,
|
|
46
|
+
{`${getLayoutStyles(layouts, layoutValues, ([area, layoutParams, hoverParams]) => {
|
|
51
47
|
const color = CntrlColor.parse(layoutParams.color);
|
|
52
|
-
const statesCSS = getStatesCSS(
|
|
53
|
-
item.id,
|
|
54
|
-
'rich-text-wrapper',
|
|
55
|
-
['angle', 'blur', 'letterSpacing', 'wordSpacing', 'color'],
|
|
56
|
-
states
|
|
57
|
-
);
|
|
58
48
|
return (`
|
|
59
49
|
.rich-text-wrapper-${item.id} {
|
|
60
50
|
font-size: ${layoutParams.fontSize * 100}vw;
|
|
@@ -70,14 +60,16 @@ export const RichTextItem: FC<ItemProps<TRichTextItem>> = ({ item, sectionId, on
|
|
|
70
60
|
transform: rotate(${area.angle}deg);
|
|
71
61
|
filter: ${layoutParams.blur !== 0 ? `blur(${layoutParams.blur * 100}vw)` : 'unset'};
|
|
72
62
|
text-transform: ${layoutParams.textTransform};
|
|
73
|
-
transition:
|
|
63
|
+
transition: ${getTransitions<ArticleItemType.RichText>(['angle', 'blur', 'letterSpacing', 'wordSpacing', 'color'], hoverParams)};
|
|
64
|
+
}
|
|
65
|
+
.rich-text-wrapper-${item.id}:hover {
|
|
66
|
+
${getHoverStyles<ArticleItemType.RichText>(['angle', 'blur', 'letterSpacing', 'wordSpacing', 'color'], hoverParams)};
|
|
74
67
|
}
|
|
75
68
|
@supports not (color: oklch(42% 0.3 90 / 1)) {
|
|
76
69
|
.rich-text-wrapper-${item.id} {
|
|
77
70
|
color: ${color.fmt('rgba')};
|
|
78
71
|
}
|
|
79
72
|
}
|
|
80
|
-
${statesCSS}
|
|
81
73
|
`);
|
|
82
74
|
})}`}
|
|
83
75
|
</JSXStyle>
|
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
import { FC, useId, useMemo, useRef, useState } from 'react';
|
|
2
2
|
import JSXStyle from 'styled-jsx/style';
|
|
3
3
|
import { CntrlColor } from '@cntrl-site/color';
|
|
4
|
-
import { getLayoutStyles, VideoItem as TVideoItem } from '@cntrl-site/sdk';
|
|
4
|
+
import { ArticleItemType, getLayoutStyles, VideoItem as TVideoItem } from '@cntrl-site/sdk';
|
|
5
5
|
import { ItemProps } from '../Item';
|
|
6
6
|
import { LinkWrapper } from '../LinkWrapper';
|
|
7
7
|
import { useFileItem } from './useFileItem';
|
|
8
8
|
import { useItemAngle } from '../useItemAngle';
|
|
9
9
|
import { useCntrlContext } from '../../provider/useCntrlContext';
|
|
10
|
+
import { getHoverStyles, getTransitions } from '../../utils/HoverStyles/HoverStyles';
|
|
10
11
|
import { useRegisterResize } from "../../common/useRegisterResize";
|
|
11
12
|
import { useLayoutContext } from '../useLayoutContext';
|
|
12
13
|
import { ScrollPlaybackVideo } from '../ScrollPlaybackVideo';
|
|
13
|
-
import { useStatesClassNames } from '../useStatesClassNames';
|
|
14
|
-
import { getStatesCSS } from '../../utils/getStatesCSS';
|
|
15
|
-
import { useStatesTransitions } from '../useStatesTransitions';
|
|
16
14
|
|
|
17
15
|
export const VideoItem: FC<ItemProps<TVideoItem>> = ({ item, sectionId, onResize }) => {
|
|
18
16
|
const id = useId();
|
|
@@ -24,12 +22,8 @@ export const VideoItem: FC<ItemProps<TVideoItem>> = ({ item, sectionId, onResize
|
|
|
24
22
|
const videoRef = useRef<HTMLVideoElement | null>(null);
|
|
25
23
|
const layoutId = useLayoutContext();
|
|
26
24
|
const scrollPlayback = layoutId ? item.layoutParams[layoutId].scrollPlayback : null;
|
|
27
|
-
const layoutValues: Record<string, any>[] = [item.area, item.layoutParams, item.state];
|
|
28
|
-
const statesWrapperClassNames = useStatesClassNames(item.id, item.state, 'video-wrapper');
|
|
29
|
-
const statesVideoClassNames = useStatesClassNames(item.id, item.state, 'video');
|
|
25
|
+
const layoutValues: Record<string, any>[] = [item.area, item.layoutParams, item.state.hover];
|
|
30
26
|
const hasScrollPlayback = scrollPlayback !== null;
|
|
31
|
-
useStatesTransitions(ref, item.state, ['angle', 'opacity', 'blur']);
|
|
32
|
-
useStatesTransitions(videoRef.current, item.state, ['strokeWidth', 'radius', 'strokeColor']);
|
|
33
27
|
useRegisterResize(ref, onResize);
|
|
34
28
|
const inlineStyles = {
|
|
35
29
|
...(radius !== undefined ? { borderRadius: `${radius * 100}vw` } : {}),
|
|
@@ -40,7 +34,7 @@ export const VideoItem: FC<ItemProps<TVideoItem>> = ({ item, sectionId, onResize
|
|
|
40
34
|
return (
|
|
41
35
|
<LinkWrapper url={item.link?.url} target={item.link?.target}>
|
|
42
36
|
<div
|
|
43
|
-
className={`video-wrapper-${item.id}
|
|
37
|
+
className={`video-wrapper-${item.id}`}
|
|
44
38
|
ref={setRef}
|
|
45
39
|
style={{
|
|
46
40
|
...(opacity !== undefined ? { opacity } : {}),
|
|
@@ -54,7 +48,7 @@ export const VideoItem: FC<ItemProps<TVideoItem>> = ({ item, sectionId, onResize
|
|
|
54
48
|
src={item.commonParams.url}
|
|
55
49
|
playbackParams={scrollPlayback}
|
|
56
50
|
style={inlineStyles}
|
|
57
|
-
className={`video video-playback-wrapper video-${item.id}
|
|
51
|
+
className={`video video-playback-wrapper video-${item.id}`}
|
|
58
52
|
/>
|
|
59
53
|
) : (
|
|
60
54
|
<video
|
|
@@ -64,7 +58,7 @@ export const VideoItem: FC<ItemProps<TVideoItem>> = ({ item, sectionId, onResize
|
|
|
64
58
|
muted
|
|
65
59
|
loop
|
|
66
60
|
playsInline
|
|
67
|
-
className={`video video-${item.id}
|
|
61
|
+
className={`video video-${item.id}`}
|
|
68
62
|
style={inlineStyles}
|
|
69
63
|
>
|
|
70
64
|
<source src={item.commonParams.url} />
|
|
@@ -98,24 +92,26 @@ export const VideoItem: FC<ItemProps<TVideoItem>> = ({ item, sectionId, onResize
|
|
|
98
92
|
display: flex;
|
|
99
93
|
justify-content: center;
|
|
100
94
|
}
|
|
101
|
-
${getLayoutStyles(layouts, layoutValues, ([area, layoutParams,
|
|
102
|
-
const wrapperStatesCSS = getStatesCSS(item.id, 'video-wrapper', ['angle', 'opacity', 'blur'], stateParams);
|
|
103
|
-
const videoStatesCSS = getStatesCSS(item.id, 'video', ['strokeWidth', 'radius', 'strokeColor'], stateParams);
|
|
95
|
+
${getLayoutStyles(layouts, layoutValues, ([area, layoutParams, hoverParams]) => {
|
|
104
96
|
return (`
|
|
105
97
|
.video-wrapper-${item.id} {
|
|
106
98
|
opacity: ${layoutParams.opacity};
|
|
107
99
|
transform: rotate(${area.angle}deg);
|
|
108
100
|
filter: ${layoutParams.blur !== 0 ? `blur(${layoutParams.blur * 100}vw)` : 'unset'};
|
|
109
|
-
transition:
|
|
101
|
+
transition: ${getTransitions<ArticleItemType.Video>(['angle', 'opacity', 'blur'], hoverParams)};
|
|
102
|
+
}
|
|
103
|
+
.video-wrapper-${item.id}:hover {
|
|
104
|
+
${getHoverStyles<ArticleItemType.Video>(['angle', 'opacity', 'blur'], hoverParams)};
|
|
110
105
|
}
|
|
111
106
|
.video-${item.id} {
|
|
112
107
|
border-color: ${CntrlColor.parse(layoutParams.strokeColor).fmt('rgba')};
|
|
113
108
|
border-radius: ${layoutParams.radius * 100}vw;
|
|
114
109
|
border-width: ${layoutParams.strokeWidth * 100}vw;
|
|
115
|
-
transition:
|
|
110
|
+
transition: ${getTransitions<ArticleItemType.Video>(['strokeWidth', 'radius', 'strokeColor'], hoverParams)};
|
|
111
|
+
}
|
|
112
|
+
.video-wrapper-${item.id}:hover .video {
|
|
113
|
+
${getHoverStyles<ArticleItemType.Video>(['strokeWidth', 'radius', 'strokeColor'], hoverParams)};
|
|
116
114
|
}
|
|
117
|
-
${wrapperStatesCSS}
|
|
118
|
-
${videoStatesCSS}
|
|
119
115
|
`);
|
|
120
116
|
})}
|
|
121
117
|
`}</JSXStyle>
|
|
@@ -5,12 +5,10 @@ import { ItemProps } from '../Item';
|
|
|
5
5
|
import { LinkWrapper } from '../LinkWrapper';
|
|
6
6
|
import { useEmbedVideoItem } from './useEmbedVideoItem';
|
|
7
7
|
import { useItemAngle } from '../useItemAngle';
|
|
8
|
-
import { getLayoutStyles, VimeoEmbedItem as TVimeoEmbedItem } from '@cntrl-site/sdk';
|
|
8
|
+
import { ArticleItemType, getLayoutStyles, VimeoEmbedItem as TVimeoEmbedItem } from '@cntrl-site/sdk';
|
|
9
9
|
import { useCntrlContext } from '../../provider/useCntrlContext';
|
|
10
|
+
import { getHoverStyles, getTransitions } from '../../utils/HoverStyles/HoverStyles';
|
|
10
11
|
import { useRegisterResize } from "../../common/useRegisterResize";
|
|
11
|
-
import { useStatesClassNames } from '../useStatesClassNames';
|
|
12
|
-
import { getStatesCSS } from '../../utils/getStatesCSS';
|
|
13
|
-
import { useStatesTransitions } from '../useStatesTransitions';
|
|
14
12
|
|
|
15
13
|
export const VimeoEmbedItem: FC<ItemProps<TVimeoEmbedItem>> = ({ item, sectionId, onResize }) => {
|
|
16
14
|
const id = useId();
|
|
@@ -23,12 +21,8 @@ export const VimeoEmbedItem: FC<ItemProps<TVimeoEmbedItem>> = ({ item, sectionId
|
|
|
23
21
|
const [ref, setRef] = useState<HTMLDivElement | null>(null);
|
|
24
22
|
const [imgRef, setImgRef] = useState<HTMLImageElement | null>(null);
|
|
25
23
|
const [isCoverVisible, setIsCoverVisible] = useState(false);
|
|
26
|
-
const layoutValues: Record<string, any>[] = [item.area, item.layoutParams, item.state];
|
|
27
|
-
const wrapperClassNames = useStatesClassNames(item.id, item.state, 'embed-video-wrapper');
|
|
28
|
-
const videoClassNames = useStatesClassNames(item.id, item.state, 'embed-video');
|
|
24
|
+
const layoutValues: Record<string, any>[] = [item.area, item.layoutParams, item.state.hover];
|
|
29
25
|
useRegisterResize(ref, onResize);
|
|
30
|
-
useStatesTransitions(ref, item.state, ['angle', 'blur', 'opacity']);
|
|
31
|
-
useStatesTransitions(iframeRef, item.state, ['radius']);
|
|
32
26
|
const getValidVimeoUrl = (url: string): string => {
|
|
33
27
|
const validURL = new URL(url);
|
|
34
28
|
validURL.searchParams.append('controls', String(controls));
|
|
@@ -66,7 +60,7 @@ export const VimeoEmbedItem: FC<ItemProps<TVimeoEmbedItem>> = ({ item, sectionId
|
|
|
66
60
|
return (
|
|
67
61
|
<LinkWrapper url={item.link?.url} target={item.link?.target}>
|
|
68
62
|
<div
|
|
69
|
-
className={`embed-video-wrapper-${item.id}
|
|
63
|
+
className={`embed-video-wrapper-${item.id}`}
|
|
70
64
|
ref={setRef}
|
|
71
65
|
style={{
|
|
72
66
|
...(opacity !== undefined ? { opacity } : {}),
|
|
@@ -102,7 +96,7 @@ export const VimeoEmbedItem: FC<ItemProps<TVimeoEmbedItem>> = ({ item, sectionId
|
|
|
102
96
|
)}
|
|
103
97
|
<iframe
|
|
104
98
|
ref={setIframeRef}
|
|
105
|
-
className=
|
|
99
|
+
className="embedVideo"
|
|
106
100
|
src={validUrl || ''}
|
|
107
101
|
allow="autoplay; fullscreen; picture-in-picture;"
|
|
108
102
|
allowFullScreen
|
|
@@ -117,29 +111,31 @@ export const VimeoEmbedItem: FC<ItemProps<TVimeoEmbedItem>> = ({ item, sectionId
|
|
|
117
111
|
width: 100%;
|
|
118
112
|
height: 100%;
|
|
119
113
|
}
|
|
120
|
-
.
|
|
114
|
+
.embedVideo {
|
|
121
115
|
width: 100%;
|
|
122
116
|
height: 100%;
|
|
123
117
|
z-index: 1;
|
|
124
118
|
border: none;
|
|
125
119
|
overflow: hidden;
|
|
126
120
|
}
|
|
127
|
-
${getLayoutStyles(layouts, layoutValues, ([area, layoutParams,
|
|
128
|
-
const wrapperStatesCSS = getStatesCSS(item.id, 'embed-video-wrapper', ['angle', 'blur', 'opacity'], stateParams);
|
|
129
|
-
const videoStatesCSS = getStatesCSS(item.id, 'embed-video', ['radius'], stateParams);
|
|
121
|
+
${getLayoutStyles(layouts, layoutValues, ([area, layoutParams, hoverParams]) => {
|
|
130
122
|
return (`
|
|
131
123
|
.embed-video-wrapper-${item.id} {
|
|
132
124
|
opacity: ${layoutParams.opacity};
|
|
133
125
|
transform: rotate(${area.angle}deg);
|
|
134
126
|
filter: ${layoutParams.blur !== 0 ? `blur(${layoutParams.blur * 100}vw)` : 'unset'};
|
|
135
|
-
transition:
|
|
127
|
+
transition: ${getTransitions<ArticleItemType.VimeoEmbed>(['angle', 'blur', 'opacity'], hoverParams)};
|
|
136
128
|
}
|
|
137
|
-
.embed-video-wrapper-${item.id}
|
|
129
|
+
.embed-video-wrapper-${item.id}:hover {
|
|
130
|
+
${getHoverStyles<ArticleItemType.VimeoEmbed>(['angle', 'blur', 'opacity'], hoverParams)}
|
|
131
|
+
}
|
|
132
|
+
.embed-video-wrapper-${item.id} .embedVideo {
|
|
138
133
|
border-radius: ${layoutParams.radius * 100}vw;
|
|
139
|
-
transition:
|
|
134
|
+
transition: ${getTransitions<ArticleItemType.VimeoEmbed>(['radius'], hoverParams)};
|
|
135
|
+
}
|
|
136
|
+
.embed-video-wrapper-${item.id}:hover .embedVideo {
|
|
137
|
+
${getHoverStyles<ArticleItemType.VimeoEmbed>(['radius'], hoverParams)};
|
|
140
138
|
}
|
|
141
|
-
${wrapperStatesCSS}
|
|
142
|
-
${videoStatesCSS}
|
|
143
139
|
`);
|
|
144
140
|
})}
|
|
145
141
|
`}</JSXStyle>
|
|
@@ -5,14 +5,12 @@ import { LinkWrapper } from '../LinkWrapper';
|
|
|
5
5
|
import { getYoutubeId } from '../../utils/getValidYoutubeUrl';
|
|
6
6
|
import { useEmbedVideoItem } from './useEmbedVideoItem';
|
|
7
7
|
import { useItemAngle } from '../useItemAngle';
|
|
8
|
-
import { getLayoutStyles, YoutubeEmbedItem as TYoutubeEmbedItem } from '@cntrl-site/sdk';
|
|
8
|
+
import { ArticleItemType, getLayoutStyles, YoutubeEmbedItem as TYoutubeEmbedItem } from '@cntrl-site/sdk';
|
|
9
|
+
import { getHoverStyles, getTransitions } from '../../utils/HoverStyles/HoverStyles';
|
|
9
10
|
import { useCntrlContext } from '../../provider/useCntrlContext';
|
|
10
11
|
import { useYouTubeIframeApi } from '../../utils/Youtube/useYouTubeIframeApi';
|
|
11
12
|
import { YTPlayer } from '../../utils/Youtube/YoutubeIframeApi';
|
|
12
13
|
import { useRegisterResize } from "../../common/useRegisterResize";
|
|
13
|
-
import { useStatesClassNames } from '../useStatesClassNames';
|
|
14
|
-
import { getStatesCSS } from '../../utils/getStatesCSS';
|
|
15
|
-
import { useStatesTransitions } from '../useStatesTransitions';
|
|
16
14
|
|
|
17
15
|
export const YoutubeEmbedItem: FC<ItemProps<TYoutubeEmbedItem>> = ({ item, sectionId, onResize }) => {
|
|
18
16
|
const id = useId();
|
|
@@ -22,16 +20,12 @@ export const YoutubeEmbedItem: FC<ItemProps<TYoutubeEmbedItem>> = ({ item, secti
|
|
|
22
20
|
const angle = useItemAngle(item, sectionId);
|
|
23
21
|
const YT = useYouTubeIframeApi();
|
|
24
22
|
const [div, setDiv] = useState<HTMLDivElement | null>(null);
|
|
25
|
-
const [wrapperRef, setWrapperRef] = useState<HTMLDivElement | null>(null);
|
|
26
23
|
const [player, setPlayer] = useState<YTPlayer | undefined>(undefined);
|
|
27
24
|
const [isCoverVisible, setIsCoverVisible] = useState(false);
|
|
28
25
|
const [imgRef, setImgRef] = useState<HTMLImageElement | null>(null);
|
|
29
|
-
const layoutValues: Record<string, any>[] = [item.area, item.layoutParams, item.state];
|
|
30
|
-
const wrapperClassNames = useStatesClassNames(item.id, item.state, 'embed-youtube-video-wrapper');
|
|
31
|
-
const embedClassNames = useStatesClassNames(item.id, item.state, 'embed');
|
|
26
|
+
const layoutValues: Record<string, any>[] = [item.area, item.layoutParams, item.state.hover];
|
|
32
27
|
useRegisterResize(div, onResize);
|
|
33
|
-
|
|
34
|
-
useStatesTransitions(div, item.state, ['radius']);
|
|
28
|
+
|
|
35
29
|
useEffect(() => {
|
|
36
30
|
const newUrl = new URL(url);
|
|
37
31
|
const videoId = getYoutubeId(newUrl);
|
|
@@ -84,8 +78,7 @@ export const YoutubeEmbedItem: FC<ItemProps<TYoutubeEmbedItem>> = ({ item, secti
|
|
|
84
78
|
return (
|
|
85
79
|
<LinkWrapper url={item.link?.url} target={item.link?.target}>
|
|
86
80
|
<div
|
|
87
|
-
|
|
88
|
-
className={`embed-youtube-video-wrapper-${item.id} ${wrapperClassNames}`}
|
|
81
|
+
className={`embed-youtube-video-wrapper-${item.id}`}
|
|
89
82
|
onMouseEnter={() => {
|
|
90
83
|
if (!player || play !== 'on-hover') return;
|
|
91
84
|
player.playVideo();
|
|
@@ -120,10 +113,11 @@ export const YoutubeEmbedItem: FC<ItemProps<TYoutubeEmbedItem>> = ({ item, secti
|
|
|
120
113
|
/>
|
|
121
114
|
)}
|
|
122
115
|
<div
|
|
123
|
-
className={`embed-${item.id}
|
|
116
|
+
className={`embed-${item.id}`}
|
|
124
117
|
ref={setDiv}
|
|
125
118
|
style={{
|
|
126
119
|
...(radius !== undefined ? { borderRadius: `${radius * 100}vw` } : {}),
|
|
120
|
+
|
|
127
121
|
}}
|
|
128
122
|
/>
|
|
129
123
|
</div>
|
|
@@ -143,22 +137,24 @@ export const YoutubeEmbedItem: FC<ItemProps<TYoutubeEmbedItem>> = ({ item, secti
|
|
|
143
137
|
z-index: 1;
|
|
144
138
|
border: none;
|
|
145
139
|
}
|
|
146
|
-
${getLayoutStyles(layouts, layoutValues, ([area, layoutParams,
|
|
147
|
-
const wrapperStatesCSS = getStatesCSS(item.id, 'embed-youtube-video-wrapper', ['angle', 'blur', 'opacity'], stateParams);
|
|
148
|
-
const embedStatesCSS = getStatesCSS(item.id, 'embed', ['radius'], stateParams);
|
|
140
|
+
${getLayoutStyles(layouts, layoutValues, ([area, layoutParams, hoverParams]) => {
|
|
149
141
|
return (`
|
|
150
142
|
.embed-youtube-video-wrapper-${item.id} {
|
|
151
143
|
opacity: ${layoutParams.opacity};
|
|
152
144
|
transform: rotate(${area.angle}deg);
|
|
153
145
|
filter: ${layoutParams.blur !== 0 ? `blur(${layoutParams.blur * 100}vw)` : 'unset'};
|
|
154
|
-
transition:
|
|
146
|
+
transition: ${getTransitions<ArticleItemType.YoutubeEmbed>(['angle', 'blur', 'opacity'], hoverParams)};
|
|
155
147
|
}
|
|
156
148
|
.embed-youtube-video-wrapper-${item.id} .embed-${item.id} {
|
|
157
149
|
border-radius: ${layoutParams.radius * 100}vw;
|
|
158
|
-
transition:
|
|
150
|
+
transition: ${getTransitions<ArticleItemType.YoutubeEmbed>(['radius'], hoverParams)};
|
|
151
|
+
}
|
|
152
|
+
.embed-youtube-video-wrapper-${item.id}:hover {
|
|
153
|
+
${getHoverStyles<ArticleItemType.YoutubeEmbed>(['angle', 'blur', 'opacity'], hoverParams)};
|
|
154
|
+
}
|
|
155
|
+
.embed-youtube-video-wrapper-${item.id}:hover .embed-${item.id} {
|
|
156
|
+
${getHoverStyles<ArticleItemType.YoutubeEmbed>(['radius'], hoverParams)};
|
|
159
157
|
}
|
|
160
|
-
${wrapperStatesCSS}
|
|
161
|
-
${embedStatesCSS}
|
|
162
158
|
`);
|
|
163
159
|
})}
|
|
164
160
|
`}</JSXStyle>
|