Skip to content

Instantly share code, notes, and snippets.

@brunolemos
Last active September 28, 2019 20:22
Show Gist options
  • Save brunolemos/f7266bcd03e3f2347fdb8f00207c9c42 to your computer and use it in GitHub Desktop.
Save brunolemos/f7266bcd03e3f2347fdb8f00207c9c42 to your computer and use it in GitHub Desktop.

Revisions

  1. brunolemos revised this gist Apr 17, 2018. 1 changed file with 9 additions and 4 deletions.
    13 changes: 9 additions & 4 deletions PlatformTouchable.tsx
    Original file line number Diff line number Diff line change
    @@ -3,6 +3,7 @@ import React, { PureComponent, ReactNode } from 'react'
    import {
    BackgroundPropType,
    Platform,
    StyleProp,
    TouchableNativeFeedback,
    TouchableNativeFeedbackProperties,
    TouchableNativeFeedbackStatic,
    @@ -54,15 +55,19 @@ TouchableComponent =
    ? TouchableWithoutFeedbackWithMethods
    : TouchableOpacityWithMethods

    export type Props = {
    export interface PlatformTouchableProperties
    extends TouchableNativeFeedbackProperties,
    TouchableOpacityProperties {
    background?: BackgroundPropType
    children: ReactNode
    foreground?: BackgroundPropType
    style?: ViewStyle
    style?: StyleProp<ViewStyle>
    useForeground?: boolean
    } & (TouchableNativeFeedbackProperties | TouchableOpacityProperties)
    }

    export default class PlatformTouchable extends PureComponent<Props> {
    export default class PlatformTouchable extends PureComponent<
    PlatformTouchableProperties
    > {
    static Ripple = TouchableComponent.Ripple
    static SelectableBackground = TouchableComponent.SelectableBackground
    static SelectableBackgroundBorderless = TouchableComponent.SelectableBackgroundBorderless
  2. brunolemos created this gist Apr 16, 2018.
    118 changes: 118 additions & 0 deletions PlatformTouchable.tsx
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,118 @@
    // Source: https://github.com/react-community/react-native-platform-touchable
    import React, { PureComponent, ReactNode } from 'react'
    import {
    BackgroundPropType,
    Platform,
    TouchableNativeFeedback,
    TouchableNativeFeedbackProperties,
    TouchableNativeFeedbackStatic,
    TouchableOpacity,
    TouchableOpacityProperties,
    TouchableWithoutFeedback,
    View,
    ViewStyle,
    } from 'react-native'

    interface TouchableMethods {
    Ripple: TouchableNativeFeedbackStatic['Ripple'] | (() => {})
    SelectableBackground:
    | TouchableNativeFeedbackStatic['SelectableBackground']
    | (() => {})
    SelectableBackgroundBorderless:
    | TouchableNativeFeedbackStatic['SelectableBackgroundBorderless']
    | (() => {})
    canUseNativeForeground: () => boolean
    }

    const defaultTouchableMethods: TouchableMethods = {
    Ripple: () => ({}),
    SelectableBackground: () => ({}),
    SelectableBackgroundBorderless: () => ({}),
    canUseNativeForeground: () => false,
    }

    const TouchableOpacityWithMethods = Object.assign(
    {},
    defaultTouchableMethods,
    TouchableOpacity,
    { displayName: 'TouchableOpacity' },
    )

    const TouchableWithoutFeedbackWithMethods = Object.assign(
    {},
    defaultTouchableMethods,
    TouchableWithoutFeedback,
    { displayName: 'TouchableWithoutFeedback' },
    )

    let TouchableComponent:
    | typeof TouchableOpacityWithMethods
    | typeof TouchableWithoutFeedbackWithMethods

    TouchableComponent =
    Platform.OS === 'android' && Platform.Version > 20
    ? TouchableWithoutFeedbackWithMethods
    : TouchableOpacityWithMethods

    export type Props = {
    background?: BackgroundPropType
    children: ReactNode
    foreground?: BackgroundPropType
    style?: ViewStyle
    useForeground?: boolean
    } & (TouchableNativeFeedbackProperties | TouchableOpacityProperties)

    export default class PlatformTouchable extends PureComponent<Props> {
    static Ripple = TouchableComponent.Ripple
    static SelectableBackground = TouchableComponent.SelectableBackground
    static SelectableBackgroundBorderless = TouchableComponent.SelectableBackgroundBorderless
    static canUseNativeForeground = TouchableComponent.canUseNativeForeground

    render() {
    const {
    background,
    children: _children,
    foreground,
    style,
    useForeground: _useForeground,
    ...props
    } = this.props

    // Even though it works for TouchableWithoutFeedback and
    // TouchableNativeFeedback with this component, we want
    // the API to be the same for all components so we require
    // exactly one direct child for every touchable type.
    const children = React.Children.only(_children)

    let useForeground = _useForeground
    if (TouchableComponent === TouchableNativeFeedback) {
    useForeground =
    !!foreground && TouchableNativeFeedback.canUseNativeForeground()

    if (foreground && background) {
    // tslint:disable-next-line no-console
    console.warn(
    'Specified foreground and background for Touchable, only one can be used at a time. Defaulted to foreground.',
    )
    }

    return (
    <TouchableNativeFeedback
    {...props}
    useForeground={useForeground}
    background={(useForeground && foreground) || background}
    >
    <View style={style}>{children}</View>
    </TouchableNativeFeedback>
    )
    }

    {
    return (
    <TouchableOpacity {...props} style={style}>
    {children}
    </TouchableOpacity>
    )
    }
    }
    }