@cntrl-site/sdk-nextjs 1.1.2 → 1.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/components/Item.js +5 -4
- package/lib/components/items/VimeoEmbed.js +1 -1
- package/lib/interactions/InteractionsRegistry.js +20 -1
- package/lib/interactions/ItemInteractionCtrl.js +4 -0
- package/package.json +1 -1
- package/src/components/Item.tsx +3 -1
- package/src/components/items/VimeoEmbed.tsx +2 -1
- package/src/interactions/InteractionsRegistry.ts +20 -1
- package/src/interactions/ItemInteractionCtrl.ts +6 -0
- package/src/interactions/types.ts +3 -1
package/lib/components/Item.js
CHANGED
|
@@ -53,7 +53,7 @@ const RichTextWrapper = ({ isRichText, children }) => {
|
|
|
53
53
|
};
|
|
54
54
|
const noop = () => null;
|
|
55
55
|
const Item = ({ item, sectionId, articleHeight, isParentVisible = true, isInGroup = false }) => {
|
|
56
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
|
|
56
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
57
57
|
const itemWrapperRef = (0, react_1.useRef)(null);
|
|
58
58
|
const itemInnerRef = (0, react_1.useRef)(null);
|
|
59
59
|
const rectObserver = (0, react_1.useContext)(ArticleRectContext_1.ArticleRectContext);
|
|
@@ -119,11 +119,12 @@ const Item = ({ item, sectionId, articleHeight, isParentVisible = true, isInGrou
|
|
|
119
119
|
const width = ((_d = (_c = innerStateProps === null || innerStateProps === void 0 ? void 0 : innerStateProps.styles) === null || _c === void 0 ? void 0 : _c.width) !== null && _d !== void 0 ? _d : dimensions === null || dimensions === void 0 ? void 0 : dimensions.width);
|
|
120
120
|
const height = ((_f = (_e = innerStateProps === null || innerStateProps === void 0 ? void 0 : innerStateProps.styles) === null || _e === void 0 ? void 0 : _e.height) !== null && _f !== void 0 ? _f : dimensions === null || dimensions === void 0 ? void 0 : dimensions.height);
|
|
121
121
|
const scale = (_h = (_g = innerStateProps === null || innerStateProps === void 0 ? void 0 : innerStateProps.styles) === null || _g === void 0 ? void 0 : _g.scale) !== null && _h !== void 0 ? _h : itemScale;
|
|
122
|
+
const hasClickTriggers = (_j = interactionCtrl === null || interactionCtrl === void 0 ? void 0 : interactionCtrl.getHasTrigger(item.id, 'click')) !== null && _j !== void 0 ? _j : false;
|
|
122
123
|
return ((0, jsx_runtime_1.jsxs)("div", { className: `item-wrapper-${item.id}`, ref: itemWrapperRef, onTransitionEnd: (e) => {
|
|
123
124
|
var _a;
|
|
124
125
|
e.stopPropagation();
|
|
125
126
|
(_a = interactionCtrl === null || interactionCtrl === void 0 ? void 0 : interactionCtrl.handleTransitionEnd) === null || _a === void 0 ? void 0 : _a.call(interactionCtrl, e.propertyName);
|
|
126
|
-
}, style: Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (position ? { top: position.top } : {})), (position ? { left: position.left } : {})), (position ? { bottom: position.bottom } : {})), (wrapperHeight !== undefined ? { height: `${wrapperHeight * 100}vw` } : {})), { transition: (
|
|
127
|
+
}, style: Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, (position ? { top: position.top } : {})), (position ? { left: position.left } : {})), (position ? { bottom: position.bottom } : {})), (wrapperHeight !== undefined ? { height: `${wrapperHeight * 100}vw` } : {})), { transition: (_k = wrapperStateProps === null || wrapperStateProps === void 0 ? void 0 : wrapperStateProps.transition) !== null && _k !== void 0 ? _k : 'none' }), children: [(0, jsx_runtime_1.jsx)("div", { suppressHydrationWarning: true, className: `item-${item.id}`, style: {
|
|
127
128
|
opacity: (keyframes.length !== 0 && !layout) ? 0 : 1,
|
|
128
129
|
top: `${stickyTop * 100}vw`,
|
|
129
130
|
height: isRichText && itemHeight ? `${itemHeight * 100}vw` : 'unset',
|
|
@@ -140,8 +141,8 @@ const Item = ({ item, sectionId, articleHeight, isParentVisible = true, isInGrou
|
|
|
140
141
|
: `${width * 100}vw`
|
|
141
142
|
: 'max-content'}`,
|
|
142
143
|
height: `${sizingAxis.y === 'manual' ? `${height * 100}vw` : 'unset'}`
|
|
143
|
-
} : {})), (scale !== undefined ? { transform: `scale(${scale})`, 'WebkitTransform': `scale(${scale})` } : {})), { transition: (
|
|
144
|
-
${(0, sdk_1.getLayoutStyles)(layouts, layoutValues, ([area, hidden, sticky, sectionHeight, layoutParams]
|
|
144
|
+
} : {})), (scale !== undefined ? { transform: `scale(${scale})`, 'WebkitTransform': `scale(${scale})` } : {})), { transition: (_l = innerStateProps === null || innerStateProps === void 0 ? void 0 : innerStateProps.transition) !== null && _l !== void 0 ? _l : 'none', cursor: hasClickTriggers ? 'pointer' : 'unset', pointerEvents: allowPointerEvents ? 'auto' : 'none' }), children: (0, jsx_runtime_1.jsx)(ItemComponent, { item: item, sectionId: sectionId, onResize: handleItemResize, articleHeight: articleHeight, interactionCtrl: interactionCtrl, onVisibilityChange: handleVisibilityChange }) }) }) }), (0, jsx_runtime_1.jsx)(style_1.default, { id: id, children: `
|
|
145
|
+
${(0, sdk_1.getLayoutStyles)(layouts, layoutValues, ([area, hidden, sticky, sectionHeight, layoutParams]) => {
|
|
145
146
|
const sizingAxis = parseSizing(layoutParams.sizing);
|
|
146
147
|
const isScreenBasedBottom = area.positionType === sdk_1.PositionType.ScreenBased && area.anchorSide === sdk_1.AnchorSide.Bottom;
|
|
147
148
|
const scaleAnchor = area.scaleAnchor;
|
|
@@ -61,7 +61,7 @@ const VimeoEmbedItem = ({ item, sectionId, onResize, interactionCtrl, onVisibili
|
|
|
61
61
|
(0, react_1.useEffect)(() => {
|
|
62
62
|
if (!vimeoPlayer || !imgRef)
|
|
63
63
|
return;
|
|
64
|
-
if (play === 'on-click'
|
|
64
|
+
if (play === 'on-click') {
|
|
65
65
|
setIsCoverVisible(true);
|
|
66
66
|
}
|
|
67
67
|
vimeoPlayer.on('pause', (e) => {
|
|
@@ -93,6 +93,21 @@ class InteractionsRegistry {
|
|
|
93
93
|
}
|
|
94
94
|
return itemStyles;
|
|
95
95
|
}
|
|
96
|
+
getItemAvailableTriggers(itemId) {
|
|
97
|
+
const available = new Set();
|
|
98
|
+
const activeStates = Object.values(this.interactionStateMap);
|
|
99
|
+
for (const interaction of this.interactions) {
|
|
100
|
+
const { triggers } = interaction;
|
|
101
|
+
for (const trigger of triggers) {
|
|
102
|
+
if (trigger.itemId !== itemId)
|
|
103
|
+
continue;
|
|
104
|
+
if (activeStates.some((stateId) => trigger.from === stateId)) {
|
|
105
|
+
available.add(trigger.type);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return available;
|
|
110
|
+
}
|
|
96
111
|
notifyTrigger(itemId, triggerType) {
|
|
97
112
|
var _a;
|
|
98
113
|
const timestamp = Date.now();
|
|
@@ -120,7 +135,11 @@ class InteractionsRegistry {
|
|
|
120
135
|
updated: timestamp
|
|
121
136
|
};
|
|
122
137
|
});
|
|
123
|
-
|
|
138
|
+
const itemsToNotify = new Set(transitioningItems);
|
|
139
|
+
for (const trigger of interaction.triggers) {
|
|
140
|
+
itemsToNotify.add(trigger.itemId);
|
|
141
|
+
}
|
|
142
|
+
this.notifyItemCtrlsChange(Array.from(itemsToNotify));
|
|
124
143
|
this.notifyTransitionStartForItems(transitioningItems, activeStateId);
|
|
125
144
|
}
|
|
126
145
|
}
|
|
@@ -51,6 +51,10 @@ class ItemInteractionController {
|
|
|
51
51
|
transition
|
|
52
52
|
};
|
|
53
53
|
}
|
|
54
|
+
getHasTrigger(itemId, triggerType) {
|
|
55
|
+
const triggers = this.registry.getItemAvailableTriggers(itemId);
|
|
56
|
+
return triggers.has(triggerType);
|
|
57
|
+
}
|
|
54
58
|
sendTrigger(type) {
|
|
55
59
|
this.registry.notifyTrigger(this.itemId, type);
|
|
56
60
|
}
|
package/package.json
CHANGED
package/src/components/Item.tsx
CHANGED
|
@@ -161,6 +161,7 @@ export const Item: FC<ItemWrapperProps> = ({ item, sectionId, articleHeight, isP
|
|
|
161
161
|
const width = (innerStateProps?.styles?.width ?? dimensions?.width) as number | undefined;
|
|
162
162
|
const height = (innerStateProps?.styles?.height ?? dimensions?.height) as number | undefined;
|
|
163
163
|
const scale = innerStateProps?.styles?.scale ?? itemScale;
|
|
164
|
+
const hasClickTriggers = interactionCtrl?.getHasTrigger(item.id, 'click') ?? false;
|
|
164
165
|
return (
|
|
165
166
|
<div
|
|
166
167
|
className={`item-wrapper-${item.id}`}
|
|
@@ -209,6 +210,7 @@ export const Item: FC<ItemWrapperProps> = ({ item, sectionId, articleHeight, isP
|
|
|
209
210
|
height: `${sizingAxis.y === 'manual' ? `${height * 100}vw` : 'unset'}` } : {}),
|
|
210
211
|
...(scale !== undefined ? { transform: `scale(${scale})`, 'WebkitTransform': `scale(${scale})` } : {}),
|
|
211
212
|
transition: innerStateProps?.transition ?? 'none',
|
|
213
|
+
cursor: hasClickTriggers ? 'pointer' : 'unset',
|
|
212
214
|
pointerEvents: allowPointerEvents ? 'auto' : 'none'
|
|
213
215
|
}}
|
|
214
216
|
>
|
|
@@ -224,7 +226,7 @@ export const Item: FC<ItemWrapperProps> = ({ item, sectionId, articleHeight, isP
|
|
|
224
226
|
</RichTextWrapper>
|
|
225
227
|
</div>
|
|
226
228
|
<JSXStyle id={id}>{`
|
|
227
|
-
${getLayoutStyles(layouts, layoutValues, ([area, hidden, sticky, sectionHeight, layoutParams]
|
|
229
|
+
${getLayoutStyles(layouts, layoutValues, ([area, hidden, sticky, sectionHeight, layoutParams]) => {
|
|
228
230
|
const sizingAxis = parseSizing(layoutParams.sizing);
|
|
229
231
|
const isScreenBasedBottom = area.positionType === PositionType.ScreenBased && area.anchorSide === AnchorSide.Bottom;
|
|
230
232
|
const scaleAnchor = area.scaleAnchor as AreaAnchor;
|
|
@@ -51,7 +51,7 @@ export const VimeoEmbedItem: FC<ItemProps<TVimeoEmbedItem>> = ({ item, sectionId
|
|
|
51
51
|
|
|
52
52
|
useEffect(() => {
|
|
53
53
|
if (!vimeoPlayer || !imgRef) return;
|
|
54
|
-
if (play === 'on-click'
|
|
54
|
+
if (play === 'on-click') {
|
|
55
55
|
setIsCoverVisible(true);
|
|
56
56
|
}
|
|
57
57
|
vimeoPlayer.on('pause', (e) => {
|
|
@@ -77,6 +77,7 @@ export const VimeoEmbedItem: FC<ItemProps<TVimeoEmbedItem>> = ({ item, sectionId
|
|
|
77
77
|
vimeoPlayer!.play();
|
|
78
78
|
setIsCoverVisible(false);
|
|
79
79
|
};
|
|
80
|
+
|
|
80
81
|
const isInteractive = opacity !== 0;
|
|
81
82
|
useEffect(() => {
|
|
82
83
|
onVisibilityChange?.(isInteractive);
|
|
@@ -92,6 +92,21 @@ export class InteractionsRegistry implements InteractionsRegistryPort {
|
|
|
92
92
|
return itemStyles;
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
+
getItemAvailableTriggers(itemId: string): Set<InteractionTrigger['type']> {
|
|
96
|
+
const available = new Set<InteractionTrigger['type']>();
|
|
97
|
+
const activeStates = Object.values(this.interactionStateMap);
|
|
98
|
+
for (const interaction of this.interactions) {
|
|
99
|
+
const { triggers } = interaction;
|
|
100
|
+
for (const trigger of triggers) {
|
|
101
|
+
if (trigger.itemId !== itemId) continue;
|
|
102
|
+
if (activeStates.some((stateId) => trigger.from === stateId)) {
|
|
103
|
+
available.add(trigger.type);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return available;
|
|
108
|
+
}
|
|
109
|
+
|
|
95
110
|
notifyTrigger(itemId: string, triggerType: TriggerType): void {
|
|
96
111
|
const timestamp = Date.now();
|
|
97
112
|
for (const interaction of this.interactions) {
|
|
@@ -118,7 +133,11 @@ export class InteractionsRegistry implements InteractionsRegistryPort {
|
|
|
118
133
|
updated: timestamp
|
|
119
134
|
};
|
|
120
135
|
});
|
|
121
|
-
|
|
136
|
+
const itemsToNotify = new Set<ItemId>(transitioningItems);
|
|
137
|
+
for (const trigger of interaction.triggers) {
|
|
138
|
+
itemsToNotify.add(trigger.itemId);
|
|
139
|
+
}
|
|
140
|
+
this.notifyItemCtrlsChange(Array.from(itemsToNotify));
|
|
122
141
|
this.notifyTransitionStartForItems(transitioningItems, activeStateId);
|
|
123
142
|
}
|
|
124
143
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { InteractionsRegistryPort, ItemInteractionCtrl } from './types';
|
|
2
2
|
import { getTransition } from './getTransition';
|
|
3
3
|
import { getStyleKeysFromCSSProperty } from './CSSPropertyNameMap';
|
|
4
|
+
import { InteractionTrigger } from '@cntrl-site/sdk';
|
|
4
5
|
|
|
5
6
|
export class ItemInteractionController implements ItemInteractionCtrl {
|
|
6
7
|
private transitionsInProgress: Set<string> = new Set();
|
|
@@ -27,6 +28,11 @@ export class ItemInteractionController implements ItemInteractionCtrl {
|
|
|
27
28
|
};
|
|
28
29
|
}
|
|
29
30
|
|
|
31
|
+
getHasTrigger(itemId: string, triggerType: InteractionTrigger['type']): boolean {
|
|
32
|
+
const triggers = this.registry.getItemAvailableTriggers(itemId);
|
|
33
|
+
return triggers.has(triggerType);
|
|
34
|
+
}
|
|
35
|
+
|
|
30
36
|
sendTrigger(type: 'click' | 'hover-in' | 'hover-out') {
|
|
31
37
|
this.registry.notifyTrigger(this.itemId, type);
|
|
32
38
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { ArticleItemType, ItemState } from '@cntrl-site/sdk';
|
|
1
|
+
import { ArticleItemType, InteractionTrigger, ItemState } from '@cntrl-site/sdk';
|
|
2
2
|
|
|
3
3
|
export interface ItemInteractionCtrl {
|
|
4
4
|
getState(keys: string[]): StateCSSInfo;
|
|
5
|
+
getHasTrigger(itemId: string, triggerType: InteractionTrigger['type']): boolean;
|
|
5
6
|
sendTrigger(type: 'click' | 'hover-in' | 'hover-out'): void;
|
|
6
7
|
handleTransitionEnd?: (styleKey: string) => void;
|
|
7
8
|
handleTransitionStart?: (styleKeys: string[]) => void;
|
|
@@ -11,6 +12,7 @@ export interface ItemInteractionCtrl {
|
|
|
11
12
|
export interface InteractionsRegistryPort {
|
|
12
13
|
register(itemId: string, ctrl: ItemInteractionCtrl): void;
|
|
13
14
|
getStatePropsForItem(itemId: string): StateProps;
|
|
15
|
+
getItemAvailableTriggers(itemId: string): Set<InteractionTrigger['type']>;
|
|
14
16
|
notifyTrigger(itemId: string, type: TriggerType): void;
|
|
15
17
|
notifyTransitionEnd(itemId: string): void;
|
|
16
18
|
}
|