react-native-ui-lib 7.44.0-snapshot.7227 → 7.44.0-snapshot.7233

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 (122) hide show
  1. package/babel.config.js +12 -0
  2. package/lib/components/HighlighterOverlayView/index.js +1 -1
  3. package/lib/components/HighlighterOverlayView/index.web.d.ts +1 -1
  4. package/lib/components/Keyboard/KeyboardTrackingView/KeyboardTrackingView.ios.js +1 -1
  5. package/lib/components/SafeArea/SafeAreaInsetsManager.d.ts +7 -4
  6. package/lib/components/SafeArea/SafeAreaInsetsManager.js +10 -13
  7. package/lib/components/SafeArea/SafeAreaSpacerView.d.ts +2 -2
  8. package/lib/components/SafeArea/SafeAreaSpacerView.js +11 -8
  9. package/lib/components/SafeArea/__tests__/SafeAreaInsetsManager.spec.js +271 -0
  10. package/lib/components/SafeArea/index.d.ts +10 -0
  11. package/lib/components/SafeArea/index.js +11 -0
  12. package/lib/components/index.d.ts +1 -1
  13. package/lib/components/index.js +1 -1
  14. package/lib/package.json +1 -1
  15. package/package.json +2 -2
  16. package/panView.d.ts +2 -0
  17. package/panView.js +1 -0
  18. package/src/commons/Constants.js +2 -10
  19. package/src/components/KeyboardAwareScrollView/KeyboardAwareBase.js +5 -1
  20. package/src/components/actionSheet/index.d.ts +2 -12
  21. package/src/components/actionSheet/index.js +3 -42
  22. package/src/components/checkbox/index.d.ts +0 -1
  23. package/src/components/checkbox/index.js +2 -4
  24. package/src/components/colorPicker/ColorPickerDialog.d.ts +1 -1
  25. package/src/components/colorPicker/ColorPickerDialog.js +1 -1
  26. package/src/components/dateTimePicker/index.d.ts +186 -5
  27. package/src/components/dateTimePicker/index.js +1 -2
  28. package/src/components/dialog/dialog.api.json +31 -37
  29. package/src/{incubator → components}/dialog/dialogHeader.api.json +2 -2
  30. package/src/components/dialog/index.d.ts +13 -105
  31. package/src/components/dialog/index.js +204 -212
  32. package/src/{incubator → components}/dialog/types.d.ts +0 -19
  33. package/src/{incubator → components}/dialog/types.js +1 -3
  34. package/src/components/featureHighlight/index.d.ts +1 -1
  35. package/src/components/index.js +0 -19
  36. package/src/components/modal/index.d.ts +5 -0
  37. package/src/components/modal/index.js +14 -10
  38. package/src/components/modal/modal.api.json +5 -0
  39. package/src/components/pageControl/index.js +6 -1
  40. package/src/{incubator → components}/panView/index.d.ts +3 -3
  41. package/src/{incubator → components}/panView/index.js +4 -4
  42. package/src/{incubator → components}/panView/usePanGesture.d.ts +1 -1
  43. package/src/components/picker/Picker.driver.new.js +1 -1
  44. package/src/components/picker/PickerItem.js +6 -20
  45. package/src/components/picker/PickerPresenter.d.ts +0 -1
  46. package/src/components/picker/PickerPresenter.js +1 -23
  47. package/src/components/picker/api/picker.api.json +0 -1
  48. package/src/components/picker/api/pickerItem.api.json +0 -5
  49. package/src/components/picker/helpers/usePickerLabel.d.ts +1 -1
  50. package/src/components/picker/helpers/usePickerLabel.js +2 -3
  51. package/src/components/picker/helpers/usePickerMigrationWarnings.d.ts +1 -1
  52. package/src/components/picker/helpers/usePickerMigrationWarnings.js +0 -12
  53. package/src/components/picker/helpers/usePickerSearch.d.ts +1 -1
  54. package/src/components/picker/helpers/usePickerSearch.js +4 -8
  55. package/src/components/picker/helpers/usePickerSelection.d.ts +1 -1
  56. package/src/components/picker/helpers/usePickerSelection.js +2 -10
  57. package/src/components/picker/index.js +4 -22
  58. package/src/components/picker/types.d.ts +1 -24
  59. package/src/components/radioButton/index.js +6 -8
  60. package/src/components/segmentedControl/index.js +3 -3
  61. package/src/components/stackAggregator/index.js +1 -1
  62. package/src/{incubator/hooks/useHiddenLocation.web.d.ts → hooks/useHiddenLocation/index.d.ts} +1 -1
  63. package/src/{incubator/hooks/useHiddenLocation.d.ts → hooks/useHiddenLocation/index.web.d.ts} +1 -1
  64. package/src/incubator/expandableOverlay/ExpandableOverlay.driver.js +1 -1
  65. package/src/incubator/expandableOverlay/index.d.ts +42 -3
  66. package/src/incubator/expandableOverlay/index.js +1 -4
  67. package/src/incubator/index.d.ts +0 -2
  68. package/src/incubator/index.js +0 -2
  69. package/src/incubator/toast/index.js +1 -1
  70. package/src/index.d.ts +3 -10
  71. package/src/index.js +41 -160
  72. package/src/style/colors.d.ts +3 -5
  73. package/src/style/designTokens.js +7 -4
  74. package/src/testkit/index.d.ts +1 -1
  75. package/src/testkit/index.js +1 -1
  76. package/src/utils/styleUtils.d.ts +1 -0
  77. package/src/utils/styleUtils.js +3 -0
  78. package/lib/components/HighlighterOverlayView/HighlighterViewNativeComponent.d.ts +0 -61
  79. package/lib/components/HighlighterOverlayView/HighlighterViewNativeComponent.js +0 -2
  80. package/lib/components/Keyboard/KeyboardTrackingView/KeyboardTrackingViewNativeComponent.d.ts +0 -58
  81. package/lib/components/Keyboard/KeyboardTrackingView/KeyboardTrackingViewNativeComponent.js +0 -2
  82. package/panningViews.d.ts +0 -2
  83. package/panningViews.js +0 -1
  84. package/sharedTransition.d.ts +0 -2
  85. package/sharedTransition.js +0 -1
  86. package/src/components/dialog/DialogDismissibleView.d.ts +0 -34
  87. package/src/components/dialog/DialogDismissibleView.js +0 -184
  88. package/src/components/dialog/OverlayFadingBackground.d.ts +0 -14
  89. package/src/components/dialog/OverlayFadingBackground.js +0 -45
  90. package/src/components/panningViews/asPanViewConsumer.d.ts +0 -3
  91. package/src/components/panningViews/asPanViewConsumer.js +0 -16
  92. package/src/components/panningViews/panDismissibleView.d.ts +0 -51
  93. package/src/components/panningViews/panDismissibleView.js +0 -350
  94. package/src/components/panningViews/panGestureView.d.ts +0 -23
  95. package/src/components/panningViews/panGestureView.js +0 -156
  96. package/src/components/panningViews/panListenerView.d.ts +0 -66
  97. package/src/components/panningViews/panListenerView.js +0 -155
  98. package/src/components/panningViews/panResponderView.d.ts +0 -19
  99. package/src/components/panningViews/panResponderView.js +0 -79
  100. package/src/components/panningViews/panningContext.d.ts +0 -3
  101. package/src/components/panningViews/panningContext.js +0 -4
  102. package/src/components/panningViews/panningProvider.d.ts +0 -73
  103. package/src/components/panningViews/panningProvider.js +0 -101
  104. package/src/components/sharedTransition/ShareTransitionContext.js +0 -3
  105. package/src/components/sharedTransition/SharedArea.js +0 -153
  106. package/src/components/sharedTransition/SourceElement.js +0 -44
  107. package/src/components/sharedTransition/TargetElement.js +0 -38
  108. package/src/components/sharedTransition/index.js +0 -9
  109. package/src/incubator/dialog/dialog.api.json +0 -54
  110. package/src/incubator/dialog/index.d.ts +0 -15
  111. package/src/incubator/dialog/index.js +0 -218
  112. /package/src/{incubator → components}/dialog/Dialog.driver.new.d.ts +0 -0
  113. /package/src/{incubator → components}/dialog/Dialog.driver.new.js +0 -0
  114. /package/src/{incubator → components}/dialog/DialogHeader.d.ts +0 -0
  115. /package/src/{incubator → components}/dialog/DialogHeader.js +0 -0
  116. /package/src/{incubator → components}/dialog/useDialogContent.d.ts +0 -0
  117. /package/src/{incubator → components}/dialog/useDialogContent.js +0 -0
  118. /package/src/{incubator → components}/panView/panningUtil.d.ts +0 -0
  119. /package/src/{incubator → components}/panView/panningUtil.js +0 -0
  120. /package/src/{incubator → components}/panView/usePanGesture.js +0 -0
  121. /package/src/{incubator/hooks/useHiddenLocation.js → hooks/useHiddenLocation/index.js} +0 -0
  122. /package/src/{incubator/hooks/useHiddenLocation.web.js → hooks/useHiddenLocation/index.web.js} +0 -0
package/babel.config.js CHANGED
@@ -1,5 +1,17 @@
1
1
  module.exports = {
2
2
  presets: ['module:@react-native/babel-preset'],
3
+ env: {
4
+ test: {
5
+ presets: [
6
+ [
7
+ 'module:@react-native/babel-preset',
8
+ {
9
+ disableStaticViewConfigsCodegen: true
10
+ }
11
+ ]
12
+ ]
13
+ }
14
+ },
3
15
  plugins: [
4
16
  'react-native-reanimated/plugin',
5
17
  [
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import { processColor, StyleSheet, Modal } from 'react-native';
3
3
  // Import the Codegen specification for New Architecture
4
- import HighlighterViewNativeComponent from "./HighlighterViewNativeComponent";
4
+ import HighlighterViewNativeComponent from "../../specs/HighlighterViewNativeComponent";
5
5
  const DefaultOverlayColor = 'rgba(0, 0, 0, 0.5)';
6
6
  const HighlighterOverlayView = props => {
7
7
  const {
@@ -19,7 +19,7 @@ export type HighlighterOverlayViewProps = {
19
19
  onRequestClose?: () => void;
20
20
  highlightFrame?: HighlightFrameType;
21
21
  style?: ViewStyle;
22
- highlightViewTag?: number | null;
22
+ highlightViewTag?: number;
23
23
  children?: JSX.Element[] | JSX.Element;
24
24
  highlightViewTagParams?: HighlightViewTagParams;
25
25
  minimumRectSize?: Pick<HighlightFrameType, 'width' | 'height'>;
@@ -1,7 +1,7 @@
1
1
  import React, { PureComponent } from 'react';
2
2
  import ReactNative, { NativeModules } from 'react-native';
3
3
  // Import the Codegen specification for New Architecture
4
- import KeyboardTrackingViewNativeComponent from "./KeyboardTrackingViewNativeComponent";
4
+ import KeyboardTrackingViewNativeComponent from "../../../specs/KeyboardTrackingViewNativeComponent";
5
5
  const KeyboardTrackingViewTempManager = NativeModules.KeyboardTrackingViewTempManager;
6
6
 
7
7
  /**
@@ -1,13 +1,16 @@
1
- type SafeAreaInsetsType = {
1
+ export type SafeAreaInsetsType = {
2
2
  top: number;
3
3
  left: number;
4
4
  bottom: number;
5
5
  right: number;
6
6
  } | null;
7
+ export type SafeAreaChangedDelegateType = {
8
+ onSafeAreaInsetsDidChangeEvent?: (insets: SafeAreaInsetsType) => void;
9
+ };
7
10
  declare class SafeAreaInsetsManager {
8
11
  _defaultInsets: SafeAreaInsetsType;
9
12
  _safeAreaInsets: SafeAreaInsetsType;
10
- _safeAreaChangedDelegates: Array<any>;
13
+ _safeAreaChangedDelegates: Array<SafeAreaChangedDelegateType>;
11
14
  _nativeModule: any;
12
15
  constructor();
13
16
  setupNativeConnection(): void;
@@ -16,8 +19,8 @@ declare class SafeAreaInsetsManager {
16
19
  notifyDelegates(insets: SafeAreaInsetsType): void;
17
20
  _updateInsets(): Promise<void>;
18
21
  getSafeAreaInsets(): Promise<SafeAreaInsetsType>;
19
- addSafeAreaChangedDelegate(delegate: any): void;
20
- removeSafeAreaChangedDelegate(delegateToRemove: any): void;
22
+ addSafeAreaChangedDelegate(delegate: SafeAreaChangedDelegateType): void;
23
+ removeSafeAreaChangedDelegate(delegateToRemove: SafeAreaChangedDelegateType): void;
21
24
  get defaultInsets(): SafeAreaInsetsType;
22
25
  refreshSafeAreaInsets(): Promise<void>;
23
26
  }
@@ -2,7 +2,7 @@ import _isEqual from "lodash/isEqual";
2
2
  import _remove from "lodash/remove";
3
3
  import _forEach from "lodash/forEach";
4
4
  /* eslint no-underscore-dangle: 0 */
5
- import { NativeModules, DeviceEventEmitter, Platform } from 'react-native';
5
+ import { NativeModules, DeviceEventEmitter } from 'react-native';
6
6
  let SafeAreaInsetsCache = null;
7
7
  class SafeAreaInsetsManager {
8
8
  _defaultInsets = {
@@ -11,12 +11,7 @@ class SafeAreaInsetsManager {
11
11
  bottom: 34,
12
12
  right: 0
13
13
  }; // Common iPhone safe area values
14
- _safeAreaInsets = {
15
- top: 47,
16
- left: 0,
17
- bottom: 34,
18
- right: 0
19
- };
14
+
20
15
  _safeAreaChangedDelegates = [];
21
16
  _nativeModule = null;
22
17
  constructor() {
@@ -45,11 +40,8 @@ class SafeAreaInsetsManager {
45
40
  }
46
41
  }
47
42
  setupEventListener() {
48
- if (Platform.OS !== 'ios') {
49
- return;
50
- }
51
43
  try {
52
- // Use DeviceEventEmitter instead of NativeEventEmitter to avoid getConstants
44
+ // Use DeviceEventEmitter instead of NativeEventEmitter to avoid getConstants
53
45
  DeviceEventEmitter.addListener('SafeAreaInsetsDidChangeEvent', data => {
54
46
  if (data) {
55
47
  SafeAreaInsetsCache = data;
@@ -86,8 +78,13 @@ class SafeAreaInsetsManager {
86
78
  async _updateInsets() {
87
79
  if (this._nativeModule && SafeAreaInsetsCache === null) {
88
80
  try {
89
- SafeAreaInsetsCache = await this._nativeModule.getSafeAreaInsets();
90
- this._safeAreaInsets = SafeAreaInsetsCache;
81
+ const insets = await this._nativeModule.getSafeAreaInsets();
82
+ if (insets) {
83
+ SafeAreaInsetsCache = insets;
84
+ this._safeAreaInsets = SafeAreaInsetsCache;
85
+ } else {
86
+ this._safeAreaInsets = this._defaultInsets;
87
+ }
91
88
  } catch (error) {
92
89
  console.warn('SafeAreaInsetsManager: Failed to get native insets:', error);
93
90
  this._safeAreaInsets = this._defaultInsets;
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
- import { ViewStyle } from 'react-native';
2
+ import { ViewStyle, StyleProp } from 'react-native';
3
3
  export type SafeAreaSpacerViewProps = {
4
- style?: ViewStyle;
4
+ style?: StyleProp<ViewStyle>;
5
5
  };
6
6
  declare const SafeAreaSpacerView: {
7
7
  ({ style }: SafeAreaSpacerViewProps): React.JSX.Element;
@@ -1,4 +1,4 @@
1
- import React, { useState, useCallback, useEffect } from 'react';
1
+ import React, { useState, useCallback, useEffect, useMemo } from 'react';
2
2
  import { View, Dimensions } from 'react-native';
3
3
  import SafeAreaInsetsManager from "./SafeAreaInsetsManager";
4
4
  const SafeAreaSpacerView = ({
@@ -10,6 +10,7 @@ const SafeAreaSpacerView = ({
10
10
  bottom: 0,
11
11
  right: 0
12
12
  });
13
+ const [componentHeight, setComponentHeight] = useState(0);
13
14
  const [spacerHeight, setSpacerHeight] = useState(0);
14
15
  useEffect(() => {
15
16
  const getSafeAreaInsets = async () => {
@@ -43,22 +44,24 @@ const SafeAreaSpacerView = ({
43
44
  const {
44
45
  y
45
46
  } = event.nativeEvent.layout;
47
+ setComponentHeight(y);
48
+ }, []);
49
+ useEffect(() => {
46
50
  const screenHeight = Dimensions.get('window').height;
47
51
  let height = 0;
48
52
  // Check if positioned within safe area bounds
49
- if (y < safeAreaInsets.top) {
53
+ if (componentHeight < safeAreaInsets.top) {
50
54
  height = safeAreaInsets.top;
51
- } else if (y > screenHeight - safeAreaInsets.bottom) {
55
+ } else if (componentHeight > screenHeight - safeAreaInsets.bottom) {
52
56
  height = safeAreaInsets.bottom;
53
57
  }
54
58
  if (height !== spacerHeight) {
55
59
  setSpacerHeight(height);
56
60
  }
57
- }, [safeAreaInsets, spacerHeight]);
58
- const spacerStyle = {
59
- height: spacerHeight,
60
- ...style
61
- };
61
+ }, [componentHeight, safeAreaInsets, spacerHeight]);
62
+ const spacerStyle = useMemo(() => [{
63
+ height: spacerHeight
64
+ }, style], [spacerHeight, style]);
62
65
  return <View style={spacerStyle} onLayout={handleLayout} />;
63
66
  };
64
67
  SafeAreaSpacerView.displayName = 'SafeAreaSpacerView';
@@ -0,0 +1,271 @@
1
+ import {NativeModules, DeviceEventEmitter} from 'react-native';
2
+
3
+ describe('SafeAreaInsetsManager', () => {
4
+ beforeEach(() => {
5
+ // Reset mocks
6
+ jest.clearAllMocks();
7
+
8
+ // Reset the SafeAreaInsetsCache by creating a fresh instance
9
+ jest.resetModules();
10
+
11
+ // Spy on console methods to verify logging
12
+ jest.spyOn(console, 'log').mockImplementation(() => {});
13
+ jest.spyOn(console, 'warn').mockImplementation(() => {});
14
+ });
15
+
16
+ afterEach(() => {
17
+ // Restore console methods
18
+ jest.restoreAllMocks();
19
+ });
20
+
21
+ describe('getSafeAreaInsets', () => {
22
+ it('should return default insets when native module is not available', async () => {
23
+ // Arrange
24
+ NativeModules.SafeAreaManager = null;
25
+ const SafeAreaInsetsManager = require('../SafeAreaInsetsManager').default;
26
+
27
+ // Act
28
+ const result = await SafeAreaInsetsManager.getSafeAreaInsets();
29
+
30
+ // Assert
31
+ expect(result).toEqual({top: 47, left: 0, bottom: 34, right: 0});
32
+ expect(console.log).toHaveBeenCalledWith('SafeAreaInsetsManager: Native SafeAreaManager not available, using defaults');
33
+ });
34
+
35
+ it('should return insets from native module when available', async () => {
36
+ // Arrange
37
+ const mockInsets = {top: 50, left: 10, bottom: 30, right: 10};
38
+ NativeModules.SafeAreaManager = {
39
+ getSafeAreaInsets: jest.fn().mockResolvedValue(mockInsets)
40
+ };
41
+
42
+ const SafeAreaInsetsManager = require('../SafeAreaInsetsManager').default;
43
+
44
+ // Act
45
+ const result = await SafeAreaInsetsManager.getSafeAreaInsets();
46
+
47
+ // Assert
48
+ expect(result).toEqual(mockInsets);
49
+ expect(NativeModules.SafeAreaManager.getSafeAreaInsets).toHaveBeenCalled();
50
+ });
51
+
52
+ it.skip('should return cached insets on subsequent calls', async () => {
53
+ // Arrange
54
+ const mockInsets = {top: 44, left: 0, bottom: 34, right: 0};
55
+ NativeModules.SafeAreaManager = {
56
+ getSafeAreaInsets: jest.fn().mockResolvedValue(mockInsets)
57
+ };
58
+
59
+ const SafeAreaInsetsManager = require('../SafeAreaInsetsManager').default;
60
+
61
+ // Act
62
+ const result1 = await SafeAreaInsetsManager.getSafeAreaInsets();
63
+ const result2 = await SafeAreaInsetsManager.getSafeAreaInsets();
64
+
65
+ // Assert
66
+ expect(result1).toEqual(mockInsets);
67
+ expect(result2).toEqual(mockInsets);
68
+ expect(NativeModules.SafeAreaManager.getSafeAreaInsets).toHaveBeenCalledTimes(1); // Should only call native once due to caching
69
+ });
70
+
71
+ it('should handle native module errors gracefully', async () => {
72
+ // Arrange
73
+ const mockError = new Error('Native module error');
74
+ NativeModules.SafeAreaManager = {
75
+ getSafeAreaInsets: jest.fn().mockRejectedValue(mockError)
76
+ };
77
+
78
+ const SafeAreaInsetsManager = require('../SafeAreaInsetsManager').default;
79
+
80
+ // Act
81
+ const result = await SafeAreaInsetsManager.getSafeAreaInsets();
82
+
83
+ // Assert
84
+ expect(result).toEqual({top: 47, left: 0, bottom: 34, right: 0}); // Should fallback to defaults
85
+ expect(console.warn).toHaveBeenCalledWith('SafeAreaInsetsManager: Failed to get initial insets:', mockError);
86
+ expect(console.warn).toHaveBeenCalledWith('SafeAreaInsetsManager: Failed to get native insets:', mockError);
87
+ });
88
+
89
+ it('should handle native module setup errors gracefully', async () => {
90
+ // Arrange
91
+ Object.defineProperty(NativeModules, 'SafeAreaManager', {
92
+ get: () => {
93
+ throw new Error('Setup error');
94
+ }
95
+ });
96
+
97
+ const SafeAreaInsetsManager = require('../SafeAreaInsetsManager').default;
98
+
99
+ // Act
100
+ const result = await SafeAreaInsetsManager.getSafeAreaInsets();
101
+
102
+ // Assert
103
+ expect(result).toEqual({top: 47, left: 0, bottom: 34, right: 0}); // Should fallback to defaults
104
+ expect(console.warn).toHaveBeenCalledWith('SafeAreaInsetsManager: Failed to connect to native module:', expect.any(Error));
105
+ });
106
+
107
+ it('should update insets when they change during the test', async () => {
108
+ // Arrange
109
+ const initialInsets = {top: 44, left: 0, bottom: 34, right: 0};
110
+ const updatedInsets = {top: 50, left: 0, bottom: 40, right: 0};
111
+
112
+ NativeModules.SafeAreaManager = {
113
+ // TODO: this will need to be changed when the we get caching to work in tests ("should return cached insets on subsequent calls")
114
+ // getSafeAreaInsets: jest.fn().mockResolvedValueOnce(initialInsets).mockResolvedValueOnce(updatedInsets)
115
+ getSafeAreaInsets: jest
116
+ .fn()
117
+ .mockResolvedValueOnce(initialInsets)
118
+ .mockResolvedValueOnce(initialInsets)
119
+ .mockResolvedValueOnce(updatedInsets)
120
+ };
121
+
122
+ const SafeAreaInsetsManager = require('../SafeAreaInsetsManager').default;
123
+
124
+ // Act & Assert - Initial insets
125
+ const result1 = await SafeAreaInsetsManager.getSafeAreaInsets();
126
+ expect(result1).toEqual(initialInsets);
127
+
128
+ // Force refresh of insets
129
+ await SafeAreaInsetsManager.refreshSafeAreaInsets();
130
+
131
+ // Simulate insets change event from native side
132
+ DeviceEventEmitter.emit('SafeAreaInsetsDidChangeEvent', updatedInsets);
133
+
134
+ // Get insets again - should reflect the change
135
+ const result2 = await SafeAreaInsetsManager.getSafeAreaInsets();
136
+ expect(result2).toEqual(updatedInsets);
137
+ });
138
+
139
+ it('should notify delegates when insets change during the test', async () => {
140
+ // Arrange
141
+ const initialInsets = {top: 44, left: 0, bottom: 34, right: 0};
142
+ const updatedInsets = {top: 50, left: 0, bottom: 40, right: 0};
143
+
144
+ NativeModules.SafeAreaManager = {
145
+ getSafeAreaInsets: jest.fn().mockResolvedValue(initialInsets)
146
+ };
147
+
148
+ const SafeAreaInsetsManager = require('../SafeAreaInsetsManager').default;
149
+
150
+ // Add a mock delegate
151
+ const mockDelegate = {
152
+ onSafeAreaInsetsDidChangeEvent: jest.fn()
153
+ };
154
+ SafeAreaInsetsManager.addSafeAreaChangedDelegate(mockDelegate);
155
+
156
+ // Act - Get initial insets
157
+ await SafeAreaInsetsManager.getSafeAreaInsets();
158
+
159
+ // Simulate insets change event from native side
160
+ DeviceEventEmitter.emit('SafeAreaInsetsDidChangeEvent', updatedInsets);
161
+
162
+ // Assert - Delegate should be notified
163
+ expect(mockDelegate.onSafeAreaInsetsDidChangeEvent).toHaveBeenCalledWith(updatedInsets);
164
+ });
165
+
166
+ it('should handle refreshSafeAreaInsets correctly', async () => {
167
+ // Arrange
168
+ const initialInsets = {top: 44, left: 0, bottom: 34, right: 0};
169
+ const refreshedInsets = {top: 48, left: 0, bottom: 36, right: 0};
170
+
171
+ NativeModules.SafeAreaManager = {
172
+ // TODO: this will need to be changed when the we get caching to work in tests ("should return cached insets on subsequent calls")
173
+ // getSafeAreaInsets: jest.fn().mockResolvedValueOnce(initialInsets).mockResolvedValueOnce(updatedInsets)
174
+ getSafeAreaInsets: jest
175
+ .fn()
176
+ .mockResolvedValueOnce(initialInsets)
177
+ .mockResolvedValueOnce(initialInsets)
178
+ .mockResolvedValueOnce(refreshedInsets)
179
+ };
180
+
181
+ const SafeAreaInsetsManager = require('../SafeAreaInsetsManager').default;
182
+
183
+ // Act
184
+ const result1 = await SafeAreaInsetsManager.getSafeAreaInsets();
185
+ expect(result1).toEqual(initialInsets);
186
+
187
+ // Refresh insets
188
+ await SafeAreaInsetsManager.refreshSafeAreaInsets();
189
+
190
+ const result2 = await SafeAreaInsetsManager.getSafeAreaInsets();
191
+
192
+ // Assert
193
+ expect(result2).toEqual(refreshedInsets);
194
+ // TODO: this will need to be changed when the we get caching to work in tests ("should return cached insets on subsequent calls")
195
+ expect(NativeModules.SafeAreaManager.getSafeAreaInsets).toHaveBeenCalledTimes(3);
196
+ });
197
+
198
+ it('should not notify delegates when insets remain the same after refresh', async () => {
199
+ // Arrange
200
+ const sameInsets = {top: 44, left: 0, bottom: 34, right: 0};
201
+
202
+ NativeModules.SafeAreaManager = {
203
+ getSafeAreaInsets: jest.fn().mockResolvedValue(sameInsets)
204
+ };
205
+
206
+ const SafeAreaInsetsManager = require('../SafeAreaInsetsManager').default;
207
+
208
+ // Add a mock delegate
209
+ const mockDelegate = {
210
+ onSafeAreaInsetsDidChangeEvent: jest.fn()
211
+ };
212
+ SafeAreaInsetsManager.addSafeAreaChangedDelegate(mockDelegate);
213
+
214
+ // Act
215
+ await SafeAreaInsetsManager.getSafeAreaInsets();
216
+ await SafeAreaInsetsManager.refreshSafeAreaInsets();
217
+
218
+ // TODO: this will need to be changed when the we get caching to work in tests ("should return cached insets on subsequent calls")
219
+ expect(NativeModules.SafeAreaManager.getSafeAreaInsets).toHaveBeenCalledTimes(3);
220
+
221
+ // Assert - Delegate should not be notified since insets didn't change
222
+ expect(mockDelegate.onSafeAreaInsetsDidChangeEvent).not.toHaveBeenCalled();
223
+ });
224
+
225
+ it('should return default insets when native getSafeAreaInsets returns null', async () => {
226
+ // Arrange
227
+ NativeModules.SafeAreaManager = {
228
+ getSafeAreaInsets: jest.fn().mockResolvedValue(null)
229
+ };
230
+
231
+ const SafeAreaInsetsManager = require('../SafeAreaInsetsManager').default;
232
+
233
+ // Act
234
+ const result = await SafeAreaInsetsManager.getSafeAreaInsets();
235
+
236
+ // Assert
237
+ expect(result).toEqual({top: 47, left: 0, bottom: 34, right: 0});
238
+ });
239
+
240
+ it('should properly manage delegate lifecycle', async () => {
241
+ // Arrange
242
+ NativeModules.SafeAreaManager = {
243
+ getSafeAreaInsets: jest.fn().mockResolvedValue({top: 44, left: 0, bottom: 34, right: 0})
244
+ };
245
+
246
+ const SafeAreaInsetsManager = require('../SafeAreaInsetsManager').default;
247
+
248
+ const mockDelegate1 = {
249
+ onSafeAreaInsetsDidChangeEvent: jest.fn()
250
+ };
251
+ const mockDelegate2 = {
252
+ onSafeAreaInsetsDidChangeEvent: jest.fn()
253
+ };
254
+
255
+ // Act
256
+ SafeAreaInsetsManager.addSafeAreaChangedDelegate(mockDelegate1);
257
+ SafeAreaInsetsManager.addSafeAreaChangedDelegate(mockDelegate2);
258
+
259
+ // Remove one delegate
260
+ SafeAreaInsetsManager.removeSafeAreaChangedDelegate(mockDelegate1);
261
+
262
+ // Trigger notification
263
+ const newInsets = {top: 50, left: 0, bottom: 40, right: 0};
264
+ SafeAreaInsetsManager.notifyDelegates(newInsets);
265
+
266
+ // Assert
267
+ expect(mockDelegate1.onSafeAreaInsetsDidChangeEvent).not.toHaveBeenCalled();
268
+ expect(mockDelegate2.onSafeAreaInsetsDidChangeEvent).toHaveBeenCalledWith(newInsets);
269
+ });
270
+ });
271
+ });
@@ -0,0 +1,10 @@
1
+ import React from 'react';
2
+ import { ViewStyle, StyleProp } from 'react-native';
3
+ export type SafeAreaSpacerViewProps = {
4
+ style?: StyleProp<ViewStyle>;
5
+ };
6
+ declare const SafeAreaSpacerView: {
7
+ ({ style }: SafeAreaSpacerViewProps): React.JSX.Element;
8
+ displayName: string;
9
+ };
10
+ export default SafeAreaSpacerView;
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ import { View, Platform } from 'react-native';
3
+ import SafeAreaSpacerViewIos from "./SafeAreaSpacerView";
4
+ const isIOS = Platform.OS === 'ios';
5
+ const SafeAreaSpacerView = ({
6
+ style
7
+ }) => {
8
+ return isIOS ? <SafeAreaSpacerViewIos style={style} /> : <View style={style} />;
9
+ };
10
+ SafeAreaSpacerView.displayName = 'SafeAreaSpacerView';
11
+ export default SafeAreaSpacerView;
@@ -1,6 +1,6 @@
1
1
  import DynamicFonts, { FontExtension } from './DynamicFonts';
2
2
  import HighlighterOverlayView from './HighlighterOverlayView';
3
- import SafeAreaSpacerView from './SafeArea/SafeAreaSpacerView';
3
+ import SafeAreaSpacerView from './SafeArea';
4
4
  import SafeAreaInsetsManager from './SafeArea/SafeAreaInsetsManager';
5
5
  import Keyboard, { KeyboardTrackingViewProps, KeyboardAccessoryViewProps } from './Keyboard';
6
6
  export { DynamicFonts, FontExtension, HighlighterOverlayView, SafeAreaSpacerView, SafeAreaInsetsManager, Keyboard, KeyboardTrackingViewProps, KeyboardAccessoryViewProps };
@@ -1,6 +1,6 @@
1
1
  import DynamicFonts, { FontExtension } from "./DynamicFonts";
2
2
  import HighlighterOverlayView from "./HighlighterOverlayView";
3
- import SafeAreaSpacerView from "./SafeArea/SafeAreaSpacerView";
3
+ import SafeAreaSpacerView from "./SafeArea";
4
4
  import SafeAreaInsetsManager from "./SafeArea/SafeAreaInsetsManager";
5
5
  import Keyboard, { KeyboardTrackingViewProps, KeyboardAccessoryViewProps } from "./Keyboard";
6
6
  export { DynamicFonts, FontExtension, HighlighterOverlayView, SafeAreaSpacerView, SafeAreaInsetsManager, Keyboard, KeyboardTrackingViewProps, KeyboardAccessoryViewProps };
package/lib/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "uilib-native",
3
- "version": "5.0.0-snapshot.7227",
3
+ "version": "5.0.0-snapshot.7233",
4
4
  "homepage": "https://github.com/wix/react-native-ui-lib",
5
5
  "description": "uilib native components (separated from js components)",
6
6
  "main": "components/index",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-ui-lib",
3
- "version": "7.44.0-snapshot.7227",
3
+ "version": "7.44.0-snapshot.7233",
4
4
  "main": "src/index.js",
5
5
  "types": "src/index.d.ts",
6
6
  "author": "Ethan Sharabi <ethan.shar@gmail.com>",
@@ -56,7 +56,7 @@
56
56
  "react-native-redash": "^12.0.3",
57
57
  "semver": "^5.5.0",
58
58
  "tinycolor2": "^1.4.2",
59
- "uilib-native": "4.5.1",
59
+ "uilib-native": "5.0.0-snapshot.7216",
60
60
  "url-parse": "^1.2.0",
61
61
  "wix-react-native-text-size": "1.0.9"
62
62
  },
package/panView.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ import {PanView} from './src';
2
+ export default PanView;
package/panView.js ADDED
@@ -0,0 +1 @@
1
+ module.exports = require('./src/components/panView').default;
@@ -24,16 +24,8 @@ function setStatusBarHeight() {
24
24
  const {
25
25
  StatusBarManager
26
26
  } = NativeModules;
27
- statusBarHeight = (StatusBar.currentHeight ?? StatusBarManager?.HEIGHT) || 0;
28
- if (isIOS && StatusBarManager) {
29
- try {
30
- // override guesstimate height with the actual height from StatusBarManager
31
- StatusBarManager.getHeight(data => statusBarHeight = data.height);
32
- } catch (error) {
33
- console.warn('Constants: StatusBarManager.getHeight not available in new architecture, using fallback');
34
- // Keep the fallback height we already set above
35
- }
36
- }
27
+ // override guesstimate height with the actual height from StatusBarManager
28
+ statusBarHeight = (StatusBar.currentHeight ?? StatusBarManager?.getConstants?.()?.HEIGHT) || 0;
37
29
  }
38
30
  function getAspectRatio() {
39
31
  return screenWidth < screenHeight ? screenHeight / screenWidth : screenWidth / screenHeight;
@@ -107,7 +107,7 @@ export default class KeyboardAwareBase extends Component {
107
107
  setTimeout(() => {
108
108
  this._keyboardAwareView
109
109
  .getScrollResponder()
110
- .scrollResponderScrollNativeHandleToKeyboard(ReactNative.findNodeHandle(textInputRef),
110
+ .scrollResponderScrollNativeHandleToKeyboard(this.findNodeHandle(textInputRef),
111
111
  this.props.scrollToInputAdditionalOffset,
112
112
  true);
113
113
  }, 0);
@@ -117,6 +117,10 @@ export default class KeyboardAwareBase extends Component {
117
117
  }
118
118
  }
119
119
 
120
+ findNodeHandle(ref) {
121
+ return ref.current?.getNodeHandle?.() || ref?.getNodeHandle?.() || ReactNative.findNodeHandle(ref.current || ref);
122
+ }
123
+
120
124
  _onKeyboardWillShow(event) {
121
125
  this._scrollToFocusedTextInput();
122
126
 
@@ -1,14 +1,9 @@
1
1
  import React from 'react';
2
2
  import { StyleProp, ViewStyle } from 'react-native';
3
- import { DialogProps } from '../dialog';
4
3
  import { ButtonProps } from '../button';
5
- import { DialogProps as IncubatorDialogProps } from '../../incubator';
4
+ import { type DialogProps } from '../dialog';
6
5
  type ActionSheetOnOptionPress = (index: number) => void;
7
6
  type ActionSheetProps = {
8
- /**
9
- * Migrate to the Incubator.Dialog component
10
- */
11
- migrateDialog?: boolean;
12
7
  /**
13
8
  * Whether to show the action sheet or not
14
9
  */
@@ -68,11 +63,6 @@ type ActionSheetProps = {
68
63
  * Note: you will need to call onOptionPress so the option's onPress will be called
69
64
  */
70
65
  renderAction?: (option: ButtonProps, index: number, onOptionPress: ActionSheetOnOptionPress) => JSX.Element;
71
- /**
72
- * @deprecated
73
- * Called once the modal has been dismissed completely
74
- */
75
- onModalDismissed?: DialogProps['onDialogDismissed'];
76
66
  /**
77
67
  * Whether or not to handle SafeArea
78
68
  */
@@ -80,7 +70,7 @@ type ActionSheetProps = {
80
70
  /**
81
71
  * Additional props to send to the Dialog
82
72
  */
83
- dialogProps?: Omit<DialogProps, 'useSafeArea' | 'testID' | 'containerStyle' | 'visible' | 'onDismiss' | 'onDialogDismissed'> | IncubatorDialogProps;
73
+ dialogProps?: Omit<DialogProps, 'useSafeArea' | 'testID' | 'containerStyle' | 'visible' | 'onDismiss' | 'onDialogDismissed'> | DialogProps;
84
74
  /**
85
75
  * testID for e2e tests
86
76
  */