@cntrl-site/sdk-nextjs 0.12.0 → 0.12.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.
@@ -18,10 +18,10 @@ const CustomItem_1 = require("./items/CustomItem");
18
18
  const useCntrlContext_1 = require("../provider/useCntrlContext");
19
19
  const useItemPosition_1 = require("./useItemPosition");
20
20
  const useItemDimensions_1 = require("./useItemDimensions");
21
- const useItemSticky_1 = require("./items/useItemSticky");
22
21
  const useCurrentLayout_1 = require("../common/useCurrentLayout");
23
22
  const useItemScale_1 = require("./useItemScale");
24
23
  const ScaleAnchorMap_1 = require("../utils/ScaleAnchorMap");
24
+ const useSectionHeightMap_1 = require("./useSectionHeightMap");
25
25
  const itemsMap = {
26
26
  [sdk_1.ArticleItemType.Rectangle]: RectangleItem_1.RectangleItem,
27
27
  [sdk_1.ArticleItemType.Image]: ImageItem_1.ImageItem,
@@ -35,13 +35,16 @@ const noop = () => null;
35
35
  const Item = ({ item, sectionId }) => {
36
36
  const id = (0, react_1.useId)();
37
37
  const { layouts } = (0, useCntrlContext_1.useCntrlContext)();
38
+ const [wrapperHeight, setWrapperHeight] = (0, react_1.useState)(undefined);
38
39
  const { scale, scaleAnchor } = (0, useItemScale_1.useItemScale)(item, sectionId);
39
- const position = (0, useItemPosition_1.useItemPosition)(item, sectionId);
40
+ const { top, left } = (0, useItemPosition_1.useItemPosition)(item, sectionId);
41
+ const sectionHeight = (0, useSectionHeightMap_1.useSectionHeightData)(sectionId);
40
42
  const layout = (0, useCurrentLayout_1.useCurrentLayout)();
41
- const { top, isFixed } = (0, useItemSticky_1.useItemSticky)(position.top, item, sectionId);
42
43
  const { width, height } = (0, useItemDimensions_1.useItemDimensions)(item, sectionId);
43
44
  const layoutValues = [item.area];
44
45
  const isInitialRef = (0, react_1.useRef)(true);
46
+ layoutValues.push(item.sticky);
47
+ layoutValues.push(sectionHeight);
45
48
  if (item.layoutParams) {
46
49
  layoutValues.push(item.layoutParams);
47
50
  }
@@ -50,37 +53,65 @@ const Item = ({ item, sectionId }) => {
50
53
  : undefined;
51
54
  const sizingAxis = parseSizing(sizing);
52
55
  const ItemComponent = itemsMap[item.type] || noop;
56
+ const handleItemResize = (height) => {
57
+ const sticky = item.sticky[layout];
58
+ if (!sticky) {
59
+ setWrapperHeight(undefined);
60
+ return;
61
+ }
62
+ const wrapperHeight = getStickyItemWrapperHeight(sticky, height);
63
+ setWrapperHeight(wrapperHeight);
64
+ };
53
65
  (0, react_1.useEffect)(() => {
54
66
  isInitialRef.current = false;
55
67
  }, []);
56
68
  const styles = {
57
69
  transform: `scale(${scale})`,
58
70
  transformOrigin: ScaleAnchorMap_1.ScaleAnchorMap[scaleAnchor],
59
- left: `${position.left * 100}vw`,
60
71
  width: `${sizingAxis.x === sdk_1.ArticleItemSizingType.Manual ? `${width * 100}vw` : 'max-content'}`,
61
72
  height: `${sizingAxis.y === sdk_1.ArticleItemSizingType.Manual ? `${height * 100}vw` : 'unset'}`,
62
- top
63
73
  };
64
- return ((0, jsx_runtime_1.jsxs)("div", { suppressHydrationWarning: true, className: `item-${item.id}`, style: isInitialRef.current ? {} : { ...styles, position: isFixed ? 'fixed' : 'absolute' }, children: [(0, jsx_runtime_1.jsx)(ItemComponent, { item: item, sectionId: sectionId }), (0, jsx_runtime_1.jsx)(style_1.default, { id: id, children: `
65
- ${(0, sdk_1.getLayoutStyles)(layouts, layoutValues, ([area, layoutParams]) => {
74
+ return ((0, jsx_runtime_1.jsxs)("div", { className: `item-wrapper-${item.id}`, style: { top, left, ...(wrapperHeight ? { height: `${wrapperHeight * 100}vw` } : {}) }, children: [(0, jsx_runtime_1.jsx)("div", { suppressHydrationWarning: true, className: `item-${item.id}`, style: isInitialRef.current ? {} : styles, children: (0, jsx_runtime_1.jsx)(ItemComponent, { item: item, sectionId: sectionId, onResize: handleItemResize }) }), (0, jsx_runtime_1.jsx)(style_1.default, { id: id, children: `
75
+ ${(0, sdk_1.getLayoutStyles)(layouts, layoutValues, ([area, sticky, sectionHeight, layoutParams]) => {
66
76
  const sizingAxis = parseSizing(layoutParams.sizing);
67
77
  return (`
68
78
  .item-${item.id} {
69
- position: absolute;
70
- z-index: ${area.zIndex};
71
- top: ${(0, useItemSticky_1.getItemTopStyle)(area.top, area.anchorSide)};
72
- left: ${area.left * 100}vw;
79
+ position: ${sticky ? 'sticky' : 'absolute'};
73
80
  width: ${sizingAxis.x === sdk_1.ArticleItemSizingType.Manual ? `${area.width * 100}vw` : 'max-content'};
74
- height: ${sizingAxis.y === sdk_1.ArticleItemSizingType.Manual ? `${area.height * 100}vw` : 'unset'};
75
- z-index: ${area.zIndex};
81
+ height: ${sizingAxis.y === sdk_1.ArticleItemSizingType.Manual ? `w${area.height * 100}vw` : 'unset'};
76
82
  transform: scale(${scale});
83
+ top: ${sticky ? `${getAnchoredItemTop(area.top - sticky.from, sectionHeight, area.anchorSide)}` : 0};
77
84
  transform-origin: ${ScaleAnchorMap_1.ScaleAnchorMap[scaleAnchor]};
85
+ pointer-events: auto;
86
+ --webkit-backface-visibility: hidden;
87
+ }
88
+ .item-wrapper-${item.id} {
89
+ position: absolute;
90
+ z-index: ${area.zIndex};
91
+ pointer-events: none;
92
+ top: ${(0, useItemPosition_1.getItemTopStyle)(area.top, area.anchorSide)};
93
+ left: ${area.left * 100}vw;
94
+ height: ${sticky ? `${getStickyItemWrapperHeight(sticky, area.height) * 100}vw` : 'unset'};
78
95
  }
79
96
  `);
80
97
  })}
81
98
  ` })] }));
82
99
  };
83
100
  exports.Item = Item;
101
+ function getAnchoredItemTop(top, sectionHeight, anchorSide) {
102
+ const styleTop = `${top * 100}vw`;
103
+ switch (anchorSide) {
104
+ case sdk_1.AnchorSide.Center: return `calc(${styleTop} + ${sectionHeight} / 2)`;
105
+ case sdk_1.AnchorSide.Bottom: return `calc(${styleTop} + ${sectionHeight})`;
106
+ case sdk_1.AnchorSide.Top:
107
+ default:
108
+ return styleTop;
109
+ }
110
+ }
111
+ function getStickyItemWrapperHeight(sticky, itemHeight) {
112
+ const end = sticky.to ?? 100;
113
+ return end - sticky.from + itemHeight;
114
+ }
84
115
  function parseSizing(sizing = 'manual') {
85
116
  const axisSizing = sizing.split(' ');
86
117
  return {
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.Section = void 0;
6
+ exports.getSectionHeight = exports.Section = void 0;
7
7
  const jsx_runtime_1 = require("react/jsx-runtime");
8
8
  const react_1 = require("react");
9
9
  const style_1 = __importDefault(require("styled-jsx/style"));
@@ -54,3 +54,4 @@ function getSectionHeight(heightData) {
54
54
  return `${units * 100}vw`;
55
55
  return '0';
56
56
  }
57
+ exports.getSectionHeight = getSectionHeight;
@@ -15,22 +15,34 @@ const RectangleItem = ({ item, sectionId }) => {
15
15
  const id = (0, react_1.useId)();
16
16
  const { fillColor, radius, strokeWidth, strokeColor } = (0, useRectangleItem_1.useRectangleItem)(item, sectionId);
17
17
  const angle = (0, useItemAngle_1.useItemAngle)(item, sectionId);
18
- const backgroundColor = (0, react_1.useMemo)(() => sdk_1.CntrlColor.parse(fillColor).toCss(), [fillColor]);
19
- const borderColor = (0, react_1.useMemo)(() => sdk_1.CntrlColor.parse(strokeColor).toCss(), [strokeColor]);
18
+ const backgroundColor = (0, react_1.useMemo)(() => sdk_1.CntrlColor.parse(fillColor), [fillColor]);
19
+ const borderColor = (0, react_1.useMemo)(() => sdk_1.CntrlColor.parse(strokeColor), [strokeColor]);
20
20
  return ((0, jsx_runtime_1.jsx)(LinkWrapper_1.LinkWrapper, { url: item.link?.url, children: (0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { className: `rectangle-${item.id}`, style: {
21
- backgroundColor: `${backgroundColor}`,
21
+ backgroundColor: `${backgroundColor.toCss()}`,
22
22
  borderRadius: `${radius * 100}vw`,
23
23
  borderWidth: `${strokeWidth * 100}vw`,
24
- borderColor: `${borderColor}`,
24
+ borderColor: `${borderColor.toCss()}`,
25
25
  transform: `rotate(${angle}deg)`
26
26
  } }), (0, jsx_runtime_1.jsx)(style_1.default, { id: id, children: `
27
- .rectangle-${item.id} {
28
- position: absolute;
29
- width: 100%;
30
- height: 100%;
31
- border-style: solid;
32
- box-sizing: border-box;
27
+ @supports (color: oklch(42% 0.3 90 / 1)) {
28
+ .rectangle-${item.id} {
29
+ background-color: ${backgroundColor.fmt('oklch')};
30
+ border-color: ${borderColor.fmt('oklch')};
33
31
  }
32
+ }
33
+ @supports not (color: oklch(42% 0.3 90 / 1)) {
34
+ .rectangle-${item.id} {
35
+ background-color: ${backgroundColor.fmt('rgba')};
36
+ border-color: ${borderColor.fmt('rgba')};
37
+ }
38
+ }
39
+ .rectangle-${item.id} {
40
+ position: absolute;
41
+ width: 100%;
42
+ height: 100%;
43
+ border-style: solid;
44
+ box-sizing: border-box;
45
+ }
34
46
  ` })] }) }));
35
47
  };
36
48
  exports.RectangleItem = RectangleItem;
@@ -5,14 +5,28 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.RichTextItem = void 0;
7
7
  const jsx_runtime_1 = require("react/jsx-runtime");
8
+ const react_1 = require("react");
8
9
  const style_1 = __importDefault(require("styled-jsx/style"));
9
10
  const useRichTextItem_1 = require("./useRichTextItem");
10
11
  const useItemAngle_1 = require("../useItemAngle");
11
- const RichTextItem = ({ item, sectionId }) => {
12
+ const RichTextItem = ({ item, sectionId, onResize }) => {
12
13
  const [content, styles, preset] = (0, useRichTextItem_1.useRichTextItem)(item);
14
+ const [ref, setRef] = (0, react_1.useState)(null);
13
15
  const angle = (0, useItemAngle_1.useItemAngle)(item, sectionId);
14
16
  const className = preset ? `cntrl-preset-${preset.id}` : undefined;
15
- return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { className: className, style: {
17
+ (0, react_1.useEffect)(() => {
18
+ if (!ref || !onResize)
19
+ return;
20
+ const observer = new ResizeObserver((entries) => {
21
+ const [entry] = entries;
22
+ onResize(entry.target.getBoundingClientRect().height / window.innerWidth);
23
+ });
24
+ observer.observe(ref);
25
+ return () => {
26
+ observer.unobserve(ref);
27
+ };
28
+ }, [ref, onResize]);
29
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { ref: setRef, className: className, style: {
16
30
  transform: `rotate(${angle}deg)`
17
31
  }, children: content }), (0, jsx_runtime_1.jsx)(style_1.default, { id: item.id, children: styles })] }));
18
32
  };
@@ -1,11 +1,29 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.useItemPosition = void 0;
3
+ exports.getItemTopStyle = exports.useItemPosition = void 0;
4
+ const sdk_1 = require("@cntrl-site/sdk");
4
5
  const useKeyframeValue_1 = require("../common/useKeyframeValue");
5
6
  const useCurrentLayout_1 = require("../common/useCurrentLayout");
6
7
  const useItemPosition = (item, sectionId) => {
7
8
  const layoutId = (0, useCurrentLayout_1.useCurrentLayout)();
8
9
  const { top, left } = (0, useKeyframeValue_1.useKeyframeValue)(item, (item, layoutId) => item.area[layoutId], (animator, scroll, value) => animator.getPositions(value, scroll), sectionId, [layoutId]);
9
- return { top, left };
10
+ return {
11
+ top: getItemTopStyle(top, item.area[layoutId].anchorSide),
12
+ left: `${left * 100}vw`
13
+ };
10
14
  };
11
15
  exports.useItemPosition = useItemPosition;
16
+ function getItemTopStyle(top, anchorSide) {
17
+ const defaultValue = `${top * 100}vw`;
18
+ if (!anchorSide)
19
+ return defaultValue;
20
+ switch (anchorSide) {
21
+ case sdk_1.AnchorSide.Top:
22
+ return defaultValue;
23
+ case sdk_1.AnchorSide.Center:
24
+ return `calc(50% + ${top * 100}vw)`;
25
+ case sdk_1.AnchorSide.Bottom:
26
+ return `calc(100% + ${top * 100}vw)`;
27
+ }
28
+ }
29
+ exports.getItemTopStyle = getItemTopStyle;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getSectionHeightMap = exports.useSectionHeightData = void 0;
4
+ const react_1 = require("react");
5
+ const CntrlContext_1 = require("../provider/CntrlContext");
6
+ const Section_1 = require("./Section");
7
+ const useSectionHeightData = (sectionId) => {
8
+ const sectionHeightContext = (0, react_1.useContext)(CntrlContext_1.CntrlContext);
9
+ const layouts = sectionHeightContext.layouts;
10
+ const sectionHeightData = sectionHeightContext.getSectionHeightData(sectionId);
11
+ return sectionHeightData ? getSectionHeightMap(sectionHeightData) : getDefaultHeightData(layouts);
12
+ };
13
+ exports.useSectionHeightData = useSectionHeightData;
14
+ function getSectionHeightMap(sectionHeight) {
15
+ return Object.fromEntries(Object.entries(sectionHeight).map(([sectionId, heightData]) => [sectionId, (0, Section_1.getSectionHeight)(heightData)]));
16
+ }
17
+ exports.getSectionHeightMap = getSectionHeightMap;
18
+ function getDefaultHeightData(layouts) {
19
+ return layouts.reduce((acc, layout) => ({ ...acc, [layout.id]: '0' }), {});
20
+ }
@@ -6,6 +6,7 @@ class CntrlSdkContext {
6
6
  this.customItems = customItems;
7
7
  this.customSections = customSections;
8
8
  this._layouts = [];
9
+ this.sectionHeightMap = new Map();
9
10
  }
10
11
  async resolveSectionData(sections) {
11
12
  const resolvers = sections.map(section => {
@@ -19,12 +20,26 @@ class CntrlSdkContext {
19
20
  }).filter(isDefined);
20
21
  return Object.fromEntries(await Promise.all(resolvers.map(async ({ name, resolver }) => [name, await resolver()])));
21
22
  }
23
+ init({ project, typePresets, article }) {
24
+ this.setTypePresets(typePresets);
25
+ this.setLayouts(project.layouts);
26
+ this.setSectionsHeight(article.sections);
27
+ }
22
28
  setTypePresets(typePresets) {
23
29
  this._typePresets = typePresets;
24
30
  }
25
31
  setLayouts(layouts) {
26
32
  this._layouts = layouts;
27
33
  }
34
+ setSectionsHeight(sections) {
35
+ for (const section of sections) {
36
+ this.sectionHeightMap.set(section.id, section.height);
37
+ }
38
+ }
39
+ getSectionHeightData(sectionId) {
40
+ const sectionHeightData = this.sectionHeightMap.get(sectionId);
41
+ return sectionHeightData;
42
+ }
28
43
  get layouts() {
29
44
  return this._layouts;
30
45
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cntrl-site/sdk-nextjs",
3
- "version": "0.12.0",
3
+ "version": "0.12.2",
4
4
  "description": "SDK for Next.js",
5
5
  "main": "lib/index.js",
6
6
  "types": "src/index.ts",
@@ -21,7 +21,7 @@
21
21
  },
22
22
  "homepage": "https://github.com/cntrl-site/sdk-nextjs#readme",
23
23
  "dependencies": {
24
- "@cntrl-site/sdk": "^1.1.1",
24
+ "@cntrl-site/sdk": "^1.1.3",
25
25
  "html-react-parser": "^3.0.1",
26
26
  "styled-jsx": "^5.0.2"
27
27
  },
@@ -1,11 +1,14 @@
1
- import { ComponentType, FC, useEffect, useId, useRef } from 'react';
1
+ import { ComponentType, FC, useEffect, useId, useRef, useState } from 'react';
2
2
  import JSXStyle from 'styled-jsx/style';
3
3
  import {
4
+ AnchorSide,
4
5
  ArticleItemSizingType as SizingType,
5
6
  ArticleItemType,
6
7
  getLayoutStyles,
7
8
  TArticleItem,
8
- TArticleItemAny
9
+ TStickyParams,
10
+ TArticleItemAny,
11
+
9
12
  } from '@cntrl-site/sdk';
10
13
  import { RectangleItem } from './items/RectangleItem';
11
14
  import { ImageItem } from './items/ImageItem';
@@ -15,16 +18,17 @@ import { VimeoEmbedItem } from './items/VimeoEmbed';
15
18
  import { YoutubeEmbedItem } from './items/YoutubeEmbed';
16
19
  import { CustomItem } from './items/CustomItem';
17
20
  import { useCntrlContext } from '../provider/useCntrlContext';
18
- import { useItemPosition } from './useItemPosition';
21
+ import { getItemTopStyle, useItemPosition } from './useItemPosition';
19
22
  import { useItemDimensions } from './useItemDimensions';
20
- import { getItemTopStyle, useItemSticky } from './items/useItemSticky';
21
23
  import { useCurrentLayout } from '../common/useCurrentLayout';
22
24
  import { useItemScale } from './useItemScale';
23
25
  import { ScaleAnchorMap } from '../utils/ScaleAnchorMap';
26
+ import { useSectionHeightData } from './useSectionHeightMap';
24
27
 
25
28
  export interface ItemProps<I extends TArticleItemAny> {
26
29
  item: I;
27
30
  sectionId: string;
31
+ onResize?: (height: number) => void;
28
32
  }
29
33
 
30
34
  const itemsMap: Record<ArticleItemType, ComponentType<ItemProps<any>>> = {
@@ -42,13 +46,16 @@ const noop = () => null;
42
46
  export const Item: FC<ItemProps<TArticleItemAny>> = ({ item, sectionId}) => {
43
47
  const id = useId();
44
48
  const { layouts } = useCntrlContext();
49
+ const [wrapperHeight, setWrapperHeight] = useState<undefined | number>(undefined);
45
50
  const { scale, scaleAnchor } = useItemScale(item, sectionId);
46
- const position = useItemPosition(item, sectionId);
51
+ const { top, left } = useItemPosition(item, sectionId);
52
+ const sectionHeight = useSectionHeightData(sectionId);
47
53
  const layout = useCurrentLayout();
48
- const { top, isFixed } = useItemSticky(position.top, item, sectionId);
49
54
  const { width, height } = useItemDimensions(item, sectionId);
50
55
  const layoutValues: Record<string, any>[] = [item.area];
51
56
  const isInitialRef = useRef(true);
57
+ layoutValues.push(item.sticky);
58
+ layoutValues.push(sectionHeight);
52
59
  if (item.layoutParams) {
53
60
  layoutValues.push(item.layoutParams);
54
61
  }
@@ -59,6 +66,16 @@ export const Item: FC<ItemProps<TArticleItemAny>> = ({ item, sectionId}) => {
59
66
  const sizingAxis = parseSizing(sizing);
60
67
  const ItemComponent = itemsMap[item.type] || noop;
61
68
 
69
+ const handleItemResize = (height: number) => {
70
+ const sticky = item.sticky[layout];
71
+ if (!sticky) {
72
+ setWrapperHeight(undefined);
73
+ return;
74
+ }
75
+ const wrapperHeight = getStickyItemWrapperHeight(sticky, height)
76
+ setWrapperHeight(wrapperHeight);
77
+ };
78
+
62
79
  useEffect(() => {
63
80
  isInitialRef.current = false;
64
81
  }, []);
@@ -66,41 +83,66 @@ export const Item: FC<ItemProps<TArticleItemAny>> = ({ item, sectionId}) => {
66
83
  const styles = {
67
84
  transform: `scale(${scale})`,
68
85
  transformOrigin: ScaleAnchorMap[scaleAnchor],
69
- left: `${position.left * 100}vw`,
70
86
  width: `${sizingAxis.x === SizingType.Manual ? `${width * 100}vw` : 'max-content'}`,
71
87
  height: `${sizingAxis.y === SizingType.Manual ? `${height * 100}vw` : 'unset'}`,
72
- top
73
88
  };
74
89
 
75
90
  return (
76
- <div
77
- suppressHydrationWarning={true}
78
- className={`item-${item.id}`}
79
- style={isInitialRef.current ? {} : { ...styles, position: isFixed ? 'fixed': 'absolute' } }
91
+ <div className={`item-wrapper-${item.id}`}
92
+ style={{ top, left, ...(wrapperHeight ? { height: `${wrapperHeight * 100}vw` } : {}) }}
80
93
  >
81
- <ItemComponent item={item} sectionId={sectionId} />
94
+ <div
95
+ suppressHydrationWarning={true}
96
+ className={`item-${item.id}`}
97
+ style={isInitialRef.current ? {} : styles }
98
+ >
99
+ <ItemComponent item={item} sectionId={sectionId} onResize={handleItemResize} />
100
+ </div>
82
101
  <JSXStyle id={id}>{`
83
- ${getLayoutStyles(layouts, layoutValues, ([area, layoutParams]) => {
84
- const sizingAxis = parseSizing(layoutParams.sizing);
85
- return (`
102
+ ${getLayoutStyles(layouts, layoutValues, ([area, sticky, sectionHeight, layoutParams]) => {
103
+ const sizingAxis = parseSizing(layoutParams.sizing);
104
+ return (`
86
105
  .item-${item.id} {
106
+ position: ${sticky ? 'sticky' : 'absolute'};
107
+ width: ${sizingAxis.x === SizingType.Manual ? `${area.width * 100}vw` : 'max-content'};
108
+ height: ${sizingAxis.y === SizingType.Manual ? `w${area.height * 100}vw` : 'unset'};
109
+ transform: scale(${scale});
110
+ top: ${sticky ? `${getAnchoredItemTop(area.top - sticky.from, sectionHeight, area.anchorSide)}` : 0};
111
+ transform-origin: ${ScaleAnchorMap[scaleAnchor]};
112
+ pointer-events: auto;
113
+ --webkit-backface-visibility: hidden;
114
+ }
115
+ .item-wrapper-${item.id} {
87
116
  position: absolute;
88
117
  z-index: ${area.zIndex};
118
+ pointer-events: none;
89
119
  top: ${getItemTopStyle(area.top, area.anchorSide)};
90
120
  left: ${area.left * 100}vw;
91
- width: ${sizingAxis.x === SizingType.Manual ? `${area.width * 100}vw` : 'max-content'};
92
- height: ${sizingAxis.y === SizingType.Manual ? `${area.height * 100}vw` : 'unset'};
93
- z-index: ${area.zIndex};
94
- transform: scale(${scale});
95
- transform-origin: ${ScaleAnchorMap[scaleAnchor]};
121
+ height: ${sticky ? `${getStickyItemWrapperHeight(sticky, area.height) * 100}vw` : 'unset'};
96
122
  }
97
123
  `);
98
- })}
124
+ })}
99
125
  `}</JSXStyle>
100
126
  </div>
101
127
  );
102
128
  };
103
129
 
130
+ function getAnchoredItemTop(top: number, sectionHeight: string, anchorSide: AnchorSide) {
131
+ const styleTop = `${top * 100}vw`;
132
+ switch (anchorSide) {
133
+ case AnchorSide.Center: return `calc(${styleTop} + ${sectionHeight} / 2)`;
134
+ case AnchorSide.Bottom: return `calc(${styleTop} + ${sectionHeight})`;
135
+ case AnchorSide.Top:
136
+ default:
137
+ return styleTop;
138
+ }
139
+ }
140
+
141
+ function getStickyItemWrapperHeight(sticky: TStickyParams, itemHeight: number): number {
142
+ const end = sticky.to ?? 100;
143
+ return end - sticky.from + itemHeight;
144
+ }
145
+
104
146
  function parseSizing(sizing: string = 'manual'): Axis {
105
147
  const axisSizing = sizing.split(' ');
106
148
  return {
@@ -70,7 +70,7 @@ export const Section: FC<Props> = ({ section, data, children }) => {
70
70
  );
71
71
  };
72
72
 
73
- function getSectionHeight(heightData: TSectionHeight): string {
73
+ export function getSectionHeight(heightData: TSectionHeight): string {
74
74
  const { units, vhUnits, mode } = heightData;
75
75
  if (mode === SectionHeightMode.ViewportHeightUnits) return `${vhUnits}vh`;
76
76
  if (mode === SectionHeightMode.ControlUnits) return `${units * 100}vw`;
@@ -10,29 +10,41 @@ export const RectangleItem: FC<ItemProps<TRectangleItem>> = ({ item, sectionId }
10
10
  const id = useId();
11
11
  const { fillColor, radius, strokeWidth, strokeColor } = useRectangleItem(item, sectionId);
12
12
  const angle = useItemAngle(item, sectionId);
13
- const backgroundColor = useMemo(() => CntrlColor.parse(fillColor).toCss(), [fillColor]);
14
- const borderColor = useMemo(() => CntrlColor.parse(strokeColor).toCss(), [strokeColor]);
13
+ const backgroundColor = useMemo(() => CntrlColor.parse(fillColor), [fillColor]);
14
+ const borderColor = useMemo(() => CntrlColor.parse(strokeColor), [strokeColor]);
15
15
 
16
16
  return (
17
17
  <LinkWrapper url={item.link?.url}>
18
18
  <>
19
- <div className={`rectangle-${item.id}`}
19
+ <div className={`rectangle-${item.id}`}
20
20
  style={{
21
- backgroundColor: `${backgroundColor}`,
21
+ backgroundColor: `${backgroundColor.toCss()}`,
22
22
  borderRadius: `${radius * 100}vw`,
23
23
  borderWidth: `${strokeWidth * 100}vw`,
24
- borderColor: `${borderColor}`,
24
+ borderColor: `${borderColor.toCss()}`,
25
25
  transform: `rotate(${angle}deg)`
26
26
  }}
27
27
  />
28
28
  <JSXStyle id={id}>{`
29
- .rectangle-${item.id} {
30
- position: absolute;
31
- width: 100%;
32
- height: 100%;
33
- border-style: solid;
34
- box-sizing: border-box;
29
+ @supports (color: oklch(42% 0.3 90 / 1)) {
30
+ .rectangle-${item.id} {
31
+ background-color: ${backgroundColor.fmt('oklch')};
32
+ border-color: ${borderColor.fmt('oklch')};
35
33
  }
34
+ }
35
+ @supports not (color: oklch(42% 0.3 90 / 1)) {
36
+ .rectangle-${item.id} {
37
+ background-color: ${backgroundColor.fmt('rgba')};
38
+ border-color: ${borderColor.fmt('rgba')};
39
+ }
40
+ }
41
+ .rectangle-${item.id} {
42
+ position: absolute;
43
+ width: 100%;
44
+ height: 100%;
45
+ border-style: solid;
46
+ box-sizing: border-box;
47
+ }
36
48
  `}</JSXStyle>
37
49
  </>
38
50
  </LinkWrapper>
@@ -1,17 +1,32 @@
1
- import { FC } from 'react';
1
+ import { FC, useEffect, useState } from 'react';
2
2
  import { TRichTextItem } from '@cntrl-site/sdk';
3
3
  import JSXStyle from 'styled-jsx/style';
4
4
  import { ItemProps } from '../Item';
5
5
  import { useRichTextItem } from './useRichTextItem';
6
6
  import { useItemAngle } from '../useItemAngle';
7
7
 
8
- export const RichTextItem: FC<ItemProps<TRichTextItem>> = ({ item, sectionId }) => {
8
+ export const RichTextItem: FC<ItemProps<TRichTextItem>> = ({ item, sectionId, onResize }) => {
9
9
  const [content, styles, preset] = useRichTextItem(item);
10
+ const [ref, setRef] = useState<HTMLDivElement | null>(null);
10
11
  const angle = useItemAngle(item, sectionId);
11
12
  const className = preset ? `cntrl-preset-${preset.id}` : undefined;
13
+
14
+ useEffect(() => {
15
+ if (!ref || !onResize) return;
16
+ const observer = new ResizeObserver((entries) => {
17
+ const [entry] = entries;
18
+ onResize(entry.target.getBoundingClientRect().height / window.innerWidth);
19
+ });
20
+ observer.observe(ref);
21
+ return () => {
22
+ observer.unobserve(ref);
23
+ };
24
+ }, [ref, onResize]);
25
+
12
26
  return (
13
27
  <>
14
28
  <div
29
+ ref={setRef}
15
30
  className={className}
16
31
  style={{
17
32
  transform: `rotate(${angle}deg)`
@@ -1,4 +1,4 @@
1
- import { TArticleItemAny } from '@cntrl-site/sdk';
1
+ import { AnchorSide, TArticleItemAny } from '@cntrl-site/sdk';
2
2
  import { useKeyframeValue } from '../common/useKeyframeValue';
3
3
  import { useCurrentLayout } from '../common/useCurrentLayout';
4
4
 
@@ -11,6 +11,23 @@ export const useItemPosition = (item: TArticleItemAny, sectionId: string) => {
11
11
  sectionId,
12
12
  [layoutId]
13
13
  );
14
- return { top, left };
14
+ return {
15
+ top: getItemTopStyle(top, item.area[layoutId].anchorSide),
16
+ left: `${left * 100}vw`
17
+ };
15
18
  };
16
19
 
20
+ export function getItemTopStyle(top: number, anchorSide?: AnchorSide) {
21
+ const defaultValue = `${top * 100}vw`;
22
+ if (!anchorSide) return defaultValue;
23
+ switch (anchorSide) {
24
+ case AnchorSide.Top:
25
+ return defaultValue;
26
+ case AnchorSide.Center:
27
+ return `calc(50% + ${top * 100}vw)`;
28
+ case AnchorSide.Bottom:
29
+ return `calc(100% + ${top * 100}vw)`;
30
+ }
31
+ }
32
+
33
+
@@ -0,0 +1,19 @@
1
+ import { useContext } from 'react';
2
+ import { CntrlContext } from '../provider/CntrlContext';
3
+ import { TLayout, TSectionHeight } from '@cntrl-site/sdk';
4
+ import { getSectionHeight } from './Section';
5
+
6
+ export const useSectionHeightData = (sectionId: string): Record<string, string> => {
7
+ const sectionHeightContext = useContext(CntrlContext);
8
+ const layouts = sectionHeightContext.layouts;
9
+ const sectionHeightData = sectionHeightContext.getSectionHeightData(sectionId);
10
+ return sectionHeightData ? getSectionHeightMap(sectionHeightData) : getDefaultHeightData(layouts);
11
+ };
12
+
13
+ export function getSectionHeightMap(sectionHeight: Record<string, TSectionHeight>): Record<string, string> {
14
+ return Object.fromEntries(Object.entries(sectionHeight).map(([sectionId, heightData]) => [sectionId, getSectionHeight(heightData)]));
15
+ }
16
+
17
+ function getDefaultHeightData(layouts: TLayout[]) {
18
+ return layouts.reduce((acc, layout) => ({...acc, [layout.id]: '0'}), {});
19
+ }
@@ -1,10 +1,17 @@
1
1
  import { CustomItemRegistry } from './CustomItemRegistry';
2
- import { TArticleSection, TLayout, TTypePresets } from '@cntrl-site/sdk';
2
+ import { TArticle, TArticleSection, TLayout, TProject, TSectionHeight, TTypePresets } from '@cntrl-site/sdk';
3
3
  import { CustomSectionRegistry } from './CustomSectionRegistry';
4
4
 
5
+ interface SdkContextInitProps {
6
+ typePresets: TTypePresets;
7
+ project: TProject;
8
+ article: TArticle;
9
+ }
10
+
5
11
  export class CntrlSdkContext {
6
12
  private _typePresets?: TTypePresets;
7
13
  private _layouts: TLayout[] = [];
14
+ private sectionHeightMap: Map<string, Record<string, TSectionHeight>> = new Map();
8
15
  constructor(
9
16
  public readonly customItems: CustomItemRegistry,
10
17
  public readonly customSections: CustomSectionRegistry
@@ -24,6 +31,12 @@ export class CntrlSdkContext {
24
31
  );
25
32
  }
26
33
 
34
+ init({ project, typePresets, article }: SdkContextInitProps) {
35
+ this.setTypePresets(typePresets);
36
+ this.setLayouts(project.layouts);
37
+ this.setSectionsHeight(article.sections);
38
+ }
39
+
27
40
  setTypePresets(typePresets: TTypePresets) {
28
41
  this._typePresets = typePresets;
29
42
  }
@@ -32,6 +45,17 @@ export class CntrlSdkContext {
32
45
  this._layouts = layouts;
33
46
  }
34
47
 
48
+ setSectionsHeight(sections: TArticleSection[]) {
49
+ for (const section of sections) {
50
+ this.sectionHeightMap.set(section.id, section.height)
51
+ }
52
+ }
53
+
54
+ getSectionHeightData(sectionId: string) {
55
+ const sectionHeightData = this.sectionHeightMap.get(sectionId);
56
+ return sectionHeightData;
57
+ }
58
+
35
59
  get layouts(): TLayout[] {
36
60
  return this._layouts;
37
61
  }
@@ -71,7 +71,7 @@ export class ArticleRectObserver extends EventEmitter<EventMap> {
71
71
  this.setScroll(scroll / this.articleWidth);
72
72
  };
73
73
 
74
- private handleResize (){
74
+ private handleResize() {
75
75
  if (!this.parent) return;
76
76
  const parentBoundary = this.parent.getBoundingClientRect();
77
77
  this.articleWidth = parentBoundary.width;
@@ -1,10 +0,0 @@
1
- <component name="InspectionProjectProfileManager">
2
- <profile version="1.0">
3
- <option name="myName" value="Project Default" />
4
- <inspection_tool class="DuplicatedCode" enabled="true" level="WEAK WARNING" enabled_by_default="true">
5
- <Languages>
6
- <language minSize="304" name="TypeScript" />
7
- </Languages>
8
- </inspection_tool>
9
- </profile>
10
- </component>
@@ -1,427 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="AutoImportSettings">
4
- <option name="autoReloadType" value="SELECTIVE" />
5
- </component>
6
- <component name="ChangeListManager">
7
- <list default="true" id="daade3cc-2214-4d1b-a6ad-012b8ae407bf" name="Changes" comment="CNTRL-1039: code fix" />
8
- <option name="SHOW_DIALOG" value="false" />
9
- <option name="HIGHLIGHT_CONFLICTS" value="true" />
10
- <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
11
- <option name="LAST_RESOLUTION" value="IGNORE" />
12
- </component>
13
- <component name="Git.Settings">
14
- <option name="RECENT_BRANCH_BY_REPOSITORY">
15
- <map>
16
- <entry key="$PROJECT_DIR$" value="main" />
17
- </map>
18
- </option>
19
- <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
20
- </component>
21
- <component name="MarkdownSettingsMigration">
22
- <option name="stateVersion" value="1" />
23
- </component>
24
- <component name="ProjectId" id="2H4nx2LrD2TTrbJMopYKifu02PK" />
25
- <component name="ProjectViewState">
26
- <option name="hideEmptyMiddlePackages" value="true" />
27
- <option name="showLibraryContents" value="true" />
28
- </component>
29
- <component name="PropertiesComponent">{
30
- &quot;keyToString&quot;: {
31
- &quot;RunOnceActivity.OpenProjectViewOnStart&quot;: &quot;true&quot;,
32
- &quot;RunOnceActivity.ShowReadmeOnStart&quot;: &quot;true&quot;,
33
- &quot;WebServerToolWindowFactoryState&quot;: &quot;false&quot;,
34
- &quot;last_opened_file_path&quot;: &quot;/Users/admin/Documents/CNTRL/sdk-nextjs&quot;,
35
- &quot;node.js.detected.package.eslint&quot;: &quot;true&quot;,
36
- &quot;node.js.detected.package.tslint&quot;: &quot;true&quot;,
37
- &quot;node.js.selected.package.eslint&quot;: &quot;(autodetect)&quot;,
38
- &quot;node.js.selected.package.tslint&quot;: &quot;(autodetect)&quot;,
39
- &quot;nodejs_package_manager_path&quot;: &quot;npm&quot;,
40
- &quot;ts.external.directory.path&quot;: &quot;/Users/admin/Documents/CNTRL/sdk-nextjs/node_modules/typescript/lib&quot;,
41
- &quot;vue.rearranger.settings.migration&quot;: &quot;true&quot;
42
- }
43
- }</component>
44
- <component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
45
- <component name="TaskManager">
46
- <task active="true" id="Default" summary="Default task">
47
- <changelist id="daade3cc-2214-4d1b-a6ad-012b8ae407bf" name="Changes" comment="" />
48
- <created>1667553465933</created>
49
- <option name="number" value="Default" />
50
- <option name="presentableId" value="Default" />
51
- <updated>1667553465933</updated>
52
- <workItem from="1667553467855" duration="59000" />
53
- <workItem from="1667577252000" duration="8061000" />
54
- <workItem from="1667926766782" duration="2182000" />
55
- <workItem from="1668162212487" duration="28710000" />
56
- <workItem from="1669397663981" duration="8121000" />
57
- <workItem from="1669630429786" duration="5568000" />
58
- <workItem from="1669712625667" duration="100000" />
59
- <workItem from="1670846885306" duration="14667000" />
60
- <workItem from="1670922174491" duration="24668000" />
61
- <workItem from="1683273070032" duration="33669000" />
62
- <workItem from="1685023468162" duration="174000" />
63
- <workItem from="1685024252092" duration="9689000" />
64
- <workItem from="1685346557713" duration="1029000" />
65
- <workItem from="1685951123113" duration="73662000" />
66
- </task>
67
- <task id="LOCAL-00001" summary="CNTRL-484 - added embed vimeo video">
68
- <created>1667586762678</created>
69
- <option name="number" value="00001" />
70
- <option name="presentableId" value="LOCAL-00001" />
71
- <option name="project" value="LOCAL" />
72
- <updated>1667586762678</updated>
73
- </task>
74
- <task id="LOCAL-00002" summary="CNTRL-484 - problem fix">
75
- <created>1667587045426</created>
76
- <option name="number" value="00002" />
77
- <option name="presentableId" value="LOCAL-00002" />
78
- <option name="project" value="LOCAL" />
79
- <updated>1667587045426</updated>
80
- </task>
81
- <task id="LOCAL-00003" summary="CNTRL-484 - version bump">
82
- <created>1667587257510</created>
83
- <option name="number" value="00003" />
84
- <option name="presentableId" value="LOCAL-00003" />
85
- <option name="project" value="LOCAL" />
86
- <updated>1667587257510</updated>
87
- </task>
88
- <task id="LOCAL-00004" summary="CNTRL-486 - added youtube item">
89
- <created>1668184730139</created>
90
- <option name="number" value="00004" />
91
- <option name="presentableId" value="LOCAL-00004" />
92
- <option name="project" value="LOCAL" />
93
- <updated>1668184730139</updated>
94
- </task>
95
- <task id="LOCAL-00005" summary="CNTRL-486 - added youtube type">
96
- <created>1668185842201</created>
97
- <option name="number" value="00005" />
98
- <option name="presentableId" value="LOCAL-00005" />
99
- <option name="project" value="LOCAL" />
100
- <updated>1668185842201</updated>
101
- </task>
102
- <task id="LOCAL-00006" summary="CNTRL-486 - youtube fixes">
103
- <created>1668193338566</created>
104
- <option name="number" value="00006" />
105
- <option name="presentableId" value="LOCAL-00006" />
106
- <option name="project" value="LOCAL" />
107
- <updated>1668193338566</updated>
108
- </task>
109
- <task id="LOCAL-00007" summary="CNTRL-486 - added mute to video when autoplay On">
110
- <created>1668504184323</created>
111
- <option name="number" value="00007" />
112
- <option name="presentableId" value="LOCAL-00007" />
113
- <option name="project" value="LOCAL" />
114
- <updated>1668504184323</updated>
115
- </task>
116
- <task id="LOCAL-00008" summary="CNTRL-486 - added search params to Url">
117
- <created>1668506131079</created>
118
- <option name="number" value="00008" />
119
- <option name="presentableId" value="LOCAL-00008" />
120
- <option name="project" value="LOCAL" />
121
- <updated>1668506131079</updated>
122
- </task>
123
- <task id="LOCAL-00009" summary="CNTRL-486 - version update">
124
- <created>1668508864371</created>
125
- <option name="number" value="00009" />
126
- <option name="presentableId" value="LOCAL-00009" />
127
- <option name="project" value="LOCAL" />
128
- <updated>1668508864371</updated>
129
- </task>
130
- <task id="LOCAL-00010" summary="CNTRL-486 - version bump">
131
- <created>1668509275485</created>
132
- <option name="number" value="00010" />
133
- <option name="presentableId" value="LOCAL-00010" />
134
- <option name="project" value="LOCAL" />
135
- <updated>1668509275485</updated>
136
- </task>
137
- <task id="LOCAL-00011" summary="CNTRL-486 - version bump">
138
- <created>1668509525445</created>
139
- <option name="number" value="00011" />
140
- <option name="presentableId" value="LOCAL-00011" />
141
- <option name="project" value="LOCAL" />
142
- <updated>1668509525445</updated>
143
- </task>
144
- <task id="LOCAL-00012" summary="CNTRL-486 - fixes">
145
- <created>1669397733023</created>
146
- <option name="number" value="00012" />
147
- <option name="presentableId" value="LOCAL-00012" />
148
- <option name="project" value="LOCAL" />
149
- <updated>1669397733023</updated>
150
- </task>
151
- <task id="LOCAL-00013" summary="CNTRL-486 - fixes">
152
- <created>1669402876183</created>
153
- <option name="number" value="00013" />
154
- <option name="presentableId" value="LOCAL-00013" />
155
- <option name="project" value="LOCAL" />
156
- <updated>1669402876183</updated>
157
- </task>
158
- <task id="LOCAL-00014" summary="CNTRL-486 - fixes">
159
- <created>1669402893251</created>
160
- <option name="number" value="00014" />
161
- <option name="presentableId" value="LOCAL-00014" />
162
- <option name="project" value="LOCAL" />
163
- <updated>1669402893251</updated>
164
- </task>
165
- <task id="LOCAL-00015" summary="CNTRL-486 - fixes">
166
- <created>1669405389296</created>
167
- <option name="number" value="00015" />
168
- <option name="presentableId" value="LOCAL-00015" />
169
- <option name="project" value="LOCAL" />
170
- <updated>1669405389296</updated>
171
- </task>
172
- <task id="LOCAL-00016" summary="CNTRL-486 - fixes">
173
- <created>1669405966077</created>
174
- <option name="number" value="00016" />
175
- <option name="presentableId" value="LOCAL-00016" />
176
- <option name="project" value="LOCAL" />
177
- <updated>1669405966077</updated>
178
- </task>
179
- <task id="LOCAL-00017" summary="CNTRL-486 - version bump">
180
- <created>1669408571358</created>
181
- <option name="number" value="00017" />
182
- <option name="presentableId" value="LOCAL-00017" />
183
- <option name="project" value="LOCAL" />
184
- <updated>1669408571358</updated>
185
- </task>
186
- <task id="LOCAL-00018" summary="CNTRL-617 Youtube anf vimeo videos Url update">
187
- <created>1669635492235</created>
188
- <option name="number" value="00018" />
189
- <option name="presentableId" value="LOCAL-00018" />
190
- <option name="project" value="LOCAL" />
191
- <updated>1669635492235</updated>
192
- </task>
193
- <task id="LOCAL-00019" summary="CNTRL-617 Version bump">
194
- <created>1669635593460</created>
195
- <option name="number" value="00019" />
196
- <option name="presentableId" value="LOCAL-00019" />
197
- <option name="project" value="LOCAL" />
198
- <updated>1669635593460</updated>
199
- </task>
200
- <task id="LOCAL-00020" summary="CNTRL-694 added valid url builder">
201
- <created>1670861002829</created>
202
- <option name="number" value="00020" />
203
- <option name="presentableId" value="LOCAL-00020" />
204
- <option name="project" value="LOCAL" />
205
- <updated>1670861002829</updated>
206
- </task>
207
- <task id="LOCAL-00021" summary="CNTRL-694 added code styling and version bump">
208
- <created>1670862883753</created>
209
- <option name="number" value="00021" />
210
- <option name="presentableId" value="LOCAL-00021" />
211
- <option name="project" value="LOCAL" />
212
- <updated>1670862883753</updated>
213
- </task>
214
- <task id="LOCAL-00022" summary="CNTRL-694 comments fix">
215
- <created>1670864771128</created>
216
- <option name="number" value="00022" />
217
- <option name="presentableId" value="LOCAL-00022" />
218
- <option name="project" value="LOCAL" />
219
- <updated>1670864771128</updated>
220
- </task>
221
- <task id="LOCAL-00023" summary="CNTRL-694 undefined url fix">
222
- <created>1670947749514</created>
223
- <option name="number" value="00023" />
224
- <option name="presentableId" value="LOCAL-00023" />
225
- <option name="project" value="LOCAL" />
226
- <updated>1670947749514</updated>
227
- </task>
228
- <task id="LOCAL-00024" summary="CNTRL-694 version bump">
229
- <created>1670948708761</created>
230
- <option name="number" value="00024" />
231
- <option name="presentableId" value="LOCAL-00024" />
232
- <option name="project" value="LOCAL" />
233
- <updated>1670948708762</updated>
234
- </task>
235
- <task id="LOCAL-00025" summary="CNTRL-427: changed Item w and h params">
236
- <created>1670952164829</created>
237
- <option name="number" value="00025" />
238
- <option name="presentableId" value="LOCAL-00025" />
239
- <option name="project" value="LOCAL" />
240
- <updated>1670952164829</updated>
241
- </task>
242
- <task id="LOCAL-00026" summary="CNTRL-427: changed white-space prop to normal for all text aligns">
243
- <created>1671017859114</created>
244
- <option name="number" value="00026" />
245
- <option name="presentableId" value="LOCAL-00026" />
246
- <option name="project" value="LOCAL" />
247
- <updated>1671017859114</updated>
248
- </task>
249
- <task id="LOCAL-00027" summary="CNTRL-427: deleted unused import">
250
- <created>1671017914825</created>
251
- <option name="number" value="00027" />
252
- <option name="presentableId" value="LOCAL-00027" />
253
- <option name="project" value="LOCAL" />
254
- <updated>1671017914825</updated>
255
- </task>
256
- <task id="LOCAL-00028" summary="CNTRL-427: version bump">
257
- <created>1671097766100</created>
258
- <option name="number" value="00028" />
259
- <option name="presentableId" value="LOCAL-00028" />
260
- <option name="project" value="LOCAL" />
261
- <updated>1671097766100</updated>
262
- </task>
263
- <task id="LOCAL-00029" summary="CNTRL-861: added scale for item">
264
- <created>1683462977817</created>
265
- <option name="number" value="00029" />
266
- <option name="presentableId" value="LOCAL-00029" />
267
- <option name="project" value="LOCAL" />
268
- <updated>1683462977817</updated>
269
- </task>
270
- <task id="LOCAL-00030" summary="CNTRL-861: added scale to cover div">
271
- <created>1683464547773</created>
272
- <option name="number" value="00030" />
273
- <option name="presentableId" value="LOCAL-00030" />
274
- <option name="project" value="LOCAL" />
275
- <updated>1683464547774</updated>
276
- </task>
277
- <task id="LOCAL-00031" summary="CNTRL-861: fixes">
278
- <created>1683464779856</created>
279
- <option name="number" value="00031" />
280
- <option name="presentableId" value="LOCAL-00031" />
281
- <option name="project" value="LOCAL" />
282
- <updated>1683464779856</updated>
283
- </task>
284
- <task id="LOCAL-00032" summary="CNTRL-861: added rotate to items">
285
- <created>1683474659610</created>
286
- <option name="number" value="00032" />
287
- <option name="presentableId" value="LOCAL-00032" />
288
- <option name="project" value="LOCAL" />
289
- <updated>1683474659610</updated>
290
- </task>
291
- <task id="LOCAL-00033" summary="CNTRL-861: fixes">
292
- <created>1683474875208</created>
293
- <option name="number" value="00033" />
294
- <option name="presentableId" value="LOCAL-00033" />
295
- <option name="project" value="LOCAL" />
296
- <updated>1683474875208</updated>
297
- </task>
298
- <task id="LOCAL-00034" summary="CNTRL-861: fixes">
299
- <created>1683474899380</created>
300
- <option name="number" value="00034" />
301
- <option name="presentableId" value="LOCAL-00034" />
302
- <option name="project" value="LOCAL" />
303
- <updated>1683474899380</updated>
304
- </task>
305
- <task id="LOCAL-00035" summary="CNTRL-861: fixe">
306
- <created>1683476057882</created>
307
- <option name="number" value="00035" />
308
- <option name="presentableId" value="LOCAL-00035" />
309
- <option name="project" value="LOCAL" />
310
- <updated>1683476057882</updated>
311
- </task>
312
- <task id="LOCAL-00036" summary="CNTRL-861: comment fix">
313
- <created>1683477122292</created>
314
- <option name="number" value="00036" />
315
- <option name="presentableId" value="LOCAL-00036" />
316
- <option name="project" value="LOCAL" />
317
- <updated>1683477122292</updated>
318
- </task>
319
- <task id="LOCAL-00037" summary="CNTRL-1039: sdk version bump">
320
- <created>1685957591389</created>
321
- <option name="number" value="00037" />
322
- <option name="presentableId" value="LOCAL-00037" />
323
- <option name="project" value="LOCAL" />
324
- <updated>1685957591389</updated>
325
- </task>
326
- <task id="LOCAL-00038" summary="CNTRL-1039: WIP: added section registry class and changed article rect observer">
327
- <created>1686058816825</created>
328
- <option name="number" value="00038" />
329
- <option name="presentableId" value="LOCAL-00038" />
330
- <option name="project" value="LOCAL" />
331
- <updated>1686058816826</updated>
332
- </task>
333
- <task id="LOCAL-00039" summary="CNTRL-1039: added section base animations and sticky">
334
- <created>1686240635490</created>
335
- <option name="number" value="00039" />
336
- <option name="presentableId" value="LOCAL-00039" />
337
- <option name="project" value="LOCAL" />
338
- <updated>1686240635490</updated>
339
- </task>
340
- <task id="LOCAL-00040" summary="CNTRL-1039: code fix">
341
- <created>1686240730070</created>
342
- <option name="number" value="00040" />
343
- <option name="presentableId" value="LOCAL-00040" />
344
- <option name="project" value="LOCAL" />
345
- <updated>1686240730070</updated>
346
- </task>
347
- <task id="LOCAL-00041" summary="CNTRL-1039: code fix">
348
- <created>1686298003197</created>
349
- <option name="number" value="00041" />
350
- <option name="presentableId" value="LOCAL-00041" />
351
- <option name="project" value="LOCAL" />
352
- <updated>1686298003197</updated>
353
- </task>
354
- <task id="LOCAL-00042" summary="CNTRL-1039: sdk version bump">
355
- <created>1686299892024</created>
356
- <option name="number" value="00042" />
357
- <option name="presentableId" value="LOCAL-00042" />
358
- <option name="project" value="LOCAL" />
359
- <updated>1686299892024</updated>
360
- </task>
361
- <task id="LOCAL-00043" summary="CNTRL-1039: sdk version bump">
362
- <created>1686301611042</created>
363
- <option name="number" value="00043" />
364
- <option name="presentableId" value="LOCAL-00043" />
365
- <option name="project" value="LOCAL" />
366
- <updated>1686301611042</updated>
367
- </task>
368
- <task id="LOCAL-00044" summary="CNTRL-1039: removed section geometry service">
369
- <created>1686302079828</created>
370
- <option name="number" value="00044" />
371
- <option name="presentableId" value="LOCAL-00044" />
372
- <option name="project" value="LOCAL" />
373
- <updated>1686302079828</updated>
374
- </task>
375
- <task id="LOCAL-00045" summary="CNTRL-1039: code fix">
376
- <created>1686302624003</created>
377
- <option name="number" value="00045" />
378
- <option name="presentableId" value="LOCAL-00045" />
379
- <option name="project" value="LOCAL" />
380
- <updated>1686302624004</updated>
381
- </task>
382
- <option name="localTasksCounter" value="46" />
383
- <servers />
384
- </component>
385
- <component name="TypeScriptGeneratedFilesManager">
386
- <option name="version" value="3" />
387
- </component>
388
- <component name="Vcs.Log.Tabs.Properties">
389
- <option name="TAB_STATES">
390
- <map>
391
- <entry key="MAIN">
392
- <value>
393
- <State />
394
- </value>
395
- </entry>
396
- </map>
397
- </option>
398
- </component>
399
- <component name="VcsManagerConfiguration">
400
- <MESSAGE value="CNTRL-486 - version update" />
401
- <MESSAGE value="CNTRL-486 - fixes" />
402
- <MESSAGE value="CNTRL-486 - version bump" />
403
- <MESSAGE value="CNTRL-617 Youtube anf vimeo videos Url update" />
404
- <MESSAGE value="CNTRL-617 Version bump" />
405
- <MESSAGE value="CNTRL-694 added valid url builder" />
406
- <MESSAGE value="CNTRL-694 added code styling and version bump" />
407
- <MESSAGE value="CNTRL-694 comments fix" />
408
- <MESSAGE value="CNTRL-694 undefined url fix" />
409
- <MESSAGE value="CNTRL-694 version bump" />
410
- <MESSAGE value="CNTRL-427: changed Item w and h params" />
411
- <MESSAGE value="CNTRL-427: changed white-space prop to normal for all text aligns" />
412
- <MESSAGE value="CNTRL-427: deleted unused import" />
413
- <MESSAGE value="CNTRL-427: version bump" />
414
- <MESSAGE value="CNTRL-861: added scale for item" />
415
- <MESSAGE value="CNTRL-861: added scale to cover div" />
416
- <MESSAGE value="CNTRL-861: added rotate to items" />
417
- <MESSAGE value="CNTRL-861: fixes" />
418
- <MESSAGE value="CNTRL-861: fixe" />
419
- <MESSAGE value="CNTRL-861: comment fix" />
420
- <MESSAGE value="CNTRL-1039: WIP: added section registry class and changed article rect observer" />
421
- <MESSAGE value="CNTRL-1039: added section base animations and sticky" />
422
- <MESSAGE value="CNTRL-1039: sdk version bump" />
423
- <MESSAGE value="CNTRL-1039: removed section geometry service" />
424
- <MESSAGE value="CNTRL-1039: code fix" />
425
- <option name="LAST_COMMIT_MESSAGE" value="CNTRL-1039: code fix" />
426
- </component>
427
- </project>
Binary file
Binary file
@@ -1,51 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getItemTopStyle = exports.useItemSticky = void 0;
4
- const react_1 = require("react");
5
- const sdk_1 = require("@cntrl-site/sdk");
6
- const StickyManager_1 = require("../../utils/StickyManager/StickyManager");
7
- const useCurrentLayout_1 = require("../../common/useCurrentLayout");
8
- const ArticleRectContext_1 = require("../../provider/ArticleRectContext");
9
- const useItemSticky = (top, item, sectionId) => {
10
- const [isFixed, setIsFixed] = (0, react_1.useState)(false);
11
- const [adjustedTop, setAdjustedTop] = (0, react_1.useState)(top);
12
- const articleRectObserver = (0, react_1.useContext)(ArticleRectContext_1.ArticleRectContext);
13
- const layoutId = (0, useCurrentLayout_1.useCurrentLayout)();
14
- const sticky = (0, react_1.useMemo)(() => item.sticky[layoutId], [layoutId]);
15
- const stickyManager = (0, react_1.useMemo)(() => new StickyManager_1.StickyManager(sticky), [sticky]);
16
- const handleSticky = (0, react_1.useCallback)((scroll) => {
17
- setIsFixed(stickyManager.getIsSticky(scroll));
18
- setAdjustedTop(stickyManager.getPosition(scroll, top));
19
- }, [top, stickyManager]);
20
- (0, react_1.useEffect)(() => {
21
- if (!articleRectObserver)
22
- return;
23
- handleSticky(articleRectObserver.getSectionScroll(sectionId));
24
- }, [handleSticky, articleRectObserver]);
25
- (0, react_1.useEffect)(() => {
26
- if (!articleRectObserver || !sticky)
27
- return;
28
- return articleRectObserver.on('scroll', () => {
29
- handleSticky(articleRectObserver.getSectionScroll(sectionId));
30
- });
31
- }, [handleSticky, articleRectObserver, sticky]);
32
- return {
33
- isFixed,
34
- top: sticky ? `${adjustedTop * 100}vw` : getItemTopStyle(adjustedTop, layoutId ? item.area[layoutId].anchorSide : sdk_1.AnchorSide.Top)
35
- };
36
- };
37
- exports.useItemSticky = useItemSticky;
38
- function getItemTopStyle(top, anchorSide) {
39
- const defaultValue = `${top * 100}vw`;
40
- if (!anchorSide)
41
- return defaultValue;
42
- switch (anchorSide) {
43
- case sdk_1.AnchorSide.Top:
44
- return defaultValue;
45
- case sdk_1.AnchorSide.Center:
46
- return `calc(50% + ${top * 100}vw)`;
47
- case sdk_1.AnchorSide.Bottom:
48
- return `calc(100% + ${top * 100}vw)`;
49
- }
50
- }
51
- exports.getItemTopStyle = getItemTopStyle;
@@ -1,25 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.StickyManager = void 0;
4
- class StickyManager {
5
- constructor(sticky) {
6
- this.sticky = sticky;
7
- }
8
- getIsSticky(scroll) {
9
- if (!this.sticky)
10
- return false;
11
- return (this.sticky.from <= scroll) && (!this.sticky.to || this.sticky.to >= scroll);
12
- }
13
- getPosition(scroll, top) {
14
- if (!this.sticky)
15
- return top;
16
- if (this.getIsSticky(scroll)) {
17
- return top - this.sticky.from;
18
- }
19
- if (this.sticky.to !== undefined && this.sticky.to <= scroll) {
20
- return top + this.sticky.to - this.sticky.from;
21
- }
22
- return top;
23
- }
24
- }
25
- exports.StickyManager = StickyManager;
@@ -1,51 +0,0 @@
1
- import { useCallback, useContext, useEffect, useMemo, useState } from 'react';
2
- import { AnchorSide, TArticleItemAny } from '@cntrl-site/sdk';
3
- import { StickyManager } from '../../utils/StickyManager/StickyManager';
4
- import { useCurrentLayout } from '../../common/useCurrentLayout';
5
- import { ArticleRectContext } from '../../provider/ArticleRectContext';
6
-
7
- export const useItemSticky = (top: number, item: TArticleItemAny, sectionId: string) => {
8
- const [isFixed, setIsFixed] = useState(false);
9
- const [adjustedTop, setAdjustedTop] = useState(top);
10
- const articleRectObserver = useContext(ArticleRectContext);
11
- const layoutId = useCurrentLayout();
12
- const sticky = useMemo(() => item.sticky[layoutId], [layoutId]);
13
- const stickyManager = useMemo(() => new StickyManager(sticky), [sticky]);
14
-
15
- const handleSticky = useCallback((scroll: number) => {
16
- setIsFixed(stickyManager.getIsSticky(scroll));
17
- setAdjustedTop(stickyManager.getPosition(
18
- scroll,
19
- top
20
- ));
21
- }, [top, stickyManager]);
22
-
23
- useEffect(() => {
24
- if (!articleRectObserver) return;
25
- handleSticky(articleRectObserver.getSectionScroll(sectionId));
26
- }, [handleSticky, articleRectObserver]);
27
-
28
- useEffect(() => {
29
- if (!articleRectObserver || !sticky) return;
30
- return articleRectObserver.on('scroll', () => {
31
- handleSticky(articleRectObserver.getSectionScroll(sectionId));
32
- });
33
- }, [handleSticky, articleRectObserver, sticky]);
34
- return {
35
- isFixed,
36
- top: sticky ? `${adjustedTop * 100}vw` : getItemTopStyle(adjustedTop, layoutId ? item.area[layoutId].anchorSide : AnchorSide.Top)
37
- };
38
- };
39
-
40
- export function getItemTopStyle(top: number, anchorSide?: AnchorSide) {
41
- const defaultValue = `${top * 100}vw`;
42
- if (!anchorSide) return defaultValue;
43
- switch (anchorSide) {
44
- case AnchorSide.Top:
45
- return defaultValue;
46
- case AnchorSide.Center:
47
- return `calc(50% + ${top * 100}vw)`;
48
- case AnchorSide.Bottom:
49
- return `calc(100% + ${top * 100}vw)`;
50
- }
51
- }