@cntrl-site/sdk-nextjs 1.9.69 → 1.9.71-0

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.
Files changed (143) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +4 -4
  3. package/TODO.md +1 -1
  4. package/cntrl-site-sdk-nextjs-1.9.64-0.tgz +0 -0
  5. package/eslint.config.mjs +35 -35
  6. package/jest.config.js +6 -6
  7. package/lib/common/useItemFXData.js +5 -5
  8. package/lib/components/Article.js +6 -7
  9. package/lib/components/LayoutStyle.js +4 -4
  10. package/lib/components/Section/Section.js +49 -30
  11. package/lib/components/StructuredBlockItem/StructuredBlockItem.js +46 -0
  12. package/lib/components/StructuredBlockItem/StructuredComponent/StructuredComponent.js +48 -0
  13. package/lib/components/StructuredContent/StructuredContent.js +37 -0
  14. package/lib/components/items/CodeEmbedItem/CodeEmbedItem.js +36 -36
  15. package/lib/components/items/ComponentItem/ComponentItem.js +13 -13
  16. package/lib/components/items/CompoundItem/CompoundChild.js +20 -20
  17. package/lib/components/items/CompoundItem/CompoundItem.js +14 -14
  18. package/lib/components/items/CustomItem/CustomItem.js +9 -9
  19. package/lib/components/items/EmbedVideoItem/VimeoEmbed.js +24 -24
  20. package/lib/components/items/EmbedVideoItem/YoutubeEmbed.js +27 -27
  21. package/lib/components/items/FileItem/ImageItem.js +40 -40
  22. package/lib/components/items/FileItem/VideoItem.js +64 -64
  23. package/lib/components/items/GroupItem/GroupItem.js +14 -14
  24. package/lib/components/items/Item.js +32 -33
  25. package/lib/components/items/RectangleItem/RectangleItem.js +27 -27
  26. package/lib/components/items/RichTextItem/RichTextItem.js +22 -22
  27. package/lib/provider/CntrlSdkContext.js +1 -1
  28. package/lib/utils/RichTextConverter/RichTextConverter.js +21 -21
  29. package/package.json +62 -62
  30. package/src/ItemGeometry/CSSPropertyNameMap.ts +37 -37
  31. package/src/ItemGeometry/GenericGeometryController.ts +59 -59
  32. package/src/ItemGeometry/ItemGeometryContext.ts +4 -4
  33. package/src/ItemGeometry/ItemGeometryController.ts +22 -22
  34. package/src/ItemGeometry/ItemGeometryService.ts +34 -34
  35. package/src/ItemGeometry/RichTextGeometryController.ts +166 -166
  36. package/src/ItemGeometry/useItemGeometry.ts +25 -25
  37. package/src/common/useCurrentLayout.ts +52 -52
  38. package/src/common/useExemplary.ts +9 -9
  39. package/src/common/useItemFXData.ts +63 -63
  40. package/src/common/useKeyframeValue.ts +85 -85
  41. package/src/common/useRegisterResize.ts +16 -16
  42. package/src/components/Article.tsx +69 -75
  43. package/src/components/ArticleWrapper.tsx +21 -21
  44. package/src/components/Head.tsx +95 -95
  45. package/src/components/LayoutStyle.tsx +21 -21
  46. package/src/components/Page.tsx +47 -47
  47. package/src/components/ScrollPlaybackVideo.tsx +75 -75
  48. package/src/components/Section/Section.tsx +164 -130
  49. package/src/components/Section/SectionImage.tsx +48 -48
  50. package/src/components/Section/SectionVideo.tsx +144 -144
  51. package/src/components/Section/useSectionColor.ts +19 -19
  52. package/src/components/Section/useSectionHeightMap.ts +19 -19
  53. package/src/components/StructuredBlockItem/StructuredBlockItem.tsx +57 -0
  54. package/src/components/StructuredBlockItem/StructuredComponent/StructuredComponent.tsx +66 -0
  55. package/src/components/StructuredContent/StructuredContent.tsx +43 -0
  56. package/src/components/items/CodeEmbedItem/CodeEmbedItem.tsx +148 -148
  57. package/src/components/items/CodeEmbedItem/useCodeEmbedItem.ts +36 -36
  58. package/src/components/items/ComponentItem/ComponentItem.tsx +85 -85
  59. package/src/components/items/ComponentItem/useComponentItem.ts +35 -35
  60. package/src/components/items/CompoundItem/CompoundChild.tsx +151 -151
  61. package/src/components/items/CompoundItem/CompoundItem.tsx +88 -88
  62. package/src/components/items/CompoundItem/useCompoundItem.ts +21 -21
  63. package/src/components/items/CustomItem/CustomItem.tsx +50 -50
  64. package/src/components/items/EmbedVideoItem/VimeoEmbed.tsx +217 -217
  65. package/src/components/items/EmbedVideoItem/YoutubeEmbed.tsx +201 -201
  66. package/src/components/items/EmbedVideoItem/useEmbedVideoItem.ts +46 -46
  67. package/src/components/items/FileItem/ImageItem.tsx +166 -166
  68. package/src/components/items/FileItem/VideoItem.tsx +287 -287
  69. package/src/components/items/FileItem/useFileItem.ts +81 -81
  70. package/src/components/items/GroupItem/GroupItem.tsx +99 -99
  71. package/src/components/items/GroupItem/useGroupItem.ts +34 -34
  72. package/src/components/items/Item.tsx +268 -268
  73. package/src/components/items/LinkWrapper.tsx +39 -39
  74. package/src/components/items/RectangleItem/RectangleItem.tsx +177 -177
  75. package/src/components/items/RectangleItem/useRectangleItem.ts +89 -89
  76. package/src/components/items/RichTextItem/RichTextItem.tsx +113 -113
  77. package/src/components/items/RichTextItem/useRichTextItem.ts +12 -12
  78. package/src/components/items/RichTextWrapper.tsx +15 -15
  79. package/src/components/items/itemsMap.ts +28 -28
  80. package/src/components/items/useDraggable.ts +252 -252
  81. package/src/components/items/useItemAngle.ts +13 -13
  82. package/src/components/items/useItemArea.ts +35 -35
  83. package/src/components/items/useItemPointerEvents.ts +23 -23
  84. package/src/components/items/useItemScale.ts +17 -17
  85. package/src/components/items/useItemTriggers.ts +15 -15
  86. package/src/components/items/useRichTextItemValues.ts +66 -66
  87. package/src/components/items/useSizing.ts +25 -25
  88. package/src/components/items/useStickyItemTop.ts +21 -21
  89. package/src/components/useLayoutContext.ts +7 -7
  90. package/src/index.ts +25 -25
  91. package/src/interactions/InteractionsRegistry.ts +513 -512
  92. package/src/interactions/ItemInteractionCtrl.ts +78 -78
  93. package/src/interactions/getTransition.ts +27 -27
  94. package/src/interactions/types.ts +36 -36
  95. package/src/interactions/useItemInteractionCtrl.ts +18 -18
  96. package/src/provider/ArticleRectContext.ts +4 -4
  97. package/src/provider/CntrlContext.ts +5 -5
  98. package/src/provider/CntrlProvider.tsx +11 -11
  99. package/src/provider/CntrlSdkContext.ts +113 -113
  100. package/src/provider/CustomItemRegistry.ts +14 -14
  101. package/src/provider/CustomItemTypes.ts +3 -3
  102. package/src/provider/CustomSectionRegistry.ts +25 -25
  103. package/src/provider/InteractionsContext.tsx +73 -73
  104. package/src/provider/Keyframes.ts +11 -11
  105. package/src/provider/KeyframesContext.ts +5 -5
  106. package/src/provider/LayoutContext.ts +3 -3
  107. package/src/provider/WebGLContextManagerContext.tsx +4 -4
  108. package/src/provider/defaultContext.ts +8 -8
  109. package/src/provider/useCntrlContext.ts +8 -8
  110. package/src/styled-jsx.d.ts +1 -1
  111. package/src/types/components-utils.d.ts +7 -7
  112. package/src/utils/Animator/Animator.ts +570 -570
  113. package/src/utils/ArticleRectManager/ArticleRectObserver.ts +93 -93
  114. package/src/utils/ArticleRectManager/useArticleRectObserver.ts +17 -17
  115. package/src/utils/ArticleRectManager/useSectionRegistry.ts +11 -11
  116. package/src/utils/CSSNumeric.ts +19 -19
  117. package/src/utils/EventEmitter.ts +41 -41
  118. package/src/utils/RichTextConverter/RichTextConverter.tsx +342 -342
  119. package/src/utils/ScaleAnchorMap.ts +13 -13
  120. package/src/utils/StickyManager/StickyManager.ts +23 -23
  121. package/src/utils/Youtube/YouTubeIframeApiLoader.ts +58 -58
  122. package/src/utils/Youtube/YoutubeIframeApi.ts +101 -101
  123. package/src/utils/Youtube/useYouTubeIframeApi.ts +12 -12
  124. package/src/utils/areFillsVisible/areFillsVisible.test.ts +63 -63
  125. package/src/utils/areFillsVisible/areFillsVisible.ts +37 -37
  126. package/src/utils/binSearchInsertAt.ts +33 -33
  127. package/src/utils/castObject.ts +10 -10
  128. package/src/utils/checkOverflowClipSupport.ts +13 -13
  129. package/src/utils/domDfs.ts +11 -11
  130. package/src/utils/effects/useImageFx.ts +154 -154
  131. package/src/utils/effects/useVideoFx.ts +156 -156
  132. package/src/utils/evaluateComponentBundle.ts +83 -83
  133. package/src/utils/getAnchoredItemTop.ts +12 -12
  134. package/src/utils/getCompoundBoundaryStyles.ts +60 -60
  135. package/src/utils/getFill.ts +46 -46
  136. package/src/utils/getFontFamilyValue.ts +3 -3
  137. package/src/utils/getInvertedRanges.ts +43 -43
  138. package/src/utils/getItemTopStyle.ts +39 -39
  139. package/src/utils/getStyleFromItemStateAndParams.ts +8 -8
  140. package/src/utils/getValidYoutubeUrl.ts +29 -29
  141. package/src/utils/isItemType.ts +5 -5
  142. package/src/utils/rangeMap.ts +13 -13
  143. package/src/utils/useElementRect.ts +23 -23
@@ -1,151 +1,151 @@
1
- import React, {
2
- FC,
3
- useEffect,
4
- useId,
5
- useRef,
6
- } from 'react';
7
- import { useCntrlContext } from '../../../provider/useCntrlContext';
8
- import { useLayoutContext } from '../../useLayoutContext';
9
- import { useExemplary } from '../../../common/useExemplary';
10
- import { useItemScale } from '../useItemScale';
11
- import { useItemInteractionCtrl } from '../../../interactions/useItemInteractionCtrl';
12
- import { ArticleItemType, getLayoutStyles, ItemAny, AreaAnchor } from '@cntrl-site/sdk';
13
- import JSXStyle from 'styled-jsx/style';
14
- import { ScaleAnchorMap } from '../../../utils/ScaleAnchorMap';
15
- import { isItemType } from '../../../utils/isItemType';
16
- import { RichTextWrapper } from '../RichTextWrapper';
17
- import { itemsMap } from '../itemsMap';
18
- import {
19
- getCompoundHeight,
20
- getCompoundLeft,
21
- getCompoundTop,
22
- getCompoundTransform,
23
- getCompoundWidth
24
- } from '../../../utils/getCompoundBoundaryStyles';
25
- import { useItemTriggers } from '../useItemTriggers';
26
- import { parseSizing, useSizing } from '../useSizing';
27
- import { useItemPointerEvents } from '../useItemPointerEvents';
28
- import { useItemArea } from '../useItemArea';
29
-
30
- interface ChildItemProps {
31
- item: ItemAny;
32
- sectionId: string;
33
- isParentVisible?: boolean;
34
- }
35
-
36
- const noop = () => null;
37
-
38
- export const CompoundChild: FC<ChildItemProps> = ({ item, sectionId, isParentVisible = true }) => {
39
- const reactId = useId();
40
- const id = `${reactId}-compound-${item.id}`;
41
- const { layouts } = useCntrlContext();
42
- const layout = useLayoutContext();
43
- const exemplary = useExemplary();
44
- const { handleVisibilityChange, allowPointerEvents } = useItemPointerEvents(
45
- item.commonParams?.pointerEvents ?? 'when_visible',
46
- isParentVisible
47
- );
48
- const itemScale = useItemScale(item, sectionId);
49
- const interactionCtrl = useItemInteractionCtrl(item.id);
50
- const triggers = useItemTriggers(interactionCtrl);
51
- const wrapperStateProps = interactionCtrl?.getState<number>(['top', 'left', 'width', 'height']);
52
- const innerStateProps = interactionCtrl?.getState<number>(['scale']);
53
- const compoundSettings = layout && item.compoundSettings ? item.compoundSettings[layout] : undefined;
54
- const { width, height, top, left } = useItemArea(item, sectionId, {
55
- top: wrapperStateProps?.styles?.top as number,
56
- left: wrapperStateProps?.styles?.left as number,
57
- width: wrapperStateProps?.styles?.width as number,
58
- height: wrapperStateProps?.styles?.height as number
59
- });
60
- const isInitialRef = useRef(true);
61
- const sizingAxis = useSizing(item);
62
- const ItemComponent = itemsMap[item.type] || noop;
63
-
64
- useEffect(() => {
65
- isInitialRef.current = false;
66
- }, []);
67
-
68
- const transformOrigin = compoundSettings ? ScaleAnchorMap[compoundSettings.positionAnchor] : 'top left';
69
- const isRichText = isItemType(item, ArticleItemType.RichText);
70
- const scale = innerStateProps?.styles?.scale ?? itemScale;
71
- const hasClickTriggers = interactionCtrl?.getHasTrigger(item.id, 'click') ?? false;
72
- if (!item.compoundSettings) return null;
73
- const layoutValues: Record<string, any>[] = [item.area, item.hidden, item.compoundSettings];
74
- if (item.layoutParams) {
75
- layoutValues.push(item.layoutParams);
76
- }
77
- return (
78
- <div
79
- className={`item-${item.id}`}
80
- onTransitionEnd={(e) => {
81
- e.stopPropagation();
82
- interactionCtrl?.handleTransitionEnd?.(e.propertyName);
83
- }}
84
- style={{
85
- ...(top !== undefined && compoundSettings ? { top: getCompoundTop(compoundSettings, top) } : {}),
86
- ...(left !== undefined && compoundSettings ? { left: getCompoundLeft(compoundSettings, left) } : {}),
87
- ...(width !== undefined && compoundSettings
88
- ? { width: `${sizingAxis.x === 'manual'
89
- ? getCompoundWidth(compoundSettings, width, isRichText, exemplary)
90
- : 'max-content'}` }
91
- : {}),
92
- ...(height !== undefined && compoundSettings
93
- ? { height: `${sizingAxis.y === 'manual'
94
- ? getCompoundHeight(compoundSettings, height)
95
- : 'unset'}` }
96
- : {}),
97
- ...(compoundSettings ? { transform: `${getCompoundTransform(compoundSettings)}` } : {}),
98
- transition: wrapperStateProps?.transition ?? 'none',
99
- cursor: hasClickTriggers ? 'pointer' : 'unset',
100
- pointerEvents: allowPointerEvents ? 'auto' : 'none'
101
- }}
102
- {...triggers}
103
- >
104
- <div
105
- className={`item-${item.id}-inner`}
106
- style={{
107
- transition: innerStateProps?.transition ?? 'none',
108
- ...(scale !== undefined ? { transform: `scale(${scale})` } : {}),
109
- }}
110
- >
111
- <RichTextWrapper isRichText={isRichText} transformOrigin={transformOrigin}>
112
- <ItemComponent
113
- item={item}
114
- sectionId={sectionId}
115
- interactionCtrl={interactionCtrl}
116
- onVisibilityChange={handleVisibilityChange}
117
- isInCompound
118
- />
119
- </RichTextWrapper>
120
- </div>
121
- <JSXStyle id={id}>{`
122
- ${getLayoutStyles(layouts, layoutValues, ([area, hidden, compoundSettings, layoutParams]) => {
123
- const sizingAxis = parseSizing(layoutParams.sizing);
124
- const scaleAnchor = area.scaleAnchor as AreaAnchor;
125
- return (`
126
- .item-${item.id}-inner {
127
- width: 100%;
128
- height: 100%;
129
- transform-origin: ${ScaleAnchorMap[scaleAnchor]};
130
- transform: scale(${area.scale});
131
- }
132
- .item-${item.id} {
133
- position: absolute;
134
- top: ${getCompoundTop(compoundSettings, area.top)};
135
- left: ${getCompoundLeft(compoundSettings, area.left)};
136
- transition: opacity 0.2s linear 0.1s;
137
- display: ${hidden ? 'none' : 'block'};
138
- width: ${sizingAxis.x === 'manual'
139
- ? `${getCompoundWidth(compoundSettings, area.width, isRichText)}`
140
- : 'max-content'};
141
- height: ${sizingAxis.y === 'manual' ? `${getCompoundHeight(compoundSettings, area.height)}` : 'unset'};
142
- transform: ${getCompoundTransform(compoundSettings)};
143
- z-index: ${area.zIndex};
144
- }
145
- `);
146
- })}
147
- `}
148
- </JSXStyle>
149
- </div>
150
- );
151
- };
1
+ import React, {
2
+ FC,
3
+ useEffect,
4
+ useId,
5
+ useRef,
6
+ } from 'react';
7
+ import { useCntrlContext } from '../../../provider/useCntrlContext';
8
+ import { useLayoutContext } from '../../useLayoutContext';
9
+ import { useExemplary } from '../../../common/useExemplary';
10
+ import { useItemScale } from '../useItemScale';
11
+ import { useItemInteractionCtrl } from '../../../interactions/useItemInteractionCtrl';
12
+ import { ArticleItemType, getLayoutStyles, ItemAny, AreaAnchor } from '@cntrl-site/sdk';
13
+ import JSXStyle from 'styled-jsx/style';
14
+ import { ScaleAnchorMap } from '../../../utils/ScaleAnchorMap';
15
+ import { isItemType } from '../../../utils/isItemType';
16
+ import { RichTextWrapper } from '../RichTextWrapper';
17
+ import { itemsMap } from '../itemsMap';
18
+ import {
19
+ getCompoundHeight,
20
+ getCompoundLeft,
21
+ getCompoundTop,
22
+ getCompoundTransform,
23
+ getCompoundWidth
24
+ } from '../../../utils/getCompoundBoundaryStyles';
25
+ import { useItemTriggers } from '../useItemTriggers';
26
+ import { parseSizing, useSizing } from '../useSizing';
27
+ import { useItemPointerEvents } from '../useItemPointerEvents';
28
+ import { useItemArea } from '../useItemArea';
29
+
30
+ interface ChildItemProps {
31
+ item: ItemAny;
32
+ sectionId: string;
33
+ isParentVisible?: boolean;
34
+ }
35
+
36
+ const noop = () => null;
37
+
38
+ export const CompoundChild: FC<ChildItemProps> = ({ item, sectionId, isParentVisible = true }) => {
39
+ const reactId = useId();
40
+ const id = `${reactId}-compound-${item.id}`;
41
+ const { layouts } = useCntrlContext();
42
+ const layout = useLayoutContext();
43
+ const exemplary = useExemplary();
44
+ const { handleVisibilityChange, allowPointerEvents } = useItemPointerEvents(
45
+ item.commonParams?.pointerEvents ?? 'when_visible',
46
+ isParentVisible
47
+ );
48
+ const itemScale = useItemScale(item, sectionId);
49
+ const interactionCtrl = useItemInteractionCtrl(item.id);
50
+ const triggers = useItemTriggers(interactionCtrl);
51
+ const wrapperStateProps = interactionCtrl?.getState<number>(['top', 'left', 'width', 'height']);
52
+ const innerStateProps = interactionCtrl?.getState<number>(['scale']);
53
+ const compoundSettings = layout && item.compoundSettings ? item.compoundSettings[layout] : undefined;
54
+ const { width, height, top, left } = useItemArea(item, sectionId, {
55
+ top: wrapperStateProps?.styles?.top as number,
56
+ left: wrapperStateProps?.styles?.left as number,
57
+ width: wrapperStateProps?.styles?.width as number,
58
+ height: wrapperStateProps?.styles?.height as number
59
+ });
60
+ const isInitialRef = useRef(true);
61
+ const sizingAxis = useSizing(item);
62
+ const ItemComponent = itemsMap[item.type] || noop;
63
+
64
+ useEffect(() => {
65
+ isInitialRef.current = false;
66
+ }, []);
67
+
68
+ const transformOrigin = compoundSettings ? ScaleAnchorMap[compoundSettings.positionAnchor] : 'top left';
69
+ const isRichText = isItemType(item, ArticleItemType.RichText);
70
+ const scale = innerStateProps?.styles?.scale ?? itemScale;
71
+ const hasClickTriggers = interactionCtrl?.getHasTrigger(item.id, 'click') ?? false;
72
+ if (!item.compoundSettings) return null;
73
+ const layoutValues: Record<string, any>[] = [item.area, item.hidden, item.compoundSettings];
74
+ if (item.layoutParams) {
75
+ layoutValues.push(item.layoutParams);
76
+ }
77
+ return (
78
+ <div
79
+ className={`item-${item.id}`}
80
+ onTransitionEnd={(e) => {
81
+ e.stopPropagation();
82
+ interactionCtrl?.handleTransitionEnd?.(e.propertyName);
83
+ }}
84
+ style={{
85
+ ...(top !== undefined && compoundSettings ? { top: getCompoundTop(compoundSettings, top) } : {}),
86
+ ...(left !== undefined && compoundSettings ? { left: getCompoundLeft(compoundSettings, left) } : {}),
87
+ ...(width !== undefined && compoundSettings
88
+ ? { width: `${sizingAxis.x === 'manual'
89
+ ? getCompoundWidth(compoundSettings, width, isRichText, exemplary)
90
+ : 'max-content'}` }
91
+ : {}),
92
+ ...(height !== undefined && compoundSettings
93
+ ? { height: `${sizingAxis.y === 'manual'
94
+ ? getCompoundHeight(compoundSettings, height)
95
+ : 'unset'}` }
96
+ : {}),
97
+ ...(compoundSettings ? { transform: `${getCompoundTransform(compoundSettings)}` } : {}),
98
+ transition: wrapperStateProps?.transition ?? 'none',
99
+ cursor: hasClickTriggers ? 'pointer' : 'unset',
100
+ pointerEvents: allowPointerEvents ? 'auto' : 'none'
101
+ }}
102
+ {...triggers}
103
+ >
104
+ <div
105
+ className={`item-${item.id}-inner`}
106
+ style={{
107
+ transition: innerStateProps?.transition ?? 'none',
108
+ ...(scale !== undefined ? { transform: `scale(${scale})` } : {}),
109
+ }}
110
+ >
111
+ <RichTextWrapper isRichText={isRichText} transformOrigin={transformOrigin}>
112
+ <ItemComponent
113
+ item={item}
114
+ sectionId={sectionId}
115
+ interactionCtrl={interactionCtrl}
116
+ onVisibilityChange={handleVisibilityChange}
117
+ isInCompound
118
+ />
119
+ </RichTextWrapper>
120
+ </div>
121
+ <JSXStyle id={id}>{`
122
+ ${getLayoutStyles(layouts, layoutValues, ([area, hidden, compoundSettings, layoutParams]) => {
123
+ const sizingAxis = parseSizing(layoutParams.sizing);
124
+ const scaleAnchor = area.scaleAnchor as AreaAnchor;
125
+ return (`
126
+ .item-${item.id}-inner {
127
+ width: 100%;
128
+ height: 100%;
129
+ transform-origin: ${ScaleAnchorMap[scaleAnchor]};
130
+ transform: scale(${area.scale});
131
+ }
132
+ .item-${item.id} {
133
+ position: absolute;
134
+ top: ${getCompoundTop(compoundSettings, area.top)};
135
+ left: ${getCompoundLeft(compoundSettings, area.left)};
136
+ transition: opacity 0.2s linear 0.1s;
137
+ display: ${hidden ? 'none' : 'block'};
138
+ width: ${sizingAxis.x === 'manual'
139
+ ? `${getCompoundWidth(compoundSettings, area.width, isRichText)}`
140
+ : 'max-content'};
141
+ height: ${sizingAxis.y === 'manual' ? `${getCompoundHeight(compoundSettings, area.height)}` : 'unset'};
142
+ transform: ${getCompoundTransform(compoundSettings)};
143
+ z-index: ${area.zIndex};
144
+ }
145
+ `);
146
+ })}
147
+ `}
148
+ </JSXStyle>
149
+ </div>
150
+ );
151
+ };
@@ -1,88 +1,88 @@
1
- import React, { FC, useContext, useEffect, useId, useState } from 'react';
2
- import { useItemAngle } from '../useItemAngle';
3
- import { useCntrlContext } from '../../../provider/useCntrlContext';
4
- import { useRegisterResize } from '../../../common/useRegisterResize';
5
- import { getStyleFromItemStateAndParams } from '../../../utils/getStyleFromItemStateAndParams';
6
- import { LinkWrapper } from '../LinkWrapper';
7
- import { ItemProps } from '../Item';
8
- import JSXStyle from 'styled-jsx/style';
9
- import { getLayoutStyles, CompoundItem as TCompoundItem } from '@cntrl-site/sdk';
10
- import { CompoundChild } from './CompoundChild';
11
- import { useCompoundItem } from './useCompoundItem';
12
- import { useItemGeometry } from '../../../ItemGeometry/useItemGeometry';
13
- import { ItemGeometryContext } from '../../../ItemGeometry/ItemGeometryContext';
14
-
15
- export const CompoundItem: FC<ItemProps<TCompoundItem>> = ({ item, sectionId, onResize, interactionCtrl, onVisibilityChange }) => {
16
- const reactId = useId();
17
- const id = `${reactId}-compounditem-${item.id}`;
18
- const { items } = item;
19
- const itemIds = items ? items.map(item => item.id) : [];
20
- const itemAngle = useItemAngle(item, sectionId);
21
- const { layouts } = useCntrlContext();
22
- const { opacity: itemOpacity } = useCompoundItem(item, sectionId);
23
- const layoutValues: Record<string, any>[] = [item.area, item.layoutParams];
24
- const [ref, setRef] = useState<HTMLDivElement | null>(null);
25
- useRegisterResize(ref, onResize);
26
- useItemGeometry(item.id, ref);
27
- const itemGeometryService = useContext(ItemGeometryContext);
28
- const stateParams = interactionCtrl?.getState<number>(['opacity', 'angle']);
29
- const angle = getStyleFromItemStateAndParams(stateParams?.styles?.angle, itemAngle);
30
- const opacity = getStyleFromItemStateAndParams(stateParams?.styles?.opacity, itemOpacity);
31
- const isInteractive = opacity !== 0 && opacity !== undefined;
32
- useEffect(() => {
33
- onVisibilityChange?.(isInteractive);
34
- }, [isInteractive, onVisibilityChange]);
35
- useEffect(() => {
36
- // because on first render controllers not yet initialized
37
- setTimeout(() => {
38
- for (const id of itemIds) {
39
- const hasItem = itemGeometryService.hasItem(id);
40
- if (hasItem) {
41
- const cntrl = itemGeometryService.getControllerById(id);
42
- cntrl.setParentId(item.id);
43
- }
44
- }
45
- }, 0);
46
- }, [itemIds, item.id]);
47
- return (
48
- <LinkWrapper url={item.link?.url} target={item.link?.target}>
49
- <>
50
- <div
51
- className={`compound-${item.id}`}
52
- ref={setRef}
53
- style={{
54
- ...(opacity !== undefined ? { opacity } : {}),
55
- ...(angle !== undefined ? { transform: `rotate(${angle}deg)` } : {}),
56
- transition: stateParams?.transition ?? 'none'
57
- }}
58
- >
59
- {items && items.map(item => (
60
- <CompoundChild
61
- item={item}
62
- key={item.id}
63
- sectionId={sectionId}
64
- isParentVisible={isInteractive}
65
- />
66
- ))}
67
- </div>
68
- <JSXStyle id={id}>{`
69
- .compound-${item.id} {
70
- overflow: ${item.commonParams.overflow};
71
- position: absolute;
72
- width: 100%;
73
- height: 100%;
74
- box-sizing: border-box;
75
- }
76
- ${getLayoutStyles(layouts, layoutValues, ([area, layoutParams]) => {
77
- return (`
78
- .compound-${item.id} {
79
- opacity: ${layoutParams.opacity};
80
- transform: rotate(${area.angle}deg);
81
- }
82
- `);
83
- })}
84
- `}</JSXStyle>
85
- </>
86
- </LinkWrapper>
87
- );
88
- };
1
+ import React, { FC, useContext, useEffect, useId, useState } from 'react';
2
+ import { useItemAngle } from '../useItemAngle';
3
+ import { useCntrlContext } from '../../../provider/useCntrlContext';
4
+ import { useRegisterResize } from '../../../common/useRegisterResize';
5
+ import { getStyleFromItemStateAndParams } from '../../../utils/getStyleFromItemStateAndParams';
6
+ import { LinkWrapper } from '../LinkWrapper';
7
+ import { ItemProps } from '../Item';
8
+ import JSXStyle from 'styled-jsx/style';
9
+ import { getLayoutStyles, CompoundItem as TCompoundItem } from '@cntrl-site/sdk';
10
+ import { CompoundChild } from './CompoundChild';
11
+ import { useCompoundItem } from './useCompoundItem';
12
+ import { useItemGeometry } from '../../../ItemGeometry/useItemGeometry';
13
+ import { ItemGeometryContext } from '../../../ItemGeometry/ItemGeometryContext';
14
+
15
+ export const CompoundItem: FC<ItemProps<TCompoundItem>> = ({ item, sectionId, onResize, interactionCtrl, onVisibilityChange }) => {
16
+ const reactId = useId();
17
+ const id = `${reactId}-compounditem-${item.id}`;
18
+ const { items } = item;
19
+ const itemIds = items ? items.map(item => item.id) : [];
20
+ const itemAngle = useItemAngle(item, sectionId);
21
+ const { layouts } = useCntrlContext();
22
+ const { opacity: itemOpacity } = useCompoundItem(item, sectionId);
23
+ const layoutValues: Record<string, any>[] = [item.area, item.layoutParams];
24
+ const [ref, setRef] = useState<HTMLDivElement | null>(null);
25
+ useRegisterResize(ref, onResize);
26
+ useItemGeometry(item.id, ref);
27
+ const itemGeometryService = useContext(ItemGeometryContext);
28
+ const stateParams = interactionCtrl?.getState<number>(['opacity', 'angle']);
29
+ const angle = getStyleFromItemStateAndParams(stateParams?.styles?.angle, itemAngle);
30
+ const opacity = getStyleFromItemStateAndParams(stateParams?.styles?.opacity, itemOpacity);
31
+ const isInteractive = opacity !== 0 && opacity !== undefined;
32
+ useEffect(() => {
33
+ onVisibilityChange?.(isInteractive);
34
+ }, [isInteractive, onVisibilityChange]);
35
+ useEffect(() => {
36
+ // because on first render controllers not yet initialized
37
+ setTimeout(() => {
38
+ for (const id of itemIds) {
39
+ const hasItem = itemGeometryService.hasItem(id);
40
+ if (hasItem) {
41
+ const cntrl = itemGeometryService.getControllerById(id);
42
+ cntrl.setParentId(item.id);
43
+ }
44
+ }
45
+ }, 0);
46
+ }, [itemIds, item.id]);
47
+ return (
48
+ <LinkWrapper url={item.link?.url} target={item.link?.target}>
49
+ <>
50
+ <div
51
+ className={`compound-${item.id}`}
52
+ ref={setRef}
53
+ style={{
54
+ ...(opacity !== undefined ? { opacity } : {}),
55
+ ...(angle !== undefined ? { transform: `rotate(${angle}deg)` } : {}),
56
+ transition: stateParams?.transition ?? 'none'
57
+ }}
58
+ >
59
+ {items && items.map(item => (
60
+ <CompoundChild
61
+ item={item}
62
+ key={item.id}
63
+ sectionId={sectionId}
64
+ isParentVisible={isInteractive}
65
+ />
66
+ ))}
67
+ </div>
68
+ <JSXStyle id={id}>{`
69
+ .compound-${item.id} {
70
+ overflow: ${item.commonParams.overflow};
71
+ position: absolute;
72
+ width: 100%;
73
+ height: 100%;
74
+ box-sizing: border-box;
75
+ }
76
+ ${getLayoutStyles(layouts, layoutValues, ([area, layoutParams]) => {
77
+ return (`
78
+ .compound-${item.id} {
79
+ opacity: ${layoutParams.opacity};
80
+ transform: rotate(${area.angle}deg);
81
+ }
82
+ `);
83
+ })}
84
+ `}</JSXStyle>
85
+ </>
86
+ </LinkWrapper>
87
+ );
88
+ };
@@ -1,21 +1,21 @@
1
- import { CompoundItem, KeyframeType } from '@cntrl-site/sdk';
2
- import { useLayoutContext } from '../../useLayoutContext';
3
- import { useKeyframeValue } from '../../../common/useKeyframeValue';
4
-
5
- export function useCompoundItem(item: CompoundItem, sectionId: string) {
6
- const layoutId = useLayoutContext();
7
- const opacity = useKeyframeValue(
8
- item,
9
- KeyframeType.Opacity,
10
- (item, layoutId) => {
11
- if (!layoutId) return;
12
- const layoutParams = item.layoutParams[layoutId];
13
- return 'opacity' in layoutParams ? layoutParams.opacity : 1;
14
- },
15
- (animator, scroll, value) => value !== undefined ? animator.getOpacity({ opacity: value }, scroll).opacity : undefined,
16
- sectionId,
17
- [layoutId]
18
- );
19
-
20
- return { opacity };
21
- }
1
+ import { CompoundItem, KeyframeType } from '@cntrl-site/sdk';
2
+ import { useLayoutContext } from '../../useLayoutContext';
3
+ import { useKeyframeValue } from '../../../common/useKeyframeValue';
4
+
5
+ export function useCompoundItem(item: CompoundItem, sectionId: string) {
6
+ const layoutId = useLayoutContext();
7
+ const opacity = useKeyframeValue(
8
+ item,
9
+ KeyframeType.Opacity,
10
+ (item, layoutId) => {
11
+ if (!layoutId) return;
12
+ const layoutParams = item.layoutParams[layoutId];
13
+ return 'opacity' in layoutParams ? layoutParams.opacity : 1;
14
+ },
15
+ (animator, scroll, value) => value !== undefined ? animator.getOpacity({ opacity: value }, scroll).opacity : undefined,
16
+ sectionId,
17
+ [layoutId]
18
+ );
19
+
20
+ return { opacity };
21
+ }
@@ -1,50 +1,50 @@
1
- import { getLayoutStyles, CustomItem as TCustomItem } from '@cntrl-site/sdk';
2
- import { FC, useState } from 'react';
3
- import { useCntrlContext } from '../../../provider/useCntrlContext';
4
- import { ItemProps } from '../Item';
5
- import JSXStyle from 'styled-jsx/style';
6
- import { useRegisterResize } from '../../../common/useRegisterResize';
7
- import { useItemAngle } from '../useItemAngle';
8
- import { useItemGeometry } from '../../../ItemGeometry/useItemGeometry';
9
-
10
- export const CustomItem: FC<ItemProps<TCustomItem>> = ({ item, onResize, sectionId, interactionCtrl }) => {
11
- const sdk = useCntrlContext();
12
- const { layouts } = useCntrlContext();
13
- const itemAngle = useItemAngle(item, sectionId);
14
- const component = sdk.customItems.get(item.commonParams.name);
15
- const layoutValues: Record<string, any>[] = [item.area];
16
- const [ref, setRef] = useState<HTMLDivElement | null>(null);
17
- useRegisterResize(ref, onResize);
18
- useItemGeometry(item.id, ref);
19
- const stateParams = interactionCtrl?.getState<number>(['angle']);
20
- const angle = stateParams?.styles?.angle ?? itemAngle;
21
- if (!component) return null;
22
- return (
23
- <>
24
- <div
25
- className={`custom-component-${item.id}`}
26
- ref={setRef}
27
- style={{
28
- ...(angle !== undefined ? { transform: `rotate(${angle}deg)` } : {}),
29
- transition: stateParams?.transition ?? 'none'
30
- }}
31
- >
32
- {component({})}
33
- </div>
34
- <JSXStyle id={item.id}>
35
- {`${getLayoutStyles(layouts, layoutValues, ([area]) => {
36
- return (`
37
- .custom-component-${item.id} {
38
- transform: rotate(${area.angle}deg);
39
- height: 100%;
40
- width: 100%;
41
- position: absolute;
42
- left: 0;
43
- top: 0;
44
- }
45
- `);
46
- })}`}
47
- </JSXStyle>
48
- </>
49
- );
50
- };
1
+ import { getLayoutStyles, CustomItem as TCustomItem } from '@cntrl-site/sdk';
2
+ import { FC, useState } from 'react';
3
+ import { useCntrlContext } from '../../../provider/useCntrlContext';
4
+ import { ItemProps } from '../Item';
5
+ import JSXStyle from 'styled-jsx/style';
6
+ import { useRegisterResize } from '../../../common/useRegisterResize';
7
+ import { useItemAngle } from '../useItemAngle';
8
+ import { useItemGeometry } from '../../../ItemGeometry/useItemGeometry';
9
+
10
+ export const CustomItem: FC<ItemProps<TCustomItem>> = ({ item, onResize, sectionId, interactionCtrl }) => {
11
+ const sdk = useCntrlContext();
12
+ const { layouts } = useCntrlContext();
13
+ const itemAngle = useItemAngle(item, sectionId);
14
+ const component = sdk.customItems.get(item.commonParams.name);
15
+ const layoutValues: Record<string, any>[] = [item.area];
16
+ const [ref, setRef] = useState<HTMLDivElement | null>(null);
17
+ useRegisterResize(ref, onResize);
18
+ useItemGeometry(item.id, ref);
19
+ const stateParams = interactionCtrl?.getState<number>(['angle']);
20
+ const angle = stateParams?.styles?.angle ?? itemAngle;
21
+ if (!component) return null;
22
+ return (
23
+ <>
24
+ <div
25
+ className={`custom-component-${item.id}`}
26
+ ref={setRef}
27
+ style={{
28
+ ...(angle !== undefined ? { transform: `rotate(${angle}deg)` } : {}),
29
+ transition: stateParams?.transition ?? 'none'
30
+ }}
31
+ >
32
+ {component({})}
33
+ </div>
34
+ <JSXStyle id={item.id}>
35
+ {`${getLayoutStyles(layouts, layoutValues, ([area]) => {
36
+ return (`
37
+ .custom-component-${item.id} {
38
+ transform: rotate(${area.angle}deg);
39
+ height: 100%;
40
+ width: 100%;
41
+ position: absolute;
42
+ left: 0;
43
+ top: 0;
44
+ }
45
+ `);
46
+ })}`}
47
+ </JSXStyle>
48
+ </>
49
+ );
50
+ };