Skip to content

Commit ce0dc73

Browse files
authored
Merge pull request #15 from vonovak/customOverflowAction
Custom onOverflowMenuPress
2 parents d399963 + d16fbfb commit ce0dc73

File tree

4 files changed

+43
-25
lines changed

4 files changed

+43
-25
lines changed

README.md

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,16 @@ static navigationOptions = {
3131

3232
`HeaderButtons` accepts:
3333

34-
| prop and type | description | note |
35-
| --------------------------------------- | ------------------------------------------------------------ | ----------------------------------------------------------------- |
36-
| left: boolean | whether this HeaderButtons are on the left from header title | false by default |
37-
| IconComponent?: React.ComponentType<\*> | component to use for the icons | |
38-
| iconSize?: number | iconSize | |
39-
| color?: string | color of icons and buttons | |
40-
| OverflowIcon?: React.Element<\*> | React element for the overflow icon | you need to provide this only if you need overflow icon |
41-
| overflowButtonWrapperStyle?: StyleObj | optional styles for overflow button | there are some default styles set, as seen in `OverflowButton.js` |
42-
| cancelButtonLabel?: string | ios only, the cancel button label for overflow menu actions | 'Cancel' by default |
34+
| prop and type | description | note |
35+
| ------------------------------------------------------------------------ | ------------------------------------------------------------ | ----------------------------------------------------------------- |
36+
| left: boolean | whether this HeaderButtons are on the left from header title | false by default |
37+
| IconComponent?: React.ComponentType<\*> | component to use for the icons | |
38+
| iconSize?: number | iconSize | |
39+
| color?: string | color of icons and buttons | |
40+
| OverflowIcon?: React.Element<\*> | React element for the overflow icon | you need to provide this only if you need overflow icon |
41+
| overflowButtonWrapperStyle?: StyleObj | optional styles for overflow button | there are some default styles set, as seen in `OverflowButton.js` |
42+
| cancelButtonLabel?: string | ios only, the cancel button label for overflow menu actions | 'Cancel' by default |
43+
| onOverflowMenuPress?: ({ hiddenButtons: Array<React.Element<\*>> })=>any | function that is called when overflow menu is pressed. | this will override the default handler |
4344

4445
`HeaderButtons.Item` accepts:
4546

src/HeaderButton.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,15 @@ import { StyleSheet, View } from 'react-native';
77
import Touchable from 'react-native-platform-touchable';
88
import type { StyleObj } from 'react-native/Libraries/StyleSheet/StyleSheetTypes';
99

10-
type Props = {
10+
export type HeaderButtonProps = {
1111
onPress: ?() => any,
12-
ButtonElement: React.Node,
1312
buttonWrapperStyle?: StyleObj,
1413
testID?: string,
1514
};
1615

17-
export class HeaderButton extends React.PureComponent<Props> {
16+
export class HeaderButton extends React.PureComponent<
17+
HeaderButtonProps & { ButtonElement: React.Node }
18+
> {
1819
render() {
1920
const { ButtonElement, onPress, buttonWrapperStyle, testID } = this.props;
2021
const RenderedComponent = !onPress ? View : Touchable;

src/HeaderButtons.js

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,23 @@
22
* @flow
33
*/
44
import * as React from 'react';
5-
import { HeaderButton } from './HeaderButton';
5+
import { HeaderButton, type HeaderButtonProps } from './HeaderButton';
66
import { StyleSheet, Platform, View, Text } from 'react-native';
7-
import { OverflowButton, textTransformer } from './OverflowButton';
7+
import { OverflowButton, type OverflowButtonProps } from './OverflowButton';
88
import type { StyleObj } from 'react-native/Libraries/StyleSheet/StyleSheetTypes';
99

10-
const OS_IOS = Platform.OS === 'ios';
10+
const textTransformer = (label: string) =>
11+
IS_IOS ? label.charAt(0).toUpperCase() + label.substr(1) : label.toUpperCase();
1112

1213
type ItemProps = {
13-
onPress: ?() => any,
1414
title: string,
1515
show: string,
1616
IconElement?: React.Node,
1717
iconName?: string,
1818
color?: string,
1919
iconSize?: number,
2020
buttonStyle?: StyleObj,
21+
...$Exact<HeaderButtonProps>,
2122
};
2223

2324
// TODO check RTL
@@ -39,9 +40,8 @@ type HeaderButtonsProps = {
3940
IconComponent?: React.ComponentType<*>,
4041
iconSize?: number,
4142
color?: string,
42-
OverflowIcon?: React.Element<*>,
4343
overflowButtonWrapperStyle?: StyleObj,
44-
cancelButtonLabel?: string,
44+
...$Exact<OverflowButtonProps>,
4545
};
4646

4747
export class HeaderButtons extends React.Component<HeaderButtonsProps> {
@@ -52,7 +52,13 @@ export class HeaderButtons extends React.Component<HeaderButtonsProps> {
5252

5353
render() {
5454
const { visibleButtons, hiddenButtons } = getVisibleAndHiddenButtons(this.props);
55-
const { color, OverflowIcon, cancelButtonLabel, overflowButtonWrapperStyle } = this.props;
55+
const {
56+
color,
57+
OverflowIcon,
58+
cancelButtonLabel,
59+
overflowButtonWrapperStyle,
60+
onOverflowMenuPress,
61+
} = this.props;
5662

5763
return (
5864
<View style={[styles.row, this.getEdgeMargin()]}>
@@ -64,6 +70,7 @@ export class HeaderButtons extends React.Component<HeaderButtonsProps> {
6470
OverflowIcon={OverflowIcon}
6571
cancelButtonLabel={cancelButtonLabel}
6672
buttonWrapperStyle={overflowButtonWrapperStyle}
73+
onOverflowMenuPress={onOverflowMenuPress}
6774
/>
6875
)}
6976
</View>

src/OverflowButton.js

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,19 @@ import {
1313
import { HeaderButton } from './HeaderButton';
1414
import type { StyleObj } from 'react-native/Libraries/StyleSheet/StyleSheetTypes';
1515

16-
export const textTransformer = (label: string) =>
17-
Platform.OS === 'ios' ? label.charAt(0).toUpperCase() + label.substr(1) : label.toUpperCase();
16+
const IS_IOS = Platform.OS === 'ios';
17+
18+
export type OverflowButtonProps = {
19+
OverflowIcon?: React.Element<*>,
20+
cancelButtonLabel: string,
21+
onOverflowMenuPress?: ({ hiddenButtons: Array<React.Element<*>> }) => any,
22+
};
1823

1924
type Props = {
2025
hiddenButtons: Array<React.Element<*>>,
2126
color: string,
22-
OverflowIcon?: React.Element<*>,
23-
cancelButtonLabel: string,
2427
buttonWrapperStyle?: StyleObj,
28+
...$Exact<OverflowButtonProps>,
2529
};
2630

2731
export class OverflowButton extends React.Component<Props> {
@@ -51,7 +55,12 @@ export class OverflowButton extends React.Component<Props> {
5155
}
5256

5357
showOverflowPopup = () => {
54-
Platform.OS === 'android' ? this.showPopupAndroid() : this.showPopupIos();
58+
const { onOverflowMenuPress, hiddenButtons } = this.props;
59+
if (onOverflowMenuPress) {
60+
onOverflowMenuPress({ hiddenButtons });
61+
} else {
62+
IS_IOS ? this.showPopupIos() : this.showPopupAndroid();
63+
}
5564
};
5665

5766
showPopupAndroid() {
@@ -71,7 +80,7 @@ export class OverflowButton extends React.Component<Props> {
7180
};
7281

7382
showPopupIos() {
74-
const actionTitles = this.props.hiddenButtons.map(btn => btn.props.title);
83+
let actionTitles = this.props.hiddenButtons.map(btn => btn.props.title);
7584
actionTitles.push(this.props.cancelButtonLabel);
7685

7786
ActionSheetIOS.showActionSheetWithOptions(

0 commit comments

Comments
 (0)