|
1 |
| -import React, {PureComponent} from 'react'; |
| 1 | +import {useModifiers, useThemeProps} from 'hooks'; |
| 2 | +import React, {useEffect, useMemo, useState} from 'react'; |
2 | 3 | import {View as RNView, SafeAreaView, Animated, ViewProps as RNViewProps, StyleProp, ViewStyle} from 'react-native';
|
3 | 4 | import Reanimated from 'react-native-reanimated';
|
4 |
| -import { |
5 |
| - Constants, |
6 |
| - asBaseComponent, |
7 |
| - forwardRef, |
8 |
| - BaseComponentInjectedProps, |
9 |
| - ForwardRefInjectedProps, |
10 |
| - ContainerModifiers |
11 |
| -} from '../../commons/new'; |
| 5 | +import {Constants, ContainerModifiers} from '../../commons/new'; |
12 | 6 |
|
13 |
| -export interface ViewProps extends Omit<RNViewProps, 'style'>, ContainerModifiers { |
| 7 | +export interface ViewProps extends Omit<RNViewProps, 'style'>, ThemeComponent, ContainerModifiers { |
14 | 8 | /**
|
15 | 9 | * If true, will render as SafeAreaView
|
16 | 10 | */
|
@@ -46,106 +40,98 @@ export interface ViewProps extends Omit<RNViewProps, 'style'>, ContainerModifier
|
46 | 40 | style?: StyleProp<ViewStyle | Animated.AnimatedProps<ViewStyle>>;
|
47 | 41 | }
|
48 | 42 |
|
49 |
| -type PropsTypes = BaseComponentInjectedProps & ForwardRefInjectedProps & ViewProps; |
50 |
| - |
51 |
| -interface ViewState { |
52 |
| - ready: boolean; |
53 |
| -} |
| 43 | +const modifiersOptions = { |
| 44 | + backgroundColor: true, |
| 45 | + borderRadius: true, |
| 46 | + paddings: true, |
| 47 | + margins: true, |
| 48 | + alignments: true, |
| 49 | + flex: true, |
| 50 | + position: true |
| 51 | +}; |
54 | 52 |
|
55 | 53 | /**
|
56 | 54 | * @description: An enhanced View component
|
57 | 55 | * @extends: View
|
58 | 56 | * @extendsLink: https://reactnative.dev/docs/view
|
59 | 57 | * @modifiers: margins, paddings, alignments, background, borderRadius
|
60 | 58 | */
|
61 |
| -class View extends PureComponent<PropsTypes, ViewState> { |
62 |
| - static displayName = 'View'; |
63 |
| - private Container: React.ClassType<any, any, any>; |
64 |
| - |
65 |
| - constructor(props: PropsTypes) { |
66 |
| - super(props); |
67 |
| - |
68 |
| - this.Container = props.useSafeArea && Constants.isIOS ? SafeAreaView : RNView; |
69 |
| - if (props.reanimated) { |
70 |
| - this.Container = Reanimated.createAnimatedComponent(this.Container); |
71 |
| - } else if (props.animated) { |
72 |
| - this.Container = Animated.createAnimatedComponent(this.Container); |
73 |
| - } |
74 |
| - |
75 |
| - this.state = { |
76 |
| - ready: !props.renderDelay |
77 |
| - }; |
78 |
| - } |
| 59 | +function View(props: ViewProps, ref: any) { |
| 60 | + const themeProps = useThemeProps(props, 'View'); |
| 61 | + const { |
| 62 | + renderDelay, |
| 63 | + style, |
| 64 | + // (!) extract left, top, bottom... props to avoid passing them on Android |
| 65 | + /* eslint-disable */ |
| 66 | + left, |
| 67 | + top, |
| 68 | + right, |
| 69 | + bottom, |
| 70 | + flex: propsFlex, |
| 71 | + /* eslint-enable */ |
| 72 | + inaccessible, |
| 73 | + useSafeArea, |
| 74 | + animated, |
| 75 | + reanimated, |
| 76 | + children, |
| 77 | + ...others |
| 78 | + } = themeProps; |
| 79 | + const {backgroundColor, borderRadius, paddings, margins, alignments, flexStyle, positionStyle} = useModifiers(themeProps, |
| 80 | + modifiersOptions); |
| 81 | + const [ready, setReady] = useState(!renderDelay); |
79 | 82 |
|
80 |
| - componentDidMount() { |
81 |
| - const {renderDelay} = this.props; |
| 83 | + useEffect(() => { |
82 | 84 | if (renderDelay) {
|
83 | 85 | setTimeout(() => {
|
84 |
| - this.setState({ready: true}); |
| 86 | + setReady(true); |
85 | 87 | }, renderDelay);
|
86 | 88 | }
|
87 |
| - } |
| 89 | + }, []); |
88 | 90 |
|
89 |
| - // TODO: do we need this? |
90 |
| - setNativeProps(nativeProps: any) { |
91 |
| - //@ts-ignore |
92 |
| - this._root.setNativeProps(nativeProps); // eslint-disable-line |
93 |
| - } |
| 91 | + const ViewContainer = useMemo(() => { |
| 92 | + const container = useSafeArea && Constants.isIOS ? SafeAreaView : RNView; |
94 | 93 |
|
95 |
| - render() { |
96 |
| - if (!this.state.ready) { |
97 |
| - return null; |
| 94 | + if (reanimated) { |
| 95 | + return Reanimated.createAnimatedComponent(container); |
| 96 | + } else if (animated) { |
| 97 | + return Animated.createAnimatedComponent(container); |
98 | 98 | }
|
99 | 99 |
|
100 |
| - // (!) extract left, top, bottom... props to avoid passing them on Android |
101 |
| - // eslint-disable-next-line |
102 |
| - const { |
103 |
| - modifiers, |
104 |
| - style, |
105 |
| - /* eslint-disable */ |
106 |
| - left, |
107 |
| - top, |
108 |
| - right, |
109 |
| - bottom, |
110 |
| - flex: propsFlex, |
111 |
| - /* eslint-enable */ |
112 |
| - forwardedRef, |
113 |
| - inaccessible, |
114 |
| - ...others |
115 |
| - } = this.props; |
116 |
| - const {backgroundColor, borderRadius, paddings, margins, alignments, flexStyle, positionStyle} = modifiers; |
117 |
| - const Element = this.Container; |
118 |
| - return ( |
119 |
| - <Element |
120 |
| - accessibilityElementsHidden={inaccessible} |
121 |
| - importantForAccessibility={inaccessible ? 'no-hide-descendants' : undefined} |
122 |
| - {...others} |
123 |
| - style={[ |
124 |
| - backgroundColor && {backgroundColor}, |
125 |
| - borderRadius && {borderRadius}, |
126 |
| - flexStyle, |
127 |
| - positionStyle, |
128 |
| - paddings, |
129 |
| - margins, |
130 |
| - alignments, |
131 |
| - style |
132 |
| - ]} |
133 |
| - ref={forwardedRef} |
134 |
| - > |
135 |
| - {this.props.children} |
136 |
| - </Element> |
137 |
| - ); |
| 100 | + return container; |
| 101 | + }, [useSafeArea, animated, reanimated]); |
| 102 | + |
| 103 | + const _style = useMemo(() => { |
| 104 | + return [ |
| 105 | + backgroundColor && { |
| 106 | + backgroundColor |
| 107 | + }, |
| 108 | + borderRadius && { |
| 109 | + borderRadius |
| 110 | + }, |
| 111 | + flexStyle, |
| 112 | + positionStyle, |
| 113 | + paddings, |
| 114 | + margins, |
| 115 | + alignments, |
| 116 | + style |
| 117 | + ]; |
| 118 | + }, [backgroundColor, borderRadius, flexStyle, positionStyle, paddings, margins, alignments, style]); |
| 119 | + |
| 120 | + if (!ready) { |
| 121 | + return null; |
138 | 122 | }
|
139 |
| -} |
140 | 123 |
|
141 |
| -const modifiersOptions = { |
142 |
| - backgroundColor: true, |
143 |
| - borderRadius: true, |
144 |
| - paddings: true, |
145 |
| - margins: true, |
146 |
| - alignments: true, |
147 |
| - flex: true, |
148 |
| - position: true |
149 |
| -}; |
| 124 | + return ( |
| 125 | + <ViewContainer |
| 126 | + accessibilityElementsHidden={inaccessible} |
| 127 | + importantForAccessibility={inaccessible ? 'no-hide-descendants' : undefined} |
| 128 | + {...others} |
| 129 | + style={_style} |
| 130 | + ref={ref} |
| 131 | + > |
| 132 | + {children} |
| 133 | + </ViewContainer> |
| 134 | + ); |
| 135 | +} |
150 | 136 |
|
151 |
| -export default asBaseComponent<ViewProps>(forwardRef(View), {modifiersOptions}); |
| 137 | +export default React.forwardRef<RNView, ViewProps>(View); |
0 commit comments