Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@ const ViewNativeComponent: HostComponent<Props> =
}));

interface NativeCommands {
+focus: () => void;
+blur: () => void;
+hotspotUpdate: (viewRef: HostInstance, x: number, y: number) => void;
+setPressed: (viewRef: HostInstance, pressed: boolean) => void;
}

export const Commands: NativeCommands = codegenNativeCommands<NativeCommands>({
supportedCommands: ['hotspotUpdate', 'setPressed'],
supportedCommands: ['focus', 'blur', 'hotspotUpdate', 'setPressed'],
});

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1540,6 +1540,62 @@ - (void)transferVisualPropertiesFromView:(UIView *)sourceView toView:(UIView *)d
}
}

- (BOOL)canBecomeFirstResponder
{
return YES;
}

- (void)handleCommand:(const NSString *)commandName args:(const NSArray *)args
{
if ([commandName isEqualToString:@"focus"]) {
[self focus];
return;
}

if ([commandName isEqualToString:@"blur"]) {
[self blur];
return;
}
}

- (void)focus
{
[self becomeFirstResponder];
}

- (void)blur
{
[self resignFirstResponder];
}

#pragma mark - Focus Events

- (BOOL)becomeFirstResponder
{
if (![super becomeFirstResponder]) {
return NO;
}

if (_eventEmitter && ReactNativeFeatureFlags::enableImperativeFocus()) {
_eventEmitter->onFocus();
}

return YES;
}

- (BOOL)resignFirstResponder
{
if (![super resignFirstResponder]) {
return NO;
}

if (_eventEmitter && ReactNativeFeatureFlags::enableImperativeFocus()) {
_eventEmitter->onBlur();
}

return YES;
}

@end

#ifdef __cplusplus
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<f089964c958dfcac00f83c3371ccbefc>>
* @generated SignedSource<<ce122427070db337420728a1028bc2b6>>
*/

/**
Expand Down Expand Up @@ -192,6 +192,12 @@ public object ReactNativeFeatureFlags {
@JvmStatic
public fun enableImmediateUpdateModeForContentOffsetChanges(): Boolean = accessor.enableImmediateUpdateModeForContentOffsetChanges()

/**
* Enable ref.focus() and ref.blur() for all views, not just TextInput.
*/
@JvmStatic
public fun enableImperativeFocus(): Boolean = accessor.enableImperativeFocus()

/**
* This is to fix the issue with interop view manager where component descriptor lookup is causing ViewManager to preload.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<912dec895495052328e7e52b94a6738a>>
* @generated SignedSource<<e7581ab264bca8b059723bd7bd788790>>
*/

/**
Expand Down Expand Up @@ -47,6 +47,7 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
private var enableImagePrefetchingAndroidCache: Boolean? = null
private var enableImagePrefetchingOnUiThreadAndroidCache: Boolean? = null
private var enableImmediateUpdateModeForContentOffsetChangesCache: Boolean? = null
private var enableImperativeFocusCache: Boolean? = null
private var enableInteropViewManagerClassLookUpOptimizationIOSCache: Boolean? = null
private var enableLayoutAnimationsOnAndroidCache: Boolean? = null
private var enableLayoutAnimationsOnIOSCache: Boolean? = null
Expand Down Expand Up @@ -337,6 +338,15 @@ internal class ReactNativeFeatureFlagsCxxAccessor : ReactNativeFeatureFlagsAcces
return cached
}

override fun enableImperativeFocus(): Boolean {
var cached = enableImperativeFocusCache
if (cached == null) {
cached = ReactNativeFeatureFlagsCxxInterop.enableImperativeFocus()
enableImperativeFocusCache = cached
}
return cached
}

override fun enableInteropViewManagerClassLookUpOptimizationIOS(): Boolean {
var cached = enableInteropViewManagerClassLookUpOptimizationIOSCache
if (cached == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<ba1e53d93b9fdaf298a034543bc44a57>>
* @generated SignedSource<<d73f5df2130479a4cd1000dc76b15d1b>>
*/

/**
Expand Down Expand Up @@ -82,6 +82,8 @@ public object ReactNativeFeatureFlagsCxxInterop {

@DoNotStrip @JvmStatic public external fun enableImmediateUpdateModeForContentOffsetChanges(): Boolean

@DoNotStrip @JvmStatic public external fun enableImperativeFocus(): Boolean

@DoNotStrip @JvmStatic public external fun enableInteropViewManagerClassLookUpOptimizationIOS(): Boolean

@DoNotStrip @JvmStatic public external fun enableLayoutAnimationsOnAndroid(): Boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<7601cbcde75ff19ef0fe67f6faef2549>>
* @generated SignedSource<<4fa15189361a6c92bdd44bafc9356167>>
*/

/**
Expand Down Expand Up @@ -77,6 +77,8 @@ public open class ReactNativeFeatureFlagsDefaults : ReactNativeFeatureFlagsProvi

override fun enableImmediateUpdateModeForContentOffsetChanges(): Boolean = false

override fun enableImperativeFocus(): Boolean = false

override fun enableInteropViewManagerClassLookUpOptimizationIOS(): Boolean = false

override fun enableLayoutAnimationsOnAndroid(): Boolean = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<3a13f8e35423b634ed4ef46fbac3c1e9>>
* @generated SignedSource<<962c60d1761b0a1f4945b44767aa7b02>>
*/

/**
Expand Down Expand Up @@ -51,6 +51,7 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
private var enableImagePrefetchingAndroidCache: Boolean? = null
private var enableImagePrefetchingOnUiThreadAndroidCache: Boolean? = null
private var enableImmediateUpdateModeForContentOffsetChangesCache: Boolean? = null
private var enableImperativeFocusCache: Boolean? = null
private var enableInteropViewManagerClassLookUpOptimizationIOSCache: Boolean? = null
private var enableLayoutAnimationsOnAndroidCache: Boolean? = null
private var enableLayoutAnimationsOnIOSCache: Boolean? = null
Expand Down Expand Up @@ -368,6 +369,16 @@ internal class ReactNativeFeatureFlagsLocalAccessor : ReactNativeFeatureFlagsAcc
return cached
}

override fun enableImperativeFocus(): Boolean {
var cached = enableImperativeFocusCache
if (cached == null) {
cached = currentProvider.enableImperativeFocus()
accessedFeatureFlags.add("enableImperativeFocus")
enableImperativeFocusCache = cached
}
return cached
}

override fun enableInteropViewManagerClassLookUpOptimizationIOS(): Boolean {
var cached = enableInteropViewManagerClassLookUpOptimizationIOSCache
if (cached == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<143b568248e68033efaefc3f178ff6db>>
* @generated SignedSource<<f9f3dee3dde2f7f6f851ce4525a4ebec>>
*/

/**
Expand Down Expand Up @@ -77,6 +77,8 @@ public interface ReactNativeFeatureFlagsProvider {

@DoNotStrip public fun enableImmediateUpdateModeForContentOffsetChanges(): Boolean

@DoNotStrip public fun enableImperativeFocus(): Boolean

@DoNotStrip public fun enableInteropViewManagerClassLookUpOptimizationIOS(): Boolean

@DoNotStrip public fun enableLayoutAnimationsOnAndroid(): Boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,14 @@ public open class ReactViewGroup public constructor(context: Context?) :
updateClippingToRect(clippingRect, excludedViews)
}

internal fun requestFocusFromJS() {
super.requestFocus(FOCUS_DOWN, null)
}

internal fun clearFocusFromJS() {
super.clearFocus()
}

override fun endViewTransition(view: View) {
super.endViewTransition(view)
childrenRemovedWhileTransitioning?.remove(view.id)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,8 @@ public open class ReactViewManager : ReactClippingViewManager<ReactViewGroup>()
when (commandId) {
HOTSPOT_UPDATE_KEY -> handleHotspotUpdate(root, args)
"setPressed" -> handleSetPressed(root, args)
"focus" -> handleFocus(root)
"blur" -> handleBlur(root)
else -> {}
}
}
Expand All @@ -428,4 +430,16 @@ public open class ReactViewManager : ReactClippingViewManager<ReactViewGroup>()
val y = args.getDouble(1).dpToPx()
root.drawableHotspotChanged(x, y)
}

private fun handleFocus(root: ReactViewGroup) {
if (ReactNativeFeatureFlags.enableImperativeFocus()) {
root.requestFocusFromJS()
}
}

private fun handleBlur(root: ReactViewGroup) {
if (ReactNativeFeatureFlags.enableImperativeFocus()) {
root.clearFocusFromJS()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<92c9aa29df580c6d12faa14e60b00e4f>>
* @generated SignedSource<<de817bc06ae5ef584db08d6a094c9d03>>
*/

/**
Expand Down Expand Up @@ -201,6 +201,12 @@ class ReactNativeFeatureFlagsJavaProvider
return method(javaProvider_);
}

bool enableImperativeFocus() override {
static const auto method =
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("enableImperativeFocus");
return method(javaProvider_);
}

bool enableInteropViewManagerClassLookUpOptimizationIOS() override {
static const auto method =
getReactNativeFeatureFlagsProviderJavaClass()->getMethod<jboolean()>("enableInteropViewManagerClassLookUpOptimizationIOS");
Expand Down Expand Up @@ -616,6 +622,11 @@ bool JReactNativeFeatureFlagsCxxInterop::enableImmediateUpdateModeForContentOffs
return ReactNativeFeatureFlags::enableImmediateUpdateModeForContentOffsetChanges();
}

bool JReactNativeFeatureFlagsCxxInterop::enableImperativeFocus(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
return ReactNativeFeatureFlags::enableImperativeFocus();
}

bool JReactNativeFeatureFlagsCxxInterop::enableInteropViewManagerClassLookUpOptimizationIOS(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop> /*unused*/) {
return ReactNativeFeatureFlags::enableInteropViewManagerClassLookUpOptimizationIOS();
Expand Down Expand Up @@ -958,6 +969,9 @@ void JReactNativeFeatureFlagsCxxInterop::registerNatives() {
makeNativeMethod(
"enableImmediateUpdateModeForContentOffsetChanges",
JReactNativeFeatureFlagsCxxInterop::enableImmediateUpdateModeForContentOffsetChanges),
makeNativeMethod(
"enableImperativeFocus",
JReactNativeFeatureFlagsCxxInterop::enableImperativeFocus),
makeNativeMethod(
"enableInteropViewManagerClassLookUpOptimizationIOS",
JReactNativeFeatureFlagsCxxInterop::enableInteropViewManagerClassLookUpOptimizationIOS),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<124d1378990fdd09a4d97f9103f81a6a>>
* @generated SignedSource<<f163997b1149c1f1ac1e60f273a5448f>>
*/

/**
Expand Down Expand Up @@ -111,6 +111,9 @@ class JReactNativeFeatureFlagsCxxInterop
static bool enableImmediateUpdateModeForContentOffsetChanges(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);

static bool enableImperativeFocus(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);

static bool enableInteropViewManagerClassLookUpOptimizationIOS(
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<42bea10b4b62a91dce8fde7674f76ceb>>
* @generated SignedSource<<50f81f60d4c2d2e08fde98f4a2d841ea>>
*/

/**
Expand Down Expand Up @@ -134,6 +134,10 @@ bool ReactNativeFeatureFlags::enableImmediateUpdateModeForContentOffsetChanges()
return getAccessor().enableImmediateUpdateModeForContentOffsetChanges();
}

bool ReactNativeFeatureFlags::enableImperativeFocus() {
return getAccessor().enableImperativeFocus();
}

bool ReactNativeFeatureFlags::enableInteropViewManagerClassLookUpOptimizationIOS() {
return getAccessor().enableInteropViewManagerClassLookUpOptimizationIOS();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @generated SignedSource<<40421ac664927693136a8e3197e3c07c>>
* @generated SignedSource<<3446eebd26c1142fd78cd5413771569d>>
*/

/**
Expand Down Expand Up @@ -174,6 +174,11 @@ class ReactNativeFeatureFlags {
*/
RN_EXPORT static bool enableImmediateUpdateModeForContentOffsetChanges();

/**
* Enable ref.focus() and ref.blur() for all views, not just TextInput.
*/
RN_EXPORT static bool enableImperativeFocus();

/**
* This is to fix the issue with interop view manager where component descriptor lookup is causing ViewManager to preload.
*/
Expand Down
Loading
Loading