Skip to content
Merged
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 @@ -44,7 +44,7 @@ class SearchBarManager :
) {
view.autoCapitalize =
when (autoCapitalize) {
null, "none" -> SearchBarView.SearchBarAutoCapitalize.NONE
null, "systemDefault", "none" -> SearchBarView.SearchBarAutoCapitalize.NONE
"words" -> SearchBarView.SearchBarAutoCapitalize.WORDS
"sentences" -> SearchBarView.SearchBarAutoCapitalize.SENTENCES
"characters" -> SearchBarView.SearchBarAutoCapitalize.CHARACTERS
Expand Down
2 changes: 1 addition & 1 deletion guides/GUIDE_FOR_LIBRARY_AUTHORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,7 @@ Along with this component's properties that can be used to customize header beha

To render a search bar use `ScreenStackHeaderSearchBarView` with `<SearchBar>` component provided as a child. `<SearchBar>` component that comes from react-native-screens supports various properties:

- `autoCapitalize` - Controls whether the text is automatically auto-capitalized as it is entered by the user. Can be one of these: `none`, `words`, `sentences`, `characters`. Defaults to `sentences` on iOS and `'none'` on Android.
- `autoCapitalize` - Controls whether the text is automatically auto-capitalized as it is entered by the user. Can be one of these: `systemDefault`, `none`, `words`, `sentences`, `characters`. Defaults to `systemDefault` which is the same as `sentences` on iOS and `none` on Android.
- `autoFocus` - If `true` automatically focuses search bar when screen is appearing. (Android only)
- `barTintColor` - The search field background color. By default bar tint color is translucent.
- `tintColor` - The color for the cursor caret and cancel button text. (iOS only)
Expand Down
1 change: 1 addition & 0 deletions ios/RNSConvert.mm
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ + (UITextAutocapitalizationType)UITextAutocapitalizationTypeFromCppEquivalent:
using enum react::RNSSearchBarAutoCapitalize;
case Words:
return UITextAutocapitalizationTypeWords;
case SystemDefault:
case Sentences:
return UITextAutocapitalizationTypeSentences;
case Characters:
Expand Down
14 changes: 13 additions & 1 deletion ios/RNSSearchBar.mm
Original file line number Diff line number Diff line change
Expand Up @@ -491,7 +491,19 @@ - (UIView *)view
RCT_EXPORT_VIEW_PROPERTY(obscureBackground, RNSOptionalBoolean)
RCT_EXPORT_VIEW_PROPERTY(hideNavigationBar, RNSOptionalBoolean)
RCT_EXPORT_VIEW_PROPERTY(hideWhenScrolling, BOOL)
RCT_EXPORT_VIEW_PROPERTY(autoCapitalize, UITextAutocapitalizationType)

// We want to use "systemDefault" option which is not in UITextAutocapitalizationType
// but RCTConvert enum conversion already exists.
RCT_CUSTOM_VIEW_PROPERTY(autoCapitalize, UITextAutocapitalizationType, RNSSearchBar)
{
RNSSearchBar *searchBarView = static_cast<RNSSearchBar *>(view);
if ([json isKindOfClass:[NSString class]] && [static_cast<NSString *>(json) isEqualToString:@"systemDefault"]) {
[searchBarView setAutoCapitalize:UITextAutocapitalizationTypeSentences];
} else {
[searchBarView setAutoCapitalize:[RCTConvert UITextAutocapitalizationType:json]];
}
}

RCT_EXPORT_VIEW_PROPERTY(placeholder, NSString)
RCT_EXPORT_VIEW_PROPERTY(barTintColor, UIColor)
RCT_EXPORT_VIEW_PROPERTY(tintColor, UIColor)
Expand Down
38 changes: 30 additions & 8 deletions src/components/SearchBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
SearchButtonPressedEvent,
ChangeTextEvent,
} from '../fabric/SearchBarNativeComponent';
import { DirectEventHandler } from 'react-native/Libraries/Types/CodegenTypes';

Check warning on line 19 in src/components/SearchBar.tsx

View workflow job for this annotation

GitHub Actions / lint-js

'react-native/Libraries/Types/CodegenTypes' React Native deep imports are deprecated. Please use the top level import instead

const NativeSearchBar: React.ComponentType<
SearchBarNativeProps & { ref?: React.RefObject<SearchBarCommands> }
Expand Down Expand Up @@ -88,27 +88,49 @@
return View as unknown as React.ReactNode;
}

// This is necessary only for legacy architecture (Paper).
const parsedProps = parseUndefinedPropsToSystemDefault(props);

const {
obscureBackground,
hideNavigationBar,
onFocus,
onBlur,
onSearchButtonPress,
onCancelButtonPress,
onChangeText,
...rest
} = parsedProps;

return (
<NativeSearchBar
ref={searchBarRef}
{...props}
{...rest}
obscureBackground={parseBooleanToOptionalBooleanNativeProp(
props.obscureBackground,
obscureBackground,
)}
hideNavigationBar={parseBooleanToOptionalBooleanNativeProp(
props.hideNavigationBar,
hideNavigationBar,
)}
onSearchFocus={props.onFocus as DirectEventHandler<SearchBarEvent>}
onSearchBlur={props.onBlur as DirectEventHandler<SearchBarEvent>}
onSearchFocus={onFocus as DirectEventHandler<SearchBarEvent>}
onSearchBlur={onBlur as DirectEventHandler<SearchBarEvent>}
onSearchButtonPress={
props.onSearchButtonPress as DirectEventHandler<SearchButtonPressedEvent>
onSearchButtonPress as DirectEventHandler<SearchButtonPressedEvent>
}
onCancelButtonPress={
props.onCancelButtonPress as DirectEventHandler<SearchBarEvent>
onCancelButtonPress as DirectEventHandler<SearchBarEvent>
}
onChangeText={props.onChangeText as DirectEventHandler<ChangeTextEvent>}
onChangeText={onChangeText as DirectEventHandler<ChangeTextEvent>}
/>
);
}

// This function is necessary for legacy architecture (Paper) to ensure
// consistent behavior for props with `systemDefault` option.
function parseUndefinedPropsToSystemDefault(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I'd say something like decorateAutocapitalizeWithSystemDefaultIfNeeded would sound better?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assumed that there might be more props that will require this kind of handling (but at the moment I'm not sure if there will be more) and wanted to use only one function for all of them so that it's easier to delete it in the future when we drop support for legacy architecture.

Also, isn't decorate a little bit too much for simple if (value === undefined) return "systemDefault"?

I'm open for suggestions here.

props: SearchBarProps,
): SearchBarProps {
return { ...props, autoCapitalize: props.autoCapitalize ?? 'systemDefault' };
}

export default React.forwardRef<SearchBarCommands, SearchBarProps>(SearchBar);
9 changes: 7 additions & 2 deletions src/fabric/SearchBarNativeComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,12 @@ type SearchBarPlacement =
| 'integratedButton'
| 'integratedCentered';

type AutoCapitalizeType = 'none' | 'words' | 'sentences' | 'characters';
type AutoCapitalizeType =
| 'systemDefault'
| 'none'
| 'words'
| 'sentences'
| 'characters';

type OptionalBoolean = 'undefined' | 'false' | 'true';

Expand All @@ -38,7 +43,7 @@ export interface NativeProps extends ViewProps {
onCancelButtonPress?: DirectEventHandler<SearchBarEvent> | null;
onChangeText?: DirectEventHandler<ChangeTextEvent> | null;
hideWhenScrolling?: WithDefault<boolean, true>;
autoCapitalize?: WithDefault<AutoCapitalizeType, 'none'>;
autoCapitalize?: WithDefault<AutoCapitalizeType, 'systemDefault'>;
placeholder?: string;
placement?: WithDefault<SearchBarPlacement, 'automatic'>;
allowToolbarIntegration?: WithDefault<boolean, true>;
Expand Down
13 changes: 11 additions & 2 deletions src/types.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -746,9 +746,18 @@ export interface SearchBarProps {
ref?: React.RefObject<SearchBarCommands>;

/**
* The auto-capitalization behavior
* The auto-capitalization behavior.
*
* Defaults to `systemDefault`:
* - on Android, it is the same as `none`,
* - on iOS, it is the same as `sentences`.
*/
autoCapitalize?: 'none' | 'words' | 'sentences' | 'characters';
autoCapitalize?:
| 'systemDefault'
| 'none'
| 'words'
| 'sentences'
| 'characters';
/**
* Automatically focuses search bar on mount
*
Expand Down
Loading