@cntrl-site/sdk-nextjs 1.8.18-alpha.0 → 1.8.18

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.
Binary file
@@ -73,7 +73,13 @@ const VideoItem = ({ item, sectionId, onResize, interactionCtrl, onVisibilityCha
73
73
  ? ((0, jsx_runtime_1.jsx)(ScrollPlaybackVideo_1.ScrollPlaybackVideo, { sectionId: sectionId, src: item.commonParams.url, playbackParams: scrollPlayback, style: inlineStyles, className: `video video-playback-wrapper video-${item.id}` }))
74
74
  : ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: hasGLEffect && isFXAllowed
75
75
  ? ((0, jsx_runtime_1.jsx)("canvas", { style: inlineStyles, ref: fxCanvas, className: `video-canvas video-${item.id}`, width: rectWidth, height: rectHeight }))
76
- : ((0, jsx_runtime_1.jsx)("video", { poster: (_p = item.commonParams.coverUrl) !== null && _p !== void 0 ? _p : '', ref: videoRef, autoPlay: true, muted: true, loop: true, playsInline: true, className: `video video-${item.id}`, style: inlineStyles, children: (0, jsx_runtime_1.jsx)("source", { src: item.commonParams.url }) })) })) }), (0, jsx_runtime_1.jsx)(style_1.default, { id: id, children: `
76
+ : ((0, jsx_runtime_1.jsx)("video", { poster: (_p = item.commonParams.coverUrl) !== null && _p !== void 0 ? _p : '', ref: videoRef, autoPlay: true, muted: true, onPlay: () => {
77
+ console.log('play');
78
+ }, onPause: () => {
79
+ console.log('pause');
80
+ }, onEnded: () => {
81
+ console.log('ended');
82
+ }, loop: true, playsInline: true, className: `video video-${item.id}`, style: inlineStyles, children: (0, jsx_runtime_1.jsx)("source", { src: item.commonParams.url }) })) })) }), (0, jsx_runtime_1.jsx)(style_1.default, { id: id, children: `
77
83
  .video-wrapper-${item.id} {
78
84
  position: absolute;
79
85
  overflow: hidden;
@@ -93,8 +93,6 @@ class InteractionsRegistry {
93
93
  for (const interaction of this.interactions) {
94
94
  const { triggers } = interaction;
95
95
  for (const trigger of triggers) {
96
- if (!('itemId' in trigger))
97
- continue;
98
96
  if (trigger.itemId !== itemId)
99
97
  continue;
100
98
  if (activeStates.includes(trigger.from)) {
@@ -104,107 +102,12 @@ class InteractionsRegistry {
104
102
  }
105
103
  return available;
106
104
  }
107
- notifyLoad() {
105
+ notifyTrigger(itemId, triggerType) {
108
106
  var _a, _b;
109
107
  const timestamp = Date.now();
110
108
  for (const interaction of this.interactions) {
111
109
  const currentStateId = this.getCurrentStateByInteractionId(interaction.id);
112
- const matchingTrigger = interaction.triggers.find(trigger => 'position' in trigger && trigger.position === 0 && trigger.from === currentStateId);
113
- if (!matchingTrigger)
114
- continue;
115
- const activeStateId = this.getActiveInteractionState(interaction.id);
116
- const isNewStateActive = matchingTrigger.to === activeStateId;
117
- this.setCurrentStateForInteraction(interaction.id, matchingTrigger.to);
118
- const transitioningItems = (_a = this.stateItemsIdsMap[activeStateId]) !== null && _a !== void 0 ? _a : [];
119
- const state = interaction.states.find((state) => state.id === matchingTrigger.to);
120
- const actions = (_b = state === null || state === void 0 ? void 0 : state.actions) !== null && _b !== void 0 ? _b : [];
121
- for (const action of actions) {
122
- const ctrl = this.ctrls.get(action.itemId);
123
- if (!ctrl)
124
- continue;
125
- ctrl.receiveAction(action.type);
126
- }
127
- this.itemsStages = this.itemsStages.map((stage) => {
128
- if (stage.interactionId !== interaction.id)
129
- return stage;
130
- return {
131
- itemId: stage.itemId,
132
- interactionId: stage.interactionId,
133
- type: 'transitioning',
134
- from: stage.type === 'transitioning' ? stage.to : stage.stateId,
135
- to: matchingTrigger.to,
136
- direction: isNewStateActive ? 'in' : 'out',
137
- updated: timestamp
138
- };
139
- });
140
- const itemsToNotify = new Set(transitioningItems);
141
- for (const trigger of interaction.triggers) {
142
- if (!('itemId' in trigger))
143
- continue;
144
- itemsToNotify.add(trigger.itemId);
145
- }
146
- this.notifyItemCtrlsChange(Array.from(itemsToNotify));
147
- this.notifyTransitionStartForItems(transitioningItems, activeStateId);
148
- }
149
- }
150
- notifyScrollTrigger(position) {
151
- var _a, _b;
152
- const timestamp = Date.now();
153
- for (const interaction of this.interactions) {
154
- const currentStateId = this.getCurrentStateByInteractionId(interaction.id);
155
- const matchingTrigger = interaction.triggers.find((trigger) => {
156
- if (!('position' in trigger) || trigger.position === 0)
157
- return false;
158
- const isScrollingDown = trigger.position < position;
159
- const relevantState = isScrollingDown ? trigger.from : trigger.to;
160
- return relevantState === currentStateId;
161
- });
162
- if (!matchingTrigger || !('position' in matchingTrigger))
163
- 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 : [];
169
- 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 : [];
171
- for (const action of actions) {
172
- const ctrl = this.ctrls.get(action.itemId);
173
- if (!ctrl)
174
- continue;
175
- ctrl.receiveAction(action.type);
176
- }
177
- const itemsStages = this.itemsStages.map((stage) => {
178
- if (stage.interactionId !== interaction.id)
179
- return stage;
180
- return {
181
- itemId: stage.itemId,
182
- interactionId: stage.interactionId,
183
- type: 'transitioning',
184
- from: stage.type === 'transitioning' ? stage.to : stage.stateId,
185
- to: targetStateId,
186
- direction: isNewStateActive ? 'in' : 'out',
187
- updated: timestamp
188
- };
189
- });
190
- this.itemsStages = itemsStages;
191
- const itemsToNotify = new Set(transitioningItems);
192
- for (const trigger of interaction.triggers) {
193
- if (!('itemId' in trigger))
194
- continue;
195
- itemsToNotify.add(trigger.itemId);
196
- }
197
- this.notifyItemCtrlsChange(Array.from(itemsToNotify));
198
- this.notifyTransitionStartForItems(transitioningItems, activeStateId);
199
- }
200
- }
201
- notifyItemTrigger(itemId, triggerType) {
202
- var _a, _b;
203
- const timestamp = Date.now();
204
- for (const interaction of this.interactions) {
205
- const currentStateId = this.getCurrentStateByInteractionId(interaction.id);
206
- const matchingTrigger = interaction.triggers.find((trigger) => 'itemId' in trigger
207
- && trigger.itemId === itemId
110
+ const matchingTrigger = interaction.triggers.find((trigger) => trigger.itemId === itemId
208
111
  && trigger.from === currentStateId
209
112
  && trigger.type === triggerType);
210
113
  if (!matchingTrigger)
@@ -236,8 +139,6 @@ class InteractionsRegistry {
236
139
  });
237
140
  const itemsToNotify = new Set(transitioningItems);
238
141
  for (const trigger of interaction.triggers) {
239
- if (!('itemId' in trigger))
240
- continue;
241
142
  itemsToNotify.add(trigger.itemId);
242
143
  }
243
144
  this.notifyItemCtrlsChange(Array.from(itemsToNotify));
@@ -56,7 +56,7 @@ class ItemInteractionController {
56
56
  return triggers.has(triggerType);
57
57
  }
58
58
  sendTrigger(type) {
59
- this.registry.notifyItemTrigger(this.itemId, type);
59
+ this.registry.notifyTrigger(this.itemId, type);
60
60
  }
61
61
  receiveAction(type) {
62
62
  var _a;
@@ -5,35 +5,14 @@ const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("react");
6
6
  const InteractionsRegistry_1 = require("../interactions/InteractionsRegistry");
7
7
  const useCurrentLayout_1 = require("../common/useCurrentLayout");
8
- const ArticleRectContext_1 = require("./ArticleRectContext");
9
8
  exports.InteractionsContext = (0, react_1.createContext)(undefined);
10
9
  const InteractionsProvider = ({ article, children }) => {
11
10
  const { layoutId } = (0, useCurrentLayout_1.useCurrentLayout)();
12
- const articleRectObserver = (0, react_1.useContext)(ArticleRectContext_1.ArticleRectContext);
13
11
  const registry = (0, react_1.useMemo)(() => {
14
12
  if (!layoutId)
15
13
  return;
16
14
  return new InteractionsRegistry_1.InteractionsRegistry(article, layoutId);
17
15
  }, [layoutId]);
18
- (0, react_1.useEffect)(() => {
19
- if (!registry || !articleRectObserver)
20
- return;
21
- const handleScroll = () => {
22
- const scrollY = window.scrollY;
23
- registry.notifyScrollTrigger(scrollY);
24
- };
25
- return articleRectObserver.on('scroll', handleScroll);
26
- }, [registry, articleRectObserver]);
27
- (0, react_1.useEffect)(() => {
28
- if (!registry)
29
- return;
30
- registry.notifyLoad();
31
- const handleLoad = () => {
32
- registry.notifyLoad();
33
- };
34
- window.addEventListener('load', handleLoad);
35
- return () => window.removeEventListener('load', handleLoad);
36
- }, [registry]);
37
16
  return ((0, jsx_runtime_1.jsx)(exports.InteractionsContext.Provider, { value: registry, children: children }));
38
17
  };
39
18
  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",
4
4
  "description": "SDK for Next.js",
5
5
  "author": "arsen@momdesign.nyc",
6
6
  "license": "MIT",
@@ -31,7 +31,7 @@
31
31
  "@antfu/eslint-config": "^3.8.0",
32
32
  "@cntrl-site/color": "^1.0.0",
33
33
  "@cntrl-site/effects": "^1.4.0",
34
- "@cntrl-site/sdk": "^1.22.17-alpha.0",
34
+ "@cntrl-site/sdk": "^1.22.16",
35
35
  "@types/vimeo__player": "^2.18.0",
36
36
  "@vimeo/player": "^2.25.0",
37
37
  "html-react-parser": "^3.0.1",
@@ -24,7 +24,7 @@ export const ScrollPlaybackVideo: FC<Props> = ({ sectionId, src, playbackParams,
24
24
  const scrollPos = articleRectObserver.getSectionScroll(sectionId);
25
25
  const time = rangeMap(scrollPos, playbackParams.from, playbackParams.to, 0, 1, true);
26
26
  setTime(toFixed(time));
27
- });
27
+ })
28
28
  }, [playbackParams?.from, playbackParams?.to, time]);
29
29
 
30
30
  const scrollVideoManager = useMemo<ScrollPlaybackVideoManager | null>(() => {
@@ -120,6 +120,15 @@ export const VideoItem: FC<ItemProps<TVideoItem>> = ({ item, sectionId, onResize
120
120
  ref={videoRef}
121
121
  autoPlay
122
122
  muted
123
+ onPlay={() => {
124
+ console.log('play');
125
+ }}
126
+ onPause={() => {
127
+ console.log('pause');
128
+ }}
129
+ onEnded={() => {
130
+ console.log('ended');
131
+ }}
123
132
  loop
124
133
  playsInline
125
134
  className={`video video-${item.id}`}
@@ -3,7 +3,7 @@ import {
3
3
  Article,
4
4
  ArticleItemType,
5
5
  Interaction,
6
- InteractionItemTrigger,
6
+ InteractionTrigger,
7
7
  ItemAny,
8
8
  } from '@cntrl-site/sdk';
9
9
  import { isItemType } from '../utils/isItemType';
@@ -96,13 +96,12 @@ export class InteractionsRegistry implements InteractionsRegistryPort {
96
96
  return itemStyles;
97
97
  }
98
98
 
99
- getItemAvailableTriggers(itemId: string): Set<InteractionItemTrigger['type']> {
100
- const available = new Set<InteractionItemTrigger['type']>();
99
+ getItemAvailableTriggers(itemId: string): Set<InteractionTrigger['type']> {
100
+ const available = new Set<InteractionTrigger['type']>();
101
101
  const activeStates = Object.values(this.interactionStateMap);
102
102
  for (const interaction of this.interactions) {
103
103
  const { triggers } = interaction;
104
104
  for (const trigger of triggers) {
105
- if (!('itemId' in trigger)) continue;
106
105
  if (trigger.itemId !== itemId) continue;
107
106
  if (activeStates.includes(trigger.from)) {
108
107
  available.add(trigger.type);
@@ -112,102 +111,12 @@ export class InteractionsRegistry implements InteractionsRegistryPort {
112
111
  return available;
113
112
  }
114
113
 
115
- notifyLoad() {
116
- const timestamp = Date.now();
117
- for (const interaction of this.interactions) {
118
- const currentStateId = this.getCurrentStateByInteractionId(interaction.id);
119
- const matchingTrigger = interaction.triggers.find(trigger =>
120
- 'position' in trigger && trigger.position === 0 && trigger.from === currentStateId
121
- );
122
- if (!matchingTrigger) continue;
123
- const activeStateId = this.getActiveInteractionState(interaction.id);
124
- const isNewStateActive = matchingTrigger.to === activeStateId;
125
- this.setCurrentStateForInteraction(interaction.id, matchingTrigger.to);
126
- const transitioningItems = this.stateItemsIdsMap[activeStateId] ?? [];
127
- const state = interaction.states.find((state) => state.id === matchingTrigger.to);
128
- const actions = state?.actions ?? [];
129
- for (const action of actions) {
130
- const ctrl = this.ctrls.get(action.itemId);
131
- if (!ctrl) continue;
132
- ctrl.receiveAction(action.type);
133
- }
134
-
135
- this.itemsStages = this.itemsStages.map((stage) => {
136
- if (stage.interactionId !== interaction.id) return stage;
137
- return {
138
- itemId: stage.itemId,
139
- interactionId: stage.interactionId,
140
- type: 'transitioning',
141
- from: stage.type === 'transitioning' ? stage.to : stage.stateId!,
142
- to: matchingTrigger.to,
143
- direction: isNewStateActive ? 'in' : 'out',
144
- updated: timestamp
145
- };
146
- });
147
-
148
- const itemsToNotify = new Set<ItemId>(transitioningItems);
149
- for (const trigger of interaction.triggers) {
150
- if (!('itemId' in trigger)) continue;
151
- itemsToNotify.add(trigger.itemId);
152
- }
153
- this.notifyItemCtrlsChange(Array.from(itemsToNotify));
154
- this.notifyTransitionStartForItems(transitioningItems, activeStateId);
155
- }
156
- }
157
-
158
- notifyScrollTrigger(position: number) {
159
- const timestamp = Date.now();
160
- for (const interaction of this.interactions) {
161
- const currentStateId = this.getCurrentStateByInteractionId(interaction.id);
162
- const matchingTrigger = interaction.triggers.find((trigger) => {
163
- 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;
167
- });
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);
173
- const transitioningItems = this.stateItemsIdsMap[activeStateId] ?? [];
174
- const state = interaction.states.find((state) => state.id === targetStateId);
175
- const actions = state?.actions ?? [];
176
- for (const action of actions) {
177
- const ctrl = this.ctrls.get(action.itemId);
178
- if (!ctrl) continue;
179
- ctrl.receiveAction(action.type);
180
- }
181
- const itemsStages = this.itemsStages.map((stage) => {
182
- if (stage.interactionId !== interaction.id) return stage;
183
- return {
184
- itemId: stage.itemId,
185
- interactionId: stage.interactionId,
186
- type: 'transitioning' as const,
187
- from: stage.type === 'transitioning' ? stage.to : stage.stateId!,
188
- to: targetStateId,
189
- direction: isNewStateActive ? 'in' as const : 'out' as const,
190
- updated: timestamp
191
- };
192
- });
193
- this.itemsStages = itemsStages;
194
- const itemsToNotify = new Set<ItemId>(transitioningItems);
195
- for (const trigger of interaction.triggers) {
196
- if (!('itemId' in trigger)) continue;
197
- itemsToNotify.add(trigger.itemId);
198
- }
199
- this.notifyItemCtrlsChange(Array.from(itemsToNotify));
200
- this.notifyTransitionStartForItems(transitioningItems, activeStateId);
201
- }
202
- }
203
-
204
- notifyItemTrigger(itemId: string, triggerType: TriggerType): void {
114
+ notifyTrigger(itemId: string, triggerType: TriggerType): void {
205
115
  const timestamp = Date.now();
206
116
  for (const interaction of this.interactions) {
207
117
  const currentStateId = this.getCurrentStateByInteractionId(interaction.id);
208
118
  const matchingTrigger = interaction.triggers.find((trigger) =>
209
- 'itemId' in trigger
210
- && trigger.itemId === itemId
119
+ trigger.itemId === itemId
211
120
  && trigger.from === currentStateId
212
121
  && trigger.type === triggerType
213
122
  );
@@ -237,7 +146,6 @@ export class InteractionsRegistry implements InteractionsRegistryPort {
237
146
  });
238
147
  const itemsToNotify = new Set<ItemId>(transitioningItems);
239
148
  for (const trigger of interaction.triggers) {
240
- if (!('itemId' in trigger)) continue;
241
149
  itemsToNotify.add(trigger.itemId);
242
150
  }
243
151
  this.notifyItemCtrlsChange(Array.from(itemsToNotify));
@@ -361,7 +269,7 @@ type TransitioningStage = {
361
269
  type ActiveStage = { type: 'active'; itemId: string; interactionId: string; stateId?: string; isStartState: boolean; updated: number; };
362
270
  type InteractionStateMap = Record<InteractionId, StateId>;
363
271
  type StateItemsIdsMap = Record<StateId, ItemId[]>;
364
- type TriggerType = InteractionItemTrigger['type'];
272
+ type TriggerType = InteractionTrigger['type'];
365
273
  type InteractionId = string;
366
274
  type StateId = string;
367
275
  type ItemId = string;
@@ -1,12 +1,11 @@
1
1
  import { InteractionsRegistryPort, ItemInteractionCtrl } from './types';
2
2
  import { getTransition } from './getTransition';
3
3
  import { getStyleKeysFromCSSProperty } from './CSSPropertyNameMap';
4
- import { InteractionItemTrigger } from '@cntrl-site/sdk';
4
+ import { InteractionTrigger } from '@cntrl-site/sdk';
5
5
 
6
6
  export class ItemInteractionController implements ItemInteractionCtrl {
7
7
  private transitionsInProgress: Set<string> = new Set();
8
8
  private actionReceiver: ((type: 'play' | 'pause') => void) | undefined;
9
-
10
9
  constructor(
11
10
  private itemId: string,
12
11
  private registry: InteractionsRegistryPort,
@@ -30,13 +29,13 @@ export class ItemInteractionController implements ItemInteractionCtrl {
30
29
  };
31
30
  }
32
31
 
33
- getHasTrigger(itemId: string, triggerType: InteractionItemTrigger['type']): boolean {
32
+ getHasTrigger(itemId: string, triggerType: InteractionTrigger['type']): boolean {
34
33
  const triggers = this.registry.getItemAvailableTriggers(itemId);
35
34
  return triggers.has(triggerType);
36
35
  }
37
36
 
38
37
  sendTrigger(type: 'click' | 'hover-in' | 'hover-out') {
39
- this.registry.notifyItemTrigger(this.itemId, type);
38
+ this.registry.notifyTrigger(this.itemId, type);
40
39
  }
41
40
 
42
41
  receiveAction(type: 'play' | 'pause') {
@@ -1,8 +1,8 @@
1
- import { ArticleItemType, InteractionItemTrigger, 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: InteractionItemTrigger['type']): boolean;
5
+ getHasTrigger(itemId: string, triggerType: InteractionTrigger['type']): boolean;
6
6
  sendTrigger(type: 'click' | 'hover-in' | 'hover-out'): void;
7
7
  handleTransitionEnd?: (styleKey: string) => void;
8
8
  handleTransitionStart?: (styleKeys: string[]) => void;
@@ -14,8 +14,8 @@ export interface ItemInteractionCtrl {
14
14
  export interface InteractionsRegistryPort {
15
15
  register(itemId: string, ctrl: ItemInteractionCtrl): void;
16
16
  getStatePropsForItem(itemId: string): StateProps;
17
- getItemAvailableTriggers(itemId: string): Set<InteractionItemTrigger['type']>;
18
- notifyItemTrigger(itemId: string, type: TriggerType): void;
17
+ getItemAvailableTriggers(itemId: string): Set<InteractionTrigger['type']>;
18
+ notifyTrigger(itemId: string, type: TriggerType): void;
19
19
  notifyTransitionEnd(itemId: string): void;
20
20
  }
21
21
 
@@ -1,8 +1,7 @@
1
- import { createContext, FC, PropsWithChildren, useContext, useEffect, useMemo } from 'react';
1
+ import { createContext, FC, PropsWithChildren, useContext, 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';
5
- import { ArticleRectContext } from './ArticleRectContext';
6
5
 
7
6
  export const InteractionsContext = createContext<InteractionsRegistry | undefined>(undefined);
8
7
 
@@ -12,32 +11,10 @@ interface Props {
12
11
 
13
12
  export const InteractionsProvider: FC<PropsWithChildren<Props>> = ({ article, children }) => {
14
13
  const { layoutId } = useCurrentLayout();
15
- const articleRectObserver = useContext(ArticleRectContext);
16
14
  const registry = useMemo(() => {
17
15
  if (!layoutId) return;
18
16
  return new InteractionsRegistry(article, layoutId);
19
17
  }, [layoutId]);
20
-
21
- useEffect(() => {
22
- if (!registry || !articleRectObserver) return;
23
- const handleScroll = () => {
24
- const scrollY = window.scrollY;
25
- registry.notifyScrollTrigger(scrollY);
26
- };
27
- return articleRectObserver.on('scroll', handleScroll);
28
- }, [registry, articleRectObserver]);
29
-
30
- useEffect(() => {
31
- if (!registry) return;
32
- registry.notifyLoad();
33
-
34
- const handleLoad = () => {
35
- registry.notifyLoad();
36
- };
37
- window.addEventListener('load', handleLoad);
38
- return () => window.removeEventListener('load', handleLoad);
39
- }, [registry]);
40
-
41
18
  return (
42
19
  <InteractionsContext.Provider value={registry}>
43
20
  {children}