Skip to content

Commit

Permalink
feat: bring Fabric to SearchBar (#1470)
Browse files Browse the repository at this point in the history
* chore: add JS for SearchBar

Component style props still have to be adjusted. Same for other props
that are not implemented yet.

* chore: add event types to codegen

* chore: add iOS props to JS

* chore: add Android only props to JS

* chore: update interface for Fabric

* chore: add enum conversion for autoCapitalization prop

* chore: add props update (except colors)

* chore: add componentDescriptorProvider & RNSSearchBarCls

* chore: make event blocks Paper specific (in interface)

* chore: make Fabric impl not emit any events (just for now)

* fix: import ComponentDescriptors header

* refact: extract common initialization code to initCommonProps

* chore: create SearchButtonPressedEvent type

* chore: create ChangeTextEvent type

* chore: create event emitting methods

* refact: make use of event emitting methods

* chore: move #import RNSSearchBar.h statemets to common section

This can be done now, as SearchBar should work on Fabric

* refact: add TODO for missing props

* chore: change ctor for Fabric in RNSSearchBarManager

I don't exactly know if it is required but it should not break anything.
If this change is useless we can restore it later.

* chore: make RNSSearchbarManager#view method paper only

* refact: update TODO comments

* chore: move RNSScreen#hideHeaderIfNecessary method to common section

This change was not tested. Usage of self.view.reactSubviews raises my
concerns as I'm not sure if this property always holds correct state on
Fabric

* chore: remove message that SearchBar is not yer Fabric compatible

* chore: udpate style for SearchBar component

* feat: implement color-related props

* chore: enable call to hideheaderIfNecessary

* chore: add Test758 from TestExample

* fix: weird merge artifact

This if def was present on main & not on current branch, but after running `git merge main` git took the version of code from the current branch?!

* chore: add Test758 to App.js
  • Loading branch information
kkafar authored Jun 22, 2022
1 parent 3a8a29c commit a10bb81
Show file tree
Hide file tree
Showing 13 changed files with 411 additions and 39 deletions.
3 changes: 2 additions & 1 deletion FabricTestExample/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ import Test42 from './src/Test42';
import Test556 from './src/Test556';
import Test624 from './src/Test624';
import Test642 from './src/Test642';
import Test758 from './src/Test758';
import Test780 from './src/Test780';
import Test860 from './src/Test860';
import Test1072 from './src/Test1072';
import Test1260 from './src/Test1260';
import Test1463 from './src/Test1463';

const App = () => {
return <Test556 />;
return <Test758 />;
};

export default App;
108 changes: 108 additions & 0 deletions FabricTestExample/src/Test758.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import * as React from 'react';
import {Button, NativeSyntheticEvent, ScrollView} from 'react-native';
import {
NavigationContainer,
NavigationProp,
ParamListBase,
} from '@react-navigation/native';
import {
createNativeStackNavigator,
NativeStackScreenProps,
} from 'react-native-screens/native-stack';
import {SearchBarProps} from 'react-native-screens';

const AppStack = createNativeStackNavigator();

export default function App(): JSX.Element {
return (
<NavigationContainer>
<AppStack.Navigator
screenOptions={{
headerLargeTitle: true,
headerTranslucent: false,
}}>
<AppStack.Screen name="First" component={First} />
<AppStack.Screen name="Second" component={Second} />
</AppStack.Navigator>
</NavigationContainer>
);
}

function First({navigation}: NativeStackScreenProps<ParamListBase>) {
React.useLayoutEffect(() => {
navigation.setOptions({
searchBar: searchBarOptions,
});
}, [navigation]);

const [search, setSearch] = React.useState('');

const searchBarOptions: SearchBarProps = {
barTintColor: 'powderblue',
tintColor: 'red',
textColor: 'red',
hideWhenScrolling: true,
obscureBackground: false,
hideNavigationBar: false,
autoCapitalize: 'sentences',
placeholder: 'Some text',
cancelButtonText: 'Some text',
onChangeText: (e: NativeSyntheticEvent<{text: string}>) =>
setSearch(e.nativeEvent.text),
onCancelButtonPress: () => console.warn('Cancel button pressed'),
onSearchButtonPress: () => console.warn('Search button pressed'),
onFocus: () => console.warn('onFocus event'),
onBlur: () => console.warn('onBlur event'),
};

const items = [
'Apples',
'Pie',
'Juice',
'Cake',
'Nuggets',
'Some',
'Other',
'Stuff',
'To',
'Fill',
'The',
'Scrolling',
'Space',
];

return (
<ScrollView
contentInsetAdjustmentBehavior="automatic"
keyboardDismissMode="on-drag">
<Button
title="Tap me for second screen"
onPress={() => navigation.navigate('Second')}
/>
{items
.filter(
(item) => item.toLowerCase().indexOf(search.toLowerCase()) !== -1,
)
.map((item) => (
<Button
title={item}
key={item}
onPress={() => {
console.warn(`${item} clicked`);
}}
/>
))}
</ScrollView>
);
}

function Second({navigation}: {navigation: NavigationProp<ParamListBase>}) {
return (
<ScrollView contentInsetAdjustmentBehavior="automatic">
<Button
title="Tap me for first screen"
onPress={() => navigation.navigate('First')}
/>
</ScrollView>
);
}
3 changes: 3 additions & 0 deletions ios/RNSConvert.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
+ (NSDictionary *)gestureResponseDistanceDictFromCppStruct:
(const facebook::react::RNSScreenGestureResponseDistanceStruct &)gestureResponseDistance;

+ (UITextAutocapitalizationType)UITextAutocapitalizationTypeFromCppEquivalent:
(facebook::react::RNSSearchBarAutoCapitalize)autoCapitalize;

@end

#endif // RN_FABRIC_ENABLED
15 changes: 15 additions & 0 deletions ios/RNSConvert.mm
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,21 @@ + (NSDictionary *)gestureResponseDistanceDictFromCppStruct:
};
}

+ (UITextAutocapitalizationType)UITextAutocapitalizationTypeFromCppEquivalent:
(facebook::react::RNSSearchBarAutoCapitalize)autoCapitalize
{
switch (autoCapitalize) {
case facebook::react::RNSSearchBarAutoCapitalize::Words:
return UITextAutocapitalizationTypeWords;
case facebook::react::RNSSearchBarAutoCapitalize::Sentences:
return UITextAutocapitalizationTypeSentences;
case facebook::react::RNSSearchBarAutoCapitalize::Characters:
return UITextAutocapitalizationTypeAllCharacters;
case facebook::react::RNSSearchBarAutoCapitalize::None:
return UITextAutocapitalizationTypeNone;
}
}

@end

#endif // RN_FABRIC_ENABLED
7 changes: 6 additions & 1 deletion ios/RNSScreen.mm
Original file line number Diff line number Diff line change
Expand Up @@ -717,7 +717,7 @@ - (void)viewWillAppear:(BOOL)animated
#ifdef RN_FABRIC_ENABLED
#else
[self hideHeaderIfNecessary];
#endif
#endif // RN_FABRIC_ENABLED
// as per documentation of these methods
_goingForward = [self isBeingPresented] || [self isMovingToParentViewController];

Expand Down Expand Up @@ -1070,7 +1070,12 @@ - (void)hideHeaderIfNecessary
RNSScreenStackHeaderConfig *config = ((RNSScreenStackHeaderConfig *)self.view.reactSubviews[0]);

BOOL wasSearchBarActive = prevNavigationItem.searchController.active;

#ifdef RN_FABRIC_ENABLED
BOOL shouldHideHeader = !config.show;
#else
BOOL shouldHideHeader = config.hide;
#endif

if (wasSearchBarActive && shouldHideHeader) {
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 0);
Expand Down
3 changes: 1 addition & 2 deletions ios/RNSScreenStackHeaderConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@
#import <React/RCTViewComponentView.h>
#else
#import <React/RCTViewManager.h>
// TODO: move this import when SearchBar is implemented on Fabric
#import "RNSSearchBar.h"
#endif

#import <React/RCTConvert.h>
#import "RNSScreen.h"
#import "RNSScreenStackHeaderSubview.h"
#import "RNSSearchBar.h"

@interface RNSScreenStackHeaderConfig :
#ifdef RN_FABRIC_ENABLED
Expand Down
8 changes: 1 addition & 7 deletions ios/RNSScreenStackHeaderConfig.mm
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,18 @@
#import <react/renderer/components/rnscreens/RCTComponentViewHelpers.h>
#import "RCTFabricComponentsPlugins.h"
#else
// TODO: move this import when SearchBar is implemented on Fabric
#import <React/RCTBridge.h>
#import <React/RCTImageLoader.h>
#import <React/RCTImageSource.h>
#import <React/RCTImageView.h>
#import <React/RCTShadowView.h>
#import <React/RCTUIManager.h>
#import <React/RCTUIManagerUtils.h>
#import "RNSSearchBar.h"
#endif
#import <React/RCTFont.h>
#import "RNSScreen.h"
#import "RNSScreenStackHeaderConfig.h"
#import "RNSSearchBar.h"
#import "RNSUIBarButtonItem.h"

#ifdef RN_FABRIC_ENABLED
Expand Down Expand Up @@ -561,9 +560,6 @@ + (void)updateViewController:(UIViewController *)vc
break;
}
case RNSScreenStackHeaderSubviewTypeSearchBar: {
#ifdef RN_FABRIC_ENABLED
RCTLogWarn(@"SearchBar is not yet Fabric compatible in react-native-screens");
#else
if (subview.subviews == nil || [subview.subviews count] == 0) {
RCTLogWarn(
@"Failed to attach search bar to the header. We recommend using `useLayoutEffect` when managing "
Expand All @@ -580,8 +576,6 @@ + (void)updateViewController:(UIViewController *)vc
}
#endif
}

#endif // RN_FABRIC_ENABLED
break;
}
case RNSScreenStackHeaderSubviewTypeBackButton: {
Expand Down
15 changes: 14 additions & 1 deletion ios/RNSSearchBar.h
Original file line number Diff line number Diff line change
@@ -1,19 +1,32 @@
#import <UIKit/UIKit.h>

#ifdef RN_FABRIC_ENABLED
#import <React/RCTViewComponentView.h>
#endif

#import <React/RCTBridge.h>
#import <React/RCTComponent.h>
#import <React/RCTViewManager.h>

@interface RNSSearchBar : UIView <UISearchBarDelegate>
@interface RNSSearchBar :
#ifdef RN_FABRIC_ENABLED
RCTViewComponentView <UISearchBarDelegate>
#else
UIView <UISearchBarDelegate>
#endif

@property (nonatomic) BOOL hideWhenScrolling;

@property (nonatomic, retain) UISearchController *controller;

#ifdef RN_FABRIC_ENABLED
#else
@property (nonatomic, copy) RCTBubblingEventBlock onChangeText;
@property (nonatomic, copy) RCTBubblingEventBlock onCancelButtonPress;
@property (nonatomic, copy) RCTBubblingEventBlock onSearchButtonPress;
@property (nonatomic, copy) RCTBubblingEventBlock onFocus;
@property (nonatomic, copy) RCTBubblingEventBlock onBlur;
#endif

@end

Expand Down
Loading

0 comments on commit a10bb81

Please sign in to comment.