diff --git a/demo/src/screens/nativeComponentScreens/SafeAreaSpacerViewScreen.tsx b/demo/src/screens/nativeComponentScreens/SafeAreaSpacerViewScreen.tsx
index 5e3871ac35..c66bfe59c9 100644
--- a/demo/src/screens/nativeComponentScreens/SafeAreaSpacerViewScreen.tsx
+++ b/demo/src/screens/nativeComponentScreens/SafeAreaSpacerViewScreen.tsx
@@ -23,6 +23,7 @@ export default class SafeAreaSpacerViewScreen extends PureComponent {
SafeAreaSpacerView
{'can be used as a BOTTOM or TOP spacer and will get the height of the safe area insets'}
+
diff --git a/lib/components/HighlighterOverlayView/HighlighterViewNativeComponent.ts b/lib/components/HighlighterOverlayView/HighlighterViewNativeComponent.ts
new file mode 100644
index 0000000000..bc6f15a75c
--- /dev/null
+++ b/lib/components/HighlighterOverlayView/HighlighterViewNativeComponent.ts
@@ -0,0 +1,77 @@
+import type {ViewProps} from 'react-native';
+import type {
+ Float,
+ Int32,
+ WithDefault
+} from 'react-native/Libraries/Types/CodegenTypes';
+import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
+
+export interface HighlightFrame {
+ x: Float;
+ y: Float;
+ width: Float;
+ height: Float;
+}
+
+export interface MinimumRectSize {
+ width: Float;
+ height: Float;
+}
+
+export interface HighlightViewTagParams {
+ paddingLeft?: WithDefault;
+ paddingTop?: WithDefault;
+ paddingRight?: WithDefault;
+ paddingBottom?: WithDefault;
+ offsetX?: WithDefault;
+ offsetY?: WithDefault;
+}
+
+export interface NativeProps extends ViewProps {
+ /**
+ * The frame to highlight with x, y, width, height coordinates
+ */
+ highlightFrame?: HighlightFrame;
+
+ /**
+ * The overlay color (processed color int for Android)
+ */
+ overlayColor?: WithDefault;
+
+ /**
+ * The border radius for the highlighted area
+ */
+ borderRadius?: WithDefault;
+
+ /**
+ * The stroke color (processed color int for Android)
+ */
+ strokeColor?: WithDefault;
+
+ /**
+ * The stroke width
+ */
+ strokeWidth?: WithDefault;
+
+ /**
+ * The React tag of the view to highlight
+ */
+ highlightViewTag?: Int32;
+
+ /**
+ * Parameters for view-based highlighting including padding and offset
+ */
+ highlightViewTagParams?: HighlightViewTagParams;
+
+ /**
+ * Minimum rectangle size for the highlight area
+ */
+ minimumRectSize?: MinimumRectSize;
+
+ /**
+ * Inner padding for the highlight area
+ */
+ innerPadding?: WithDefault;
+}
+
+export default codegenNativeComponent('HighlighterView');
diff --git a/lib/components/HighlighterOverlayView.tsx b/lib/components/HighlighterOverlayView/index.tsx
similarity index 58%
rename from lib/components/HighlighterOverlayView.tsx
rename to lib/components/HighlighterOverlayView/index.tsx
index ee3997515a..8d2dd2495b 100644
--- a/lib/components/HighlighterOverlayView.tsx
+++ b/lib/components/HighlighterOverlayView/index.tsx
@@ -1,7 +1,10 @@
import React from 'react';
-import {requireNativeComponent, processColor, Platform, StyleSheet, Modal, ViewStyle} from 'react-native';
+import {processColor, StyleSheet, Modal, ViewStyle} from 'react-native';
+// Import the Codegen specification for New Architecture
+import HighlighterViewNativeComponent, {
+ HighlightViewTagParams as NativeHighlightViewTagParams
+} from './HighlighterViewNativeComponent';
-const NativeHighlighterView = requireNativeComponent('HighlighterView');
const DefaultOverlayColor = 'rgba(0, 0, 0, 0.5)';
type HighlightFrameType = {
@@ -25,7 +28,7 @@ export type HighlighterOverlayViewProps = {
onRequestClose?: () => void;
highlightFrame?: HighlightFrameType;
style?: ViewStyle;
- highlightViewTag?: number | null;
+ highlightViewTag?: number;
children?: JSX.Element[] | JSX.Element;
highlightViewTagParams?: HighlightViewTagParams;
minimumRectSize?: Pick;
@@ -34,7 +37,6 @@ export type HighlighterOverlayViewProps = {
testID?: string;
};
-
const HighlighterOverlayView = (props: HighlighterOverlayViewProps) => {
const {
overlayColor,
@@ -52,13 +54,22 @@ const HighlighterOverlayView = (props: HighlighterOverlayViewProps) => {
innerPadding
} = props;
- let overlayColorToUse = overlayColor || DefaultOverlayColor;
- let strokeColorToUse = strokeColor;
- if (Platform.OS === 'android') {
- // @ts-ignore
- overlayColorToUse = processColor(overlayColorToUse);
- // @ts-ignore
- strokeColorToUse = processColor(strokeColorToUse);
+ // Process colors for New Architecture Codegen component
+ const overlayColorToUse = processColor(overlayColor || DefaultOverlayColor) as number;
+ const strokeColorToUse = strokeColor ? (processColor(strokeColor) as number) : undefined;
+
+ // Convert highlightViewTagParams to match native Codegen spec
+ let nativeHighlightViewTagParams: NativeHighlightViewTagParams | undefined;
+ if (highlightViewTagParams) {
+ const padding = typeof highlightViewTagParams.padding === 'number' ? highlightViewTagParams.padding : 0;
+ nativeHighlightViewTagParams = {
+ paddingLeft: padding,
+ paddingTop: padding,
+ paddingRight: padding,
+ paddingBottom: padding,
+ offsetX: highlightViewTagParams.offset?.x || 0,
+ offsetY: highlightViewTagParams.offset?.y || 0
+ };
}
return (
@@ -68,8 +79,7 @@ const HighlighterOverlayView = (props: HighlighterOverlayViewProps) => {
transparent
onRequestClose={() => onRequestClose?.()}
>
- {
strokeColor={strokeColorToUse}
strokeWidth={strokeWidth}
highlightViewTag={highlightViewTag}
- highlightViewTagParams={highlightViewTagParams}
+ highlightViewTagParams={nativeHighlightViewTagParams}
minimumRectSize={minimumRectSize}
innerPadding={innerPadding}
+ testID={props.testID}
+ accessible={props.accessible}
/>
{children}
diff --git a/lib/components/HighlighterOverlayView.web.tsx b/lib/components/HighlighterOverlayView/index.web.tsx
similarity index 100%
rename from lib/components/HighlighterOverlayView.web.tsx
rename to lib/components/HighlighterOverlayView/index.web.tsx
diff --git a/lib/components/Keyboard/KeyboardInput/CustomKeyboardView/CustomKeyboardView.android.tsx b/lib/components/Keyboard/KeyboardAccessoryView/CustomKeyboardView/CustomKeyboardView.android.tsx
similarity index 97%
rename from lib/components/Keyboard/KeyboardInput/CustomKeyboardView/CustomKeyboardView.android.tsx
rename to lib/components/Keyboard/KeyboardAccessoryView/CustomKeyboardView/CustomKeyboardView.android.tsx
index b9c9288623..0da262b847 100644
--- a/lib/components/Keyboard/KeyboardInput/CustomKeyboardView/CustomKeyboardView.android.tsx
+++ b/lib/components/Keyboard/KeyboardAccessoryView/CustomKeyboardView/CustomKeyboardView.android.tsx
@@ -1,7 +1,7 @@
import React from 'react';
import {Keyboard, View} from 'react-native';
import KeyboardRegistry from '../KeyboardRegistry';
-import CustomKeyboardViewBase, {CustomKeyboardViewBaseProps} from '../CustomKeyboardViewBase';
+import CustomKeyboardViewBase, {CustomKeyboardViewBaseProps} from './CustomKeyboardViewBase';
export default class CustomKeyboardView extends CustomKeyboardViewBase {
static displayName = 'IGNORE';
diff --git a/lib/components/Keyboard/KeyboardInput/CustomKeyboardView/CustomKeyboardView.ios.tsx b/lib/components/Keyboard/KeyboardAccessoryView/CustomKeyboardView/CustomKeyboardView.ios.tsx
similarity index 91%
rename from lib/components/Keyboard/KeyboardInput/CustomKeyboardView/CustomKeyboardView.ios.tsx
rename to lib/components/Keyboard/KeyboardAccessoryView/CustomKeyboardView/CustomKeyboardView.ios.tsx
index 7bb0b35d6e..6107599903 100644
--- a/lib/components/Keyboard/KeyboardInput/CustomKeyboardView/CustomKeyboardView.ios.tsx
+++ b/lib/components/Keyboard/KeyboardAccessoryView/CustomKeyboardView/CustomKeyboardView.ios.tsx
@@ -1,6 +1,6 @@
-import TextInputKeyboardManager from './../TextInputKeyboardManager/TextInputKeyboardManager.ios';
-import KeyboardRegistry from './../KeyboardRegistry';
-import CustomKeyboardViewBase, {CustomKeyboardViewBaseProps} from './../CustomKeyboardViewBase';
+import TextInputKeyboardManager from '../TextInputKeyboardManager/TextInputKeyboardManager.ios';
+import KeyboardRegistry from '../KeyboardRegistry';
+import CustomKeyboardViewBase, {CustomKeyboardViewBaseProps} from './CustomKeyboardViewBase';
export type CustomKeyboardViewProps = CustomKeyboardViewBaseProps & {
/**
diff --git a/lib/components/Keyboard/KeyboardInput/CustomKeyboardViewBase.tsx b/lib/components/Keyboard/KeyboardAccessoryView/CustomKeyboardView/CustomKeyboardViewBase.tsx
similarity index 98%
rename from lib/components/Keyboard/KeyboardInput/CustomKeyboardViewBase.tsx
rename to lib/components/Keyboard/KeyboardAccessoryView/CustomKeyboardView/CustomKeyboardViewBase.tsx
index 2a52db0fca..0622ac48e3 100644
--- a/lib/components/Keyboard/KeyboardInput/CustomKeyboardViewBase.tsx
+++ b/lib/components/Keyboard/KeyboardAccessoryView/CustomKeyboardView/CustomKeyboardViewBase.tsx
@@ -1,6 +1,6 @@
import React, {Component} from 'react';
-import KeyboardRegistry from './KeyboardRegistry';
import {EventSubscription} from 'react-native';
+import KeyboardRegistry from '../KeyboardRegistry';
export type CustomKeyboardViewBaseProps = {
inputRef?: any;
diff --git a/lib/components/Keyboard/KeyboardInput/CustomKeyboardView/index.tsx b/lib/components/Keyboard/KeyboardAccessoryView/CustomKeyboardView/index.tsx
similarity index 100%
rename from lib/components/Keyboard/KeyboardInput/CustomKeyboardView/index.tsx
rename to lib/components/Keyboard/KeyboardAccessoryView/CustomKeyboardView/index.tsx
diff --git a/lib/components/Keyboard/KeyboardInput/CustomKeyboardView/index.web.tsx b/lib/components/Keyboard/KeyboardAccessoryView/CustomKeyboardView/index.web.tsx
similarity index 100%
rename from lib/components/Keyboard/KeyboardInput/CustomKeyboardView/index.web.tsx
rename to lib/components/Keyboard/KeyboardAccessoryView/CustomKeyboardView/index.web.tsx
diff --git a/lib/components/Keyboard/KeyboardInput/utils/__tests__/EventEmitterManager.spec.js b/lib/components/Keyboard/KeyboardAccessoryView/KeyboardRegistry/EventEmitterManager/__tests__/EventEmitterManager.spec.js
similarity index 98%
rename from lib/components/Keyboard/KeyboardInput/utils/__tests__/EventEmitterManager.spec.js
rename to lib/components/Keyboard/KeyboardAccessoryView/KeyboardRegistry/EventEmitterManager/__tests__/EventEmitterManager.spec.js
index d730a36c35..a9497bada4 100644
--- a/lib/components/Keyboard/KeyboardInput/utils/__tests__/EventEmitterManager.spec.js
+++ b/lib/components/Keyboard/KeyboardAccessoryView/KeyboardRegistry/EventEmitterManager/__tests__/EventEmitterManager.spec.js
@@ -1,4 +1,4 @@
-const EventEmitterManager = require('../EventEmitterManager').default;
+const EventEmitterManager = require('../index').default;
let EventEmitter;
diff --git a/lib/components/Keyboard/KeyboardInput/utils/EventEmitterManager.ts b/lib/components/Keyboard/KeyboardAccessoryView/KeyboardRegistry/EventEmitterManager/index.ts
similarity index 100%
rename from lib/components/Keyboard/KeyboardInput/utils/EventEmitterManager.ts
rename to lib/components/Keyboard/KeyboardAccessoryView/KeyboardRegistry/EventEmitterManager/index.ts
diff --git a/lib/components/Keyboard/KeyboardInput/__tests__/KeyboardRegistry.spec.js b/lib/components/Keyboard/KeyboardAccessoryView/KeyboardRegistry/__tests__/KeyboardRegistry.spec.js
similarity index 99%
rename from lib/components/Keyboard/KeyboardInput/__tests__/KeyboardRegistry.spec.js
rename to lib/components/Keyboard/KeyboardAccessoryView/KeyboardRegistry/__tests__/KeyboardRegistry.spec.js
index 79283e5850..bc3daec1b0 100644
--- a/lib/components/Keyboard/KeyboardInput/__tests__/KeyboardRegistry.spec.js
+++ b/lib/components/Keyboard/KeyboardAccessoryView/KeyboardRegistry/__tests__/KeyboardRegistry.spec.js
@@ -1,6 +1,6 @@
import {AppRegistry, View} from 'react-native';
import React from 'react';
-import KeyboardRegistry from '../KeyboardRegistry';
+import KeyboardRegistry from '../index';
describe('KeyboardRegistry - components', () => {
const mockComponent = 'test_component';
diff --git a/lib/components/Keyboard/KeyboardInput/KeyboardRegistry.ts b/lib/components/Keyboard/KeyboardAccessoryView/KeyboardRegistry/index.ts
similarity index 98%
rename from lib/components/Keyboard/KeyboardInput/KeyboardRegistry.ts
rename to lib/components/Keyboard/KeyboardAccessoryView/KeyboardRegistry/index.ts
index a281f615d7..4de878ac1b 100644
--- a/lib/components/Keyboard/KeyboardInput/KeyboardRegistry.ts
+++ b/lib/components/Keyboard/KeyboardAccessoryView/KeyboardRegistry/index.ts
@@ -1,6 +1,6 @@
-import {AppRegistry} from 'react-native';
import _ from 'lodash';
-import EventEmitterManager from './utils/EventEmitterManager';
+import {AppRegistry} from 'react-native';
+import EventEmitterManager from './EventEmitterManager';
/*
* Tech debt: how to deal with multiple registries in the app?
diff --git a/lib/components/Keyboard/KeyboardInput/keyboardRegistry.api.json b/lib/components/Keyboard/KeyboardAccessoryView/KeyboardRegistry/keyboardRegistry.api.json
similarity index 78%
rename from lib/components/Keyboard/KeyboardInput/keyboardRegistry.api.json
rename to lib/components/Keyboard/KeyboardAccessoryView/KeyboardRegistry/keyboardRegistry.api.json
index c35b74c43c..dbc210527c 100644
--- a/lib/components/Keyboard/KeyboardInput/keyboardRegistry.api.json
+++ b/lib/components/Keyboard/KeyboardAccessoryView/KeyboardRegistry/keyboardRegistry.api.json
@@ -1,49 +1,49 @@
{
"name": "KeyboardRegistry",
"category": "infra",
- "description": "used for registering keyboards and performing certain actions on the keyboards.",
+ "description": "used for registering keyboards and performing certain actions on the keyboards",
"example": "https://github.com/wix/react-native-ui-lib/blob/master/demo/src/screens/nativeComponentScreens/keyboardAccessory/demoKeyboards.js",
"props": [
{
"name": "registerKeyboard",
"type": "static function",
- "description": "Register a new keyboard.\ncomponentID (string) - the ID of the keyboard.\ngenerator (function) - a function for the creation of the keyboard.\nparams (object) - to be returned when using other methods (i.e. getKeyboards and getAllKeyboards)."
+ "description": "Register a new keyboard.\ncomponentID (string) - the ID of the keyboard.\ngenerator (function) - a function for the creation of the keyboard.\nparams (object) - to be returned when using other methods (i.e. getKeyboards and getAllKeyboards)"
},
{
"name": "getKeyboard",
"type": "static function",
- "description": "Get a specific keyboard\ncomponentID (string) - the ID of the keyboard."
+ "description": "Get a specific keyboard\ncomponentID (string) - the ID of the keyboard"
},
{
"name": "getKeyboards",
"type": "static function",
- "description": "Get keyboards by IDs\ncomponentIDs (string[]) - the ID of the keyboard."
+ "description": "Get keyboards by IDs\ncomponentIDs (string[]) - the ID of the keyboard"
},
{"name": "getAllKeyboards", "type": "static function", "description": "Get all keyboards"},
{
"name": "addListener",
"type": "static function",
- "description": "Add a listener for a callback.\nglobalID (string) - ID that includes the componentID and the event name\n (i.e. if componentID='kb1' globalID='kb1.onItemSelected')\ncallback (function) - the callback to be called when the said event happens"
+ "description": "Add a listener for a callback.\nglobalID (string) - ID that includes the componentID and the event name\n(i.e. if componentID='kb1' globalID='kb1.onItemSelected')\ncallback (function) - the callback to be called when the said event happens"
},
{
"name": "notifyListeners",
"type": "static function",
- "description": "Notify that an event has occurred.\nglobalID (string) - ID that includes the componentID and the event name\n (i.e. if componentID='kb1' globalID='kb1.onItemSelected')\nargs (object) - data to be sent to the listener."
+ "description": "Notify that an event has occurred.\nglobalID (string) - ID that includes the componentID and the event name\n(i.e. if componentID='kb1' globalID='kb1.onItemSelected')\nargs (object) - data to be sent to the listener"
},
{
"name": "removeListeners",
"type": "static function",
- "description": "Remove a listener for a callback.\nglobalID (string) - ID that includes the componentID and the event name\n (i.e. if componentID='kb1' globalID='kb1.onItemSelected')"
+ "description": "Remove a listener for a callback.\nglobalID (string) - ID that includes the componentID and the event name\n(i.e. if componentID='kb1' globalID='kb1.onItemSelected')"
},
{
"name": "onItemSelected",
"type": "static function",
- "description": "Default event to be used for when an item on the keyboard has been pressed.\ncomponentID (string) - the ID of the keyboard.\nargs (object) - data to be sent to the listener."
+ "description": "Default event to be used for when an item on the keyboard has been pressed.\ncomponentID (string) - the ID of the keyboard.\nargs (object) - data to be sent to the listener"
},
{
"name": "requestShowKeyboard",
"type": "static function",
- "description": "Request to show the keyboard\ncomponentID (string) - the ID of the keyboard."
+ "description": "Request to show the keyboard\ncomponentID (string) - the ID of the keyboard"
}
],
"snippet": ["KeyboardRegistry.registerKeyboard('keyboardName$1', () => KeyboardComponent$2)"]
diff --git a/lib/components/Keyboard/KeyboardInput/utils/KeyboardUtils.ts b/lib/components/Keyboard/KeyboardAccessoryView/KeyboardUtils/index.ts
similarity index 100%
rename from lib/components/Keyboard/KeyboardInput/utils/KeyboardUtils.ts
rename to lib/components/Keyboard/KeyboardAccessoryView/KeyboardUtils/index.ts
diff --git a/lib/components/Keyboard/KeyboardInput/TextInputKeyboardManager/TextInputKeyboardManager.android.ts b/lib/components/Keyboard/KeyboardAccessoryView/TextInputKeyboardManager/TextInputKeyboardManager.android.ts
similarity index 100%
rename from lib/components/Keyboard/KeyboardInput/TextInputKeyboardManager/TextInputKeyboardManager.android.ts
rename to lib/components/Keyboard/KeyboardAccessoryView/TextInputKeyboardManager/TextInputKeyboardManager.android.ts
diff --git a/lib/components/Keyboard/KeyboardInput/TextInputKeyboardManager/TextInputKeyboardManager.ios.ts b/lib/components/Keyboard/KeyboardAccessoryView/TextInputKeyboardManager/TextInputKeyboardManager.ios.ts
similarity index 100%
rename from lib/components/Keyboard/KeyboardInput/TextInputKeyboardManager/TextInputKeyboardManager.ios.ts
rename to lib/components/Keyboard/KeyboardAccessoryView/TextInputKeyboardManager/TextInputKeyboardManager.ios.ts
diff --git a/lib/components/Keyboard/KeyboardInput/TextInputKeyboardManager/index.ts b/lib/components/Keyboard/KeyboardAccessoryView/TextInputKeyboardManager/index.ts
similarity index 100%
rename from lib/components/Keyboard/KeyboardInput/TextInputKeyboardManager/index.ts
rename to lib/components/Keyboard/KeyboardAccessoryView/TextInputKeyboardManager/index.ts
diff --git a/lib/components/Keyboard/KeyboardInput/KeyboardAccessoryView.tsx b/lib/components/Keyboard/KeyboardAccessoryView/index.tsx
similarity index 98%
rename from lib/components/Keyboard/KeyboardInput/KeyboardAccessoryView.tsx
rename to lib/components/Keyboard/KeyboardAccessoryView/index.tsx
index 1a4e77b2c9..c65d796f2b 100644
--- a/lib/components/Keyboard/KeyboardInput/KeyboardAccessoryView.tsx
+++ b/lib/components/Keyboard/KeyboardAccessoryView/index.tsx
@@ -9,9 +9,9 @@ import {
BackHandler,
LayoutChangeEvent
} from 'react-native';
-import KeyboardTrackingView, {KeyboardTrackingViewProps} from '../KeyboardTracking/KeyboardTrackingView';
+import KeyboardTrackingView, {KeyboardTrackingViewProps} from '../KeyboardTrackingView';
import CustomKeyboardView from './CustomKeyboardView';
-import KeyboardUtils, {KeyboardHeightListener} from './utils/KeyboardUtils';
+import KeyboardUtils, {KeyboardHeightListener} from './KeyboardUtils';
const IsIOS = Platform.OS === 'ios';
const IsAndroid = Platform.OS === 'android';
diff --git a/lib/components/Keyboard/KeyboardInput/keyboardAccessoryView.api.json b/lib/components/Keyboard/KeyboardAccessoryView/keyboardAccessoryView.api.json
similarity index 91%
rename from lib/components/Keyboard/KeyboardInput/keyboardAccessoryView.api.json
rename to lib/components/Keyboard/KeyboardAccessoryView/keyboardAccessoryView.api.json
index 3238e0e4e3..eed4a41410 100644
--- a/lib/components/Keyboard/KeyboardInput/keyboardAccessoryView.api.json
+++ b/lib/components/Keyboard/KeyboardAccessoryView/keyboardAccessoryView.api.json
@@ -15,9 +15,9 @@
{
"name": "kbInputRef",
"type": "any",
- "description": "The reference to the actual text input (or the keyboard may not reset when instructed to, etc.).",
- "required": true,
- "note": "iOS only"
+ "description": "The reference to the actual text input (or the keyboard may not reset when instructed to, etc.)",
+ "note": "iOS only",
+ "required": true
},
{
"name": "kbComponent",
@@ -33,12 +33,12 @@
{
"name": "onItemSelected",
"type": "() => void",
- "description": "Callback that will be called when an item on the keyboard has been pressed."
+ "description": "Callback that will be called when an item on the keyboard has been pressed"
},
{
"name": "onRequestShowKeyboard",
"type": "() => void",
- "description": "Callback that will be called if KeyboardRegistry.requestShowKeyboard is called."
+ "description": "Callback that will be called if KeyboardRegistry.requestShowKeyboard is called"
},
{
"name": "onKeyboardResigned",
diff --git a/lib/components/Keyboard/KeyboardTracking/KeyboardAwareInsetsView.tsx b/lib/components/Keyboard/KeyboardAwareInsetsView/index.tsx
similarity index 97%
rename from lib/components/Keyboard/KeyboardTracking/KeyboardAwareInsetsView.tsx
rename to lib/components/Keyboard/KeyboardAwareInsetsView/index.tsx
index f2248479dc..81347a50e2 100644
--- a/lib/components/Keyboard/KeyboardTracking/KeyboardAwareInsetsView.tsx
+++ b/lib/components/Keyboard/KeyboardAwareInsetsView/index.tsx
@@ -1,6 +1,6 @@
import React from 'react';
import {StyleSheet, Dimensions} from 'react-native';
-import KeyboardTrackingView, {KeyboardTrackingViewProps} from './KeyboardTrackingView';
+import KeyboardTrackingView, {KeyboardTrackingViewProps} from '../KeyboardTrackingView';
type Props = KeyboardTrackingViewProps & {
offset?: number;
diff --git a/lib/components/Keyboard/KeyboardTracking/keyboardAwareInsetsView.api.json b/lib/components/Keyboard/KeyboardAwareInsetsView/keyboardAwareInsetsView.api.json
similarity index 100%
rename from lib/components/Keyboard/KeyboardTracking/keyboardAwareInsetsView.api.json
rename to lib/components/Keyboard/KeyboardAwareInsetsView/keyboardAwareInsetsView.api.json
diff --git a/lib/components/Keyboard/KeyboardTracking/KeyboardTrackingView/KeyboardTrackingView.android.tsx b/lib/components/Keyboard/KeyboardTrackingView/KeyboardTrackingView.android.tsx
similarity index 100%
rename from lib/components/Keyboard/KeyboardTracking/KeyboardTrackingView/KeyboardTrackingView.android.tsx
rename to lib/components/Keyboard/KeyboardTrackingView/KeyboardTrackingView.android.tsx
diff --git a/lib/components/Keyboard/KeyboardTracking/KeyboardTrackingView/KeyboardTrackingView.ios.tsx b/lib/components/Keyboard/KeyboardTrackingView/KeyboardTrackingView.ios.tsx
similarity index 77%
rename from lib/components/Keyboard/KeyboardTracking/KeyboardTrackingView/KeyboardTrackingView.ios.tsx
rename to lib/components/Keyboard/KeyboardTrackingView/KeyboardTrackingView.ios.tsx
index abf730f6d8..e32b3275ae 100644
--- a/lib/components/Keyboard/KeyboardTracking/KeyboardTrackingView/KeyboardTrackingView.ios.tsx
+++ b/lib/components/Keyboard/KeyboardTrackingView/KeyboardTrackingView.ios.tsx
@@ -1,16 +1,13 @@
-/**
- * Created by artald on 15/05/2016.
- */
-
import React, {PureComponent} from 'react';
-import ReactNative, {requireNativeComponent, NativeModules} from 'react-native';
+import ReactNative, {NativeModules} from 'react-native';
+// Import the Codegen specification for New Architecture
+import KeyboardTrackingViewNativeComponent from './KeyboardTrackingViewNativeComponent';
import {KeyboardTrackingViewProps} from './index';
-const NativeKeyboardTrackingView = requireNativeComponent('KeyboardTrackingViewTemp');
const KeyboardTrackingViewTempManager = NativeModules.KeyboardTrackingViewTempManager;
/**
- * @description: A UI component that enables “keyboard tracking" for this view and it's sub-views.
+ * @description: A UI component that enables "keyboard tracking" for this view and it's sub-views.
* Would typically be used when you have a TextField or TextInput inside this view.
*
* @example: https://github.com/wix/react-native-ui-lib/blob/master/demo/src/screens/nativeComponentScreens/KeyboardTrackingViewScreen.js
@@ -27,7 +24,7 @@ class KeyboardTrackingView extends PureComponent {
ref?: any;
render() {
- return (this.ref = r)}/>;
+ return (this.ref = r)}/>;
}
async getNativeProps() {
diff --git a/lib/components/Keyboard/KeyboardTrackingView/KeyboardTrackingViewNativeComponent.ts b/lib/components/Keyboard/KeyboardTrackingView/KeyboardTrackingViewNativeComponent.ts
new file mode 100644
index 0000000000..0c602c6897
--- /dev/null
+++ b/lib/components/Keyboard/KeyboardTrackingView/KeyboardTrackingViewNativeComponent.ts
@@ -0,0 +1,72 @@
+import type {ViewProps} from 'react-native';
+import type {
+ Int32,
+ WithDefault
+} from 'react-native/Libraries/Types/CodegenTypes';
+import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
+
+export interface NativeProps extends ViewProps {
+ /**
+ * Enables tracking of the keyboard when it's dismissed interactively (false by default).
+ */
+ trackInteractive?: WithDefault;
+
+ /**
+ * iOS only.
+ * Show the keyboard on a negative scroll
+ */
+ revealKeyboardInteractive?: WithDefault;
+
+ /**
+ * iOS only.
+ * Set to false to turn off inset management and manage it yourself
+ */
+ manageScrollView?: WithDefault;
+
+ /**
+ * iOS only.
+ * Set to true manageScrollView is set to true and still does not work
+ */
+ requiresSameParentToManageScrollView?: WithDefault;
+
+ /**
+ * iOS only.
+ * Allow hitting sub-views that are placed beyond the view bounds
+ */
+ allowHitsOutsideBounds?: WithDefault;
+
+ /**
+ * Should the scrollView scroll to the focused input
+ */
+ scrollToFocusedInput?: WithDefault;
+
+ /**
+ * iOS only.
+ * The scrolling behavior (NONE | SCROLL_TO_BOTTOM_INVERTED_ONLY | FIXED_OFFSET)
+ */
+ scrollBehavior?: WithDefault;
+
+ /**
+ * iOS only.
+ * Add a SafeArea view beneath the KeyboardAccessoryView
+ */
+ addBottomView?: WithDefault;
+
+ /**
+ * iOS only.
+ * The bottom view's color
+ */
+ bottomViewColor?: string;
+
+ /**
+ * Allow control safe area
+ */
+ useSafeArea?: WithDefault;
+
+ /**
+ * Whether or not to include bottom tab bar inset
+ */
+ usesBottomTabs?: WithDefault;
+}
+
+export default codegenNativeComponent('KeyboardTrackingViewTemp');
diff --git a/lib/components/Keyboard/KeyboardTracking/KeyboardTrackingView/index.tsx b/lib/components/Keyboard/KeyboardTrackingView/index.tsx
similarity index 100%
rename from lib/components/Keyboard/KeyboardTracking/KeyboardTrackingView/index.tsx
rename to lib/components/Keyboard/KeyboardTrackingView/index.tsx
diff --git a/lib/components/Keyboard/KeyboardTracking/KeyboardTrackingView/index.web.tsx b/lib/components/Keyboard/KeyboardTrackingView/index.web.tsx
similarity index 100%
rename from lib/components/Keyboard/KeyboardTracking/KeyboardTrackingView/index.web.tsx
rename to lib/components/Keyboard/KeyboardTrackingView/index.web.tsx
diff --git a/lib/components/Keyboard/KeyboardTracking/KeyboardTrackingView/keyboardTrackingView.api.json b/lib/components/Keyboard/KeyboardTrackingView/keyboardTrackingView.api.json
similarity index 82%
rename from lib/components/Keyboard/KeyboardTracking/KeyboardTrackingView/keyboardTrackingView.api.json
rename to lib/components/Keyboard/KeyboardTrackingView/keyboardTrackingView.api.json
index 360bf3fadc..9a208f7df9 100644
--- a/lib/components/Keyboard/KeyboardTracking/KeyboardTrackingView/keyboardTrackingView.api.json
+++ b/lib/components/Keyboard/KeyboardTrackingView/keyboardTrackingView.api.json
@@ -1,8 +1,8 @@
{
"name": "KeyboardTrackingView",
"category": "infra",
- "description": "A UI component that enables 'keyboard tracking' for this view and it's sub-views.\nWould typically be used when you have a TextField or TextInput inside this view.",
- "note": "This view is useful only for iOS.",
+ "description": "A UI component that enables 'keyboard tracking' for this view and it's sub-views.\nWould typically be used when you have a TextField or TextInput inside this view",
+ "note": "This view is useful only for iOS",
"example": "https://github.com/wix/react-native-ui-lib/blob/master/demo/src/screens/nativeComponentScreens/KeyboardTrackingViewScreen.js",
"images": [
"https://github.com/wix/react-native-ui-lib/blob/master/demo/showcase/KeyboardTrackingView/KeyboardTrackingView.gif?raw=true"
@@ -21,63 +21,54 @@
{
"name": "scrollBehavior",
"type": "number",
- "description": "The scrolling behavior (use KeyboardTrackingView.scrollBehaviors.NONE | SCROLL_TO_BOTTOM_INVERTED_ONLY | FIXED_OFFSET)",
- "note": "iOS only"
+ "description": "The scrolling behavior (use KeyboardTrackingView.scrollBehaviors.NONE | SCROLL_TO_BOTTOM_INVERTED_ONLY | FIXED_OFFSET)"
},
{
"name": "revealKeyboardInteractive",
"type": "boolean",
- "description": "Show the keyboard on a negative scroll.",
- "note": "iOS only",
+ "description": "Show the keyboard on a negative scroll",
"default": "false"
},
{
"name": "manageScrollView",
"type": "boolean",
- "description": "Set to false to turn off inset management and manage it yourself.",
- "note": "iOS only",
+ "description": "Set to false to turn off inset management and manage it yourself",
"default": "true"
},
{
"name": "requiresSameParentToManageScrollView",
"type": "boolean",
- "description": "Set to true manageScrollView is set to true and still does not work,\nit means that the ScrollView found is the wrong one and you'll have\nto have the KeyboardAccessoryView and the ScrollView as siblings\nand set this to true.",
- "note": "iOS only",
+ "description": "Set to true manageScrollView is set to true and still does not work,\nit means that the ScrollView found is the wrong one and you'll have\nto have the KeyboardAccessoryView and the ScrollView as siblings\nand set this to true",
"default": "false"
},
{
"name": "allowHitsOutsideBounds",
"type": "boolean",
- "description": "Allow hitting sub-views that are placed beyond the view bounds.",
- "note": "iOS only",
+ "description": "Allow hitting sub-views that are placed beyond the view bounds",
"default": "false"
},
{
"name": "addBottomView",
"type": "boolean",
- "description": "Add a view beneath the KeyboardAccessoryView.",
- "note": "iOS only",
+ "description": "Add a view beneath the KeyboardAccessoryView",
"default": "false"
},
{
"name": "bottomViewColor",
"type": "string",
- "description": "The bottom view's color.",
- "note": "iOS only",
+ "description": "The bottom view's color",
"default": "white"
},
{
"name": "useSafeArea",
"type": "boolean",
- "description": "Whether or not to handle SafeArea.",
- "note": "iOS only",
+ "description": "Whether or not to handle SafeArea",
"default": "true"
},
{
"name": "usesBottomTabs",
"type": "boolean",
- "description": "Whether or not to include bottom tab bar inset.",
- "note": "iOS only",
+ "description": "Whether or not to include bottom tab bar inset",
"default": "false"
},
{"name": "ref", "type": "any", "description": ""},
diff --git a/lib/components/Keyboard/index.ts b/lib/components/Keyboard/index.ts
index dd170502e2..ff4d49cd23 100644
--- a/lib/components/Keyboard/index.ts
+++ b/lib/components/Keyboard/index.ts
@@ -1,15 +1,15 @@
-import KeyboardTrackingView, {KeyboardTrackingViewProps} from './KeyboardTracking/KeyboardTrackingView';
-import KeyboardAwareInsetsView from './KeyboardTracking/KeyboardAwareInsetsView';
-import KeyboardRegistry from './KeyboardInput/KeyboardRegistry';
-import KeyboardAccessoryView, {KeyboardAccessoryViewProps} from './KeyboardInput/KeyboardAccessoryView';
-import KeyboardUtils from './KeyboardInput/utils/KeyboardUtils';
+import KeyboardTrackingView, {KeyboardTrackingViewProps} from './KeyboardTrackingView';
+import KeyboardAwareInsetsView from './KeyboardAwareInsetsView';
+import KeyboardAccessoryView, {KeyboardAccessoryViewProps} from './KeyboardAccessoryView';
+import KeyboardRegistry from './KeyboardAccessoryView/KeyboardRegistry';
+import KeyboardUtils from './KeyboardAccessoryView/KeyboardUtils';
export {KeyboardTrackingViewProps, KeyboardAccessoryViewProps};
export default {
KeyboardTrackingView,
KeyboardAwareInsetsView,
- KeyboardRegistry,
KeyboardAccessoryView,
+ KeyboardRegistry,
KeyboardUtils
};
diff --git a/lib/components/SafeArea/SafeAreaInsetsManager.ts b/lib/components/SafeArea/SafeAreaInsetsManager.ts
index ab0cc3fbc1..3a699479ad 100644
--- a/lib/components/SafeArea/SafeAreaInsetsManager.ts
+++ b/lib/components/SafeArea/SafeAreaInsetsManager.ts
@@ -1,46 +1,104 @@
/* eslint no-underscore-dangle: 0 */
-import {NativeModules, NativeEventEmitter} from 'react-native';
import _ from 'lodash';
+import {NativeModules, DeviceEventEmitter, Platform} from 'react-native';
-type SafeAreaInsetsType = { top: number; left: number; bottom: number; right: number; } | null
+type SafeAreaInsetsType = { top: number; left: number; bottom: number; right: number; } | null;
let SafeAreaInsetsCache: SafeAreaInsetsType = null;
-const NativeSafeAreaManager = NativeModules.SafeAreaManager;
-
class SafeAreaInsetsManager {
-
- _defaultInsets: SafeAreaInsetsType = {top: 0, left: 0, bottom: 0, right: 0};
- _safeAreaInsets: SafeAreaInsetsType = {top: 0, left: 0, bottom: 0, right: 0};
+ _defaultInsets: SafeAreaInsetsType = {top: 47, left: 0, bottom: 34, right: 0}; // Common iPhone safe area values
+ _safeAreaInsets: SafeAreaInsetsType = {top: 47, left: 0, bottom: 34, right: 0};
_safeAreaChangedDelegates: Array = [];
+ _nativeModule: any = null;
constructor() {
- this.addSafeAreaChangedListener();
+ // Initialize with default values
+ this._safeAreaInsets = this._defaultInsets;
+
+ // Try to connect to native module
+ this.setupNativeConnection();
+ }
+
+ setupNativeConnection() {
+ try {
+ // Access the native module directly without causing getConstants
+ this._nativeModule = NativeModules.SafeAreaManager;
+
+ if (this._nativeModule) {
+ // Set up event listener using DeviceEventEmitter instead of NativeEventEmitter
+ // This avoids getConstants issues
+ this.setupEventListener();
+
+ // Get initial safe area insets
+ this.getInitialInsets();
+ } else {
+ console.log('SafeAreaInsetsManager: Native SafeAreaManager not available, using defaults');
+ }
+ } catch (error) {
+ console.warn('SafeAreaInsetsManager: Failed to connect to native module:', error);
+ }
}
- addSafeAreaChangedListener() {
- if (!NativeSafeAreaManager) {
+ setupEventListener() {
+ if (Platform.OS !== 'ios') {
return;
}
- const NativeSafeAreaEvents = new NativeEventEmitter(NativeSafeAreaManager);
- NativeSafeAreaEvents.addListener('SafeAreaInsetsDidChangeEvent', (safeAreaInsets) => {
- SafeAreaInsetsCache = safeAreaInsets;
- this._safeAreaInsets = SafeAreaInsetsCache;
- _.forEach(this._safeAreaChangedDelegates, (delegate) => {
- if (delegate.onSafeAreaInsetsDidChangeEvent) {
- delegate.onSafeAreaInsetsDidChangeEvent(this._safeAreaInsets);
- } else {
- console.warn('ERROR', 'SafeAreaInsetsManager', 'safe area changed delegate was added, but it does not implement the onSafeAreaInsetsDidChangeEvent method'); //eslint-disable-line
+
+ try {
+ // Use DeviceEventEmitter instead of NativeEventEmitter to avoid getConstants
+ DeviceEventEmitter.addListener('SafeAreaInsetsDidChangeEvent', (data) => {
+ if (data) {
+ SafeAreaInsetsCache = data;
+ this._safeAreaInsets = data;
+ this.notifyDelegates(data);
}
});
+ } catch (error) {
+ console.warn('SafeAreaInsetsManager: Failed to setup event listener:', error);
+ }
+ }
+
+ async getInitialInsets() {
+ if (!this._nativeModule) {
+ return;
+ }
+
+ try {
+ const insets = await this._nativeModule.getSafeAreaInsets();
+
+ if (insets) {
+ SafeAreaInsetsCache = insets;
+ this._safeAreaInsets = insets;
+ // Don't notify delegates yet as components might not be ready
+ }
+ } catch (error) {
+ console.warn('SafeAreaInsetsManager: Failed to get initial insets:', error);
+ }
+ }
+
+ notifyDelegates(insets: SafeAreaInsetsType) {
+ _.forEach(this._safeAreaChangedDelegates, (delegate) => {
+ if (delegate.onSafeAreaInsetsDidChangeEvent) {
+ delegate.onSafeAreaInsetsDidChangeEvent(insets);
+ }
});
}
async _updateInsets() {
- if (NativeSafeAreaManager && SafeAreaInsetsCache === null) {
- SafeAreaInsetsCache = await NativeSafeAreaManager.getSafeAreaInsets();
+ if (this._nativeModule && SafeAreaInsetsCache === null) {
+ try {
+ SafeAreaInsetsCache = await this._nativeModule.getSafeAreaInsets();
+ this._safeAreaInsets = SafeAreaInsetsCache;
+ } catch (error) {
+ console.warn('SafeAreaInsetsManager: Failed to get native insets:', error);
+ this._safeAreaInsets = this._defaultInsets;
+ }
+ } else if (SafeAreaInsetsCache !== null) {
this._safeAreaInsets = SafeAreaInsetsCache;
+ } else {
+ this._safeAreaInsets = this._defaultInsets;
}
}
@@ -62,6 +120,20 @@ class SafeAreaInsetsManager {
get defaultInsets() {
return this._defaultInsets;
}
+
+ // Method to manually refresh safe area insets and notify delegates
+ async refreshSafeAreaInsets() {
+ const previousInsets = this._safeAreaInsets;
+ SafeAreaInsetsCache = null; // Force refresh
+ await this._updateInsets();
+
+ // Notify delegates if insets changed
+ if (!_.isEqual(previousInsets, this._safeAreaInsets)) {
+ this.notifyDelegates(this._safeAreaInsets);
+ }
+ }
}
-export default new SafeAreaInsetsManager();
+const instance = new SafeAreaInsetsManager();
+
+export default instance;
diff --git a/lib/components/SafeArea/SafeAreaSpacerView.tsx b/lib/components/SafeArea/SafeAreaSpacerView.tsx
index 602ab5a5fc..5d19fe11a0 100644
--- a/lib/components/SafeArea/SafeAreaSpacerView.tsx
+++ b/lib/components/SafeArea/SafeAreaSpacerView.tsx
@@ -1,19 +1,70 @@
-import React from 'react';
-import {View, requireNativeComponent, ViewStyle, Platform} from 'react-native';
-
-const NativeSafeAreaSpacerView = requireNativeComponent('SafeAreaSpacerView');
-const isIOS = Platform.OS === 'ios';
+import React, {useState, useCallback, useEffect} from 'react';
+import {View, ViewStyle, Dimensions} from 'react-native';
+import SafeAreaInsetsManager from './SafeAreaInsetsManager';
export type SafeAreaSpacerViewProps = {
style?: ViewStyle;
};
-const SafeAreaSpacerView = ({style}: SafeAreaSpacerViewProps) => {
- return (
- // @ts-ignore
- isIOS ? :
- );
+const SafeAreaSpacerView = ({style}: SafeAreaSpacerViewProps) => {
+ const [safeAreaInsets, setSafeAreaInsets] = useState({top: 0, left: 0, bottom: 0, right: 0});
+ const [spacerHeight, setSpacerHeight] = useState(0);
+
+ useEffect(() => {
+ const getSafeAreaInsets = async () => {
+ try {
+ const insets = await SafeAreaInsetsManager.getSafeAreaInsets();
+ if (insets) {
+ setSafeAreaInsets(insets);
+ }
+ } catch (error) {
+ console.warn('SafeAreaSpacerView: Failed to get initial safe area insets:', error);
+ }
+ };
+
+ getSafeAreaInsets();
+
+ // Add delegate to listen for safe area changes from native component
+ const delegate = {
+ onSafeAreaInsetsDidChangeEvent: (insets: any) => {
+ if (insets) {
+ setSafeAreaInsets(insets);
+ }
+ }
+ };
+
+ SafeAreaInsetsManager.addSafeAreaChangedDelegate(delegate);
+
+ return () => {
+ SafeAreaInsetsManager.removeSafeAreaChangedDelegate(delegate);
+ };
+ }, []);
+
+ // Position detection with useCallback
+ const handleLayout = useCallback((event: any) => {
+ const {y} = event.nativeEvent.layout;
+ const screenHeight = Dimensions.get('window').height;
+
+ let height = 0;
+ // Check if positioned within safe area bounds
+ if (y < safeAreaInsets.top) {
+ height = safeAreaInsets.top;
+ } else if (y > screenHeight - safeAreaInsets.bottom) {
+ height = safeAreaInsets.bottom;
+ }
+
+ if (height !== spacerHeight) {
+ setSpacerHeight(height);
+ }
+ }, [safeAreaInsets, spacerHeight]);
+
+ const spacerStyle = {
+ height: spacerHeight,
+ ...style
+ };
+
+ return ;
};
-SafeAreaSpacerView.displayName = 'IGNORE';
+SafeAreaSpacerView.displayName = 'SafeAreaSpacerView';
export default SafeAreaSpacerView;
diff --git a/lib/package.json b/lib/package.json
index faff2f00b1..ee0b1823fc 100644
--- a/lib/package.json
+++ b/lib/package.json
@@ -1,6 +1,6 @@
{
"name": "uilib-native",
- "version": "4.5.2",
+ "version": "5.0.0",
"homepage": "https://github.com/wix/react-native-ui-lib",
"description": "uilib native components (separated from js components)",
"main": "components/index",
diff --git a/src/commons/Constants.ts b/src/commons/Constants.ts
index 3323371a1f..978d043813 100644
--- a/src/commons/Constants.ts
+++ b/src/commons/Constants.ts
@@ -44,8 +44,13 @@ function setStatusBarHeight() {
statusBarHeight = (StatusBar.currentHeight ?? StatusBarManager?.HEIGHT) || 0;
if (isIOS && StatusBarManager) {
- // override guesstimate height with the actual height from StatusBarManager
- StatusBarManager.getHeight((data:{height:number}) => (statusBarHeight = data.height));
+ try {
+ // override guesstimate height with the actual height from StatusBarManager
+ StatusBarManager.getHeight((data:{height:number}) => (statusBarHeight = data.height));
+ } catch (error) {
+ console.warn('Constants: StatusBarManager.getHeight not available in new architecture, using fallback');
+ // Keep the fallback height we already set above
+ }
}
}