Skip to content

Commit

Permalink
remove createReactClass from ToolbarAndroid/ToolbarAndroid.android.js (
Browse files Browse the repository at this point in the history
…#21893)

Summary:
Related to #21581 .
Removed createReactClass from the Libraries/Components/ToolbarAndroid/ToolbarAndroid.android.js

- [x] npm run prettier
- [x] npm run flow-check-ios
- [x] npm run flow-check-android
[GENERAL] [ENHANCEMENT] [Libraries/Components/ToolbarAndroid/ToolbarAndroid.android.js] - remove createReactClass dependency
Pull Request resolved: #21893

Reviewed By: TheSavior

Differential Revision: D12826971

Pulled By: RSNara

fbshipit-source-id: 3d3fb88a3c9faf3ef89e386ca0d41d939f5d14dd
  • Loading branch information
nissy-dev authored and facebook-github-bot committed Nov 5, 2018
1 parent 79712c3 commit 147c38a
Showing 1 changed file with 167 additions and 128 deletions.
295 changes: 167 additions & 128 deletions Libraries/Components/ToolbarAndroid/ToolbarAndroid.android.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,22 @@
* LICENSE file in the root directory of this source tree.
*
* @format
* @flow
*/

'use strict';

const DeprecatedColorPropType = require('DeprecatedColorPropType');
const DeprecatedViewPropTypes = require('DeprecatedViewPropTypes');
const Image = require('Image');
const NativeMethodsMixin = require('NativeMethodsMixin');
const PropTypes = require('prop-types');
const React = require('React');
const UIManager = require('UIManager');

const createReactClass = require('create-react-class');
const requireNativeComponent = require('requireNativeComponent');
const resolveAssetSource = require('resolveAssetSource');

const optionalImageSource = PropTypes.oneOfType([
Image.propTypes.source,
// Image.propTypes.source is required but we want it to be optional, so we OR
// it with a nullable propType.
PropTypes.oneOf([]),
]);
import type {SyntheticEvent} from 'CoreEventTypes';
import type {ImageSource} from 'ImageSource';
import type {ColorValue} from 'StyleSheetTypes';
import type {ViewProps} from 'ViewPropTypes';
import type {NativeComponent} from 'ReactNative';

/**
* React component that wraps the Android-only [`Toolbar` widget][0]. A Toolbar can display a logo,
Expand Down Expand Up @@ -63,124 +57,157 @@ const optionalImageSource = PropTypes.oneOfType([
*
* [0]: https://developer.android.com/reference/android/support/v7/widget/Toolbar.html
*/
const ToolbarAndroid = createReactClass({
displayName: 'ToolbarAndroid',
mixins: [NativeMethodsMixin],

propTypes: {
...DeprecatedViewPropTypes,
/**
* Sets possible actions on the toolbar as part of the action menu. These are displayed as icons
* or text on the right side of the widget. If they don't fit they are placed in an 'overflow'
* menu.
*
* This property takes an array of objects, where each object has the following keys:
*
* * `title`: **required**, the title of this action
* * `icon`: the icon for this action, e.g. `require('./some_icon.png')`
* * `show`: when to show this action as an icon or hide it in the overflow menu: `always`,
* `ifRoom` or `never`
* * `showWithText`: boolean, whether to show text alongside the icon or not
*/
actions: PropTypes.arrayOf(
PropTypes.shape({
title: PropTypes.string.isRequired,
icon: optionalImageSource,
show: PropTypes.oneOf(['always', 'ifRoom', 'never']),
showWithText: PropTypes.bool,
}),
),
/**
* Sets the toolbar logo.
*/
logo: optionalImageSource,
/**
* Sets the navigation icon.
*/
navIcon: optionalImageSource,
/**
* Callback that is called when an action is selected. The only argument that is passed to the
* callback is the position of the action in the actions array.
*/
onActionSelected: PropTypes.func,
/**
* Callback called when the icon is selected.
*/
onIconClicked: PropTypes.func,
/**
* Sets the overflow icon.
*/
overflowIcon: optionalImageSource,
/**
* Sets the toolbar subtitle.
*/
subtitle: PropTypes.string,
/**
* Sets the toolbar subtitle color.
*/
subtitleColor: DeprecatedColorPropType,
/**
* Sets the toolbar title.
*/
title: PropTypes.string,
/**
* Sets the toolbar title color.
*/
titleColor: DeprecatedColorPropType,
/**
* Sets the content inset for the toolbar starting edge.
*
* The content inset affects the valid area for Toolbar content other than
* the navigation button and menu. Insets define the minimum margin for
* these components and can be used to effectively align Toolbar content
* along well-known gridlines.
*/
contentInsetStart: PropTypes.number,
/**
* Sets the content inset for the toolbar ending edge.
*
* The content inset affects the valid area for Toolbar content other than
* the navigation button and menu. Insets define the minimum margin for
* these components and can be used to effectively align Toolbar content
* along well-known gridlines.
*/
contentInsetEnd: PropTypes.number,
/**
* Used to set the toolbar direction to RTL.
* In addition to this property you need to add
*
* android:supportsRtl="true"
*
* to your application AndroidManifest.xml and then call
* `setLayoutDirection(LayoutDirection.RTL)` in your MainActivity
* `onCreate` method.
*/
rtl: PropTypes.bool,
/**
* Used to locate this view in end-to-end tests.
*/
testID: PropTypes.string,
},

render: function() {
const nativeProps = {
...this.props,
const NativeToolbar = requireNativeComponent('ToolbarAndroid');

type Action = $ReadOnly<{|
title: string,
icon?: ?ImageSource,
show?: 'always' | 'ifRoom' | 'never',
showWithText?: boolean,
|}>;

type ToolbarAndroidChangeEvent = SyntheticEvent<
$ReadOnly<{|
position: number,
|}>,
>;

type ToolbarAndroidProps = $ReadOnly<{|
...ViewProps,
/**
* or text on the right side of the widget. If they don't fit they are placed in an 'overflow'
* Sets possible actions on the toolbar as part of the action menu. These are displayed as icons
* menu.
*
* This property takes an array of objects, where each object has the following keys:
*
* * `title`: **required**, the title of this action
* * `icon`: the icon for this action, e.g. `require('./some_icon.png')`
* * `show`: when to show this action as an icon or hide it in the overflow menu: `always`,
* `ifRoom` or `never`
* * `showWithText`: boolean, whether to show text alongside the icon or not
*/
actions?: ?Array<Action>,
/**
* Sets the toolbar logo.
*/
logo?: ?ImageSource,
/**
* Sets the navigation icon.
*/
navIcon?: ?ImageSource,
/**
* Callback that is called when an action is selected. The only argument that is passed to the
* callback is the position of the action in the actions array.
*/
onActionSelected?: ?(position: number) => void,
/**
* Callback called when the icon is selected.
*/
onIconClicked?: ?() => void,
/**
* Sets the overflow icon.
*/
overflowIcon?: ?ImageSource,
/**
* Sets the toolbar subtitle.
*/
subtitle?: ?string,
/**
* Sets the toolbar subtitle color.
*/
subtitleColor?: ?ColorValue,
/**
* Sets the toolbar title.
*/
title?: ?Stringish,
/**
* Sets the toolbar title color.
*/
titleColor?: ?ColorValue,
/**
* Sets the content inset for the toolbar starting edge.
*
* The content inset affects the valid area for Toolbar content other than
* the navigation button and menu. Insets define the minimum margin for
* these components and can be used to effectively align Toolbar content
* along well-known gridlines.
*/
contentInsetStart?: ?number,
/**
* Sets the content inset for the toolbar ending edge.
*
* The content inset affects the valid area for Toolbar content other than
* the navigation button and menu. Insets define the minimum margin for
* these components and can be used to effectively align Toolbar content
* along well-known gridlines.
*/
contentInsetEnd?: ?number,
/**
* Used to set the toolbar direction to RTL.
* In addition to this property you need to add
*
* android:supportsRtl="true"
*
* to your application AndroidManifest.xml and then call
* `setLayoutDirection(LayoutDirection.RTL)` in your MainActivity
* `onCreate` method.
*/
rtl?: ?boolean,
/**
* Used to locate this view in end-to-end tests.
*/
testID?: ?string,
|}>;

type Props = $ReadOnly<{|
...ToolbarAndroidProps,
forwardedRef: ?React.Ref<typeof NativeToolbar>,
|}>;

class ToolbarAndroid extends React.Component<Props> {
_onSelect = (event: ToolbarAndroidChangeEvent) => {
const position = event.nativeEvent.position;
if (position === -1) {
this.props.onIconClicked && this.props.onIconClicked();
} else {
this.props.onActionSelected && this.props.onActionSelected(position);
}
};

render() {
const {
onIconClicked,
onActionSelected,
forwardedRef,
...otherProps
} = this.props;

const nativeProps: {...typeof otherProps, nativeActions?: Array<Action>} = {
...otherProps,
};

if (this.props.logo) {
nativeProps.logo = resolveAssetSource(this.props.logo);
}

if (this.props.navIcon) {
nativeProps.navIcon = resolveAssetSource(this.props.navIcon);
}

if (this.props.overflowIcon) {
nativeProps.overflowIcon = resolveAssetSource(this.props.overflowIcon);
}

if (this.props.actions) {
const nativeActions = [];
for (let i = 0; i < this.props.actions.length; i++) {
const action = {
...this.props.actions[i],
icon: this.props.actions[i].icon,
show: this.props.actions[i].show,
};

if (action.icon) {
action.icon = resolveAssetSource(action.icon);
}
Expand All @@ -189,24 +216,36 @@ const ToolbarAndroid = createReactClass({
'ToolbarAndroid',
).Constants.ShowAsAction[action.show];
}
nativeActions.push(action);

nativeActions.push({
...this.props.actions[i],
...action,
});
}

nativeProps.nativeActions = nativeActions;
}

return <NativeToolbar onSelect={this._onSelect} {...nativeProps} />;
},
return (
<NativeToolbar
onSelect={this._onSelect}
{...nativeProps}
ref={forwardedRef}
/>
);
}
}

_onSelect: function(event) {
const position = event.nativeEvent.position;
if (position === -1) {
this.props.onIconClicked && this.props.onIconClicked();
} else {
this.props.onActionSelected && this.props.onActionSelected(position);
}
// $FlowFixMe - TODO T29156721 `React.forwardRef` is not defined in Flow, yet.
const ToolbarAndroidToExport = React.forwardRef(
(
props: ToolbarAndroidProps,
forwardedRef: ?React.Ref<typeof NativeToolbar>,
) => {
return <ToolbarAndroid {...props} forwardedRef={forwardedRef} />;
},
});

const NativeToolbar = requireNativeComponent('ToolbarAndroid');
);

module.exports = ToolbarAndroid;
module.exports = (ToolbarAndroidToExport: Class<
NativeComponent<ToolbarAndroidProps>,
>);

0 comments on commit 147c38a

Please sign in to comment.