@cntrl-site/sdk-nextjs 0.16.0 → 0.16.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/common/useExemplary.js +13 -0
- package/lib/components/Article.js +9 -1
- package/lib/components/Item.js +13 -8
- package/lib/utils/ArticleRectManager/ArticleRectObserver.js +5 -1
- package/package.json +1 -1
- package/src/common/useExemplary.ts +9 -0
- package/src/components/Article.tsx +20 -3
- package/src/components/Item.tsx +23 -10
- package/src/utils/ArticleRectManager/ArticleRectObserver.ts +7 -2
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useExemplary = void 0;
|
|
4
|
+
const useCntrlContext_1 = require("../provider/useCntrlContext");
|
|
5
|
+
const useLayoutContext_1 = require("../components/useLayoutContext");
|
|
6
|
+
const useExemplary = () => {
|
|
7
|
+
var _a, _b;
|
|
8
|
+
const { layouts } = (0, useCntrlContext_1.useCntrlContext)();
|
|
9
|
+
const layout = (0, useLayoutContext_1.useLayoutContext)();
|
|
10
|
+
const exemplary = (_b = (_a = layouts.find(l => l.id === layout)) === null || _a === void 0 ? void 0 : _a.exemplary) !== null && _b !== void 0 ? _b : 1;
|
|
11
|
+
return exemplary;
|
|
12
|
+
};
|
|
13
|
+
exports.useExemplary = useExemplary;
|
|
@@ -16,9 +16,17 @@ const Article = ({ article, sectionData }) => {
|
|
|
16
16
|
const articleRef = (0, react_1.useRef)(null);
|
|
17
17
|
const articleRectObserver = (0, useArticleRectObserver_1.useArticleRectObserver)(articleRef.current);
|
|
18
18
|
const id = (0, react_1.useId)();
|
|
19
|
+
const [articleHeight, setArticleHeight] = (0, react_1.useState)(1);
|
|
20
|
+
(0, react_1.useEffect)(() => {
|
|
21
|
+
if (!articleRectObserver)
|
|
22
|
+
return;
|
|
23
|
+
return articleRectObserver.on('resize', (rect) => {
|
|
24
|
+
setArticleHeight(rect.height / rect.width);
|
|
25
|
+
});
|
|
26
|
+
}, [articleRectObserver]);
|
|
19
27
|
return ((0, jsx_runtime_1.jsxs)(ArticleRectContext_1.ArticleRectContext.Provider, Object.assign({ value: articleRectObserver }, { children: [(0, jsx_runtime_1.jsx)(ArticleWrapper_1.ArticleWrapper, { children: (0, jsx_runtime_1.jsx)("div", Object.assign({ className: "article", ref: articleRef }, { children: article.sections.map((section, i) => {
|
|
20
28
|
const data = section.name ? sectionData[section.name] : {};
|
|
21
|
-
return ((0, jsx_runtime_1.jsx)(Section_1.Section, Object.assign({ section: section, data: data }, { children: article.sections[i].items.map(item => ((0, jsx_runtime_1.jsx)(Item_1.Item, { item: item, sectionId: section.id }, item.id))) }), section.id));
|
|
29
|
+
return ((0, jsx_runtime_1.jsx)(Section_1.Section, Object.assign({ section: section, data: data }, { children: article.sections[i].items.map(item => ((0, jsx_runtime_1.jsx)(Item_1.Item, { item: item, sectionId: section.id, articleHeight: articleHeight }, item.id))) }), section.id));
|
|
22
30
|
}) })) }), (0, jsx_runtime_1.jsx)(style_1.default, Object.assign({ id: id }, { children: `
|
|
23
31
|
.article {
|
|
24
32
|
position: relative;
|
package/lib/components/Item.js
CHANGED
|
@@ -26,6 +26,8 @@ const getItemTopStyle_1 = require("../utils/getItemTopStyle");
|
|
|
26
26
|
const useStickyItemTop_1 = require("./items/useStickyItemTop");
|
|
27
27
|
const getAnchoredItemTop_1 = require("../utils/getAnchoredItemTop");
|
|
28
28
|
const useLayoutContext_1 = require("./useLayoutContext");
|
|
29
|
+
const ArticleRectContext_1 = require("../provider/ArticleRectContext");
|
|
30
|
+
const useExemplary_1 = require("../common/useExemplary");
|
|
29
31
|
const itemsMap = {
|
|
30
32
|
[sdk_1.ArticleItemType.Rectangle]: RectangleItem_1.RectangleItem,
|
|
31
33
|
[sdk_1.ArticleItemType.Image]: ImageItem_1.ImageItem,
|
|
@@ -41,12 +43,13 @@ const RichTextWrapper = ({ isRichText, children }) => {
|
|
|
41
43
|
return ((0, jsx_runtime_1.jsx)("div", Object.assign({ style: { transformOrigin: 'top left', transform: 'scale(var(--layout-deviation))' } }, { children: children })));
|
|
42
44
|
};
|
|
43
45
|
const noop = () => null;
|
|
44
|
-
const Item = ({ item, sectionId }) => {
|
|
45
|
-
|
|
46
|
+
const Item = ({ item, sectionId, articleHeight }) => {
|
|
47
|
+
const itemWrapperRef = (0, react_1.useRef)(null);
|
|
48
|
+
const rectObserver = (0, react_1.useContext)(ArticleRectContext_1.ArticleRectContext);
|
|
46
49
|
const id = (0, react_1.useId)();
|
|
47
50
|
const { layouts } = (0, useCntrlContext_1.useCntrlContext)();
|
|
48
51
|
const layout = (0, useLayoutContext_1.useLayoutContext)();
|
|
49
|
-
const exemplary = (
|
|
52
|
+
const exemplary = (0, useExemplary_1.useExemplary)();
|
|
50
53
|
const [wrapperHeight, setWrapperHeight] = (0, react_1.useState)(undefined);
|
|
51
54
|
const [itemHeight, setItemHeight] = (0, react_1.useState)(undefined);
|
|
52
55
|
const { scale, scaleAnchor } = (0, useItemScale_1.useItemScale)(item, sectionId);
|
|
@@ -66,7 +69,10 @@ const Item = ({ item, sectionId }) => {
|
|
|
66
69
|
: undefined;
|
|
67
70
|
const sizingAxis = parseSizing(sizing);
|
|
68
71
|
const ItemComponent = itemsMap[item.type] || noop;
|
|
72
|
+
const sectionTop = rectObserver ? rectObserver.getSectionTop(sectionId) : 0;
|
|
69
73
|
const handleItemResize = (height) => {
|
|
74
|
+
var _a, _b;
|
|
75
|
+
const itemSectionTop = (_b = (_a = itemWrapperRef.current) === null || _a === void 0 ? void 0 : _a.offsetTop) !== null && _b !== void 0 ? _b : 0;
|
|
70
76
|
if (!layout)
|
|
71
77
|
return;
|
|
72
78
|
const sticky = item.sticky[layout];
|
|
@@ -74,7 +80,7 @@ const Item = ({ item, sectionId }) => {
|
|
|
74
80
|
setWrapperHeight(undefined);
|
|
75
81
|
return;
|
|
76
82
|
}
|
|
77
|
-
const wrapperHeight = getStickyItemWrapperHeight(sticky, height);
|
|
83
|
+
const wrapperHeight = getStickyItemWrapperHeight(sticky, height, articleHeight, (sectionTop + itemSectionTop) / window.innerWidth);
|
|
78
84
|
setItemHeight(height);
|
|
79
85
|
setWrapperHeight(wrapperHeight);
|
|
80
86
|
};
|
|
@@ -86,7 +92,7 @@ const Item = ({ item, sectionId }) => {
|
|
|
86
92
|
top: stickyTop,
|
|
87
93
|
height: isRichText && itemHeight ? `${itemHeight * 100}vw` : 'unset'
|
|
88
94
|
};
|
|
89
|
-
return ((0, jsx_runtime_1.jsxs)("div", Object.assign({ className: `item-wrapper-${item.id}`, style: isInitialRef.current ? {} : Object.assign({ top, left }, (wrapperHeight ? { height: `${wrapperHeight * 100}vw` } : {})) }, { children: [(0, jsx_runtime_1.jsx)("div", Object.assign({ suppressHydrationWarning: true, className: `item-${item.id}`, style: isInitialRef.current ? {} : styles }, { children: (0, jsx_runtime_1.jsx)(RichTextWrapper, Object.assign({ isRichText: isRichText }, { children: (0, jsx_runtime_1.jsx)("div", Object.assign({ className: `item-${item.id}-inner`, style: {
|
|
95
|
+
return ((0, jsx_runtime_1.jsxs)("div", Object.assign({ className: `item-wrapper-${item.id}`, ref: itemWrapperRef, style: isInitialRef.current ? {} : Object.assign({ top, left }, (wrapperHeight !== undefined ? { height: `${wrapperHeight * 100}vw` } : {})) }, { children: [(0, jsx_runtime_1.jsx)("div", Object.assign({ suppressHydrationWarning: true, className: `item-${item.id}`, style: isInitialRef.current ? {} : styles }, { children: (0, jsx_runtime_1.jsx)(RichTextWrapper, Object.assign({ isRichText: isRichText }, { children: (0, jsx_runtime_1.jsx)("div", Object.assign({ className: `item-${item.id}-inner`, style: {
|
|
90
96
|
width: `${sizingAxis.x === sdk_1.ArticleItemSizingType.Manual
|
|
91
97
|
? isRichText
|
|
92
98
|
? `${width * exemplary}px`
|
|
@@ -123,7 +129,6 @@ const Item = ({ item, sectionId }) => {
|
|
|
123
129
|
pointer-events: none;
|
|
124
130
|
top: ${(0, getItemTopStyle_1.getItemTopStyle)(area.top, area.anchorSide)};
|
|
125
131
|
left: ${area.left * 100}vw;
|
|
126
|
-
height: ${sticky ? `${getStickyItemWrapperHeight(sticky, area.height) * 100}vw` : 'unset'};
|
|
127
132
|
transition: ${(0, HoverStyles_1.getTransitions)(['left', 'top'], hoverParams)};
|
|
128
133
|
}
|
|
129
134
|
.item-${item.id}-inner:hover {
|
|
@@ -137,9 +142,9 @@ const Item = ({ item, sectionId }) => {
|
|
|
137
142
|
` }))] })));
|
|
138
143
|
};
|
|
139
144
|
exports.Item = Item;
|
|
140
|
-
function getStickyItemWrapperHeight(sticky, itemHeight) {
|
|
145
|
+
function getStickyItemWrapperHeight(sticky, itemHeight, articleHeight, itemArticleOffset) {
|
|
141
146
|
var _a;
|
|
142
|
-
const end = (_a = sticky.to) !== null && _a !== void 0 ? _a :
|
|
147
|
+
const end = (_a = sticky.to) !== null && _a !== void 0 ? _a : articleHeight - itemArticleOffset - itemHeight;
|
|
143
148
|
return end - sticky.from + itemHeight;
|
|
144
149
|
}
|
|
145
150
|
function parseSizing(sizing = 'manual') {
|
|
@@ -29,6 +29,10 @@ class ArticleRectObserver extends EventEmitter_1.EventEmitter {
|
|
|
29
29
|
return 0;
|
|
30
30
|
return -(sectionTop / this.articleWidth - this.scrollPos);
|
|
31
31
|
}
|
|
32
|
+
getSectionTop(sectionId) {
|
|
33
|
+
const sectionTop = this.sectionsScrollMap.get(sectionId);
|
|
34
|
+
return sectionTop !== null && sectionTop !== void 0 ? sectionTop : 0;
|
|
35
|
+
}
|
|
32
36
|
get width() {
|
|
33
37
|
return this.articleWidth;
|
|
34
38
|
}
|
|
@@ -70,7 +74,7 @@ class ArticleRectObserver extends EventEmitter_1.EventEmitter {
|
|
|
70
74
|
const parentBoundary = this.parent.getBoundingClientRect();
|
|
71
75
|
this.articleWidth = parentBoundary.width;
|
|
72
76
|
this.setScroll(window.scrollY / this.articleWidth);
|
|
73
|
-
this.emit('resize',
|
|
77
|
+
this.emit('resize', parentBoundary);
|
|
74
78
|
for (const sectionId of this.registry.keys()) {
|
|
75
79
|
const el = this.registry.get(sectionId);
|
|
76
80
|
if (!el)
|
package/package.json
CHANGED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { useCntrlContext } from "../provider/useCntrlContext";
|
|
2
|
+
import { useLayoutContext } from "../components/useLayoutContext";
|
|
3
|
+
|
|
4
|
+
export const useExemplary = () => {
|
|
5
|
+
const { layouts } = useCntrlContext();
|
|
6
|
+
const layout = useLayoutContext();
|
|
7
|
+
const exemplary = layouts.find(l => l.id === layout)?.exemplary ?? 1;
|
|
8
|
+
return exemplary;
|
|
9
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { FC, useId, useRef } from 'react';
|
|
1
|
+
import { FC, useEffect, useId, useRef, useState } from 'react';
|
|
2
2
|
import JSXStyle from 'styled-jsx/style';
|
|
3
3
|
import { TArticle } from '@cntrl-site/sdk';
|
|
4
4
|
import { Section } from './Section';
|
|
@@ -16,6 +16,14 @@ export const Article: FC<Props> = ({ article, sectionData }) => {
|
|
|
16
16
|
const articleRef = useRef<HTMLDivElement | null>(null);
|
|
17
17
|
const articleRectObserver = useArticleRectObserver(articleRef.current);
|
|
18
18
|
const id = useId();
|
|
19
|
+
const [articleHeight, setArticleHeight] = useState(1);
|
|
20
|
+
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
if (!articleRectObserver) return;
|
|
23
|
+
return articleRectObserver.on('resize', (rect) => {
|
|
24
|
+
setArticleHeight(rect.height / rect.width);
|
|
25
|
+
});
|
|
26
|
+
}, [articleRectObserver]);
|
|
19
27
|
|
|
20
28
|
return (
|
|
21
29
|
<ArticleRectContext.Provider value={articleRectObserver}>
|
|
@@ -24,9 +32,18 @@ export const Article: FC<Props> = ({ article, sectionData }) => {
|
|
|
24
32
|
{article.sections.map((section, i) => {
|
|
25
33
|
const data = section.name ? sectionData[section.name] : {};
|
|
26
34
|
return (
|
|
27
|
-
<Section
|
|
35
|
+
<Section
|
|
36
|
+
section={section}
|
|
37
|
+
key={section.id}
|
|
38
|
+
data={data}
|
|
39
|
+
>
|
|
28
40
|
{article.sections[i].items.map(item => (
|
|
29
|
-
<Item
|
|
41
|
+
<Item
|
|
42
|
+
item={item}
|
|
43
|
+
key={item.id}
|
|
44
|
+
sectionId={section.id}
|
|
45
|
+
articleHeight={articleHeight}
|
|
46
|
+
/>
|
|
30
47
|
))}
|
|
31
48
|
</Section>
|
|
32
49
|
);
|
package/src/components/Item.tsx
CHANGED
|
@@ -1,14 +1,12 @@
|
|
|
1
|
-
import { ComponentType, FC, PropsWithChildren, useEffect, useId, useRef, useState } from 'react';
|
|
1
|
+
import { ComponentType, FC, PropsWithChildren, useContext, useEffect, useId, useRef, useState } from 'react';
|
|
2
2
|
import JSXStyle from 'styled-jsx/style';
|
|
3
3
|
import {
|
|
4
|
-
AnchorSide,
|
|
5
4
|
ArticleItemSizingType as SizingType,
|
|
6
5
|
ArticleItemType,
|
|
7
6
|
getLayoutStyles,
|
|
8
7
|
TArticleItem,
|
|
9
8
|
TStickyParams,
|
|
10
9
|
TArticleItemAny,
|
|
11
|
-
|
|
12
10
|
} from '@cntrl-site/sdk';
|
|
13
11
|
import { RectangleItem } from './items/RectangleItem';
|
|
14
12
|
import { ImageItem } from './items/ImageItem';
|
|
@@ -28,6 +26,8 @@ import { getItemTopStyle } from '../utils/getItemTopStyle';
|
|
|
28
26
|
import { useStickyItemTop } from './items/useStickyItemTop';
|
|
29
27
|
import { getAnchoredItemTop } from '../utils/getAnchoredItemTop';
|
|
30
28
|
import { useLayoutContext } from './useLayoutContext';
|
|
29
|
+
import { ArticleRectContext } from "../provider/ArticleRectContext";
|
|
30
|
+
import { useExemplary } from "../common/useExemplary";
|
|
31
31
|
|
|
32
32
|
export interface ItemProps<I extends TArticleItemAny> {
|
|
33
33
|
item: I;
|
|
@@ -35,6 +35,10 @@ export interface ItemProps<I extends TArticleItemAny> {
|
|
|
35
35
|
onResize?: (height: number) => void;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
export interface ItemWrapperProps extends ItemProps<TArticleItemAny> {
|
|
39
|
+
articleHeight: number;
|
|
40
|
+
}
|
|
41
|
+
|
|
38
42
|
const itemsMap: Record<ArticleItemType, ComponentType<ItemProps<any>>> = {
|
|
39
43
|
[ArticleItemType.Rectangle]: RectangleItem,
|
|
40
44
|
[ArticleItemType.Image]: ImageItem,
|
|
@@ -60,11 +64,13 @@ const RichTextWrapper: FC<PropsWithChildren<RTWrapperProps>> = ({ isRichText, ch
|
|
|
60
64
|
|
|
61
65
|
const noop = () => null;
|
|
62
66
|
|
|
63
|
-
export const Item: FC<
|
|
67
|
+
export const Item: FC<ItemWrapperProps> = ({ item, sectionId, articleHeight }) => {
|
|
68
|
+
const itemWrapperRef = useRef<HTMLDivElement | null>(null);
|
|
69
|
+
const rectObserver = useContext(ArticleRectContext);
|
|
64
70
|
const id = useId();
|
|
65
71
|
const { layouts } = useCntrlContext();
|
|
66
72
|
const layout = useLayoutContext();
|
|
67
|
-
const exemplary =
|
|
73
|
+
const exemplary = useExemplary();
|
|
68
74
|
const [wrapperHeight, setWrapperHeight] = useState<undefined | number>(undefined);
|
|
69
75
|
const [itemHeight, setItemHeight] = useState<undefined | number>(undefined);
|
|
70
76
|
const { scale, scaleAnchor } = useItemScale(item, sectionId);
|
|
@@ -85,15 +91,17 @@ export const Item: FC<ItemProps<TArticleItemAny>> = ({ item, sectionId}) => {
|
|
|
85
91
|
: undefined;
|
|
86
92
|
const sizingAxis = parseSizing(sizing);
|
|
87
93
|
const ItemComponent = itemsMap[item.type] || noop;
|
|
94
|
+
const sectionTop = rectObserver ? rectObserver.getSectionTop(sectionId) : 0;
|
|
88
95
|
|
|
89
96
|
const handleItemResize = (height: number) => {
|
|
97
|
+
const itemSectionTop = itemWrapperRef.current?.offsetTop ?? 0;
|
|
90
98
|
if (!layout) return;
|
|
91
99
|
const sticky = item.sticky[layout];
|
|
92
100
|
if (!sticky) {
|
|
93
101
|
setWrapperHeight(undefined);
|
|
94
102
|
return;
|
|
95
103
|
}
|
|
96
|
-
const wrapperHeight = getStickyItemWrapperHeight(sticky, height);
|
|
104
|
+
const wrapperHeight = getStickyItemWrapperHeight(sticky, height, articleHeight, (sectionTop + itemSectionTop) / window.innerWidth);
|
|
97
105
|
setItemHeight(height);
|
|
98
106
|
setWrapperHeight(wrapperHeight);
|
|
99
107
|
};
|
|
@@ -112,7 +120,8 @@ export const Item: FC<ItemProps<TArticleItemAny>> = ({ item, sectionId}) => {
|
|
|
112
120
|
return (
|
|
113
121
|
<div
|
|
114
122
|
className={`item-wrapper-${item.id}`}
|
|
115
|
-
|
|
123
|
+
ref={itemWrapperRef}
|
|
124
|
+
style={isInitialRef.current ? {} : { top, left, ...(wrapperHeight !== undefined ? { height: `${wrapperHeight * 100}vw` } : {}) }}
|
|
116
125
|
>
|
|
117
126
|
<div
|
|
118
127
|
suppressHydrationWarning={true}
|
|
@@ -165,7 +174,6 @@ export const Item: FC<ItemProps<TArticleItemAny>> = ({ item, sectionId}) => {
|
|
|
165
174
|
pointer-events: none;
|
|
166
175
|
top: ${getItemTopStyle(area.top, area.anchorSide)};
|
|
167
176
|
left: ${area.left * 100}vw;
|
|
168
|
-
height: ${sticky ? `${getStickyItemWrapperHeight(sticky, area.height) * 100}vw` : 'unset'};
|
|
169
177
|
transition: ${getTransitions(['left', 'top'], hoverParams)};
|
|
170
178
|
}
|
|
171
179
|
.item-${item.id}-inner:hover {
|
|
@@ -181,8 +189,13 @@ export const Item: FC<ItemProps<TArticleItemAny>> = ({ item, sectionId}) => {
|
|
|
181
189
|
);
|
|
182
190
|
};
|
|
183
191
|
|
|
184
|
-
function getStickyItemWrapperHeight(
|
|
185
|
-
|
|
192
|
+
function getStickyItemWrapperHeight(
|
|
193
|
+
sticky: TStickyParams,
|
|
194
|
+
itemHeight: number,
|
|
195
|
+
articleHeight: number,
|
|
196
|
+
itemArticleOffset: number,
|
|
197
|
+
) {
|
|
198
|
+
const end = sticky.to ?? articleHeight - itemArticleOffset - itemHeight;
|
|
186
199
|
return end - sticky.from + itemHeight;
|
|
187
200
|
}
|
|
188
201
|
|
|
@@ -3,7 +3,7 @@ import ResizeObserver from 'resize-observer-polyfill';
|
|
|
3
3
|
|
|
4
4
|
interface EventMap {
|
|
5
5
|
'scroll': undefined;
|
|
6
|
-
'resize':
|
|
6
|
+
'resize': DOMRect;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
export class ArticleRectObserver extends EventEmitter<EventMap> {
|
|
@@ -30,6 +30,11 @@ export class ArticleRectObserver extends EventEmitter<EventMap> {
|
|
|
30
30
|
return - (sectionTop / this.articleWidth - this.scrollPos);
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
getSectionTop(sectionId: string): number {
|
|
34
|
+
const sectionTop = this.sectionsScrollMap.get(sectionId);
|
|
35
|
+
return sectionTop ?? 0;
|
|
36
|
+
}
|
|
37
|
+
|
|
33
38
|
get width(): number {
|
|
34
39
|
return this.articleWidth;
|
|
35
40
|
}
|
|
@@ -77,7 +82,7 @@ export class ArticleRectObserver extends EventEmitter<EventMap> {
|
|
|
77
82
|
const parentBoundary = this.parent.getBoundingClientRect();
|
|
78
83
|
this.articleWidth = parentBoundary.width;
|
|
79
84
|
this.setScroll(window.scrollY / this.articleWidth);
|
|
80
|
-
this.emit('resize',
|
|
85
|
+
this.emit('resize', parentBoundary);
|
|
81
86
|
for (const sectionId of this.registry.keys()) {
|
|
82
87
|
const el = this.registry.get(sectionId);
|
|
83
88
|
if (!el) continue;
|