From 0dc133a2ff87ca33f8b8811da1f78f9cedcc19e8 Mon Sep 17 00:00:00 2001 From: Freddy Harris Date: Thu, 19 Mar 2026 20:26:28 +0100 Subject: [PATCH 1/4] remove bindings --- src/apis/SoundManager.bs.js | 1 - src/apis/SoundManager.res | 3 --- src/apis/YellowBox.bs.js | 1 - src/apis/YellowBox.res | 2 -- src/elements/ViewPagerAndroidElement.bs.js | 10 ---------- src/elements/ViewPagerAndroidElement.res | 10 ---------- src/elements/ViewPagerAndroidMethods.bs.js | 9 --------- src/elements/ViewPagerAndroidMethods.res | 9 --------- 8 files changed, 45 deletions(-) delete mode 100644 src/apis/SoundManager.bs.js delete mode 100644 src/apis/SoundManager.res delete mode 100644 src/apis/YellowBox.bs.js delete mode 100644 src/apis/YellowBox.res delete mode 100644 src/elements/ViewPagerAndroidElement.bs.js delete mode 100644 src/elements/ViewPagerAndroidElement.res delete mode 100644 src/elements/ViewPagerAndroidMethods.bs.js delete mode 100644 src/elements/ViewPagerAndroidMethods.res diff --git a/src/apis/SoundManager.bs.js b/src/apis/SoundManager.bs.js deleted file mode 100644 index ae1b9f17e..000000000 --- a/src/apis/SoundManager.bs.js +++ /dev/null @@ -1 +0,0 @@ -/* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */ diff --git a/src/apis/SoundManager.res b/src/apis/SoundManager.res deleted file mode 100644 index e1531a22a..000000000 --- a/src/apis/SoundManager.res +++ /dev/null @@ -1,3 +0,0 @@ -// Android-only -@module("react-native") @scope("SoundManager") -external playTouchSound: unit => unit = "playTouchSound" diff --git a/src/apis/YellowBox.bs.js b/src/apis/YellowBox.bs.js deleted file mode 100644 index ae1b9f17e..000000000 --- a/src/apis/YellowBox.bs.js +++ /dev/null @@ -1 +0,0 @@ -/* This output is empty. Its source's type definitions, externals and/or unused code got optimized away. */ diff --git a/src/apis/YellowBox.res b/src/apis/YellowBox.res deleted file mode 100644 index 0222a5c5e..000000000 --- a/src/apis/YellowBox.res +++ /dev/null @@ -1,2 +0,0 @@ -@module("react-native") @scope("YellowBox") -external ignoreWarnings: array => unit = "ignoreWarnings" diff --git a/src/elements/ViewPagerAndroidElement.bs.js b/src/elements/ViewPagerAndroidElement.bs.js deleted file mode 100644 index 92a101b69..000000000 --- a/src/elements/ViewPagerAndroidElement.bs.js +++ /dev/null @@ -1,10 +0,0 @@ -'use strict'; - -var NativeMethods$ReactNative = require("./NativeMethods.bs.js"); -var ViewPagerAndroidMethods$ReactNative = require("./ViewPagerAndroidMethods.bs.js"); - -ViewPagerAndroidMethods$ReactNative.Make({}); - -NativeMethods$ReactNative.Make({}); - -/* Not a pure module */ diff --git a/src/elements/ViewPagerAndroidElement.res b/src/elements/ViewPagerAndroidElement.res deleted file mode 100644 index 74a740871..000000000 --- a/src/elements/ViewPagerAndroidElement.res +++ /dev/null @@ -1,10 +0,0 @@ -type element -type ref = Ref.t - -include ViewPagerAndroidMethods.Make({ - type t = element -}) - -include NativeMethods.Make({ - type t = element -}) diff --git a/src/elements/ViewPagerAndroidMethods.bs.js b/src/elements/ViewPagerAndroidMethods.bs.js deleted file mode 100644 index 643aa1ca3..000000000 --- a/src/elements/ViewPagerAndroidMethods.bs.js +++ /dev/null @@ -1,9 +0,0 @@ -'use strict'; - - -function Make(T) { - return {}; -} - -exports.Make = Make; -/* No side effect */ diff --git a/src/elements/ViewPagerAndroidMethods.res b/src/elements/ViewPagerAndroidMethods.res deleted file mode 100644 index 1bcc99a9b..000000000 --- a/src/elements/ViewPagerAndroidMethods.res +++ /dev/null @@ -1,9 +0,0 @@ -module Make = ( - T: { - type t - }, -) => { - @send external setPage: (T.t, int) => unit = "setPage" - @send - external setPageWithoutAnimation: (T.t, int) => unit = "setPageWithoutAnimation" -} From c4e860d221cc8b6494f92e1b7c205fbbdd2bca27 Mon Sep 17 00:00:00 2001 From: Freddy Harris Date: Fri, 20 Mar 2026 17:00:26 +0100 Subject: [PATCH 2/4] codex review batch 1 --- src/apis/AccessibilityInfo.res | 30 +++++++++++++++++++++++++++++- src/apis/AppRegistry.res | 4 ++-- src/apis/AppState.res | 3 +++ src/apis/BackHandler.res | 7 ++----- src/apis/Keyboard.res | 12 +++++++++--- src/apis/Linking.res | 6 +++--- src/apis/Platform.res | 12 ++++++++++++ src/apis/Share.res | 2 +- src/components/Image.res | 28 ++++++++++++++++++++++++---- src/components/VirtualizedList.res | 2 +- 10 files changed, 86 insertions(+), 20 deletions(-) diff --git a/src/apis/AccessibilityInfo.res b/src/apis/AccessibilityInfo.res index 774860c9a..f13a309e9 100644 --- a/src/apis/AccessibilityInfo.res +++ b/src/apis/AccessibilityInfo.res @@ -9,12 +9,21 @@ external addEventListener: @string | #reduceMotionChanged(bool => unit) | #screenReaderChanged(bool => unit) | #reduceTransparencyChanged(bool => unit) + | #highTextContrastChanged(bool => unit) + | #darkerSystemColorsChanged(bool => unit) + | #accessibilityServiceChanged(bool => unit) | #announcementFinished(announcementResult => unit) ] => EventSubscription.t = "addEventListener" @scope("AccessibilityInfo") @module("react-native") external announceForAccessibility: string => unit = "announceForAccessibility" +type announceForAccessibilityOptions = {queue?: bool} + +@scope("AccessibilityInfo") @module("react-native") +external announceForAccessibilityWithOptions: (string, announceForAccessibilityOptions) => unit = + "announceForAccessibilityWithOptions" + @scope("AccessibilityInfo") @module("react-native") external getRecommendedTimeoutMillis: float => promise = "getRecommendedTimeoutMillis" @@ -37,10 +46,29 @@ external isReduceTransparencyEnabled: unit => promise = "isReduceTranspare external isScreenReaderEnabled: unit => promise = "isScreenReaderEnabled" @scope("AccessibilityInfo") @module("react-native") -external isAccessibilityServiceEnabled: unit => promise = "isAccessibilityServiceEnabled" +external isHighTextContrastEnabled: unit => promise = "isHighTextContrastEnabled" + +@scope("AccessibilityInfo") @module("react-native") +external isDarkerSystemColorsEnabled: unit => promise = "isDarkerSystemColorsEnabled" @scope("AccessibilityInfo") @module("react-native") +external isAccessibilityServiceEnabled: unit => promise = "isAccessibilityServiceEnabled" + +@deprecated("Prefer using sendAccessibilityEvent with eventType focus instead.") +@scope("AccessibilityInfo") +@module("react-native") external setAccessibilityFocus: NativeTypes.nodeHandle => unit = "setAccessibilityFocus" +type accessibilityEventTypes = [ + | #click + | #focus + | #viewHoverEnter + | #windowStateChange +] + +@scope("AccessibilityInfo") @module("react-native") +external sendAccessibilityEvent: (NativeElement.ref, accessibilityEventTypes) => unit = + "sendAccessibilityEvent" + @scope("AccessibilityInfo") @module("react-native") external prefersCrossFadeTransitions: unit => promise = "prefersCrossFadeTransitions" diff --git a/src/apis/AppRegistry.res b/src/apis/AppRegistry.res index 69c8355a5..8b96f56a2 100644 --- a/src/apis/AppRegistry.res +++ b/src/apis/AppRegistry.res @@ -50,7 +50,7 @@ external getSections: unit => dict> = "getSections" // multiple externals @module("react-native") @scope("AppRegistry") -external registerComponent: (appKey, componentProvider<'a>) => unit = "registerComponent" +external registerComponent: (appKey, componentProvider<'a>) => string = "registerComponent" // multiple externals @module("react-native") @scope("AppRegistry") @@ -74,7 +74,7 @@ external setWrapperComponentProvider: wrapperComponentProvider<'a, 'b> => unit = "setWrapperComponentProvider" @module("react-native") @scope("AppRegistry") -external unmountApplicationComponentAtRootTag: string => unit = +external unmountApplicationComponentAtRootTag: float => unit = "unmountApplicationComponentAtRootTag" // Android only diff --git a/src/apis/AppState.res b/src/apis/AppState.res index 84862bd08..2d6ef1ff3 100644 --- a/src/apis/AppState.res +++ b/src/apis/AppState.res @@ -3,6 +3,9 @@ type t = [#active | #background | #inactive | #unknown | #extension] @scope("AppState") @module("react-native") external currentState: t = "currentState" +@scope("AppState") @module("react-native") +external isAvailable: bool = "isAvailable" + @scope("AppState") @module("react-native") external addEventListener: @string [ diff --git a/src/apis/BackHandler.res b/src/apis/BackHandler.res index d49b0fe8e..9b872cd6c 100644 --- a/src/apis/BackHandler.res +++ b/src/apis/BackHandler.res @@ -3,10 +3,7 @@ type remove = {@meth "remove": unit => unit} @scope("BackHandler") @module("react-native") external exitApp: unit => unit = "exitApp" -type eventType = [#backPress | #hardwareBackPress] +type eventType = [#hardwareBackPress] @scope("BackHandler") @module("react-native") -external addEventListener: (eventType, unit => bool) => remove = "addEventListener" - -@scope("BackHandler") @module("react-native") -external removeEventListener: (eventType, unit => bool) => unit = "removeEventListener" +external addEventListener: (eventType, unit => Js.Nullable.t) => remove = "addEventListener" diff --git a/src/apis/Keyboard.res b/src/apis/Keyboard.res index 95c4645e2..30e78f916 100644 --- a/src/apis/Keyboard.res +++ b/src/apis/Keyboard.res @@ -1,4 +1,4 @@ -type screenRect = { +type keyboardMetrics = { screenX: float, screenY: float, width: float, @@ -17,8 +17,8 @@ type eventType = [ type keyboardEvent = { duration: float, easing: LayoutAnimation.animationType, - endCoordinates: screenRect, - startCoordinates: screenRect, + endCoordinates: keyboardMetrics, + startCoordinates: keyboardMetrics, isEventFromThisApp: bool, } @@ -35,3 +35,9 @@ external dismiss: unit => unit = "dismiss" @module("react-native") @scope("Keyboard") external isVisible: unit => bool = "isVisible" + +@module("react-native") @scope("Keyboard") +external scheduleLayoutAnimation: keyboardEvent => unit = "scheduleLayoutAnimation" + +@module("react-native") @scope("Keyboard") @return(nullable) +external metrics: unit => option = "metrics" diff --git a/src/apis/Linking.res b/src/apis/Linking.res index fbe540d1b..eb84e1d86 100644 --- a/src/apis/Linking.res +++ b/src/apis/Linking.res @@ -21,15 +21,15 @@ external canOpenURL: string => promise = "canOpenURL" external getInitialURL: unit => promise> = "getInitialURL" @scope("Linking") @module("react-native") -external openSettings: unit => promise<'a> = "openSettings" +external openSettings: unit => promise = "openSettings" // multiple externals @scope("Linking") @module("react-native") -external sendIntent: string => unit = "sendIntent" +external sendIntent: string => promise = "sendIntent" // multiple externals @scope("Linking") @module("react-native") -external sendIntentWithExtras: (string, array) => unit = "sendIntent" +external sendIntentWithExtras: (string, array) => promise = "sendIntent" type url = {url: string} diff --git a/src/apis/Platform.res b/src/apis/Platform.res index 66508fbe9..ef150b45a 100644 --- a/src/apis/Platform.res +++ b/src/apis/Platform.res @@ -13,3 +13,15 @@ Platform.os === #ios @module("react-native") @scope("Platform") external os: os = "OS" + +@module("react-native") @scope("Platform") +external isPad: bool = "isPad" + +@module("react-native") @scope("Platform") +external isTV: bool = "isTV" + +@module("react-native") @scope("Platform") +external isVision: bool = "isVision" + +@module("react-native") @scope("Platform") +external isTesting: bool = "isTesting" diff --git a/src/apis/Share.res b/src/apis/Share.res index 60eacde32..9957d5718 100644 --- a/src/apis/Share.res +++ b/src/apis/Share.res @@ -33,4 +33,4 @@ external share: content => promise = "share" // multiple externals @module("react-native") @scope("Share") -external shareWithOptions: (content, options) => promise = "share" +external shareWithOptions: (content, options) => promise = "share" diff --git a/src/components/Image.res b/src/components/Image.res index c652d906a..14a1b45c7 100644 --- a/src/components/Image.res +++ b/src/components/Image.res @@ -69,7 +69,7 @@ module ProgressEvent = { type progressEvent = ProgressEvent.t -type resizeMethod = [#auto | #resize | #scale] +type resizeMethod = [#auto | #resize | #scale | #none] type referrerPolicy = [ | #"no-referrer" @@ -97,7 +97,7 @@ type imageProps = { defaultSource?: Source.t, fadeDuration?: float, height?: float, - loadingIndicatorSource?: array, + loadingIndicatorSource?: Source.t, onError?: errorEvent => unit, onLayout?: Event.layoutEvent => unit, onLoad?: imageLoadEvent => unit, @@ -128,17 +128,37 @@ external make: React.component = "Image" type sizeError +type imageSize = { + height: float, + width: float, +} + @module("react-native") @scope("Image") -external getSize: ( +external getSize_legacy: ( ~uri: string, ~success: (~width: float, ~height: float) => unit, ~failure: sizeError => unit=?, ) => unit = "getSize" +@module("react-native") @scope("Image") +external getSize: (~uri: string) => promise = "getSize" + +@module("react-native") @scope("Image") +external getSizeWithHeaders: (~uri: string, ~header: dict) => promise = + "getSizeWithHeaders" + type requestId @module("react-native") @scope("Image") -external prefetch: (~uri: string) => requestId = "prefetch" +external prefetch: (~uri: string, ~callback: requestId => unit=?) => promise = "prefetch" + +@module("react-native") @scope("Image") +external prefetchWithMetadata: ( + ~uri: string, + ~queryRootName: string, + ~rootTag: float=?, + ~callback: requestId => unit=?, +) => promise = "prefetchWithMetadata" @module("react-native") @scope("Image") external abortPrefetch: requestId => unit = "abortPrefetch" diff --git a/src/components/VirtualizedList.res b/src/components/VirtualizedList.res index 089bd9a7f..6a7160ed2 100644 --- a/src/components/VirtualizedList.res +++ b/src/components/VirtualizedList.res @@ -31,7 +31,7 @@ type itemLayout = { index: int, } -type onStartReachedParams = {distanceFromEnd: float} +type onStartReachedParams = {distanceFromStart: float} type onEndReachedParams = {distanceFromEnd: float} type onScrollToIndexFailedParams = { From 26ba9dfa78732b1548c674ba0ba239d53d6b23d5 Mon Sep 17 00:00:00 2001 From: Freddy Harris Date: Sun, 22 Mar 2026 18:20:55 +0100 Subject: [PATCH 3/4] codex review batch 2 --- src/apis/ActionSheetIOS.res | 5 +++- src/apis/Alert.res | 1 + src/apis/LogBox.res | 10 ++++++-- src/apis/PermissionsAndroid.res | 3 +++ src/apis/PermissionsAndroid.resi | 3 +++ src/components/Button.res | 2 +- src/components/DrawerLayoutAndroid.res | 4 +-- src/components/Modal.res | 3 ++- src/components/Switch.res | 1 + src/components/Text.res | 20 ++++++++++++--- src/components/TextInput.res | 30 ++++++++++++++++++++++ src/components/TouchableNativeFeedback.res | 7 ++--- src/components/TouchableOpacity.res | 6 ++++- src/components/View.res | 12 ++++++++- 14 files changed, 92 insertions(+), 15 deletions(-) diff --git a/src/apis/ActionSheetIOS.res b/src/apis/ActionSheetIOS.res index b99eeadb9..5ec41eae0 100644 --- a/src/apis/ActionSheetIOS.res +++ b/src/apis/ActionSheetIOS.res @@ -2,11 +2,14 @@ type options = { options: array, cancelButtonIndex?: int, destructiveButtonIndex?: array, - disabledButtonIndices?: int, + disabledButtonIndices?: array, title?: string, message?: string, + anchor?: int, tintColor?: Color.t, cancelButtonTintColor?: Color.t, + userInterfaceStyle?: Appearance.t, + disabledButtonTintColor?: Color.t, } @module("react-native") @scope("ActionSheetIOS") diff --git a/src/apis/Alert.res b/src/apis/Alert.res index 374aeabc7..4fdc835b2 100644 --- a/src/apis/Alert.res +++ b/src/apis/Alert.res @@ -1,5 +1,6 @@ type options = { cancelable?: bool, + userInterfaceStyle?: Appearance.t, onDismiss?: unit => unit, } diff --git a/src/apis/LogBox.res b/src/apis/LogBox.res index 6794357c1..cdf45e07c 100644 --- a/src/apis/LogBox.res +++ b/src/apis/LogBox.res @@ -1,5 +1,11 @@ @module("react-native") @scope("LogBox") -external ignoreLogs: array => unit = "ignoreLogs" +external ignoreLogs: array => unit = "ignoreLogs" @module("react-native") @scope("LogBox") -external ignoreAllLogs: unit => unit = "ignoreAllLogs" +external ignoreAllLogs: (~ignore: bool=?) => unit = "ignoreAllLogs" + +@module("react-native") @scope("LogBox") +external install: unit => unit = "install" + +@module("react-native") @scope("LogBox") +external uninstall: unit => unit = "install" diff --git a/src/apis/PermissionsAndroid.res b/src/apis/PermissionsAndroid.res index 269363a10..472d04dcf 100644 --- a/src/apis/PermissionsAndroid.res +++ b/src/apis/PermissionsAndroid.res @@ -79,6 +79,9 @@ module Permission = { @module("react-native") @scope(("PermissionsAndroid", "PERMISSIONS")) external readMediaVideo: t = "READ_MEDIA_VIDEO" + @module("react-native") @scope(("PermissionsAndroid", "PERMISSIONS")) + external readMediaVisualUserSelected: t = "READ_MEDIA_VISUAL_USER_SELECTED" + @module("react-native") @scope(("PermissionsAndroid", "PERMISSIONS")) external readPhoneNumbers: t = "READ_PHONE_NUMBERS" diff --git a/src/apis/PermissionsAndroid.resi b/src/apis/PermissionsAndroid.resi index b3e95ef23..7709742d9 100644 --- a/src/apis/PermissionsAndroid.resi +++ b/src/apis/PermissionsAndroid.resi @@ -79,6 +79,9 @@ module Permission: { @module("react-native") @scope(("PermissionsAndroid", "PERMISSIONS")) external readMediaVideo: t = "READ_MEDIA_VIDEO" + @module("react-native") @scope(("PermissionsAndroid", "PERMISSIONS")) + external readMediaVisualUserSelected: t = "READ_MEDIA_VISUAL_USER_SELECTED" + @module("react-native") @scope(("PermissionsAndroid", "PERMISSIONS")) external readPhoneNumbers: t = "READ_PHONE_NUMBERS" diff --git a/src/components/Button.res b/src/components/Button.res index 392b9fc13..b1e619c9f 100644 --- a/src/components/Button.res +++ b/src/components/Button.res @@ -18,7 +18,7 @@ type props = { onAccessibilityAction?: Accessibility.actionEvent => unit, onPress: Event.pressEvent => unit, testID?: string, - title?: string, + title: string, touchSoundDisabled?: bool, } diff --git a/src/components/DrawerLayoutAndroid.res b/src/components/DrawerLayoutAndroid.res index ebb923f9f..6c86cd501 100644 --- a/src/components/DrawerLayoutAndroid.res +++ b/src/components/DrawerLayoutAndroid.res @@ -12,7 +12,7 @@ type drawerSlideEvent = DrawerSlideEvent.t type t -type androidInteractionState = [#idle | #dragging | #settling] +type androidInteractionState = [#Idle | #Dragging | #Settling] type drawerLockMode = [ | #unlocked @@ -27,7 +27,7 @@ type keyboardDismissMode = [#none | #"on-drag"] type props = { ref?: ref, ...View.viewProps, - renderNavigationView?: unit => React.element, + renderNavigationView: unit => React.element, onDrawerClose?: unit => unit, drawerLockMode?: drawerLockMode, drawerPosition?: drawerPosition, diff --git a/src/components/Modal.res b/src/components/Modal.res index 37f20bbc4..7ba6035e5 100644 --- a/src/components/Modal.res +++ b/src/components/Modal.res @@ -31,12 +31,14 @@ type presentationStyle = [ type props = { ref?: ref, + ...View.viewProps, animationType?: animationType, backdropColor?: Color.t, hardwareAccelerated?: bool, navigationBarTranslucent?: bool, onDismiss?: unit => unit, onOrientationChange?: orientationChangeEvent => unit, + allowSwipeDismissal?: bool, onRequestClose?: unit => unit, onShow?: unit => unit, presentationStyle?: presentationStyle, @@ -44,7 +46,6 @@ type props = { supportedOrientations?: array, transparent?: bool, visible?: bool, - children?: React.element, } @module("react-native") diff --git a/src/components/Switch.res b/src/components/Switch.res index c3ed2ea42..a8bb3f336 100644 --- a/src/components/Switch.res +++ b/src/components/Switch.res @@ -11,6 +11,7 @@ type props = { disabled?: bool, trackColor?: trackColor, ios_backgroundColor?: Color.t, + onChange?: Event.switchChangeEvent => unit, onValueChange?: bool => unit, thumbColor?: Color.t, value?: bool, diff --git a/src/components/Text.res b/src/components/Text.res index a07609e95..1d2eb007b 100644 --- a/src/components/Text.res +++ b/src/components/Text.res @@ -8,14 +8,27 @@ type android_hyphenationFrequency = [ type dataDetectorType = [ | #phoneNumber | #link - | #address - | #calendarEvent + | #email | #none | #all ] type ellipsizeMode = [#clip | #head | #middle | #tail] +type dynamicTypeRamp = [ + | #caption2 + | #caption1 + | #footnote + | #subheadline + | #callout + | #body + | #headline + | #title3 + | #title2 + | #title1 + | #largeTitle +] + type textBreakStrategy = [#simple | #highQuality | #balanced] type lineBreakStrategyIOS = [ @@ -54,8 +67,9 @@ type props = { allowFontScaling?: bool, android_hyphenationFrequency?: android_hyphenationFrequency, ariaLevel?: int, - dataDetectorTypes?: array, + dataDetectorType?: dataDetectorType, disabled?: bool, + dynamicTypeRamp?: dynamicTypeRamp, ellipsizeMode?: ellipsizeMode, lineBreakStrategyIOS?: lineBreakStrategyIOS, maxFontSizeMultiplier?: int, diff --git a/src/components/TextInput.res b/src/components/TextInput.res index af38ec345..d42c77da4 100644 --- a/src/components/TextInput.res +++ b/src/components/TextInput.res @@ -214,6 +214,9 @@ type textContentType = [ | #password | #newPassword | #oneTimeCode + | #creditCardExpiration + | #birthdate + | #cellularIMEI ] type inputMode = [ @@ -242,6 +245,27 @@ type submitBehavior = [ | #newline ] +type lineBreakModeIOS = [ + | #wordWrapping + | #char + | #clip + | #head + | #middle + | #tail +] + +type dataDetectorType = [ + | #phoneNumber + | #link + | #address + | #calendarEvent + | #trackingNumber + | #flightNumber + | #lookupSuggestion + | #none + | #all +] + type props = { ref?: ref, ...View.gestureResponderHandlersProps, @@ -268,6 +292,8 @@ type props = { clearTextOnFocus?: bool, contextMenuHidden?: bool, defaultValue?: string, + disableKeyboardShortcuts?: bool, + cursorColor?: Color.t, disableFullscreenUI?: bool, dataDetectorTypes?: array, editable?: bool, @@ -283,6 +309,7 @@ type props = { keyboardAppearance?: keyboardAppearance, keyboardType?: keyboardType, lineBreakStrategyIOS?: Text.lineBreakStrategyIOS, + lineBreakModeIOS?: lineBreakModeIOS, maxFontSizeMultiplier?: float, maxLength?: int, multiline?: bool, @@ -312,13 +339,16 @@ type props = { secureTextEntry?: bool, selection?: selection, selectionColor?: Color.t, + selectionHandleColor?: Color.t, selectTextOnFocus?: bool, showSoftInputOnFocus?: bool, + smartInsertDelete?: bool, spellCheck?: bool, textAlign?: [#left | #center | #right], textAlignVertical?: Style.textAlignVertical, textBreakStrategy?: Text.textBreakStrategy, textContentType?: textContentType, + passwordRules?: string, underlineColorAndroid?: Color.t, value?: string, } diff --git a/src/components/TouchableNativeFeedback.res b/src/components/TouchableNativeFeedback.res index 87adbe804..750cea4d2 100644 --- a/src/components/TouchableNativeFeedback.res +++ b/src/components/TouchableNativeFeedback.res @@ -4,16 +4,17 @@ module Background = { type t @module("react-native") @scope("TouchableNativeFeedback") - external selectableBackground: unit => t = "SelectableBackground" + external selectableBackground: (~rippleRadius: float=?) => t = "SelectableBackground" @module("react-native") @scope("TouchableNativeFeedback") - external selectableBackgroundBorderless: unit => t = "SelectableBackgroundBorderless" + external selectableBackgroundBorderless: (~rippleRadius: float=?) => t = + "SelectableBackgroundBorderless" @module("react-native") @scope("TouchableNativeFeedback") external canUseNativeForeground: unit => bool = "canUseNativeForeground" @module("react-native") @scope("TouchableNativeFeedback") - external ripple: (string, bool) => t = "Ripple" + external ripple: (string, bool, ~rippleRadius: float=?) => t = "Ripple" } type props = { diff --git a/src/components/TouchableOpacity.res b/src/components/TouchableOpacity.res index 64a1d33a8..d77ebd78d 100644 --- a/src/components/TouchableOpacity.res +++ b/src/components/TouchableOpacity.res @@ -4,7 +4,11 @@ type props = { ref?: ref, ...TouchableWithoutFeedback.coreProps, activeOpacity?: float, - focusedOpacity?: float, + nextFocusDown?: float, + nextFocusForward?: float, + nextFocusLeft?: float, + nextFocusRight?: float, + nextFocusUp?: float, hasTVPreferredFocus?: bool, style?: Style.t, tvParallaxProperties?: TV.parallax, diff --git a/src/components/View.res b/src/components/View.res index 26622e484..1176f1cae 100644 --- a/src/components/View.res +++ b/src/components/View.res @@ -57,7 +57,14 @@ type accessibilityProps = { type iosProps = {shouldRasterizeIOS?: bool} -type androidProps = {collapsable?: bool, renderToHardwareTextureAndroid?: bool} +@unboxed +type tabIndex = | @as(0) Focusable | @as(-1) NotFocusable + +type androidProps = { + renderToHardwareTextureAndroid?: bool, + focusable?: bool, + tabIndex?: tabIndex, +} type webLinkProps = { href?: string, @@ -103,10 +110,13 @@ type webProps = { type coreProps = { hitSlop?: Rect.t, nativeID?: string, + id?: string, needsOffscreenAlphaCompositing?: bool, onLayout?: Event.layoutEvent => unit, pointerEvents?: pointerEvents, removeClippedSubviews?: bool, + collapsable?: bool, + collapsableChildren?: bool, style?: Style.t, testID?: string, children?: React.element, From c681d5a66ec3dcd374294ce5f864b8000802378b Mon Sep 17 00:00:00 2001 From: Freddy Harris Date: Mon, 23 Mar 2026 09:33:55 +0100 Subject: [PATCH 4/4] codex review batch 3 --- src/components/VirtualizedList.bs.js | 2 ++ src/components/VirtualizedList.res | 16 +++++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/components/VirtualizedList.bs.js b/src/components/VirtualizedList.bs.js index ca4d50a8f..a53e5f75d 100644 --- a/src/components/VirtualizedList.bs.js +++ b/src/components/VirtualizedList.bs.js @@ -2,5 +2,7 @@ var VirtualizedListElement$ReactNative = require("../elements/VirtualizedListElement.bs.js"); +var Separators = {}; +exports.Separators = Separators; /* VirtualizedListElement-ReactNative Not a pure module */ diff --git a/src/components/VirtualizedList.res b/src/components/VirtualizedList.res index 6a7160ed2..c5860c48c 100644 --- a/src/components/VirtualizedList.res +++ b/src/components/VirtualizedList.res @@ -1,9 +1,19 @@ include VirtualizedListElement +module Separators = { + type t + + type select = [#leading | #trailing] + + @send external highlight: t => unit = "highlight" + @send external unhighlight: t => unit = "unhighlight" + @send external updateProps: (t, select, {..}) => unit = "updateProps" +} + type renderItemProps<'item> = { item: 'item, index: int, - // separators: TODO + separators: Separators.t, } type renderItemCallback<'item> = renderItemProps<'item> => React.element @@ -71,7 +81,7 @@ type virtualizedListProps<'data, 'item, 'extraData> = { initialNumToRender?: int, initialScrollIndex?: int, inverted?: bool, - keyExtractor: ('item, int) => string, + keyExtractor?: ('item, int) => string, maxToRenderPerBatch?: int, onStartReached?: onStartReachedParams => unit, onStartReachedThreshold?: float, @@ -82,7 +92,7 @@ type virtualizedListProps<'data, 'item, 'extraData> = { onViewableItemsChanged?: viewableItemsChanged<'item> => unit, progressViewOffset?: float, refreshing?: bool, - renderScrollComponent?: unit => React.element, // TODO?: params? + renderScrollComponent?: ScrollView.scrollViewProps => React.element, updateCellsBatchingPeriod?: float, viewabilityConfig?: viewabilityConfig, viewabilityConfigCallbackPairs?: viewabilityConfigCallbackPairs<'item>,