diff --git a/src/components/touchables/GenericTouchable.tsx b/src/components/touchables/GenericTouchable.tsx index 83cfae8762..a5026b9e2b 100644 --- a/src/components/touchables/GenericTouchable.tsx +++ b/src/components/touchables/GenericTouchable.tsx @@ -3,9 +3,8 @@ import { Component } from 'react'; import { Animated, Platform, - StyleProp, - ViewStyle, TouchableWithoutFeedbackProps, + StyleSheet, } from 'react-native'; import { State } from '../../State'; @@ -17,6 +16,7 @@ import { } from '../../handlers/gestureHandlerCommon'; import { NativeViewGestureHandlerPayload } from '../../handlers/NativeViewGestureHandler'; import { TouchableNativeFeedbackExtraProps } from './TouchableNativeFeedback.android'; +import splitStyleProp from './splitStyleProp'; /** * Each touchable is a states' machine which preforms transitions. @@ -46,8 +46,6 @@ export interface GenericTouchableProps extends TouchableWithoutFeedbackProps { nativeID?: string; shouldActivateOnStart?: boolean; disallowInterruption?: boolean; - - containerStyle?: StyleProp; } interface InternalProps { @@ -261,10 +259,11 @@ export default class GenericTouchable extends Component< onLayout: this.props.onLayout, hitSlop: this.props.hitSlop, }; + const { outer, inner } = splitStyleProp(this.props.style); return ( - + {this.props.children} ); } } + +const styles = StyleSheet.create({ + innerView: { + flexGrow: 1, + }, +}); diff --git a/src/components/touchables/splitStyleProp.ts b/src/components/touchables/splitStyleProp.ts new file mode 100644 index 0000000000..1acee639e0 --- /dev/null +++ b/src/components/touchables/splitStyleProp.ts @@ -0,0 +1,61 @@ +import { FlexStyle, StyleProp, StyleSheet } from 'react-native'; + +const OUTER_PROPS: { [key in keyof FlexStyle]?: true } = { + alignSelf: true, + bottom: true, + display: true, + end: true, + flex: true, + flexBasis: true, + flexGrow: true, + flexShrink: true, + height: true, + left: true, + margin: true, + marginBottom: true, + marginEnd: true, + marginHorizontal: true, + marginLeft: true, + marginRight: true, + marginStart: true, + marginTop: true, + marginVertical: true, + maxHeight: true, + maxWidth: true, + minHeight: true, + minWidth: true, + position: true, + right: true, + start: true, + top: true, + width: true, + zIndex: true, +}; + +/** + * Split a style prop between an "outer" and "inner" views in a way that makes it behave + * as if it was a single view. + * + * @example + * const { outer, inner } = splitStyleProp(style); + * return ( + * + * + * + * ); + */ +export default function splitStyleProp( + style?: StyleProp +): { outer: T; inner: T } { + const resolvedStyle = StyleSheet.flatten(style); + const inner: Record = {}; + const outer: Record = {}; + Object.entries(resolvedStyle).forEach(([key, value]) => { + if ((OUTER_PROPS as { [key: string]: true | undefined })[key] === true) { + outer[key] = value; + } else { + inner[key] = value; + } + }); + return { outer: outer as T, inner: inner as T }; +}