@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.
@@ -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: (_j = wrapperStateProps === null || wrapperStateProps === void 0 ? void 0 : wrapperStateProps.transition) !== null && _j !== void 0 ? _j : 'none' }), children: [(0, jsx_runtime_1.jsx)("div", { suppressHydrationWarning: true, className: `item-${item.id}`, style: {
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: (_k = innerStateProps === null || innerStateProps === void 0 ? void 0 : innerStateProps.transition) !== null && _k !== void 0 ? _k : 'none', 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: `
144
- ${(0, sdk_1.getLayoutStyles)(layouts, layoutValues, ([area, hidden, sticky, sectionHeight, layoutParams], exemplary) => {
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' && !controls) {
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
- this.notifyItemCtrlsChange(transitioningItems);
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cntrl-site/sdk-nextjs",
3
- "version": "1.1.2",
3
+ "version": "1.1.4",
4
4
  "description": "SDK for Next.js",
5
5
  "main": "lib/index.js",
6
6
  "types": "src/index.ts",
@@ -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], exemplary) => {
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' && !controls) {
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
- this.notifyItemCtrlsChange(transitioningItems);
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
  }