-
Notifications
You must be signed in to change notification settings - Fork 738
Infra/refactor view - convert to function component and use modifiers and themeProps hooks #2146
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
e90fd0c
a5baa77
adf50bd
e7f0117
6bc6566
3519b4d
a7c28c7
0498c80
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,10 @@ | ||
import React, {PureComponent} from 'react'; | ||
import {useModifiers, useThemeProps} from 'hooks'; | ||
import React, {useEffect, useMemo, useState} from 'react'; | ||
import {View as RNView, SafeAreaView, Animated, ViewProps as RNViewProps, StyleProp, ViewStyle} from 'react-native'; | ||
import Reanimated from 'react-native-reanimated'; | ||
import { | ||
Constants, | ||
asBaseComponent, | ||
forwardRef, | ||
BaseComponentInjectedProps, | ||
ForwardRefInjectedProps, | ||
ContainerModifiers | ||
} from '../../commons/new'; | ||
import {Constants, ContainerModifiers} from '../../commons/new'; | ||
|
||
export interface ViewProps extends Omit<RNViewProps, 'style'>, ContainerModifiers { | ||
export interface ViewProps extends Omit<RNViewProps, 'style'>, ThemeComponent, ContainerModifiers { | ||
/** | ||
* If true, will render as SafeAreaView | ||
*/ | ||
|
@@ -46,106 +40,98 @@ export interface ViewProps extends Omit<RNViewProps, 'style'>, ContainerModifier | |
style?: StyleProp<ViewStyle | Animated.AnimatedProps<ViewStyle>>; | ||
} | ||
|
||
type PropsTypes = BaseComponentInjectedProps & ForwardRefInjectedProps & ViewProps; | ||
|
||
interface ViewState { | ||
ready: boolean; | ||
} | ||
const modifiersOptions = { | ||
backgroundColor: true, | ||
borderRadius: true, | ||
paddings: true, | ||
margins: true, | ||
alignments: true, | ||
flex: true, | ||
position: true | ||
}; | ||
|
||
/** | ||
* @description: An enhanced View component | ||
* @extends: View | ||
* @extendsLink: https://reactnative.dev/docs/view | ||
* @modifiers: margins, paddings, alignments, background, borderRadius | ||
*/ | ||
class View extends PureComponent<PropsTypes, ViewState> { | ||
static displayName = 'View'; | ||
private Container: React.ClassType<any, any, any>; | ||
|
||
constructor(props: PropsTypes) { | ||
super(props); | ||
|
||
this.Container = props.useSafeArea && Constants.isIOS ? SafeAreaView : RNView; | ||
if (props.reanimated) { | ||
this.Container = Reanimated.createAnimatedComponent(this.Container); | ||
} else if (props.animated) { | ||
this.Container = Animated.createAnimatedComponent(this.Container); | ||
} | ||
|
||
this.state = { | ||
ready: !props.renderDelay | ||
}; | ||
} | ||
function View(props: ViewProps, ref: any) { | ||
const themeProps = useThemeProps(props, 'View'); | ||
const { | ||
renderDelay, | ||
style, | ||
// (!) extract left, top, bottom... props to avoid passing them on Android | ||
/* eslint-disable */ | ||
left, | ||
top, | ||
right, | ||
bottom, | ||
flex: propsFlex, | ||
/* eslint-enable */ | ||
inaccessible, | ||
useSafeArea, | ||
animated, | ||
reanimated, | ||
children, | ||
...others | ||
} = themeProps; | ||
const {backgroundColor, borderRadius, paddings, margins, alignments, flexStyle, positionStyle} = useModifiers(themeProps, | ||
modifiersOptions); | ||
const [ready, setReady] = useState(!renderDelay); | ||
|
||
componentDidMount() { | ||
const {renderDelay} = this.props; | ||
useEffect(() => { | ||
if (renderDelay) { | ||
setTimeout(() => { | ||
this.setState({ready: true}); | ||
setReady(true); | ||
}, renderDelay); | ||
} | ||
} | ||
}, []); | ||
|
||
// TODO: do we need this? | ||
setNativeProps(nativeProps: any) { | ||
//@ts-ignore | ||
this._root.setNativeProps(nativeProps); // eslint-disable-line | ||
} | ||
const ViewContainer = useMemo(() => { | ||
const container = useSafeArea && Constants.isIOS ? SafeAreaView : RNView; | ||
M-i-k-e-l marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
render() { | ||
if (!this.state.ready) { | ||
return null; | ||
if (reanimated) { | ||
return Reanimated.createAnimatedComponent(container); | ||
} else if (animated) { | ||
return Animated.createAnimatedComponent(container); | ||
} | ||
|
||
// (!) extract left, top, bottom... props to avoid passing them on Android | ||
// eslint-disable-next-line | ||
const { | ||
modifiers, | ||
style, | ||
/* eslint-disable */ | ||
left, | ||
top, | ||
right, | ||
bottom, | ||
flex: propsFlex, | ||
/* eslint-enable */ | ||
forwardedRef, | ||
inaccessible, | ||
...others | ||
} = this.props; | ||
const {backgroundColor, borderRadius, paddings, margins, alignments, flexStyle, positionStyle} = modifiers; | ||
const Element = this.Container; | ||
return ( | ||
<Element | ||
accessibilityElementsHidden={inaccessible} | ||
importantForAccessibility={inaccessible ? 'no-hide-descendants' : undefined} | ||
{...others} | ||
style={[ | ||
backgroundColor && {backgroundColor}, | ||
borderRadius && {borderRadius}, | ||
flexStyle, | ||
positionStyle, | ||
paddings, | ||
margins, | ||
alignments, | ||
style | ||
]} | ||
ref={forwardedRef} | ||
> | ||
{this.props.children} | ||
</Element> | ||
); | ||
return container; | ||
}, [useSafeArea, animated, reanimated]); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I can see There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree, And if they won't change there's no harm having them here (: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It might have some performance implications, but they are probably minor |
||
|
||
const _style = useMemo(() => { | ||
return [ | ||
backgroundColor && { | ||
backgroundColor | ||
}, | ||
borderRadius && { | ||
borderRadius | ||
}, | ||
flexStyle, | ||
positionStyle, | ||
paddings, | ||
margins, | ||
alignments, | ||
style | ||
]; | ||
}, [backgroundColor, borderRadius, flexStyle, positionStyle, paddings, margins, alignments, style]); | ||
|
||
if (!ready) { | ||
return null; | ||
} | ||
} | ||
|
||
const modifiersOptions = { | ||
backgroundColor: true, | ||
borderRadius: true, | ||
paddings: true, | ||
margins: true, | ||
alignments: true, | ||
flex: true, | ||
position: true | ||
}; | ||
return ( | ||
<ViewContainer | ||
accessibilityElementsHidden={inaccessible} | ||
importantForAccessibility={inaccessible ? 'no-hide-descendants' : undefined} | ||
{...others} | ||
style={_style} | ||
ref={ref} | ||
> | ||
{children} | ||
</ViewContainer> | ||
); | ||
} | ||
|
||
export default asBaseComponent<ViewProps>(forwardRef(View), {modifiersOptions}); | ||
export default React.forwardRef<RNView, ViewProps>(View); |
Uh oh!
There was an error while loading. Please reload this page.