@shoutem/ui 7.2.2-rc.2 → 7.3.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/ScrollView/ScrollView.js +1 -20
- package/const.js +4 -14
- package/helpers/device-selector.js +19 -111
- package/helpers/index.js +3 -7
- package/helpers/keyboard.js +7 -3
- package/index.js +2 -7
- package/package.json +3 -2
- package/theme.js +6 -336
- package/components/NavigationBar/NavigationBar.js +0 -113
- package/components/NavigationBar/NavigationBarAnimations.js +0 -47
- package/components/NavigationBar/composeChildren.js +0 -86
- package/components/NavigationBar/index.js +0 -2
|
@@ -5,12 +5,8 @@ import _ from 'lodash';
|
|
|
5
5
|
import PropTypes from 'prop-types';
|
|
6
6
|
import { DriverShape, ScrollDriver } from '@shoutem/animation';
|
|
7
7
|
import { connectStyle } from '@shoutem/theme';
|
|
8
|
-
import { Device } from '../../helpers';
|
|
9
8
|
import { ScrollDriverProvider } from './ScrollDriverProvider.js';
|
|
10
9
|
|
|
11
|
-
const isTabBarOnScreen = true;
|
|
12
|
-
const IPHONE_X_HOME_INDICATOR_PADDING = isTabBarOnScreen ? 0 : 34;
|
|
13
|
-
|
|
14
10
|
class ScrollView extends PureComponent {
|
|
15
11
|
static contextTypes = {
|
|
16
12
|
animationDriver: DriverShape,
|
|
@@ -63,21 +59,6 @@ class ScrollView extends PureComponent {
|
|
|
63
59
|
this.wrappedInstance = component;
|
|
64
60
|
}
|
|
65
61
|
|
|
66
|
-
addIphoneXPadding(style) {
|
|
67
|
-
const resolvedStyle = { ...style };
|
|
68
|
-
|
|
69
|
-
if (typeof resolvedStyle.paddingBottom !== 'number') {
|
|
70
|
-
resolvedStyle.paddingBottom = 0;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
resolvedStyle.paddingBottom = Device.select({
|
|
74
|
-
iPhoneX: resolvedStyle.paddingBottom + IPHONE_X_HOME_INDICATOR_PADDING,
|
|
75
|
-
default: resolvedStyle.paddingBottom,
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
return resolvedStyle;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
62
|
render() {
|
|
82
63
|
const { style, ...otherProps } = this.props;
|
|
83
64
|
const { scrollViewProps } = this.animationDriver;
|
|
@@ -86,7 +67,7 @@ class ScrollView extends PureComponent {
|
|
|
86
67
|
return (
|
|
87
68
|
<Animated.ScrollView
|
|
88
69
|
ref={this.setWrappedInstance}
|
|
89
|
-
contentContainerStyle={
|
|
70
|
+
contentContainerStyle={contentContainerStyle}
|
|
90
71
|
{...scrollViewProps}
|
|
91
72
|
{..._.omit(otherProps, 'onScroll')}
|
|
92
73
|
style={otherStyle}
|
package/const.js
CHANGED
|
@@ -1,14 +1,9 @@
|
|
|
1
1
|
import { Platform, StatusBar } from 'react-native';
|
|
2
2
|
import {
|
|
3
|
-
|
|
4
|
-
IPHONE_12_MAX_LONG_SIDE,
|
|
5
|
-
IPHONE_X_HOME_INDICATOR_PADDING,
|
|
6
|
-
IPHONE_X_LONG_SIDE,
|
|
7
|
-
IPHONE_X_NOTCH_PADDING,
|
|
8
|
-
IPHONE_XR_LONG_SIDE,
|
|
9
|
-
IPHONE_XR_NOTCH_PADDING,
|
|
3
|
+
HOME_INDICATOR_PADDING,
|
|
10
4
|
NAVIGATION_BAR_HEIGHT,
|
|
11
5
|
NAVIGATION_HEADER_HEIGHT,
|
|
6
|
+
NOTCH_AREA_HEIGHT,
|
|
12
7
|
} from './helpers';
|
|
13
8
|
|
|
14
9
|
const STATUS_BAR_OFFSET =
|
|
@@ -17,14 +12,9 @@ const STATUS_BAR_OFFSET =
|
|
|
17
12
|
// TODO: Deprecate and remove exports from here
|
|
18
13
|
// Currently leaving for backwards compatibility
|
|
19
14
|
export {
|
|
20
|
-
|
|
21
|
-
IPHONE_12_MAX_LONG_SIDE,
|
|
22
|
-
IPHONE_X_HOME_INDICATOR_PADDING,
|
|
23
|
-
IPHONE_X_LONG_SIDE,
|
|
24
|
-
IPHONE_X_NOTCH_PADDING,
|
|
25
|
-
IPHONE_XR_LONG_SIDE,
|
|
26
|
-
IPHONE_XR_NOTCH_PADDING,
|
|
15
|
+
HOME_INDICATOR_PADDING,
|
|
27
16
|
NAVIGATION_BAR_HEIGHT,
|
|
28
17
|
NAVIGATION_HEADER_HEIGHT,
|
|
18
|
+
NOTCH_AREA_HEIGHT,
|
|
29
19
|
STATUS_BAR_OFFSET,
|
|
30
20
|
};
|
|
@@ -1,124 +1,32 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Platform, StatusBar } from 'react-native';
|
|
2
2
|
import DeviceInfo from 'react-native-device-info';
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
const { OS, isPad, isTVOS } = Platform;
|
|
6
|
-
const { width, height } = Dimensions.get('window');
|
|
7
|
-
|
|
8
|
-
export const IPHONE_X_HOME_INDICATOR_PADDING = 34;
|
|
9
|
-
export const IPHONE_X_LONG_SIDE = 812;
|
|
10
|
-
export const IPHONE_X_NOTCH_PADDING = 30;
|
|
11
|
-
|
|
12
|
-
export const IPHONE_XR_LONG_SIDE = 896;
|
|
13
|
-
export const IPHONE_XR_NOTCH_PADDING = 34;
|
|
14
|
-
|
|
15
|
-
export const IPHONE_12_LONG_SIDE = 844;
|
|
16
|
-
export const IPHONE_12_MAX_LONG_SIDE = 926;
|
|
3
|
+
import { initialWindowMetrics } from 'react-native-safe-area-context';
|
|
17
4
|
|
|
18
5
|
export const NAVIGATION_HEADER_HEIGHT = 64;
|
|
19
6
|
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
const xrDimensionsMatch =
|
|
24
|
-
height === IPHONE_XR_LONG_SIDE || width === IPHONE_XR_LONG_SIDE;
|
|
25
|
-
|
|
26
|
-
const twelveDimensionsMatch =
|
|
27
|
-
height === IPHONE_12_LONG_SIDE || width === IPHONE_12_LONG_SIDE;
|
|
28
|
-
|
|
29
|
-
const twelveMaxDimensionsMatch =
|
|
30
|
-
height === IPHONE_12_MAX_LONG_SIDE || width === IPHONE_12_MAX_LONG_SIDE;
|
|
31
|
-
|
|
32
|
-
const isIphoneX = OS === 'ios' && !isPad && !isTVOS && xDimensionsMatch;
|
|
33
|
-
// isIphoneXR also includes iPhone 12, iPhone 12 Pro, iPhone 12 Pro Max
|
|
34
|
-
const isIphoneXR =
|
|
35
|
-
OS === 'ios' &&
|
|
36
|
-
!isPad &&
|
|
37
|
-
!isTVOS &&
|
|
38
|
-
(xrDimensionsMatch || twelveDimensionsMatch || twelveMaxDimensionsMatch);
|
|
39
|
-
|
|
40
|
-
const isNotchedAndroid = OS === 'android' && DeviceInfo.hasNotch();
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Receives settings for different devices
|
|
44
|
-
* If the device is recognized, it returns only settings for that device
|
|
45
|
-
* If not, it returns settings for 'default'
|
|
46
|
-
*
|
|
47
|
-
* @param {object} settings The settings provided for
|
|
48
|
-
* @return {settings} Returns device specific (or 'default') settings
|
|
49
|
-
*/
|
|
50
|
-
|
|
51
|
-
function select(settings) {
|
|
52
|
-
if (settings.iPhoneX && isIphoneX) {
|
|
53
|
-
return settings.iPhoneX;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
if (settings.iPhoneXR && isIphoneXR) {
|
|
57
|
-
return settings.iPhoneXR;
|
|
58
|
-
}
|
|
7
|
+
export const isNotchedAndroid =
|
|
8
|
+
Platform.OS === 'android' && DeviceInfo.hasNotch();
|
|
59
9
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
export const NAVIGATION_BAR_HEIGHT = select({
|
|
68
|
-
iPhoneX: NAVIGATION_HEADER_HEIGHT + IPHONE_X_NOTCH_PADDING,
|
|
69
|
-
iPhoneXR: NAVIGATION_HEADER_HEIGHT + IPHONE_XR_NOTCH_PADDING,
|
|
70
|
-
notchedAndroid: NAVIGATION_HEADER_HEIGHT + StatusBar.currentHeight,
|
|
10
|
+
export const NAVIGATION_BAR_HEIGHT = Platform.select({
|
|
11
|
+
ios: NAVIGATION_HEADER_HEIGHT + initialWindowMetrics.insets.top,
|
|
12
|
+
android: isNotchedAndroid
|
|
13
|
+
? NAVIGATION_HEADER_HEIGHT + StatusBar.currentHeight
|
|
14
|
+
: NAVIGATION_HEADER_HEIGHT,
|
|
71
15
|
default: NAVIGATION_HEADER_HEIGHT,
|
|
72
16
|
});
|
|
73
17
|
|
|
74
|
-
export const
|
|
75
|
-
|
|
76
|
-
return 0;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// Apple identifier
|
|
80
|
-
const deviceId = DeviceInfo.getDeviceId();
|
|
81
|
-
|
|
82
|
-
// Extract the numbers from the deviceId string using a regular expression
|
|
83
|
-
const versions = deviceId.match(/(\d+),(\d+)/);
|
|
84
|
-
|
|
85
|
-
// Only checks if regex found X,Y, it does not resolve any of device ID-padding logic.
|
|
86
|
-
// If version is present, e.g. in iPhone 9,1, it'll always return array of length 3.
|
|
87
|
-
if (!versions && versions.length < 3) {
|
|
88
|
-
return 0;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
// Extracted numbers as strings
|
|
92
|
-
const majorVersion = versions[1];
|
|
93
|
-
const minorVersion = versions[2];
|
|
18
|
+
export const HOME_INDICATOR_PADDING =
|
|
19
|
+
Platform.OS === 'ios' ? HOME_INDICATOR_PADDING.insets.bottom : 0;
|
|
94
20
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
iPhoneSeGen2: 12.8,
|
|
101
|
-
iPhoneSeGen3: 14.6,
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
// Home indicator is present since iPhone X series with id of iPhone10,3.
|
|
105
|
-
// There are few newer models that do not have home indicator.
|
|
106
|
-
// They're included in excludedIphones object above.
|
|
107
|
-
if (
|
|
108
|
-
numericVersion >= 10.3 &&
|
|
109
|
-
!Object.values(excludedIphones).includes(numericVersion)
|
|
110
|
-
) {
|
|
111
|
-
// Devices with home indicator
|
|
112
|
-
return 34;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
// Devices without home indicator
|
|
116
|
-
return 0;
|
|
117
|
-
};
|
|
21
|
+
export const NOTCH_AREA_HEIGHT = Platform.select({
|
|
22
|
+
ios: initialWindowMetrics.insets.top,
|
|
23
|
+
android: isNotchedAndroid ? StatusBar.currentHeight : 0,
|
|
24
|
+
default: 0,
|
|
25
|
+
});
|
|
118
26
|
|
|
119
27
|
export const Device = {
|
|
120
|
-
isIphoneX,
|
|
121
|
-
isIphoneXR,
|
|
122
28
|
isNotchedAndroid,
|
|
123
|
-
|
|
29
|
+
HOME_INDICATOR_PADDING,
|
|
30
|
+
NOTCH_AREA_HEIGHT,
|
|
31
|
+
NAVIGATION_HEADER_HEIGHT,
|
|
124
32
|
};
|
package/helpers/index.js
CHANGED
|
@@ -1,13 +1,9 @@
|
|
|
1
1
|
export {
|
|
2
2
|
Device,
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
IPHONE_X_HOME_INDICATOR_PADDING,
|
|
6
|
-
IPHONE_X_LONG_SIDE,
|
|
7
|
-
IPHONE_X_NOTCH_PADDING,
|
|
8
|
-
IPHONE_XR_LONG_SIDE,
|
|
9
|
-
IPHONE_XR_NOTCH_PADDING,
|
|
3
|
+
HOME_INDICATOR_PADDING,
|
|
4
|
+
isNotchedAndroid,
|
|
10
5
|
NAVIGATION_BAR_HEIGHT,
|
|
11
6
|
NAVIGATION_HEADER_HEIGHT,
|
|
7
|
+
NOTCH_AREA_HEIGHT,
|
|
12
8
|
} from './device-selector';
|
|
13
9
|
export { calculateKeyboardOffset, default as Keyboard } from './keyboard';
|
package/helpers/keyboard.js
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import { Platform, StatusBar } from 'react-native';
|
|
2
|
-
import { NAVIGATION_BAR_HEIGHT } from './device-selector';
|
|
2
|
+
import { isNotchedAndroid, NAVIGATION_BAR_HEIGHT } from './device-selector';
|
|
3
3
|
|
|
4
4
|
export function calculateKeyboardOffset(extraOffset = 0) {
|
|
5
5
|
const resolvedOffset = NAVIGATION_BAR_HEIGHT + extraOffset;
|
|
6
6
|
|
|
7
|
-
if (Platform.OS === 'ios') {
|
|
7
|
+
if (Platform.OS === 'ios' || isNotchedAndroid) {
|
|
8
8
|
return resolvedOffset;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
if (Platform.OS === 'android' && !isNotchedAndroid) {
|
|
12
|
+
return StatusBar.currentHeight + resolvedOffset;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return resolvedOffset;
|
|
12
16
|
}
|
|
13
17
|
|
|
14
18
|
// TODO: Deprecate and remove Keyboard.calculateKeyboardOffset
|
package/index.js
CHANGED
|
@@ -50,8 +50,6 @@ export { LinearGradient } from './components/LinearGradient';
|
|
|
50
50
|
export { ListView } from './components/ListView';
|
|
51
51
|
export { LoadingContainer } from './components/LoadingContainer';
|
|
52
52
|
export { LoadingIndicator } from './components/LoadingIndicator';
|
|
53
|
-
export { NavigationBar } from './components/NavigationBar';
|
|
54
|
-
export { NavigationBarAnimations } from './components/NavigationBar/NavigationBarAnimations';
|
|
55
53
|
export { NumberInput } from './components/NumberInput';
|
|
56
54
|
export { Overlay } from './components/Overlay';
|
|
57
55
|
export { PageIndicators } from './components/PageIndicators';
|
|
@@ -83,12 +81,9 @@ export { SimpleHtml } from './html';
|
|
|
83
81
|
|
|
84
82
|
// Constants
|
|
85
83
|
export {
|
|
86
|
-
|
|
87
|
-
IPHONE_X_LONG_SIDE,
|
|
88
|
-
IPHONE_X_NOTCH_PADDING,
|
|
89
|
-
IPHONE_XR_LONG_SIDE,
|
|
90
|
-
IPHONE_XR_NOTCH_PADDING,
|
|
84
|
+
HOME_INDICATOR_PADDING,
|
|
91
85
|
NAVIGATION_BAR_HEIGHT,
|
|
92
86
|
NAVIGATION_HEADER_HEIGHT,
|
|
87
|
+
NOTCH_AREA_HEIGHT,
|
|
93
88
|
STATUS_BAR_OFFSET,
|
|
94
89
|
} from './const';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shoutem/ui",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.3.0-rc.0",
|
|
4
4
|
"description": "Styleable set of components for React Native applications",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"lint": "eslint .",
|
|
@@ -49,7 +49,8 @@
|
|
|
49
49
|
"peerDependencies": {
|
|
50
50
|
"react": ">=16.9.0",
|
|
51
51
|
"react-native": ">=0.61.5",
|
|
52
|
-
"react-native-gesture-handler": "*"
|
|
52
|
+
"react-native-gesture-handler": "*",
|
|
53
|
+
"react-native-safe-area-context": "*"
|
|
53
54
|
},
|
|
54
55
|
"devDependencies": {
|
|
55
56
|
"@babel/core": "7.16.7",
|
package/theme.js
CHANGED
|
@@ -7,16 +7,12 @@ import {
|
|
|
7
7
|
INCLUDE,
|
|
8
8
|
inverseColorBrightnessForAmount,
|
|
9
9
|
} from '@shoutem/theme';
|
|
10
|
-
import { getHomeIndicatorPadding } from './helpers/device-selector';
|
|
11
10
|
import {
|
|
12
|
-
|
|
13
|
-
IPHONE_XR_NOTCH_PADDING,
|
|
11
|
+
HOME_INDICATOR_PADDING,
|
|
14
12
|
NAVIGATION_BAR_HEIGHT,
|
|
15
|
-
NAVIGATION_HEADER_HEIGHT,
|
|
16
13
|
STATUS_BAR_OFFSET,
|
|
17
14
|
} from './const';
|
|
18
|
-
import {
|
|
19
|
-
import { isAndroid, isIos, resolveVariable } from './services';
|
|
15
|
+
import { isIos, resolveVariable } from './services';
|
|
20
16
|
|
|
21
17
|
const window = Dimensions.get('window');
|
|
22
18
|
|
|
@@ -869,7 +865,7 @@ export default () => {
|
|
|
869
865
|
[INCLUDE]: ['commonVariants', 'guttersPadding'],
|
|
870
866
|
|
|
871
867
|
'.with-home-indicator-padding': {
|
|
872
|
-
paddingBottom:
|
|
868
|
+
paddingBottom: HOME_INDICATOR_PADDING,
|
|
873
869
|
},
|
|
874
870
|
|
|
875
871
|
'.horizontal': {
|
|
@@ -974,16 +970,16 @@ export default () => {
|
|
|
974
970
|
// This was created with home indicator padding in mind. Use with-home-indicator-padding
|
|
975
971
|
// if you need bottom padding. For actual notch - top of the screen padding, use SafeAreaView component instead.
|
|
976
972
|
'.with-notch-padding': {
|
|
977
|
-
paddingBottom:
|
|
973
|
+
paddingBottom: HOME_INDICATOR_PADDING,
|
|
978
974
|
},
|
|
979
975
|
|
|
980
976
|
'.with-home-indicator-padding': {
|
|
981
|
-
paddingBottom:
|
|
977
|
+
paddingBottom: HOME_INDICATOR_PADDING,
|
|
982
978
|
},
|
|
983
979
|
|
|
984
980
|
'shoutem.ui.ListView': {
|
|
985
981
|
listContent: {
|
|
986
|
-
paddingBottom:
|
|
982
|
+
paddingBottom: HOME_INDICATOR_PADDING,
|
|
987
983
|
},
|
|
988
984
|
},
|
|
989
985
|
|
|
@@ -1537,332 +1533,6 @@ export default () => {
|
|
|
1537
1533
|
//
|
|
1538
1534
|
// Other
|
|
1539
1535
|
//
|
|
1540
|
-
// Deprecated on ShoutEm platform ( not used for navigationBar elements )
|
|
1541
|
-
navigationBar: {
|
|
1542
|
-
'.featured': {
|
|
1543
|
-
'shoutem.ui.Button': {
|
|
1544
|
-
'shoutem.ui.Icon': {
|
|
1545
|
-
color: resolveVariable('featuredNavBarIconsColor'),
|
|
1546
|
-
},
|
|
1547
|
-
'shoutem.ui.Text': {
|
|
1548
|
-
color: resolveVariable('featuredNavBarIconsColor'),
|
|
1549
|
-
},
|
|
1550
|
-
|
|
1551
|
-
'shoutem.ui.View': {
|
|
1552
|
-
'.badge': {
|
|
1553
|
-
backgroundColor: resolveVariable('featuredNavBarIconsColor'),
|
|
1554
|
-
borderColor: resolveVariable('featuredColor'),
|
|
1555
|
-
|
|
1556
|
-
'shoutem.ui.Text': {
|
|
1557
|
-
color: resolveVariable('featuredColor'),
|
|
1558
|
-
},
|
|
1559
|
-
},
|
|
1560
|
-
},
|
|
1561
|
-
},
|
|
1562
|
-
|
|
1563
|
-
'shoutem.ui.DropDownMenu': {
|
|
1564
|
-
selectedOption: {
|
|
1565
|
-
'shoutem.ui.Icon': {
|
|
1566
|
-
color: resolveVariable('featuredNavBarIconsColor'),
|
|
1567
|
-
},
|
|
1568
|
-
'shoutem.ui.Text': {
|
|
1569
|
-
color: resolveVariable('featuredNavBarIconsColor'),
|
|
1570
|
-
},
|
|
1571
|
-
},
|
|
1572
|
-
},
|
|
1573
|
-
|
|
1574
|
-
...createSharedStyle(
|
|
1575
|
-
['shoutem.ui.Title', 'shoutem.ui.Icon', 'shoutem.ui.Text'],
|
|
1576
|
-
{
|
|
1577
|
-
fontFamily: resolveFontFamily(
|
|
1578
|
-
resolveVariable('title.fontFamily'),
|
|
1579
|
-
resolveVariable('title.fontWeight'),
|
|
1580
|
-
resolveVariable('title.fontStyle'),
|
|
1581
|
-
),
|
|
1582
|
-
fontWeight: resolveFontWeight(resolveVariable('title.fontWeight')),
|
|
1583
|
-
fontStyle: resolveFontStyle(resolveVariable('title.fontStyle')),
|
|
1584
|
-
color: resolveVariable('featuredNavBarTitleColor'),
|
|
1585
|
-
},
|
|
1586
|
-
),
|
|
1587
|
-
|
|
1588
|
-
container: {
|
|
1589
|
-
[INCLUDE]: ['featuredBackground'],
|
|
1590
|
-
borderBottomWidth: 0,
|
|
1591
|
-
},
|
|
1592
|
-
},
|
|
1593
|
-
|
|
1594
|
-
'shoutem.ui.Icon': {
|
|
1595
|
-
color: resolveVariable('navBarIconsColor'),
|
|
1596
|
-
width: 24,
|
|
1597
|
-
height: 24,
|
|
1598
|
-
paddingHorizontal: 9,
|
|
1599
|
-
},
|
|
1600
|
-
|
|
1601
|
-
'shoutem.ui.Text': {
|
|
1602
|
-
...resolveVariable('navBarText'),
|
|
1603
|
-
fontFamily: resolveFontFamily(
|
|
1604
|
-
resolveVariable('navBarText.fontFamily'),
|
|
1605
|
-
resolveVariable('navBarText.fontWeight'),
|
|
1606
|
-
resolveVariable('navBarText.fontStyle'),
|
|
1607
|
-
),
|
|
1608
|
-
fontWeight: resolveFontWeight(resolveVariable('navBarText.fontWeight')),
|
|
1609
|
-
fontStyle: resolveFontStyle(resolveVariable('navBarText.fontStyle')),
|
|
1610
|
-
paddingHorizontal: 9,
|
|
1611
|
-
},
|
|
1612
|
-
|
|
1613
|
-
'shoutem.ui.ShareButton': {
|
|
1614
|
-
'.clear': {
|
|
1615
|
-
'shoutem.ui.Button': {
|
|
1616
|
-
[INCLUDE]: ['clearButton'],
|
|
1617
|
-
},
|
|
1618
|
-
},
|
|
1619
|
-
},
|
|
1620
|
-
|
|
1621
|
-
'shoutem.ui.Button': {
|
|
1622
|
-
[INCLUDE]: ['clearButton', 'tightButton'],
|
|
1623
|
-
'shoutem.ui.Icon': {
|
|
1624
|
-
color: resolveVariable('navBarIconsColor'),
|
|
1625
|
-
marginVertical: 9,
|
|
1626
|
-
},
|
|
1627
|
-
'shoutem.ui.Text': {
|
|
1628
|
-
...resolveVariable('navBarText'),
|
|
1629
|
-
fontFamily: resolveFontFamily(
|
|
1630
|
-
resolveVariable('navBarText.fontFamily'),
|
|
1631
|
-
'normal',
|
|
1632
|
-
resolveVariable('navBarText.fontStyle'),
|
|
1633
|
-
),
|
|
1634
|
-
fontWeight: resolveFontWeight('normal'),
|
|
1635
|
-
fontStyle: resolveFontStyle(resolveVariable('navBarText.fontStyle')),
|
|
1636
|
-
color: resolveVariable('navBarIconsColor'),
|
|
1637
|
-
letterSpacing: 0,
|
|
1638
|
-
},
|
|
1639
|
-
'shoutem.ui.View': {
|
|
1640
|
-
'.badge': {
|
|
1641
|
-
top: 5,
|
|
1642
|
-
right: 5,
|
|
1643
|
-
},
|
|
1644
|
-
},
|
|
1645
|
-
paddingHorizontal: 9,
|
|
1646
|
-
},
|
|
1647
|
-
},
|
|
1648
|
-
|
|
1649
|
-
'shoutem.ui.NavigationBar': {
|
|
1650
|
-
title: {
|
|
1651
|
-
color: resolveVariable('navBarText.color'),
|
|
1652
|
-
lineHeight: calculateLineHeight(resolveVariable('navBarText.fontSize')),
|
|
1653
|
-
...resolveVariable('navBarText'),
|
|
1654
|
-
fontFamily: resolveFontFamily(
|
|
1655
|
-
resolveVariable('navBarText.fontFamily'),
|
|
1656
|
-
resolveVariable('navBarText.fontWeight'),
|
|
1657
|
-
resolveVariable('navBarText.fontStyle'),
|
|
1658
|
-
),
|
|
1659
|
-
fontWeight: resolveFontWeight(resolveVariable('navBarText.fontWeight')),
|
|
1660
|
-
fontStyle: resolveFontStyle(resolveVariable('navBarText.fontStyle')),
|
|
1661
|
-
},
|
|
1662
|
-
icon: {
|
|
1663
|
-
color: resolveVariable('navBarIconsColor'),
|
|
1664
|
-
},
|
|
1665
|
-
statusBar: {
|
|
1666
|
-
backgroundColor: resolveVariable('statusBarColor'),
|
|
1667
|
-
statusBarStyle: resolveVariable('statusBarStyle'),
|
|
1668
|
-
},
|
|
1669
|
-
container: {
|
|
1670
|
-
backgroundColor: resolveVariable('navBarBackground'),
|
|
1671
|
-
borderBottomColor: resolveVariable('navBarBorderColor'),
|
|
1672
|
-
borderBottomWidth: StyleSheet.hairlineWidth,
|
|
1673
|
-
},
|
|
1674
|
-
leftContainer: {
|
|
1675
|
-
paddingLeft: resolveVariable('mediumGutter'),
|
|
1676
|
-
},
|
|
1677
|
-
rightContainer: {
|
|
1678
|
-
paddingRight: resolveVariable('mediumGutter'),
|
|
1679
|
-
},
|
|
1680
|
-
|
|
1681
|
-
'.clear': {
|
|
1682
|
-
container: {
|
|
1683
|
-
backgroundColor: 'transparent',
|
|
1684
|
-
borderBottomColor: 'transparent',
|
|
1685
|
-
},
|
|
1686
|
-
},
|
|
1687
|
-
|
|
1688
|
-
'.featured': {
|
|
1689
|
-
title: {
|
|
1690
|
-
color: resolveVariable('featuredNavBarTitleColor'),
|
|
1691
|
-
},
|
|
1692
|
-
icon: {
|
|
1693
|
-
color: resolveVariable('featuredNavBarIconsColor'),
|
|
1694
|
-
},
|
|
1695
|
-
|
|
1696
|
-
container: {
|
|
1697
|
-
backgroundColor: resolveVariable('featuredColor'),
|
|
1698
|
-
borderBottomWidth: 0,
|
|
1699
|
-
shadowOpacity: 0,
|
|
1700
|
-
},
|
|
1701
|
-
},
|
|
1702
|
-
|
|
1703
|
-
'.no-border': {
|
|
1704
|
-
container: {
|
|
1705
|
-
borderBottomWidth: 0,
|
|
1706
|
-
shadowOpacity: 0,
|
|
1707
|
-
},
|
|
1708
|
-
},
|
|
1709
|
-
|
|
1710
|
-
boxingAnimation(driver) {
|
|
1711
|
-
return {
|
|
1712
|
-
container: {
|
|
1713
|
-
borderBottomColor: driver.interpolate({
|
|
1714
|
-
// Animate to approx title top offset
|
|
1715
|
-
inputRange: [0, 45],
|
|
1716
|
-
outputRange: [
|
|
1717
|
-
'transparent',
|
|
1718
|
-
resolveVariable('navBarBorderColor'),
|
|
1719
|
-
],
|
|
1720
|
-
extrapolate: 'clamp',
|
|
1721
|
-
}),
|
|
1722
|
-
borderBottomWidth: 1,
|
|
1723
|
-
},
|
|
1724
|
-
title: {
|
|
1725
|
-
opacity: driver.interpolate({
|
|
1726
|
-
inputRange: [250, 300],
|
|
1727
|
-
outputRange: [0, 1],
|
|
1728
|
-
extrapolate: 'clamp',
|
|
1729
|
-
}),
|
|
1730
|
-
},
|
|
1731
|
-
};
|
|
1732
|
-
},
|
|
1733
|
-
|
|
1734
|
-
solidifyAnimation(driver) {
|
|
1735
|
-
return {
|
|
1736
|
-
icon: {
|
|
1737
|
-
opacity: driver.interpolate({
|
|
1738
|
-
inputRange: [250, 300],
|
|
1739
|
-
outputRange: [0, 1],
|
|
1740
|
-
extrapolate: 'clamp',
|
|
1741
|
-
}),
|
|
1742
|
-
},
|
|
1743
|
-
title: {
|
|
1744
|
-
color: driver.interpolate({
|
|
1745
|
-
inputRange: [250, 300],
|
|
1746
|
-
outputRange: ['transparent', resolveVariable('navBarText.color')],
|
|
1747
|
-
extrapolate: 'clamp',
|
|
1748
|
-
}),
|
|
1749
|
-
},
|
|
1750
|
-
container: {
|
|
1751
|
-
backgroundColor: driver.interpolate({
|
|
1752
|
-
inputRange: [250, 300],
|
|
1753
|
-
outputRange: ['transparent', resolveVariable('navBarBackground')],
|
|
1754
|
-
extrapolate: 'clamp',
|
|
1755
|
-
}),
|
|
1756
|
-
borderBottomColor: driver.interpolate({
|
|
1757
|
-
inputRange: [250, 300],
|
|
1758
|
-
outputRange: [
|
|
1759
|
-
'transparent',
|
|
1760
|
-
resolveVariable('navBarBorderColor'),
|
|
1761
|
-
],
|
|
1762
|
-
extrapolate: 'clamp',
|
|
1763
|
-
}),
|
|
1764
|
-
opacity: driver.interpolate({
|
|
1765
|
-
inputRange: [250, 300],
|
|
1766
|
-
outputRange: [0, 1],
|
|
1767
|
-
extrapolate: 'clamp',
|
|
1768
|
-
}),
|
|
1769
|
-
},
|
|
1770
|
-
};
|
|
1771
|
-
},
|
|
1772
|
-
|
|
1773
|
-
fadeAnimation(driver) {
|
|
1774
|
-
return {
|
|
1775
|
-
container: {
|
|
1776
|
-
gradient: {
|
|
1777
|
-
colors: ['transparent', 'rgba(0, 0, 0, 0.5)', 'transparent'],
|
|
1778
|
-
locations: [0.0, 0.25, 1.0],
|
|
1779
|
-
opacity: driver.interpolate({
|
|
1780
|
-
inputRange: [250, 300],
|
|
1781
|
-
outputRange: [1, 0],
|
|
1782
|
-
}),
|
|
1783
|
-
},
|
|
1784
|
-
},
|
|
1785
|
-
};
|
|
1786
|
-
},
|
|
1787
|
-
},
|
|
1788
|
-
|
|
1789
|
-
// Deprecated on ShoutEm platform ( not used for navigationBar elements )
|
|
1790
|
-
'shoutem.ui.navigation.NavigationBar': {
|
|
1791
|
-
[INCLUDE]: ['navigationBar'],
|
|
1792
|
-
|
|
1793
|
-
'.fade': {
|
|
1794
|
-
// Clear navigation bar is currently disabled on Android
|
|
1795
|
-
// due to overflow issues.
|
|
1796
|
-
gradient: {
|
|
1797
|
-
[INCLUDE]: ['fillParent'],
|
|
1798
|
-
colors: ['transparent', 'rgba(0, 0, 0, 0.15)', 'transparent'],
|
|
1799
|
-
locations: [0.0, 0.25, 1.0],
|
|
1800
|
-
solidifyAnimation(driver) {
|
|
1801
|
-
return {
|
|
1802
|
-
opacity: driver.interpolate({
|
|
1803
|
-
inputRange: [250, 300],
|
|
1804
|
-
outputRange: [1, 0],
|
|
1805
|
-
}),
|
|
1806
|
-
};
|
|
1807
|
-
},
|
|
1808
|
-
},
|
|
1809
|
-
},
|
|
1810
|
-
|
|
1811
|
-
container: {
|
|
1812
|
-
paddingTop: NAVIGATION_BAR_HEIGHT,
|
|
1813
|
-
backgroundColor: resolveVariable('navBarBackground'),
|
|
1814
|
-
borderBottomColor: resolveVariable('navBarBorderColor'),
|
|
1815
|
-
borderBottomWidth: StyleSheet.hairlineWidth,
|
|
1816
|
-
},
|
|
1817
|
-
navigationHeader: {
|
|
1818
|
-
position: 'absolute',
|
|
1819
|
-
top: Device.select({
|
|
1820
|
-
iPhoneX: 6,
|
|
1821
|
-
iPhoneXR: 8,
|
|
1822
|
-
default: isAndroid ? 0 : -4,
|
|
1823
|
-
}),
|
|
1824
|
-
left: 0,
|
|
1825
|
-
right: 0,
|
|
1826
|
-
height: NAVIGATION_BAR_HEIGHT,
|
|
1827
|
-
},
|
|
1828
|
-
statusBar: {
|
|
1829
|
-
backgroundColor: resolveVariable('statusBarColor'),
|
|
1830
|
-
statusBarStyle: resolveVariable('statusBarStyle'),
|
|
1831
|
-
height: Device.select({
|
|
1832
|
-
iPhoneX: IPHONE_X_NOTCH_PADDING,
|
|
1833
|
-
iPhoneXR: IPHONE_XR_NOTCH_PADDING,
|
|
1834
|
-
default: 0,
|
|
1835
|
-
}),
|
|
1836
|
-
},
|
|
1837
|
-
screenBackground: resolveVariable('backgroundColor'),
|
|
1838
|
-
navigationBarImage: {
|
|
1839
|
-
marginTop: Device.select({
|
|
1840
|
-
iPhoneX: IPHONE_X_NOTCH_PADDING,
|
|
1841
|
-
iPhoneXR: IPHONE_XR_NOTCH_PADDING,
|
|
1842
|
-
default: 0,
|
|
1843
|
-
}),
|
|
1844
|
-
flex: 1,
|
|
1845
|
-
flexGrow: 1,
|
|
1846
|
-
height: NAVIGATION_HEADER_HEIGHT,
|
|
1847
|
-
left: 0,
|
|
1848
|
-
solidifyAnimation(driver) {
|
|
1849
|
-
return {
|
|
1850
|
-
opacity: driver.interpolate({
|
|
1851
|
-
inputRange: [250, 300],
|
|
1852
|
-
outputRange: [0, 1],
|
|
1853
|
-
extrapolate: 'clamp',
|
|
1854
|
-
}),
|
|
1855
|
-
};
|
|
1856
|
-
},
|
|
1857
|
-
boxingAnimation() {
|
|
1858
|
-
return {};
|
|
1859
|
-
},
|
|
1860
|
-
position: 'absolute',
|
|
1861
|
-
right: 0,
|
|
1862
|
-
top: 0,
|
|
1863
|
-
width: window.width,
|
|
1864
|
-
},
|
|
1865
|
-
},
|
|
1866
1536
|
|
|
1867
1537
|
sectionHeaderDivider: {
|
|
1868
1538
|
'shoutem.ui.Caption': {
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
import React, { PureComponent } from 'react';
|
|
2
|
-
import { Animated, Platform, StatusBar, View } from 'react-native';
|
|
3
|
-
import _ from 'lodash';
|
|
4
|
-
import PropTypes from 'prop-types';
|
|
5
|
-
import color from 'tinycolor2';
|
|
6
|
-
import { connectAnimation } from '@shoutem/animation';
|
|
7
|
-
import { connectStyle } from '@shoutem/theme';
|
|
8
|
-
import { Device } from '../../helpers';
|
|
9
|
-
import composeChildren from './composeChildren';
|
|
10
|
-
|
|
11
|
-
function getBackgroundColor(style) {
|
|
12
|
-
const styleWithBg = _.find(
|
|
13
|
-
style,
|
|
14
|
-
styleDef =>
|
|
15
|
-
styleDef.backgroundColor && styleDef.backgroundColor !== 'transparent',
|
|
16
|
-
);
|
|
17
|
-
|
|
18
|
-
return (styleWithBg && styleWithBg.backgroundColor) || 'transparent';
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
// eslint-disable-next-line react/prefer-stateless-function
|
|
22
|
-
class NavigationBar extends PureComponent {
|
|
23
|
-
setStatusBarStyle(backgroundColor) {
|
|
24
|
-
function chooseBarStyle(bgColor) {
|
|
25
|
-
return color(bgColor).isDark() ? 'light-content' : 'default';
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function setStyle(bgColor) {
|
|
29
|
-
const statusBarColor = _.get(this.props, 'statusBarColor', bgColor);
|
|
30
|
-
|
|
31
|
-
const color = statusBarColor || bgColor;
|
|
32
|
-
|
|
33
|
-
if (Platform.OS === 'android') {
|
|
34
|
-
StatusBar.setBackgroundColor('rgba(0, 0, 0, 0.2)');
|
|
35
|
-
} else {
|
|
36
|
-
const barStyle = chooseBarStyle(color);
|
|
37
|
-
StatusBar.setBarStyle(barStyle);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// This is little bit hacky, but is the only way
|
|
42
|
-
// to determine the current value of interpolated Animated.Value
|
|
43
|
-
// Other way would be to ask developer to provide Animated.Value
|
|
44
|
-
// used to interpolate backgroundColor. But this way developer doesn't
|
|
45
|
-
// have to concern about status bar if he animates navigation bar color
|
|
46
|
-
if (backgroundColor && backgroundColor._parent instanceof Animated.Value) {
|
|
47
|
-
backgroundColor._parent.addListener(animation => {
|
|
48
|
-
setStyle(backgroundColor._interpolation(animation.value));
|
|
49
|
-
});
|
|
50
|
-
setStyle(backgroundColor._interpolation(0));
|
|
51
|
-
} else {
|
|
52
|
-
setStyle(backgroundColor);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
renderStatusBar() {
|
|
57
|
-
const { style } = this.props;
|
|
58
|
-
|
|
59
|
-
return Device.select({
|
|
60
|
-
iPhoneX: <View style={style.statusBar} />,
|
|
61
|
-
default: null,
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
render() {
|
|
66
|
-
const {
|
|
67
|
-
leftComponent,
|
|
68
|
-
rightComponent,
|
|
69
|
-
centerComponent,
|
|
70
|
-
style,
|
|
71
|
-
id,
|
|
72
|
-
} = this.props;
|
|
73
|
-
|
|
74
|
-
const backgroundColor = getBackgroundColor(style);
|
|
75
|
-
this.setStatusBarStyle(backgroundColor);
|
|
76
|
-
// Key must be set to render new screen NavigationBar
|
|
77
|
-
return (
|
|
78
|
-
<Animated.View style={style.container} key={id}>
|
|
79
|
-
{this.renderStatusBar()}
|
|
80
|
-
<View style={style.componentsContainer}>
|
|
81
|
-
<View style={style.leftComponent}>{leftComponent}</View>
|
|
82
|
-
<View style={style.centerComponent}>{centerComponent}</View>
|
|
83
|
-
<View style={style.rightComponent}>{rightComponent}</View>
|
|
84
|
-
</View>
|
|
85
|
-
</Animated.View>
|
|
86
|
-
);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
NavigationBar.propTypes = {
|
|
91
|
-
style: PropTypes.object.isRequired,
|
|
92
|
-
centerComponent: PropTypes.node,
|
|
93
|
-
id: PropTypes.string,
|
|
94
|
-
leftComponent: PropTypes.node,
|
|
95
|
-
rightComponent: PropTypes.node,
|
|
96
|
-
// eslint-disable-next-line react/no-unused-prop-types
|
|
97
|
-
statusBarColor: PropTypes.string,
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
NavigationBar.defaultProps = {
|
|
101
|
-
id: 'default',
|
|
102
|
-
leftComponent: undefined,
|
|
103
|
-
centerComponent: undefined,
|
|
104
|
-
rightComponent: undefined,
|
|
105
|
-
statusBarColor: undefined,
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
const AnimatedNavigationBar = connectAnimation(composeChildren(NavigationBar));
|
|
109
|
-
const StyledNavigationBar = connectStyle('shoutem.ui.NavigationBar')(
|
|
110
|
-
AnimatedNavigationBar,
|
|
111
|
-
);
|
|
112
|
-
|
|
113
|
-
export { StyledNavigationBar as NavigationBar };
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import _ from 'lodash';
|
|
2
|
-
|
|
3
|
-
class ColorAnimation {
|
|
4
|
-
constructor(options) {
|
|
5
|
-
_.assign(this, options);
|
|
6
|
-
if (!_.isFunction(this[this.preset])) {
|
|
7
|
-
throw new Error(`Color animation preset:(${options.preset})
|
|
8
|
-
you tried to create doesn't exist`);
|
|
9
|
-
}
|
|
10
|
-
this.animatedValue = this.driver.value;
|
|
11
|
-
this.style = {};
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
setColors(backgroundColor, textColor) {
|
|
15
|
-
this.backgroundColor = backgroundColor;
|
|
16
|
-
this.textColor = textColor;
|
|
17
|
-
|
|
18
|
-
this.style = this[this.preset](this.scrollOffset);
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
clearToStandard(atAnimatedValue) {
|
|
22
|
-
const defaultAnimatedValue = atAnimatedValue || 150;
|
|
23
|
-
const standardTextColor = this.textColor || 'rgba(0,0,0,1)';
|
|
24
|
-
const { animatedValue } = this;
|
|
25
|
-
return {
|
|
26
|
-
color: animatedValue.interpolate({
|
|
27
|
-
inputRange: [0, defaultAnimatedValue],
|
|
28
|
-
outputRange: ['rgba(0,0,0,0)', standardTextColor],
|
|
29
|
-
extrapolate: 'clamp',
|
|
30
|
-
}),
|
|
31
|
-
backgroundColor: animatedValue.interpolate({
|
|
32
|
-
inputRange: [0, defaultAnimatedValue],
|
|
33
|
-
outputRange: ['rgba(0,0,0,0)', 'rgba(255,255,255,1)'],
|
|
34
|
-
extrapolate: 'clamp',
|
|
35
|
-
}),
|
|
36
|
-
borderBottomColor: animatedValue.interpolate({
|
|
37
|
-
inputRange: [defaultAnimatedValue / 2, defaultAnimatedValue],
|
|
38
|
-
outputRange: ['rgba(0,0,0,0)', 'rgba(51, 51, 51, 0.2)'],
|
|
39
|
-
extrapolate: 'clamp',
|
|
40
|
-
}),
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export const NavigationBarAnimations = {
|
|
46
|
-
ColorAnimation,
|
|
47
|
-
};
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import React, { PureComponent } from 'react';
|
|
2
|
-
import _ from 'lodash';
|
|
3
|
-
import { Button } from '../Button';
|
|
4
|
-
import { Icon } from '../Icon';
|
|
5
|
-
import { ShareButton } from '../ShareButton';
|
|
6
|
-
import { Title } from '../Text';
|
|
7
|
-
|
|
8
|
-
const composers = {
|
|
9
|
-
title: (value, props) => ({
|
|
10
|
-
centerComponent: (
|
|
11
|
-
<Title animationName={props.animationName} numberOfLines={1}>
|
|
12
|
-
{value || ''}
|
|
13
|
-
</Title>
|
|
14
|
-
),
|
|
15
|
-
}),
|
|
16
|
-
share: (value, props) => {
|
|
17
|
-
if (!value.link) {
|
|
18
|
-
return null;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const { title, text, link } = value;
|
|
22
|
-
|
|
23
|
-
return {
|
|
24
|
-
rightComponent: (
|
|
25
|
-
<ShareButton
|
|
26
|
-
animationName={props.animationName}
|
|
27
|
-
title={title || props.title}
|
|
28
|
-
message={text}
|
|
29
|
-
url={link}
|
|
30
|
-
/>
|
|
31
|
-
),
|
|
32
|
-
};
|
|
33
|
-
},
|
|
34
|
-
hasHistory: (value, props) => {
|
|
35
|
-
const { navigateBack } = props;
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* onPress sets `event` as first param, which leads to ignoring default navigateBack
|
|
39
|
-
* first argument (navigator) so we have to wrap navigateBack into function to leave first
|
|
40
|
-
* argument empty, default
|
|
41
|
-
*/
|
|
42
|
-
function navigateBackWithoutEventParameter() {
|
|
43
|
-
navigateBack();
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
const leftComponent = value ? (
|
|
47
|
-
<Button styleName="clear" onPress={navigateBackWithoutEventParameter}>
|
|
48
|
-
<Icon name="back" animationName={props.animationName} />
|
|
49
|
-
</Button>
|
|
50
|
-
) : null;
|
|
51
|
-
|
|
52
|
-
return { leftComponent };
|
|
53
|
-
},
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* If source (usually state set by component) has undefined
|
|
58
|
-
* property values, ignore those properties.
|
|
59
|
-
* @param objValue
|
|
60
|
-
* @param srcValue
|
|
61
|
-
* @returns {*}
|
|
62
|
-
*/
|
|
63
|
-
function skipUndefined(objValue, srcValue) {
|
|
64
|
-
return _.isUndefined(srcValue) ? objValue : srcValue;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// eslint-disable-next-line react/prefer-stateless-function
|
|
68
|
-
const composeChildren = NavigationBarComponent =>
|
|
69
|
-
class extends PureComponent {
|
|
70
|
-
render() {
|
|
71
|
-
const newProps = {};
|
|
72
|
-
_.forEach(this.props, (value, key) => {
|
|
73
|
-
if (_.isFunction(composers[key])) {
|
|
74
|
-
_.assign(newProps, composers[key](value, this.props));
|
|
75
|
-
}
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
return (
|
|
79
|
-
<NavigationBarComponent
|
|
80
|
-
{..._.assignWith(newProps, this.props, skipUndefined)}
|
|
81
|
-
/>
|
|
82
|
-
);
|
|
83
|
-
}
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
export default composeChildren;
|