react-navigation-header-buttons
react-navigation-header-buttons copied to clipboard
Allow arbitrary props to be passed to the icon component
Firstly, thanks for taking the time to create this library.
I'm trying to use this library along with https://github.com/shyaniv7/react-native-fontawesome-pro. With react-native-fontawesome-pro
, you can use an icon like so:
<Icon name="square" type="light" size={24} color="black" />
You can see that most of the props are the same as what you'd use with react-native-vector-icons
, but with one additional and important prop, type
, which defines whether you're using the solid
, regular
, or light
family of icons. I need to be able to specify this prop, on a per-icon basis, but I can't see how I'd do this with react-navigation-header-buttons
.
Here's my current code:
// FontAwesomeHeaderButtons.js
import React from 'react';
import HeaderButtons, { HeaderButton, Item } from 'react-navigation-header-buttons';
import Icon from 'react-native-fontawesome-pro';
const FontAwesomeHeaderButton = props => (
<HeaderButton {...props} IconComponent={Icon} iconSize={24} />
);
const FontAwesomeHeaderButtons = props => {
return (
<HeaderButtons
HeaderButtonComponent={FontAwesomeHeaderButton}
OverflowIcon={<Icon name="ellipsis-v" type="light" size={24} />}
{...props}
/>
);
};
export default FontAwesomeHeaderButtons;
// MyScreen.js
static navigationOptions = {
headerRight: (
<FontAwesomeHeaderButtons>
<HeaderButtons.Item title="add" iconName="plus-circle" onPress={() => console.warn('add')} />
<HeaderButtons.Item title="edit" onPress={() => console.warn('edit')} />
</FontAwesomeHeaderButtons>
),
};
Any suggestions for how I can specify the type
for my header button icons?
hi @jordanmkoncz, I wasn't aware the library existed, and the way the lib is done does not does not make this as easy as it could be. That being said I think this approach should work - add the type
(or IconComponent
for that matter) prop to the HeaderButtons.Item
and then do
import Icon from 'react-native-fontawesome-pro';
const SolidIcon = (props) => <Icon type="solid" {...props} />
const FontAwesomeHeaderButton = props => {
const FAIcon = props.type === 'solid' ? SolidIcon : Icon; // this will be something more clever, but you get the idea
return <HeaderButton {...props} IconComponent={FAIcon} iconSize={24} />
}
However, this approach will require that you specify the type
/ IconComponent
for each HeaderButtons.Item
. Sure, you can have a default value, but still, it would be ideal to have something like HeaderButtons.SolidItem
or HeaderButtons.LightItem
which, I'm afraid, is not possible with the way I wrote the lib. Hope this helps, let me know if something is unclear.
Thanks @vonovak, your solution worked.
In case anyone else runs into the same problem as I did, here's the working code that I'm now using.
// FontAwesomeHeaderButtons.js
/**
* @flow
*/
// See https://github.com/vonovak/react-navigation-header-buttons#how-to-integrate-in-your-project.
import React from 'react';
import { View } from 'react-native';
import HeaderButtons, { HeaderButton } from 'react-navigation-header-buttons';
import Icon from 'react-native-fontawesome-pro';
const SolidIcon = ({ style, ...otherProps }) => (
<View style={style}>
<Icon type="solid" {...otherProps} />
</View>
);
const RegularIcon = ({ style, ...otherProps }) => (
<View style={style}>
<Icon type="regular" {...otherProps} />
</View>
);
const LightIcon = ({ style, ...otherProps }) => (
<View style={style}>
<Icon type="light" {...otherProps} />
</View>
);
type Props = {
iconType?: string,
iconSize?: number,
};
const FontAwesomeHeaderButton = (props: Props) => {
let FontAwesomeIcon;
if (props.iconType === 'solid') {
FontAwesomeIcon = SolidIcon;
} else if (props.iconType === 'regular') {
FontAwesomeIcon = RegularIcon;
} else {
FontAwesomeIcon = LightIcon;
}
return <HeaderButton {...props} IconComponent={FontAwesomeIcon} />;
};
FontAwesomeHeaderButton.defaultProps = {
iconType: 'light',
iconSize: 18,
};
const FontAwesomeHeaderButtons = props => (
<HeaderButtons
HeaderButtonComponent={FontAwesomeHeaderButton}
OverflowIcon={<Icon name="ellipsis-v" type="light" size={24} />}
{...props}
/>
);
export default FontAwesomeHeaderButtons;
Usage:
headerRight: (
<FontAwesomeHeaderButtons>
<HeaderButtons.Item title="Search" iconName="search" onPress={() => console.log('search')} />
</FontAwesomeHeaderButtons>
),
@vonovak I'll leave it up to you whether to close this issue. It may be worth considering changing this library so that there's a more straightforward and flexible way to pass any arbitrary props to your icon component.
For example, adding an iconProps
prop, which is an object, and whose value is passed through to the icon component as props (via standard object spread). In practice you could then use it like so:
headerRight: (
<HeaderButtons>
<HeaderButtons.Item title="Search" iconProps={{ name: 'search', size: 24, type: 'light', someOtherProp: 'foo' }} onPress={() => console.log('search')} />
</HeaderButtons>
),
This would mean that you can easily pass through any props that you want to use for the icon component, which would be more flexible than having a specific prop like iconSize
which is then passed through to the icon component as a pre-determined prop like size
.
Alternative solution: use the Button Element prop like here https://github.com/vonovak/react-navigation-header-buttons/blob/master/example/navbar-buttons-demo/screens/UsageCustom.js