123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238 |
- /**
- * Copyright (c) Facebook, Inc. and its affiliates.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- *
- * @format
- * @flow
- */
- 'use strict';
- const Platform = require('../Utilities/Platform');
- const React = require('react');
- const StyleSheet = require('../StyleSheet/StyleSheet');
- const Text = require('../Text/Text');
- const TouchableNativeFeedback = require('./Touchable/TouchableNativeFeedback');
- const TouchableOpacity = require('./Touchable/TouchableOpacity');
- const View = require('./View/View');
- const invariant = require('invariant');
- import type {PressEvent} from '../Types/CoreEventTypes';
- import type {ColorValue} from '../StyleSheet/StyleSheetTypes';
- type ButtonProps = $ReadOnly<{|
- /**
- * Text to display inside the button
- */
- title: string,
- /**
- * Handler to be called when the user taps the button
- */
- onPress: (event?: PressEvent) => mixed,
- /**
- * If true, doesn't play system sound on touch (Android Only)
- **/
- touchSoundDisabled?: ?boolean,
- /**
- * Color of the text (iOS), or background color of the button (Android)
- */
- color?: ?ColorValue,
- /**
- * TV preferred focus (see documentation for the View component).
- */
- hasTVPreferredFocus?: ?boolean,
- /**
- * TV next focus down (see documentation for the View component).
- *
- * @platform android
- */
- nextFocusDown?: ?number,
- /**
- * TV next focus forward (see documentation for the View component).
- *
- * @platform android
- */
- nextFocusForward?: ?number,
- /**
- * TV next focus left (see documentation for the View component).
- *
- * @platform android
- */
- nextFocusLeft?: ?number,
- /**
- * TV next focus right (see documentation for the View component).
- *
- * @platform android
- */
- nextFocusRight?: ?number,
- /**
- * TV next focus up (see documentation for the View component).
- *
- * @platform android
- */
- nextFocusUp?: ?number,
- /**
- * Text to display for blindness accessibility features
- */
- accessibilityLabel?: ?string,
- /**
- * If true, disable all interactions for this component.
- */
- disabled?: ?boolean,
- /**
- * Used to locate this view in end-to-end tests.
- */
- testID?: ?string,
- |}>;
- /**
- * A basic button component that should render nicely on any platform. Supports
- * a minimal level of customization.
- *
- * <center><img src="img/buttonExample.png"></img></center>
- *
- * If this button doesn't look right for your app, you can build your own
- * button using [TouchableOpacity](docs/touchableopacity.html)
- * or [TouchableNativeFeedback](docs/touchablenativefeedback.html).
- * For inspiration, look at the [source code for this button component](https://github.com/facebook/react-native/blob/master/Libraries/Components/Button.js).
- * Or, take a look at the [wide variety of button components built by the community](https://js.coach/react-native?search=button).
- *
- * Example usage:
- *
- * ```
- * import { Button } from 'react-native';
- * ...
- *
- * <Button
- * onPress={onPressLearnMore}
- * title="Learn More"
- * color="#841584"
- * accessibilityLabel="Learn more about this purple button"
- * />
- * ```
- *
- */
- class Button extends React.Component<ButtonProps> {
- render(): React.Node {
- const {
- accessibilityLabel,
- color,
- onPress,
- touchSoundDisabled,
- title,
- hasTVPreferredFocus,
- nextFocusDown,
- nextFocusForward,
- nextFocusLeft,
- nextFocusRight,
- nextFocusUp,
- disabled,
- testID,
- } = this.props;
- const buttonStyles = [styles.button];
- const textStyles = [styles.text];
- if (color) {
- if (Platform.OS === 'ios') {
- textStyles.push({color: color});
- } else {
- buttonStyles.push({backgroundColor: color});
- }
- }
- const accessibilityState = {};
- if (disabled) {
- buttonStyles.push(styles.buttonDisabled);
- textStyles.push(styles.textDisabled);
- accessibilityState.disabled = true;
- }
- invariant(
- typeof title === 'string',
- 'The title prop of a Button must be a string',
- );
- const formattedTitle =
- Platform.OS === 'android' ? title.toUpperCase() : title;
- const Touchable =
- Platform.OS === 'android' ? TouchableNativeFeedback : TouchableOpacity;
- return (
- <Touchable
- accessibilityLabel={accessibilityLabel}
- accessibilityRole="button"
- accessibilityState={accessibilityState}
- hasTVPreferredFocus={hasTVPreferredFocus}
- nextFocusDown={nextFocusDown}
- nextFocusForward={nextFocusForward}
- nextFocusLeft={nextFocusLeft}
- nextFocusRight={nextFocusRight}
- nextFocusUp={nextFocusUp}
- testID={testID}
- disabled={disabled}
- onPress={onPress}
- touchSoundDisabled={touchSoundDisabled}>
- <View style={buttonStyles}>
- <Text style={textStyles} disabled={disabled}>
- {formattedTitle}
- </Text>
- </View>
- </Touchable>
- );
- }
- }
- const styles = StyleSheet.create({
- button: Platform.select({
- ios: {},
- android: {
- elevation: 4,
- // Material design blue from https://material.google.com/style/color.html#color-color-palette
- backgroundColor: '#2196F3',
- borderRadius: 2,
- },
- }),
- text: {
- textAlign: 'center',
- margin: 8,
- ...Platform.select({
- ios: {
- // iOS blue from https://developer.apple.com/ios/human-interface-guidelines/visual-design/color/
- color: '#007AFF',
- fontSize: 18,
- },
- android: {
- color: 'white',
- fontWeight: '500',
- },
- }),
- },
- buttonDisabled: Platform.select({
- ios: {},
- android: {
- elevation: 0,
- backgroundColor: '#dfdfdf',
- },
- }),
- textDisabled: Platform.select({
- ios: {
- color: '#cdcdcd',
- },
- android: {
- color: '#a1a1a1',
- },
- }),
- });
- module.exports = Button;
|