@cntrl-site/sdk-nextjs 1.8.18-alpha.0 → 1.8.18-alpha.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.
@@ -29,7 +29,6 @@ class InteractionsRegistry {
29
29
  }
30
30
  return map;
31
31
  }, {});
32
- const itemStages = this.getDefaultItemStages();
33
32
  const stateItemsIdsMap = activeStatesIds.reduce((map, stateId) => {
34
33
  map[stateId] = this.items
35
34
  .filter((item) => {
@@ -42,9 +41,10 @@ class InteractionsRegistry {
42
41
  return map;
43
42
  }, {});
44
43
  this.interactions = interactions;
45
- this.itemsStages = itemStages;
46
44
  this.stateItemsIdsMap = stateItemsIdsMap;
47
45
  this.interactionStateMap = interactionStateMap;
46
+ const itemStages = this.getDefaultItemStages();
47
+ this.itemsStages = itemStages;
48
48
  }
49
49
  register(itemId, ctrl) {
50
50
  this.ctrls.set(itemId, ctrl);
@@ -147,27 +147,31 @@ class InteractionsRegistry {
147
147
  this.notifyTransitionStartForItems(transitioningItems, activeStateId);
148
148
  }
149
149
  }
150
- notifyScrollTrigger(position) {
151
- var _a, _b;
150
+ notifyScroll(position) {
151
+ var _a, _b, _c;
152
152
  const timestamp = Date.now();
153
153
  for (const interaction of this.interactions) {
154
154
  const currentStateId = this.getCurrentStateByInteractionId(interaction.id);
155
+ const activeStateId = (_a = interaction.states.find((state) => state.id !== interaction.startStateId)) === null || _a === void 0 ? void 0 : _a.id;
155
156
  const matchingTrigger = interaction.triggers.find((trigger) => {
156
157
  if (!('position' in trigger) || trigger.position === 0)
157
158
  return false;
158
- const isScrollingDown = trigger.position < position;
159
- const relevantState = isScrollingDown ? trigger.from : trigger.to;
160
- return relevantState === currentStateId;
159
+ const triggerPosition = trigger.position * window.innerWidth;
160
+ const isScrolledPastTrigger = triggerPosition < position;
161
+ if (!isScrolledPastTrigger && !trigger.isReverse)
162
+ return false;
163
+ const stateId = isScrolledPastTrigger ? trigger.from : trigger.to;
164
+ return stateId === currentStateId;
161
165
  });
162
- if (!matchingTrigger || !('position' in matchingTrigger))
166
+ if (!matchingTrigger || !('position' in matchingTrigger) || !activeStateId)
163
167
  continue;
164
- const activeStateId = this.getActiveInteractionState(interaction.id);
165
- const targetStateId = matchingTrigger.position > position ? matchingTrigger.from : matchingTrigger.to;
166
- const isNewStateActive = targetStateId === activeStateId;
167
- this.setCurrentStateForInteraction(interaction.id, targetStateId !== null && targetStateId !== void 0 ? targetStateId : activeStateId);
168
- const transitioningItems = (_a = this.stateItemsIdsMap[activeStateId]) !== null && _a !== void 0 ? _a : [];
168
+ const triggerPosition = matchingTrigger.position * window.innerWidth;
169
+ const isScrolledPastTrigger = triggerPosition < position;
170
+ const targetStateId = isScrolledPastTrigger ? matchingTrigger.to : matchingTrigger.from;
171
+ this.setCurrentStateForInteraction(interaction.id, targetStateId);
172
+ const transitioningItems = (_b = this.stateItemsIdsMap[activeStateId]) !== null && _b !== void 0 ? _b : [];
169
173
  const state = interaction.states.find((state) => state.id === targetStateId);
170
- const actions = (_b = state === null || state === void 0 ? void 0 : state.actions) !== null && _b !== void 0 ? _b : [];
174
+ const actions = (_c = state === null || state === void 0 ? void 0 : state.actions) !== null && _c !== void 0 ? _c : [];
171
175
  for (const action of actions) {
172
176
  const ctrl = this.ctrls.get(action.itemId);
173
177
  if (!ctrl)
@@ -177,15 +181,16 @@ class InteractionsRegistry {
177
181
  const itemsStages = this.itemsStages.map((stage) => {
178
182
  if (stage.interactionId !== interaction.id)
179
183
  return stage;
180
- return {
184
+ const newStage = {
181
185
  itemId: stage.itemId,
182
186
  interactionId: stage.interactionId,
183
187
  type: 'transitioning',
184
188
  from: stage.type === 'transitioning' ? stage.to : stage.stateId,
185
189
  to: targetStateId,
186
- direction: isNewStateActive ? 'in' : 'out',
190
+ direction: targetStateId === activeStateId ? 'in' : 'out',
187
191
  updated: timestamp
188
192
  };
193
+ return newStage;
189
194
  });
190
195
  this.itemsStages = itemsStages;
191
196
  const itemsToNotify = new Set(transitioningItems);
@@ -322,6 +327,7 @@ class InteractionsRegistry {
322
327
  return allItems;
323
328
  }
324
329
  getDefaultItemStages() {
330
+ var _a;
325
331
  const timestamp = Date.now();
326
332
  const { items } = this;
327
333
  const stages = [];
@@ -338,7 +344,8 @@ class InteractionsRegistry {
338
344
  interactionId,
339
345
  type: 'active',
340
346
  isStartState: true,
341
- updated: timestamp
347
+ updated: timestamp,
348
+ stateId: (_a = this.interactions.find((interaction) => interaction.id === interactionId)) === null || _a === void 0 ? void 0 : _a.startStateId
342
349
  });
343
350
  }
344
351
  }
@@ -20,20 +20,35 @@ const InteractionsProvider = ({ article, children }) => {
20
20
  return;
21
21
  const handleScroll = () => {
22
22
  const scrollY = window.scrollY;
23
- registry.notifyScrollTrigger(scrollY);
23
+ registry.notifyScroll(scrollY);
24
24
  };
25
25
  return articleRectObserver.on('scroll', handleScroll);
26
26
  }, [registry, articleRectObserver]);
27
- (0, react_1.useEffect)(() => {
27
+ const notifyLoad = (0, react_1.useCallback)(() => {
28
28
  if (!registry)
29
29
  return;
30
- registry.notifyLoad();
31
- const handleLoad = () => {
32
- registry.notifyLoad();
33
- };
34
- window.addEventListener('load', handleLoad);
35
- return () => window.removeEventListener('load', handleLoad);
30
+ requestAnimationFrame(() => {
31
+ setTimeout(() => {
32
+ registry.notifyLoad();
33
+ }, 0);
34
+ });
36
35
  }, [registry]);
36
+ (0, react_1.useEffect)(() => {
37
+ if (document.readyState === 'complete') {
38
+ notifyLoad();
39
+ }
40
+ else {
41
+ window.addEventListener('load', notifyLoad);
42
+ }
43
+ return () => window.removeEventListener('load', notifyLoad);
44
+ }, [notifyLoad]);
45
+ (0, react_1.useEffect)(() => {
46
+ const log = () => {
47
+ console.log('load');
48
+ };
49
+ window.addEventListener('load', log);
50
+ return () => window.removeEventListener('load', log);
51
+ }, []);
37
52
  return ((0, jsx_runtime_1.jsx)(exports.InteractionsContext.Provider, { value: registry, children: children }));
38
53
  };
39
54
  exports.InteractionsProvider = InteractionsProvider;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cntrl-site/sdk-nextjs",
3
- "version": "1.8.18-alpha.0",
3
+ "version": "1.8.18-alpha.2",
4
4
  "description": "SDK for Next.js",
5
5
  "author": "arsen@momdesign.nyc",
6
6
  "license": "MIT",
@@ -39,7 +39,6 @@ export class InteractionsRegistry implements InteractionsRegistryPort {
39
39
  }
40
40
  return map;
41
41
  }, {});
42
- const itemStages = this.getDefaultItemStages();
43
42
  const stateItemsIdsMap = activeStatesIds.reduce<StateItemsIdsMap>((map, stateId) => {
44
43
  map[stateId] = this.items
45
44
  .filter((item) => {
@@ -51,9 +50,10 @@ export class InteractionsRegistry implements InteractionsRegistryPort {
51
50
  return map;
52
51
  }, {});
53
52
  this.interactions = interactions;
54
- this.itemsStages = itemStages;
55
53
  this.stateItemsIdsMap = stateItemsIdsMap;
56
54
  this.interactionStateMap = interactionStateMap;
55
+ const itemStages = this.getDefaultItemStages();
56
+ this.itemsStages = itemStages;
57
57
  }
58
58
 
59
59
  register(itemId: ItemId, ctrl: ItemInteractionCtrl) {
@@ -155,21 +155,24 @@ export class InteractionsRegistry implements InteractionsRegistryPort {
155
155
  }
156
156
  }
157
157
 
158
- notifyScrollTrigger(position: number) {
158
+ notifyScroll(position: number) {
159
159
  const timestamp = Date.now();
160
160
  for (const interaction of this.interactions) {
161
161
  const currentStateId = this.getCurrentStateByInteractionId(interaction.id);
162
+ const activeStateId = interaction.states.find((state) => state.id !== interaction.startStateId)?.id;
162
163
  const matchingTrigger = interaction.triggers.find((trigger) => {
163
164
  if (!('position' in trigger) || trigger.position === 0) return false;
164
- const isScrollingDown = trigger.position < position;
165
- const relevantState = isScrollingDown ? trigger.from : trigger.to;
166
- return relevantState === currentStateId;
165
+ const triggerPosition = trigger.position * window.innerWidth;
166
+ const isScrolledPastTrigger = triggerPosition < position;
167
+ if (!isScrolledPastTrigger && !trigger.isReverse) return false;
168
+ const stateId = isScrolledPastTrigger ? trigger.from : trigger.to;
169
+ return stateId === currentStateId;
167
170
  });
168
- if (!matchingTrigger || !('position' in matchingTrigger)) continue;
169
- const activeStateId = this.getActiveInteractionState(interaction.id);
170
- const targetStateId = matchingTrigger.position > position ? matchingTrigger.from : matchingTrigger.to;
171
- const isNewStateActive = targetStateId === activeStateId;
172
- this.setCurrentStateForInteraction(interaction.id, targetStateId ?? activeStateId);
171
+ if (!matchingTrigger || !('position' in matchingTrigger) || !activeStateId) continue;
172
+ const triggerPosition = matchingTrigger.position * window.innerWidth;
173
+ const isScrolledPastTrigger = triggerPosition < position;
174
+ const targetStateId = isScrolledPastTrigger ? matchingTrigger.to : matchingTrigger.from;
175
+ this.setCurrentStateForInteraction(interaction.id, targetStateId);
173
176
  const transitioningItems = this.stateItemsIdsMap[activeStateId] ?? [];
174
177
  const state = interaction.states.find((state) => state.id === targetStateId);
175
178
  const actions = state?.actions ?? [];
@@ -180,15 +183,16 @@ export class InteractionsRegistry implements InteractionsRegistryPort {
180
183
  }
181
184
  const itemsStages = this.itemsStages.map((stage) => {
182
185
  if (stage.interactionId !== interaction.id) return stage;
183
- return {
186
+ const newStage = {
184
187
  itemId: stage.itemId,
185
188
  interactionId: stage.interactionId,
186
189
  type: 'transitioning' as const,
187
190
  from: stage.type === 'transitioning' ? stage.to : stage.stateId!,
188
191
  to: targetStateId,
189
- direction: isNewStateActive ? 'in' as const : 'out' as const,
192
+ direction: targetStateId === activeStateId ? 'in' as const : 'out' as const,
190
193
  updated: timestamp
191
194
  };
195
+ return newStage;
192
196
  });
193
197
  this.itemsStages = itemsStages;
194
198
  const itemsToNotify = new Set<ItemId>(transitioningItems);
@@ -340,7 +344,8 @@ export class InteractionsRegistry implements InteractionsRegistryPort {
340
344
  interactionId,
341
345
  type: 'active',
342
346
  isStartState: true,
343
- updated: timestamp
347
+ updated: timestamp,
348
+ stateId: this.interactions.find((interaction) => interaction.id === interactionId)?.startStateId
344
349
  });
345
350
  }
346
351
  }
@@ -1,4 +1,4 @@
1
- import { createContext, FC, PropsWithChildren, useContext, useEffect, useMemo } from 'react';
1
+ import { createContext, FC, PropsWithChildren, useCallback, useContext, useEffect, useMemo } from 'react';
2
2
  import { InteractionsRegistry } from '../interactions/InteractionsRegistry';
3
3
  import { Article } from '@cntrl-site/sdk';
4
4
  import { useCurrentLayout } from '../common/useCurrentLayout';
@@ -22,21 +22,37 @@ export const InteractionsProvider: FC<PropsWithChildren<Props>> = ({ article, ch
22
22
  if (!registry || !articleRectObserver) return;
23
23
  const handleScroll = () => {
24
24
  const scrollY = window.scrollY;
25
- registry.notifyScrollTrigger(scrollY);
25
+ registry.notifyScroll(scrollY);
26
26
  };
27
27
  return articleRectObserver.on('scroll', handleScroll);
28
28
  }, [registry, articleRectObserver]);
29
29
 
30
- useEffect(() => {
30
+ const notifyLoad = useCallback(() => {
31
31
  if (!registry) return;
32
- registry.notifyLoad();
32
+ requestAnimationFrame(() => {
33
+ setTimeout(() => {
34
+ registry.notifyLoad();
35
+ }, 0);
36
+ });
37
+ }, [registry]);
38
+
39
+ useEffect(() => {
40
+ if (document.readyState === 'complete') {
41
+ notifyLoad();
42
+ } else {
43
+ window.addEventListener('load', notifyLoad);
44
+ }
33
45
 
34
- const handleLoad = () => {
35
- registry.notifyLoad();
46
+ return () => window.removeEventListener('load', notifyLoad);
47
+ }, [notifyLoad]);
48
+
49
+ useEffect(() => {
50
+ const log = () => {
51
+ console.log('load');
36
52
  };
37
- window.addEventListener('load', handleLoad);
38
- return () => window.removeEventListener('load', handleLoad);
39
- }, [registry]);
53
+ window.addEventListener('load', log);
54
+ return () => window.removeEventListener('load', log);
55
+ }, []);
40
56
 
41
57
  return (
42
58
  <InteractionsContext.Provider value={registry}>