stream-chat-react-native-core 9.10.0 → 9.10.1-beta.1

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 (48) hide show
  1. package/lib/commonjs/components/UIComponents/PortalWhileClosingView.js +8 -5
  2. package/lib/commonjs/components/UIComponents/PortalWhileClosingView.js.map +1 -1
  3. package/lib/commonjs/contexts/overlayContext/ClosingPortalHostsLayer.js +8 -4
  4. package/lib/commonjs/contexts/overlayContext/ClosingPortalHostsLayer.js.map +1 -1
  5. package/lib/commonjs/contexts/overlayContext/MessageOverlayHostLayer.js +25 -11
  6. package/lib/commonjs/contexts/overlayContext/MessageOverlayHostLayer.js.map +1 -1
  7. package/lib/commonjs/contexts/overlayContext/OverlayHostLayerContext.js +10 -0
  8. package/lib/commonjs/contexts/overlayContext/OverlayHostLayerContext.js.map +1 -0
  9. package/lib/commonjs/contexts/overlayContext/OverlayProvider.js +16 -6
  10. package/lib/commonjs/contexts/overlayContext/OverlayProvider.js.map +1 -1
  11. package/lib/commonjs/state-store/message-overlay-store.js +47 -18
  12. package/lib/commonjs/state-store/message-overlay-store.js.map +1 -1
  13. package/lib/commonjs/version.json +1 -1
  14. package/lib/module/components/UIComponents/PortalWhileClosingView.js +8 -5
  15. package/lib/module/components/UIComponents/PortalWhileClosingView.js.map +1 -1
  16. package/lib/module/contexts/overlayContext/ClosingPortalHostsLayer.js +8 -4
  17. package/lib/module/contexts/overlayContext/ClosingPortalHostsLayer.js.map +1 -1
  18. package/lib/module/contexts/overlayContext/MessageOverlayHostLayer.js +25 -11
  19. package/lib/module/contexts/overlayContext/MessageOverlayHostLayer.js.map +1 -1
  20. package/lib/module/contexts/overlayContext/OverlayHostLayerContext.js +10 -0
  21. package/lib/module/contexts/overlayContext/OverlayHostLayerContext.js.map +1 -0
  22. package/lib/module/contexts/overlayContext/OverlayProvider.js +16 -6
  23. package/lib/module/contexts/overlayContext/OverlayProvider.js.map +1 -1
  24. package/lib/module/state-store/message-overlay-store.js +47 -18
  25. package/lib/module/state-store/message-overlay-store.js.map +1 -1
  26. package/lib/module/version.json +1 -1
  27. package/lib/typescript/components/UIComponents/PortalWhileClosingView.d.ts.map +1 -1
  28. package/lib/typescript/contexts/overlayContext/ClosingPortalHostsLayer.d.ts +10 -1
  29. package/lib/typescript/contexts/overlayContext/ClosingPortalHostsLayer.d.ts.map +1 -1
  30. package/lib/typescript/contexts/overlayContext/MessageOverlayHostLayer.d.ts +9 -1
  31. package/lib/typescript/contexts/overlayContext/MessageOverlayHostLayer.d.ts.map +1 -1
  32. package/lib/typescript/contexts/overlayContext/OverlayHostLayerContext.d.ts +8 -0
  33. package/lib/typescript/contexts/overlayContext/OverlayHostLayerContext.d.ts.map +1 -0
  34. package/lib/typescript/contexts/overlayContext/OverlayProvider.d.ts.map +1 -1
  35. package/lib/typescript/state-store/message-overlay-store.d.ts +16 -0
  36. package/lib/typescript/state-store/message-overlay-store.d.ts.map +1 -1
  37. package/package.json +1 -1
  38. package/src/components/UIComponents/PortalWhileClosingView.tsx +15 -4
  39. package/src/components/UIComponents/__tests__/PortalWhileClosingView.test.tsx +38 -0
  40. package/src/contexts/overlayContext/ClosingPortalHostsLayer.tsx +18 -2
  41. package/src/contexts/overlayContext/MessageOverlayHostLayer.tsx +47 -16
  42. package/src/contexts/overlayContext/OverlayHostLayerContext.ts +9 -0
  43. package/src/contexts/overlayContext/OverlayProvider.tsx +12 -7
  44. package/src/contexts/overlayContext/__tests__/ClosingPortalHostsLayer.test.tsx +27 -0
  45. package/src/contexts/overlayContext/__tests__/MessageOverlayHostLayer.test.tsx +84 -6
  46. package/src/state-store/__tests__/message-overlay-store.test.tsx +97 -0
  47. package/src/state-store/message-overlay-store.ts +70 -11
  48. package/src/version.json +1 -1
@@ -8,10 +8,12 @@ import { PortalProvider } from 'react-native-teleport';
8
8
 
9
9
  import { MessageOverlayHostLayer } from './MessageOverlayHostLayer';
10
10
  import { OverlayContext, OverlayProviderProps } from './OverlayContext';
11
+ import { OverlayHostLayerContext } from './OverlayHostLayerContext';
11
12
 
12
13
  import { OverlayA11yShield } from '../../components/Accessibility/OverlayA11yShield';
13
14
  import { ImageGallery } from '../../components/ImageGallery/ImageGallery';
14
15
  import { useStreami18n } from '../../hooks/useStreami18n';
16
+ import { createOverlayHostLayerId } from '../../state-store';
15
17
 
16
18
  import { AccessibilityProvider } from '../accessibilityContext/AccessibilityContext';
17
19
  import { ImageGalleryProvider } from '../imageGalleryContext/ImageGalleryContext';
@@ -55,6 +57,7 @@ export const OverlayProvider = (props: PropsWithChildren<OverlayProviderProps>)
55
57
  } = props;
56
58
 
57
59
  const [overlay, setOverlay] = useState(value?.overlay || 'none');
60
+ const [overlayHostLayerId] = useState(createOverlayHostLayerId);
58
61
 
59
62
  const overlayOpacity = useSharedValue(0);
60
63
 
@@ -110,13 +113,15 @@ export const OverlayProvider = (props: PropsWithChildren<OverlayProviderProps>)
110
113
  <ImageGalleryProvider value={imageGalleryProviderProps}>
111
114
  <ThemeProvider style={overlayContext.style}>
112
115
  <PortalProvider>
113
- {accessibility?.enabled ? (
114
- <OverlayA11yShield>{children}</OverlayA11yShield>
115
- ) : (
116
- children
117
- )}
118
- {overlay === 'gallery' && <ImageGallery overlayOpacity={overlayOpacity} />}
119
- <MessageOverlayHostLayer />
116
+ <OverlayHostLayerContext.Provider value={overlayHostLayerId}>
117
+ {accessibility?.enabled ? (
118
+ <OverlayA11yShield>{children}</OverlayA11yShield>
119
+ ) : (
120
+ children
121
+ )}
122
+ {overlay === 'gallery' && <ImageGallery overlayOpacity={overlayOpacity} />}
123
+ <MessageOverlayHostLayer hostLayerId={overlayHostLayerId} />
124
+ </OverlayHostLayerContext.Provider>
120
125
  </PortalProvider>
121
126
  </ThemeProvider>
122
127
  </ImageGalleryProvider>
@@ -115,4 +115,31 @@ describe('ClosingPortalHostsLayer', () => {
115
115
  expect(screen.getAllByTestId('closing-portal-host-slot-overlay-header')).toHaveLength(1);
116
116
  expect(screen.getAllByTestId('closing-portal-host-slot-overlay-composer')).toHaveLength(1);
117
117
  });
118
+
119
+ it('parks its hosts under names unique to its host layer while that layer is not the top one', () => {
120
+ const renderLayer = (isTopHostLayer: boolean) => (
121
+ <ClosingPortalHostsLayer
122
+ closeCoverOpacity={{ value: 0 } as SharedValue<number>}
123
+ hostLayerId='root-layer'
124
+ isTopHostLayer={isTopHostLayer}
125
+ />
126
+ );
127
+ const getHostsNamed = (name: string) =>
128
+ screen.UNSAFE_root.findAll(
129
+ (node) => typeof node.type === 'string' && node.props.name === name,
130
+ );
131
+ const { rerender } = render(renderLayer(false));
132
+
133
+ act(() => {
134
+ setClosingPortalLayout('overlay-composer', 'composer-entry', FIRST_RECT);
135
+ });
136
+
137
+ expect(getHostsNamed('overlay-composer')).toHaveLength(0);
138
+ expect(getHostsNamed('overlay-composer:root-layer')).toHaveLength(1);
139
+
140
+ rerender(renderLayer(true));
141
+
142
+ expect(getHostsNamed('overlay-composer')).toHaveLength(1);
143
+ expect(getHostsNamed('overlay-composer:root-layer')).toHaveLength(0);
144
+ });
118
145
  });
@@ -159,7 +159,7 @@ describe('MessageOverlayHostLayer', () => {
159
159
  const CustomBackground = () => <Text testID='custom-background'>Background</Text>;
160
160
  render(
161
161
  <WithComponents overrides={{ MessageOverlayBackground: CustomBackground }}>
162
- <MessageOverlayHostLayer />
162
+ <MessageOverlayHostLayer hostLayerId='layer' />
163
163
  </WithComponents>,
164
164
  );
165
165
 
@@ -197,7 +197,7 @@ describe('MessageOverlayHostLayer', () => {
197
197
 
198
198
  render(
199
199
  <WithComponents overrides={{ MessageOverlayBackground: NoopBackground }}>
200
- <MessageOverlayHostLayer />
200
+ <MessageOverlayHostLayer hostLayerId='layer' />
201
201
  </WithComponents>,
202
202
  );
203
203
 
@@ -239,7 +239,7 @@ describe('MessageOverlayHostLayer', () => {
239
239
  it('positions and translates the top, message, and bottom hosts using the registered rects', () => {
240
240
  const renderTree = () => (
241
241
  <WithComponents overrides={{ MessageOverlayBackground: NoopBackground }}>
242
- <MessageOverlayHostLayer />
242
+ <MessageOverlayHostLayer hostLayerId='layer' />
243
243
  </WithComponents>
244
244
  );
245
245
  const { rerender } = render(renderTree());
@@ -289,7 +289,7 @@ describe('MessageOverlayHostLayer', () => {
289
289
  it('keeps the hosts mounted but resets their geometry after finalizeCloseOverlay', () => {
290
290
  const renderTree = () => (
291
291
  <WithComponents overrides={{ MessageOverlayBackground: NoopBackground }}>
292
- <MessageOverlayHostLayer />
292
+ <MessageOverlayHostLayer hostLayerId='layer' />
293
293
  </WithComponents>
294
294
  );
295
295
  const { rerender } = render(renderTree());
@@ -341,7 +341,7 @@ describe('MessageOverlayHostLayer', () => {
341
341
 
342
342
  const renderTree = () => (
343
343
  <WithComponents overrides={{ MessageOverlayBackground: NoopBackground }}>
344
- <MessageOverlayHostLayer />
344
+ <MessageOverlayHostLayer hostLayerId='layer' />
345
345
  </WithComponents>
346
346
  );
347
347
  const { rerender } = render(renderTree());
@@ -396,7 +396,7 @@ describe('MessageOverlayHostLayer', () => {
396
396
  MessageOverlayBackground: NoopBackground,
397
397
  }}
398
398
  >
399
- <MessageOverlayHostLayer />
399
+ <MessageOverlayHostLayer hostLayerId='layer' />
400
400
  </WithComponents>
401
401
  );
402
402
  const { rerender } = render(renderTree());
@@ -433,4 +433,82 @@ describe('MessageOverlayHostLayer', () => {
433
433
  width: BOTTOM_RECT.w,
434
434
  });
435
435
  });
436
+
437
+ it('lets the most recently mounted host layer own the overlay and hands it back once that layer unmounts', () => {
438
+ const renderTree = (withNestedLayer: boolean) => (
439
+ <WithComponents overrides={{ MessageOverlayBackground: NoopBackground }}>
440
+ <MessageOverlayHostLayer hostLayerId='root-layer' />
441
+ {withNestedLayer ? <MessageOverlayHostLayer hostLayerId='nested-layer' /> : null}
442
+ </WithComponents>
443
+ );
444
+ const getHostsNamed = (name: string) =>
445
+ screen.UNSAFE_root.findAll(
446
+ (node) => typeof node.type === 'string' && node.props.name === name,
447
+ );
448
+ const { rerender } = render(renderTree(true));
449
+
450
+ // The nested layer owns the shared host names, the root layer parks its own.
451
+ expect(getHostsNamed('bottom-item')).toHaveLength(1);
452
+ expect(getHostsNamed('bottom-item:root-layer')).toHaveLength(1);
453
+
454
+ act(() => {
455
+ setOverlayTopH(TOP_RECT);
456
+ setOverlayMessageH(MESSAGE_RECT);
457
+ setOverlayBottomH(BOTTOM_RECT);
458
+ openOverlay('message-1');
459
+ });
460
+
461
+ rerender(renderTree(true));
462
+
463
+ expect(screen.getAllByTestId('message-overlay-backdrop')).toHaveLength(1);
464
+ const [rootBottomSlot, nestedBottomSlot] = screen.getAllByTestId('message-overlay-bottom');
465
+ expect(StyleSheet.flatten(nestedBottomSlot.props.style)).toMatchObject({
466
+ height: BOTTOM_RECT.h,
467
+ width: BOTTOM_RECT.w,
468
+ });
469
+ expect(StyleSheet.flatten(rootBottomSlot.props.style)).toMatchObject({ height: 0 });
470
+
471
+ act(() => {
472
+ finalizeCloseOverlay();
473
+ });
474
+
475
+ rerender(renderTree(false));
476
+
477
+ expect(getHostsNamed('bottom-item')).toHaveLength(1);
478
+ expect(getHostsNamed('bottom-item:root-layer')).toHaveLength(0);
479
+
480
+ act(() => {
481
+ setOverlayTopH(TOP_RECT);
482
+ setOverlayMessageH(MESSAGE_RECT);
483
+ setOverlayBottomH(BOTTOM_RECT);
484
+ openOverlay('message-2');
485
+ });
486
+
487
+ rerender(renderTree(false));
488
+
489
+ expect(screen.getAllByTestId('message-overlay-backdrop')).toHaveLength(1);
490
+ expect(
491
+ StyleSheet.flatten(screen.getByTestId('message-overlay-bottom').props.style),
492
+ ).toMatchObject({
493
+ height: BOTTOM_RECT.h,
494
+ width: BOTTOM_RECT.w,
495
+ });
496
+ });
497
+
498
+ it('renders a MessageActions override only in the top host layer', () => {
499
+ const renderTree = () => (
500
+ <WithComponents
501
+ overrides={{
502
+ MessageActions: CustomMessageActions,
503
+ MessageOverlayBackground: NoopBackground,
504
+ }}
505
+ >
506
+ <MessageOverlayHostLayer hostLayerId='root-layer' />
507
+ <MessageOverlayHostLayer hostLayerId='nested-layer' />
508
+ </WithComponents>
509
+ );
510
+ render(renderTree());
511
+
512
+ expect(screen.getAllByTestId('custom-message-actions')).toHaveLength(1);
513
+ });
436
514
  });
@@ -9,10 +9,15 @@ import {
9
9
  finalizeCloseOverlay,
10
10
  openOverlay,
11
11
  overlayStore,
12
+ registerOverlayHostLayer,
13
+ registerOverlaySharedValueController,
12
14
  scheduleActionOnClose,
13
15
  setClosingPortalLayout,
16
+ setOverlayBottomH,
17
+ setOverlayMessageH,
14
18
  useClosingPortalHostBlacklist,
15
19
  useClosingPortalHostBlacklistState,
20
+ useIsTopOverlayHostLayer,
16
21
  useShouldTeleportToClosingPortal,
17
22
  } from '../message-overlay-store';
18
23
 
@@ -308,3 +313,95 @@ describe('message overlay store portal hooks', () => {
308
313
  allowed.unmount();
309
314
  });
310
315
  });
316
+
317
+ describe('message overlay host layer stack', () => {
318
+ const createController = () => ({
319
+ incrementCloseCorrectionY: jest.fn(),
320
+ reset: jest.fn(),
321
+ resetCloseCorrectionY: jest.fn(),
322
+ setBottomH: jest.fn(),
323
+ setMessageH: jest.fn(),
324
+ setTopH: jest.fn(),
325
+ });
326
+
327
+ afterEach(() => {
328
+ cleanup();
329
+ });
330
+
331
+ it('routes the overlay geometry to the most recently registered controller and hands it back once that one unregisters', () => {
332
+ const rootController = createController();
333
+ const nestedController = createController();
334
+ const unregisterRoot = registerOverlaySharedValueController(rootController);
335
+ const unregisterNested = registerOverlaySharedValueController(nestedController);
336
+
337
+ setOverlayMessageH(BASE_RECT);
338
+
339
+ expect(nestedController.setMessageH).toHaveBeenCalledWith(BASE_RECT);
340
+ expect(rootController.setMessageH).not.toHaveBeenCalled();
341
+
342
+ unregisterNested();
343
+ setOverlayMessageH(BASE_RECT);
344
+
345
+ expect(rootController.setMessageH).toHaveBeenCalledWith(BASE_RECT);
346
+ expect(nestedController.setMessageH).toHaveBeenCalledTimes(1);
347
+
348
+ unregisterRoot();
349
+ });
350
+
351
+ it('keeps routing to the top controller when a controller below it unregisters', () => {
352
+ const rootController = createController();
353
+ const nestedController = createController();
354
+ const unregisterRoot = registerOverlaySharedValueController(rootController);
355
+ const unregisterNested = registerOverlaySharedValueController(nestedController);
356
+
357
+ unregisterRoot();
358
+ setOverlayBottomH(BASE_RECT);
359
+
360
+ expect(nestedController.setBottomH).toHaveBeenCalledWith(BASE_RECT);
361
+ expect(rootController.setBottomH).not.toHaveBeenCalled();
362
+
363
+ unregisterNested();
364
+ });
365
+
366
+ it('reports only the most recently registered host layer as the top one', () => {
367
+ const root = renderHook(() => useIsTopOverlayHostLayer('root-layer'));
368
+ const nested = renderHook(() => useIsTopOverlayHostLayer('nested-layer'));
369
+ const withoutLayer = renderHook(() => useIsTopOverlayHostLayer(undefined));
370
+
371
+ expect(root.result.current).toBe(true);
372
+ expect(nested.result.current).toBe(true);
373
+
374
+ let unregisterRoot = () => {};
375
+ let unregisterNested = () => {};
376
+
377
+ act(() => {
378
+ unregisterRoot = registerOverlayHostLayer('root-layer');
379
+ });
380
+
381
+ expect(root.result.current).toBe(true);
382
+ expect(nested.result.current).toBe(false);
383
+
384
+ act(() => {
385
+ unregisterNested = registerOverlayHostLayer('nested-layer');
386
+ });
387
+
388
+ expect(root.result.current).toBe(false);
389
+ expect(nested.result.current).toBe(true);
390
+ expect(withoutLayer.result.current).toBe(true);
391
+
392
+ act(() => {
393
+ unregisterNested();
394
+ });
395
+
396
+ expect(root.result.current).toBe(true);
397
+ expect(nested.result.current).toBe(false);
398
+
399
+ act(() => {
400
+ unregisterRoot();
401
+ });
402
+
403
+ root.unmount();
404
+ nested.unmount();
405
+ withoutLayer.unmount();
406
+ });
407
+ });
@@ -51,37 +51,43 @@ type OverlaySharedValueController = {
51
51
  setTopH: (rect: Rect) => void;
52
52
  };
53
53
 
54
- let sharedValueController: OverlaySharedValueController | undefined;
54
+ // Every mounted `MessageOverlayHostLayer` registers its controller and the most recently registered
55
+ // one drives the overlay. Unregistering hands control back to the previous controller, so nested
56
+ // `OverlayProvider`s (one at the root and one inside a native modal, for example) can come and go.
57
+ let sharedValueControllerStack: OverlaySharedValueController[] = [];
58
+
59
+ const getSharedValueController = () =>
60
+ sharedValueControllerStack[sharedValueControllerStack.length - 1];
55
61
 
56
62
  export const registerOverlaySharedValueController = (controller: OverlaySharedValueController) => {
57
- sharedValueController = controller;
63
+ sharedValueControllerStack = [...sharedValueControllerStack, controller];
58
64
  return () => {
59
- if (sharedValueController === controller) {
60
- sharedValueController = undefined;
61
- }
65
+ sharedValueControllerStack = sharedValueControllerStack.filter(
66
+ (registeredController) => registeredController !== controller,
67
+ );
62
68
  };
63
69
  };
64
70
 
65
71
  export const setOverlayMessageH = (messageH: Rect) => {
66
- sharedValueController?.setMessageH(messageH);
72
+ getSharedValueController()?.setMessageH(messageH);
67
73
  };
68
74
 
69
75
  export const setOverlayTopH = (topH: Rect) => {
70
- sharedValueController?.setTopH(topH);
76
+ getSharedValueController()?.setTopH(topH);
71
77
  };
72
78
 
73
79
  export const setOverlayBottomH = (bottomH: Rect) => {
74
- sharedValueController?.setBottomH(bottomH);
80
+ getSharedValueController()?.setBottomH(bottomH);
75
81
  };
76
82
 
77
83
  export const bumpOverlayLayoutRevision = (closeCorrectionDeltaY = 0) => {
78
- sharedValueController?.incrementCloseCorrectionY(closeCorrectionDeltaY);
84
+ getSharedValueController()?.incrementCloseCorrectionY(closeCorrectionDeltaY);
79
85
  };
80
86
 
81
87
  export const openOverlay = (params: OpenOverlayParams | string) => {
82
88
  const overlayPayload = typeof params === 'string' ? { id: params, messageId: undefined } : params;
83
89
 
84
- sharedValueController?.resetCloseCorrectionY();
90
+ getSharedValueController()?.resetCloseCorrectionY();
85
91
  overlayStore.partialNext({
86
92
  closing: false,
87
93
  closingPortalHostBlacklist: getCurrentClosingPortalHostBlacklist(),
@@ -122,7 +128,7 @@ export const finalizeCloseOverlay = () => {
122
128
  ...DefaultState,
123
129
  closingPortalHostBlacklist: getCurrentClosingPortalHostBlacklist(),
124
130
  });
125
- sharedValueController?.reset();
131
+ getSharedValueController()?.reset();
126
132
  };
127
133
 
128
134
  export const overlayStore = new StateStore<OverlayState>(DefaultState);
@@ -133,6 +139,59 @@ const closingPortalLayoutsStore = new StateStore<ClosingPortalLayoutsState>(
133
139
  export const createClosingPortalLayoutRegistrationId = () =>
134
140
  `closing-portal-layout-${closingPortalLayoutRegistrationCounter++}`;
135
141
 
142
+ type OverlayHostLayersState = {
143
+ hostLayerIds: string[];
144
+ };
145
+
146
+ let overlayHostLayerRegistrationCounter = 0;
147
+
148
+ const overlayHostLayersStore = new StateStore<OverlayHostLayersState>({ hostLayerIds: [] });
149
+
150
+ export const createOverlayHostLayerId = () =>
151
+ `overlay-host-layer-${overlayHostLayerRegistrationCounter++}`;
152
+
153
+ /**
154
+ * Registers a `MessageOverlayHostLayer` (one per `OverlayProvider`) using stack semantics.
155
+ *
156
+ * Only the most recently registered layer drives the overlay and owns the shared portal host names.
157
+ * Portal hosts are looked up by name in a single native registry, so two layers using the same
158
+ * names would take them over from each other. The other layers park their hosts under names unique
159
+ * to them, and when the top layer unregisters the previous one takes the shared names back.
160
+ */
161
+ export const registerOverlayHostLayer = (id: string) => {
162
+ overlayHostLayersStore.partialNext({
163
+ hostLayerIds: [...overlayHostLayersStore.getLatestValue().hostLayerIds, id],
164
+ });
165
+
166
+ return () => {
167
+ overlayHostLayersStore.partialNext({
168
+ hostLayerIds: overlayHostLayersStore
169
+ .getLatestValue()
170
+ .hostLayerIds.filter((hostLayerId) => hostLayerId !== id),
171
+ });
172
+ };
173
+ };
174
+
175
+ const topOverlayHostLayer = { isTop: true };
176
+ const notTopOverlayHostLayer = { isTop: false };
177
+
178
+ /**
179
+ * Whether the host layer with the given id is the one that currently owns the overlay. A missing
180
+ * id (used outside of an `OverlayProvider`) or an empty stack counts as the top, which keeps the
181
+ * single provider setup identical to before the stack existed.
182
+ */
183
+ export const useIsTopOverlayHostLayer = (id: string | undefined) => {
184
+ const isTopOverlayHostLayerSelector = useCallback(
185
+ ({ hostLayerIds }: OverlayHostLayersState) =>
186
+ !id || !hostLayerIds.length || hostLayerIds[hostLayerIds.length - 1] === id
187
+ ? topOverlayHostLayer
188
+ : notTopOverlayHostLayer,
189
+ [id],
190
+ );
191
+
192
+ return useStateStore(overlayHostLayersStore, isTopOverlayHostLayerSelector).isTop;
193
+ };
194
+
136
195
  const getCurrentClosingPortalHostBlacklist = () =>
137
196
  closingPortalHostBlacklistStack[closingPortalHostBlacklistStack.length - 1]?.hostNames ?? [];
138
197
 
package/src/version.json CHANGED
@@ -1,3 +1,3 @@
1
1
  {
2
- "version": "9.10.0"
2
+ "version": "9.10.1-beta.1"
3
3
  }