@shoutem/ui 5.2.2 → 5.4.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/__tests__/View-test.js +55 -0
- package/__tests__/__snapshots__/View-test.js.snap +15 -0
- package/components/Button.js +2 -2
- package/components/EmptyListImage.js +0 -1
- package/components/GridRow.js +2 -2
- package/components/Icon/assets/delete.svg +3 -0
- package/components/Icon/assets/index.js +5 -3
- package/components/Image.js +2 -1
- package/components/ImagePreview.js +0 -3
- package/components/Lightbox.js +1 -1
- package/components/ScrollView/ScrollView.js +8 -6
- package/components/Text.js +2 -1
- package/components/TextInput.js +5 -2
- package/components/Touchable.js +3 -3
- package/components/TouchableNativeFeedback.js +2 -2
- package/components/TouchableOpacity.js +2 -2
- package/components/View.js +5 -7
- package/const.js +21 -13
- package/helpers/device-selector.js +20 -7
- package/helpers/index.js +13 -4
- package/helpers/keyboard.js +5 -1
- package/index.js +14 -11
- package/package.json +31 -19
- package/theme.js +48 -41
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import renderer from 'react-test-renderer';
|
|
3
|
+
import { View } from '../components/View';
|
|
4
|
+
|
|
5
|
+
test('View renders correctly', () => {
|
|
6
|
+
const tree = renderer.create(
|
|
7
|
+
<View style={{ height: 40, width: 40, backgroundColor: 'red' }} />,
|
|
8
|
+
).toJSON();
|
|
9
|
+
|
|
10
|
+
expect(tree).toMatchSnapshot();
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
test('View renders children vertically with vertical styleName', () => {
|
|
14
|
+
const tree = renderer.create(
|
|
15
|
+
<View styleName="vertical">
|
|
16
|
+
<View style={{ height: 40, width: 40, backgroundColor: 'red' }} />
|
|
17
|
+
<View style={{ height: 40, width: 40, backgroundColor: 'green' }} />
|
|
18
|
+
</View>
|
|
19
|
+
);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
test('View centers children horizontally with h-center styleName', () => {
|
|
23
|
+
const tree = renderer.create(
|
|
24
|
+
<View style={{ width: 100 }} styleName="vertical h-center">
|
|
25
|
+
<View style={{ height: 40, width: 40, backgroundColor: 'red' }} />
|
|
26
|
+
<View style={{ height: 40, width: 40, backgroundColor: 'green' }} />
|
|
27
|
+
</View>
|
|
28
|
+
);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
test('View renders children horizontally with horizontal styleName', () => {
|
|
32
|
+
const tree = renderer.create(
|
|
33
|
+
<View styleName="horizontal">
|
|
34
|
+
<View style={{ height: 40, width: 40, backgroundColor: 'red' }} />
|
|
35
|
+
<View style={{ height: 40, width: 40, backgroundColor: 'green' }} />
|
|
36
|
+
</View>
|
|
37
|
+
);
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
test('View centers children vertically with v-center styleName', () => {
|
|
41
|
+
const tree = renderer.create(
|
|
42
|
+
<View style={{ height: 100 }} styleName="horizontal v-center">
|
|
43
|
+
<View style={{ height: 40, width: 40, backgroundColor: 'red' }} />
|
|
44
|
+
<View style={{ height: 40, width: 40, backgroundColor: 'green' }} />
|
|
45
|
+
</View>
|
|
46
|
+
);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
test('View fills parent with fill-parent styleName', () => {
|
|
50
|
+
const tree = renderer.create(
|
|
51
|
+
<View style={{ height: 40, width: 40 }}>
|
|
52
|
+
<View style={{ backgroundColor: 'red' }} styleName="fill-parent" />
|
|
53
|
+
</View>
|
|
54
|
+
);
|
|
55
|
+
});
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`View renders correctly 1`] = `
|
|
4
|
+
<View
|
|
5
|
+
animationOptions={Object {}}
|
|
6
|
+
onLayout={[Function]}
|
|
7
|
+
style={
|
|
8
|
+
Object {
|
|
9
|
+
"backgroundColor": "red",
|
|
10
|
+
"height": 40,
|
|
11
|
+
"width": 40,
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
/>
|
|
15
|
+
`;
|
package/components/Button.js
CHANGED
|
@@ -5,12 +5,12 @@ import { connectStyle } from '@shoutem/theme';
|
|
|
5
5
|
|
|
6
6
|
class Button extends PureComponent {
|
|
7
7
|
render() {
|
|
8
|
-
const { style
|
|
8
|
+
const { style } = this.props;
|
|
9
9
|
const { underlayColor, ...otherStyle } = style;
|
|
10
10
|
|
|
11
11
|
return (
|
|
12
12
|
<TouchableOpacity
|
|
13
|
-
{...
|
|
13
|
+
{...this.props}
|
|
14
14
|
style={otherStyle}
|
|
15
15
|
underlayColor={underlayColor}
|
|
16
16
|
/>
|
package/components/GridRow.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React, { Children, PureComponent } from 'react';
|
|
2
|
-
import { View as RNView
|
|
2
|
+
import { View as RNView } from 'react-native';
|
|
3
3
|
import _ from 'lodash';
|
|
4
4
|
import PropTypes from 'prop-types';
|
|
5
5
|
import { connectAnimation } from '@shoutem/animation';
|
|
@@ -35,7 +35,7 @@ class GridRow extends PureComponent {
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
GridRow.propTypes = {
|
|
38
|
-
...
|
|
38
|
+
...View.propTypes,
|
|
39
39
|
columns: PropTypes.number.isRequired,
|
|
40
40
|
};
|
|
41
41
|
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.82322 3.82322C9.87011 3.77634 9.9337 3.75 10 3.75H14C14.0663 3.75 14.1299 3.77634 14.1768 3.82322C14.2237 3.87011 14.25 3.9337 14.25 4V6.25H9.75V4C9.75 3.9337 9.77634 3.87011 9.82322 3.82322ZM8.25 6.25V4C8.25 3.53587 8.43437 3.09075 8.76256 2.76256C9.09075 2.43437 9.53587 2.25 10 2.25H14C14.4641 2.25 14.9092 2.43437 15.2374 2.76256C15.5656 3.09075 15.75 3.53587 15.75 4V6.25H18.9912H19.0071H20C20.4142 6.25 20.75 6.58579 20.75 7C20.75 7.41421 20.4142 7.75 20 7.75H19.6901L18.7498 19.0337C18.741 19.7508 18.4523 20.4368 17.9445 20.9445C17.4288 21.4603 16.7293 21.75 16 21.75H8C7.27065 21.75 6.57118 21.4603 6.05546 20.9445C5.54767 20.4368 5.25898 19.7508 5.25021 19.0337L4.3099 7.75H4C3.58579 7.75 3.25 7.41421 3.25 7C3.25 6.58579 3.58579 6.25 4 6.25H4.9929H5.00877H8.25ZM15 7.75H9H5.8151L6.74741 18.9377C6.74914 18.9584 6.75 18.9792 6.75 19C6.75 19.3315 6.8817 19.6495 7.11612 19.8839C7.35054 20.1183 7.66848 20.25 8 20.25H16C16.3315 20.25 16.6495 20.1183 16.8839 19.8839C17.1183 19.6495 17.25 19.3315 17.25 19C17.25 18.9792 17.2509 18.9584 17.2526 18.9377L18.1849 7.75H15ZM10 10.25C10.4142 10.25 10.75 10.5858 10.75 11V17C10.75 17.4142 10.4142 17.75 10 17.75C9.58579 17.75 9.25 17.4142 9.25 17V11C9.25 10.5858 9.58579 10.25 10 10.25ZM14.75 11C14.75 10.5858 14.4142 10.25 14 10.25C13.5858 10.25 13.25 10.5858 13.25 11V17C13.25 17.4142 13.5858 17.75 14 17.75C14.4142 17.75 14.75 17.4142 14.75 17V11Z" fill="black"/>
|
|
3
|
+
</svg>
|
|
@@ -23,6 +23,7 @@ import close from './close.svg';
|
|
|
23
23
|
import comment from './comment.svg';
|
|
24
24
|
import comments from './comments.svg';
|
|
25
25
|
import deals from './deals.svg';
|
|
26
|
+
import deleteIcon from './delete.svg';
|
|
26
27
|
import directions from './directions.svg';
|
|
27
28
|
import downArrow from './down-arrow.svg';
|
|
28
29
|
import download from './download.svg';
|
|
@@ -38,10 +39,10 @@ import eyeCrossed from './eye-crossed.svg';
|
|
|
38
39
|
import facebook from './facebook.svg';
|
|
39
40
|
import facebookLogo from './facebook-logo.svg';
|
|
40
41
|
import folder from './folder.svg';
|
|
42
|
+
import forward from './forward.svg';
|
|
41
43
|
import forward5 from './forward-5.svg';
|
|
42
44
|
import forward10 from './forward-10.svg';
|
|
43
45
|
import forward30 from './forward-30.svg';
|
|
44
|
-
import forward from './forward.svg';
|
|
45
46
|
import friends from './friends.svg';
|
|
46
47
|
import gallery from './gallery.svg';
|
|
47
48
|
import garbageCan from './garbage-can.svg';
|
|
@@ -83,10 +84,10 @@ import radiobuttonOff from './radiobutton-off.svg';
|
|
|
83
84
|
import radiobuttonOn from './radiobutton-on.svg';
|
|
84
85
|
import receipt from './receipt.svg';
|
|
85
86
|
import refresh from './refresh.svg';
|
|
87
|
+
import replay from './replay.svg';
|
|
86
88
|
import replay5 from './replay-5.svg';
|
|
87
89
|
import replay10 from './replay-10.svg';
|
|
88
90
|
import replay30 from './replay-30.svg';
|
|
89
|
-
import replay from './replay.svg';
|
|
90
91
|
import restaurant from './restaurant.svg';
|
|
91
92
|
import restaurantMenu from './restaurant-menu.svg';
|
|
92
93
|
import restore from './restore.svg';
|
|
@@ -97,8 +98,8 @@ import search from './search.svg';
|
|
|
97
98
|
import settings from './settings.svg';
|
|
98
99
|
import share from './share.svg';
|
|
99
100
|
import shareAndroid from './share-android.svg';
|
|
100
|
-
import sleep from './sleep.svg';
|
|
101
101
|
import sidebar from './sidebar.svg';
|
|
102
|
+
import sleep from './sleep.svg';
|
|
102
103
|
import socialWall from './social-wall.svg';
|
|
103
104
|
import stamp from './stamp.svg';
|
|
104
105
|
import stop from './stop.svg';
|
|
@@ -142,6 +143,7 @@ export const defaultConfig = [
|
|
|
142
143
|
{ name: 'comment', icon: comment },
|
|
143
144
|
{ name: 'comments', icon: comments },
|
|
144
145
|
{ name: 'deals', icon: deals },
|
|
146
|
+
{ name: 'delete', icon: deleteIcon },
|
|
145
147
|
{ name: 'directions', icon: directions },
|
|
146
148
|
{ name: 'down-arrow', icon: downArrow },
|
|
147
149
|
{ name: 'download', icon: download },
|
package/components/Image.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React, { PureComponent } from 'react';
|
|
2
2
|
import { Image as RNImage, Platform } from 'react-native';
|
|
3
3
|
import autoBindReact from 'auto-bind/react';
|
|
4
|
+
import { ImagePropTypes } from 'deprecated-react-native-prop-types';
|
|
4
5
|
import _ from 'lodash';
|
|
5
6
|
import { connectAnimation } from '@shoutem/animation';
|
|
6
7
|
import { connectStyle } from '@shoutem/theme';
|
|
@@ -82,7 +83,7 @@ class Image extends PureComponent {
|
|
|
82
83
|
}
|
|
83
84
|
|
|
84
85
|
Image.propTypes = {
|
|
85
|
-
...
|
|
86
|
+
...ImagePropTypes,
|
|
86
87
|
};
|
|
87
88
|
|
|
88
89
|
const AnimatedImage = connectAnimation(Image);
|
|
@@ -8,9 +8,6 @@ import Icon from './Icon/Icon';
|
|
|
8
8
|
|
|
9
9
|
const ZoomableImage = makeZoomable(Image);
|
|
10
10
|
|
|
11
|
-
const CLOSE_ICON_NAME = 'clear';
|
|
12
|
-
const CLOSE_ICON_SIZE = 25;
|
|
13
|
-
|
|
14
11
|
/**
|
|
15
12
|
* Renders an ImagePreview which shows an inline image preview.
|
|
16
13
|
* When clicked, the image is displayed in full screen.
|
package/components/Lightbox.js
CHANGED
|
@@ -64,16 +64,18 @@ class ScrollView extends PureComponent {
|
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
addIphoneXPadding(style) {
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
const resolvedStyle = { ...style };
|
|
68
|
+
|
|
69
|
+
if (typeof resolvedStyle.paddingBottom !== 'number') {
|
|
70
|
+
resolvedStyle.paddingBottom = 0;
|
|
69
71
|
}
|
|
70
72
|
|
|
71
|
-
|
|
72
|
-
iPhoneX:
|
|
73
|
-
default:
|
|
73
|
+
resolvedStyle.paddingBottom = Device.select({
|
|
74
|
+
iPhoneX: resolvedStyle.paddingBottom + IPHONE_X_HOME_INDICATOR_PADDING,
|
|
75
|
+
default: resolvedStyle.paddingBottom,
|
|
74
76
|
});
|
|
75
77
|
|
|
76
|
-
return
|
|
78
|
+
return resolvedStyle;
|
|
77
79
|
}
|
|
78
80
|
|
|
79
81
|
render() {
|
package/components/Text.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React, { PureComponent } from 'react';
|
|
2
2
|
import { Text as RNText } from 'react-native';
|
|
3
|
+
import { TextPropTypes } from 'deprecated-react-native-prop-types';
|
|
3
4
|
import { connectAnimation } from '@shoutem/animation';
|
|
4
5
|
import { connectStyle } from '@shoutem/theme';
|
|
5
6
|
|
|
@@ -10,7 +11,7 @@ class Text extends PureComponent {
|
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
Text.propTypes = {
|
|
13
|
-
...
|
|
14
|
+
...TextPropTypes,
|
|
14
15
|
};
|
|
15
16
|
|
|
16
17
|
const AnimatedText = connectAnimation(Text);
|
package/components/TextInput.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React, { PureComponent } from 'react';
|
|
2
2
|
import { TextInput as RNTextInput } from 'react-native';
|
|
3
3
|
import autoBindReact from 'auto-bind/react';
|
|
4
|
+
import { TextInputPropTypes } from 'deprecated-react-native-prop-types';
|
|
4
5
|
import PropTypes from 'prop-types';
|
|
5
6
|
import { connectAnimation, Wiggle } from '@shoutem/animation';
|
|
6
7
|
import { connectStyle } from '@shoutem/theme';
|
|
@@ -81,7 +82,9 @@ class TextInput extends PureComponent {
|
|
|
81
82
|
/>
|
|
82
83
|
</Wiggle>
|
|
83
84
|
{!!errorMessage && (
|
|
84
|
-
<Caption styleName="form-error sm-gutter-top" style={errorText}>
|
|
85
|
+
<Caption styleName="form-error sm-gutter-top" style={errorText}>
|
|
86
|
+
{errorMessage}
|
|
87
|
+
</Caption>
|
|
85
88
|
)}
|
|
86
89
|
</View>
|
|
87
90
|
);
|
|
@@ -89,7 +92,7 @@ class TextInput extends PureComponent {
|
|
|
89
92
|
}
|
|
90
93
|
|
|
91
94
|
TextInput.propTypes = {
|
|
92
|
-
...
|
|
95
|
+
...TextInputPropTypes,
|
|
93
96
|
style: PropTypes.object.isRequired,
|
|
94
97
|
animate: PropTypes.bool,
|
|
95
98
|
errorMessage: PropTypes.string,
|
package/components/Touchable.js
CHANGED
|
@@ -13,13 +13,13 @@ import { View } from './View';
|
|
|
13
13
|
*/
|
|
14
14
|
class Touchable extends PureComponent {
|
|
15
15
|
render() {
|
|
16
|
-
const { children, style, styleName
|
|
16
|
+
const { children, style, styleName } = this.props;
|
|
17
17
|
const { touchableNativeFeedback, touchableOpacity, ...otherStyle } = style;
|
|
18
18
|
|
|
19
19
|
if (Platform.OS === 'android') {
|
|
20
20
|
return (
|
|
21
21
|
<TouchableNativeFeedback
|
|
22
|
-
{...
|
|
22
|
+
{...this.props}
|
|
23
23
|
style={touchableNativeFeedback}
|
|
24
24
|
>
|
|
25
25
|
<View virtual style={otherStyle} styleName={styleName}>
|
|
@@ -31,7 +31,7 @@ class Touchable extends PureComponent {
|
|
|
31
31
|
|
|
32
32
|
return (
|
|
33
33
|
<TouchableOpacity
|
|
34
|
-
{...
|
|
34
|
+
{...this.props}
|
|
35
35
|
style={{
|
|
36
36
|
...otherStyle,
|
|
37
37
|
...touchableOpacity,
|
|
@@ -5,12 +5,12 @@ import { connectStyle } from '@shoutem/theme';
|
|
|
5
5
|
|
|
6
6
|
class TouchableNativeFeedback extends PureComponent {
|
|
7
7
|
render() {
|
|
8
|
-
const { children, style
|
|
8
|
+
const { children, style } = this.props;
|
|
9
9
|
const { background, useForeground, ...otherStyle } = style;
|
|
10
10
|
|
|
11
11
|
return (
|
|
12
12
|
<RNTouchableNativeFeedback
|
|
13
|
-
{...
|
|
13
|
+
{...this.props}
|
|
14
14
|
style={otherStyle}
|
|
15
15
|
background={background}
|
|
16
16
|
useForeground={useForeground}
|
|
@@ -4,12 +4,12 @@ import { connectStyle } from '@shoutem/theme';
|
|
|
4
4
|
|
|
5
5
|
class TouchableOpacity extends PureComponent {
|
|
6
6
|
render() {
|
|
7
|
-
const { children, style
|
|
7
|
+
const { children, style } = this.props;
|
|
8
8
|
const { activeOpacity, ...otherStyle } = style;
|
|
9
9
|
|
|
10
10
|
return (
|
|
11
11
|
<RNTouchableOpacity
|
|
12
|
-
{...
|
|
12
|
+
{...this.props}
|
|
13
13
|
style={otherStyle}
|
|
14
14
|
activeOpacity={activeOpacity}
|
|
15
15
|
>
|
package/components/View.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React, { PureComponent } from 'react';
|
|
2
|
-
import { View as RNView
|
|
2
|
+
import { View as RNView } from 'react-native';
|
|
3
|
+
import { ViewPropTypes } from 'deprecated-react-native-prop-types';
|
|
3
4
|
import PropTypes from 'prop-types';
|
|
4
5
|
import { connectAnimation } from '@shoutem/animation';
|
|
5
6
|
import { connectStyle } from '@shoutem/theme';
|
|
@@ -7,21 +8,18 @@ import { LinearGradient } from './LinearGradient';
|
|
|
7
8
|
|
|
8
9
|
class View extends PureComponent {
|
|
9
10
|
render() {
|
|
10
|
-
const { children, style
|
|
11
|
+
const { children, style } = this.props;
|
|
11
12
|
const { backgroundGradient, ...viewStyle } = style;
|
|
12
13
|
|
|
13
14
|
let gradient = null;
|
|
14
15
|
if (backgroundGradient) {
|
|
15
16
|
gradient = (
|
|
16
|
-
<LinearGradient
|
|
17
|
-
styleName="fill-parent"
|
|
18
|
-
style={style.backgroundGradient}
|
|
19
|
-
/>
|
|
17
|
+
<LinearGradient styleName="fill-parent" style={backgroundGradient} />
|
|
20
18
|
);
|
|
21
19
|
}
|
|
22
20
|
|
|
23
21
|
return (
|
|
24
|
-
<RNView {...
|
|
22
|
+
<RNView {...this.props} style={viewStyle}>
|
|
25
23
|
{gradient}
|
|
26
24
|
{children}
|
|
27
25
|
</RNView>
|
package/const.js
CHANGED
|
@@ -1,22 +1,30 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const IPHONE_XR_LONG_SIDE = 896;
|
|
6
|
-
const IPHONE_XR_NOTCH_PADDING = 34;
|
|
7
|
-
|
|
8
|
-
const IPHONE_12_LONG_SIDE = 844;
|
|
9
|
-
const IPHONE_12_MAX_LONG_SIDE = 926;
|
|
10
|
-
|
|
11
|
-
const NAVIGATION_HEADER_HEIGHT = 64;
|
|
12
|
-
|
|
13
|
-
module.exports = {
|
|
1
|
+
import { Platform, StatusBar } from 'react-native';
|
|
2
|
+
import {
|
|
3
|
+
IPHONE_12_LONG_SIDE,
|
|
4
|
+
IPHONE_12_MAX_LONG_SIDE,
|
|
14
5
|
IPHONE_X_HOME_INDICATOR_PADDING,
|
|
15
6
|
IPHONE_X_LONG_SIDE,
|
|
16
7
|
IPHONE_X_NOTCH_PADDING,
|
|
17
8
|
IPHONE_XR_LONG_SIDE,
|
|
18
9
|
IPHONE_XR_NOTCH_PADDING,
|
|
10
|
+
NAVIGATION_BAR_HEIGHT,
|
|
11
|
+
NAVIGATION_HEADER_HEIGHT,
|
|
12
|
+
} from './helpers';
|
|
13
|
+
|
|
14
|
+
const STATUS_BAR_OFFSET =
|
|
15
|
+
Platform.OS === 'android' ? -StatusBar.currentHeight : 0;
|
|
16
|
+
|
|
17
|
+
// TODO: Deprecate and remove exports from here
|
|
18
|
+
// Currently leaving for backwards compatibility
|
|
19
|
+
export {
|
|
19
20
|
IPHONE_12_LONG_SIDE,
|
|
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,
|
|
27
|
+
NAVIGATION_BAR_HEIGHT,
|
|
21
28
|
NAVIGATION_HEADER_HEIGHT,
|
|
29
|
+
STATUS_BAR_OFFSET,
|
|
22
30
|
};
|
|
@@ -1,16 +1,22 @@
|
|
|
1
|
-
import { Dimensions, Platform } from 'react-native';
|
|
1
|
+
import { Dimensions, Platform, StatusBar } from 'react-native';
|
|
2
2
|
import { hasNotch } from 'react-native-device-info';
|
|
3
3
|
import _ from 'lodash';
|
|
4
|
-
import {
|
|
5
|
-
IPHONE_12_LONG_SIDE,
|
|
6
|
-
IPHONE_12_MAX_LONG_SIDE,
|
|
7
|
-
IPHONE_X_LONG_SIDE,
|
|
8
|
-
IPHONE_XR_LONG_SIDE,
|
|
9
|
-
} from '../const';
|
|
10
4
|
|
|
11
5
|
const { OS, isPad, isTVOS } = Platform;
|
|
12
6
|
const { width, height } = Dimensions.get('window');
|
|
13
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;
|
|
17
|
+
|
|
18
|
+
export const NAVIGATION_HEADER_HEIGHT = 64;
|
|
19
|
+
|
|
14
20
|
const xDimensionsMatch =
|
|
15
21
|
height === IPHONE_X_LONG_SIDE || width === IPHONE_X_LONG_SIDE;
|
|
16
22
|
|
|
@@ -58,6 +64,13 @@ function select(settings) {
|
|
|
58
64
|
return _.get(settings, 'default');
|
|
59
65
|
}
|
|
60
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,
|
|
71
|
+
default: NAVIGATION_HEADER_HEIGHT,
|
|
72
|
+
});
|
|
73
|
+
|
|
61
74
|
export const Device = {
|
|
62
75
|
isIphoneX,
|
|
63
76
|
isIphoneXR,
|
package/helpers/index.js
CHANGED
|
@@ -1,4 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
export {
|
|
2
|
+
Device,
|
|
3
|
+
IPHONE_12_LONG_SIDE,
|
|
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,
|
|
10
|
+
NAVIGATION_BAR_HEIGHT,
|
|
11
|
+
NAVIGATION_HEADER_HEIGHT,
|
|
12
|
+
} from './device-selector';
|
|
13
|
+
export { calculateKeyboardOffset, default as Keyboard } from './keyboard';
|
package/helpers/keyboard.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Platform, StatusBar } from 'react-native';
|
|
2
|
-
import { NAVIGATION_BAR_HEIGHT } from '
|
|
2
|
+
import { NAVIGATION_BAR_HEIGHT } from './device-selector';
|
|
3
3
|
|
|
4
4
|
export function calculateKeyboardOffset(extraOffset = 0) {
|
|
5
5
|
const resolvedOffset = NAVIGATION_BAR_HEIGHT + extraOffset;
|
|
@@ -11,4 +11,8 @@ export function calculateKeyboardOffset(extraOffset = 0) {
|
|
|
11
11
|
return StatusBar.currentHeight + resolvedOffset;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
+
// TODO: Deprecate and remove Keyboard.calculateKeyboardOffset
|
|
15
|
+
// Replace with direct function call. It's cleaner for any practical use of this
|
|
16
|
+
// because we will usually import Keyboard from react-native alongside this, so
|
|
17
|
+
// we're forced to rename imports.
|
|
14
18
|
export default { calculateKeyboardOffset };
|
package/index.js
CHANGED
|
@@ -1,12 +1,4 @@
|
|
|
1
1
|
import { setDefaultThemeStyle } from './init';
|
|
2
|
-
import getTheme, {
|
|
3
|
-
calculateLineHeight,
|
|
4
|
-
defaultThemeVariables,
|
|
5
|
-
dimensionRelativeToIphone,
|
|
6
|
-
resolveFontFamily,
|
|
7
|
-
resolveFontStyle,
|
|
8
|
-
resolveFontWeight,
|
|
9
|
-
} from './theme';
|
|
10
2
|
|
|
11
3
|
setDefaultThemeStyle();
|
|
12
4
|
|
|
@@ -15,12 +7,15 @@ export {
|
|
|
15
7
|
calculateLineHeight,
|
|
16
8
|
defaultThemeVariables,
|
|
17
9
|
dimensionRelativeToIphone,
|
|
18
|
-
getTheme,
|
|
10
|
+
default as getTheme,
|
|
19
11
|
resolveFontFamily,
|
|
20
12
|
resolveFontStyle,
|
|
21
13
|
resolveFontWeight,
|
|
22
|
-
|
|
14
|
+
responsiveHeight,
|
|
15
|
+
responsiveWidth,
|
|
16
|
+
} from './theme';
|
|
23
17
|
|
|
18
|
+
// Services
|
|
24
19
|
export {
|
|
25
20
|
createScopedResolver,
|
|
26
21
|
resolveVariable,
|
|
@@ -76,8 +71,14 @@ export { TouchableOpacity } from './components/TouchableOpacity';
|
|
|
76
71
|
export { Video } from './components/Video';
|
|
77
72
|
export { View } from './components/View';
|
|
78
73
|
export { YearRangePicker } from './components/YearRangePicker';
|
|
74
|
+
|
|
75
|
+
// Examples
|
|
79
76
|
export { Examples } from './examples/components';
|
|
80
|
-
|
|
77
|
+
|
|
78
|
+
// Helpers
|
|
79
|
+
export { calculateKeyboardOffset, Device, Keyboard } from './helpers';
|
|
80
|
+
|
|
81
|
+
// HTML
|
|
81
82
|
export { Html } from './html';
|
|
82
83
|
export { SimpleHtml } from './html';
|
|
83
84
|
|
|
@@ -89,5 +90,7 @@ export {
|
|
|
89
90
|
IPHONE_XR_LONG_SIDE,
|
|
90
91
|
IPHONE_XR_NOTCH_PADDING,
|
|
91
92
|
nativeDependencies,
|
|
93
|
+
NAVIGATION_BAR_HEIGHT,
|
|
92
94
|
NAVIGATION_HEADER_HEIGHT,
|
|
95
|
+
STATUS_BAR_OFFSET,
|
|
93
96
|
} from './const';
|
package/package.json
CHANGED
|
@@ -1,46 +1,48 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shoutem/ui",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.4.0",
|
|
4
4
|
"description": "Styleable set of components for React Native applications",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"lint": "eslint .",
|
|
7
7
|
"lint-fix": "eslint . --fix",
|
|
8
8
|
"postinstall": "node ./scripts/add-native-deps",
|
|
9
|
-
"test": "
|
|
9
|
+
"test": "jest"
|
|
10
10
|
},
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"@react-native-community/datetimepicker": "
|
|
12
|
+
"@react-native-community/datetimepicker": "6.2.0",
|
|
13
13
|
"@shoutem/animation": "~0.15.0",
|
|
14
14
|
"@shoutem/eslint-config-react": "~1.0.6",
|
|
15
15
|
"@shoutem/theme": "~0.13.0",
|
|
16
16
|
"auto-bind": "4.0.0",
|
|
17
17
|
"babel-plugin-transform-decorators-legacy": "1.3.5",
|
|
18
18
|
"buffer": "5.6.0",
|
|
19
|
+
"deprecated-react-native-prop-types": "2.3.0",
|
|
19
20
|
"events": "1.1.0",
|
|
20
21
|
"fs-extra": "7.0.1",
|
|
21
22
|
"html-entities": "1.3.1",
|
|
22
23
|
"htmlparser2": "3.10.1",
|
|
23
24
|
"lodash": "4.17.21",
|
|
24
|
-
"lottie-
|
|
25
|
+
"lottie-ios": "3.4.0",
|
|
26
|
+
"lottie-react-native": "5.1.4",
|
|
25
27
|
"prop-types": "15.8.1",
|
|
26
28
|
"qs": "6.9.3",
|
|
27
|
-
"react-native-device-info": "
|
|
29
|
+
"react-native-device-info": "9.0.2",
|
|
28
30
|
"react-native-lightbox": "github:shoutem/react-native-lightbox#v0.7.2",
|
|
29
|
-
"react-native-linear-gradient": "2.
|
|
31
|
+
"react-native-linear-gradient": "2.6.2",
|
|
30
32
|
"react-native-modal": "11.7.0",
|
|
31
|
-
"react-native-photo-view": "github:shoutem/react-native-photo-view#
|
|
33
|
+
"react-native-photo-view": "github:shoutem/react-native-photo-view#a296aa2",
|
|
32
34
|
"react-native-render-html": "4.2.5",
|
|
33
35
|
"react-native-render-html-table-bridge": "0.6.0",
|
|
34
|
-
"react-native-svg": "12.
|
|
35
|
-
"react-native-svg-transformer": "0.
|
|
36
|
+
"react-native-svg": "12.3.0",
|
|
37
|
+
"react-native-svg-transformer": "1.0.0",
|
|
36
38
|
"react-native-transformable-image": "github:shoutem/react-native-transformable-image#v0.0.20",
|
|
37
|
-
"react-native-webview": "11.0
|
|
38
|
-
"react-native-youtube-iframe": "2.
|
|
39
|
+
"react-native-webview": "11.23.0",
|
|
40
|
+
"react-native-youtube-iframe": "2.2.2",
|
|
39
41
|
"stream": "0.0.2",
|
|
40
42
|
"tinycolor2": "1.4.1"
|
|
41
43
|
},
|
|
42
44
|
"peerDependencies": {
|
|
43
|
-
"react": "
|
|
45
|
+
"react": ">=16.9.0",
|
|
44
46
|
"react-native": ">=0.61.5"
|
|
45
47
|
},
|
|
46
48
|
"devDependencies": {
|
|
@@ -49,8 +51,6 @@
|
|
|
49
51
|
"@babel/plugin-proposal-decorators": "7.16.7",
|
|
50
52
|
"@shoutem/eslint-config-react-native": "~1.0.2",
|
|
51
53
|
"babel-eslint": "10.1.0",
|
|
52
|
-
"chai": "4.2.0",
|
|
53
|
-
"deep-freeze": "0.0.1",
|
|
54
54
|
"eslint": "6.8.0",
|
|
55
55
|
"eslint-plugin-import": "2.25.4",
|
|
56
56
|
"eslint-plugin-jsx-a11y": "6.5.1",
|
|
@@ -59,18 +59,20 @@
|
|
|
59
59
|
"eslint-plugin-react-hooks": "4.2.0",
|
|
60
60
|
"eslint-plugin-react-native": "3.11.0",
|
|
61
61
|
"eslint-plugin-simple-import-sort": "7.0.0",
|
|
62
|
+
"jest": "27.5.1",
|
|
62
63
|
"metro-react-native-babel-preset": "0.66.2",
|
|
63
|
-
"mocha": "7.1.2",
|
|
64
64
|
"prettier": "1.19.1",
|
|
65
|
-
"react
|
|
66
|
-
"react-dom": "16.
|
|
67
|
-
"react-native
|
|
65
|
+
"react": "17.0.2",
|
|
66
|
+
"react-dom": "16.9.0",
|
|
67
|
+
"react-native": "0.68.2",
|
|
68
|
+
"react-test-renderer": "17.0.2"
|
|
68
69
|
},
|
|
69
70
|
"nativeDependencies": [
|
|
70
71
|
"@react-native-community/datetimepicker",
|
|
72
|
+
"lottie-ios",
|
|
73
|
+
"lottie-react-native",
|
|
71
74
|
"react-native-device-info",
|
|
72
75
|
"react-native-linear-gradient",
|
|
73
|
-
"lottie-react-native",
|
|
74
76
|
"react-native-photo-view",
|
|
75
77
|
"react-native-svg",
|
|
76
78
|
"react-native-webview"
|
|
@@ -115,5 +117,15 @@
|
|
|
115
117
|
"jsxBracketSameLine": false,
|
|
116
118
|
"singleQuote": true,
|
|
117
119
|
"trailingComma": "all"
|
|
120
|
+
},
|
|
121
|
+
"jest": {
|
|
122
|
+
"preset": "react-native",
|
|
123
|
+
"testPathIgnorePatterns": [
|
|
124
|
+
"/node_modules/",
|
|
125
|
+
"examples/"
|
|
126
|
+
],
|
|
127
|
+
"transformIgnorePatterns": [
|
|
128
|
+
"!/node_modules/@shoutem"
|
|
129
|
+
]
|
|
118
130
|
}
|
|
119
131
|
}
|
package/theme.js
CHANGED
|
@@ -11,22 +11,15 @@ import {
|
|
|
11
11
|
IPHONE_X_HOME_INDICATOR_PADDING,
|
|
12
12
|
IPHONE_X_NOTCH_PADDING,
|
|
13
13
|
IPHONE_XR_NOTCH_PADDING,
|
|
14
|
+
NAVIGATION_BAR_HEIGHT,
|
|
14
15
|
NAVIGATION_HEADER_HEIGHT,
|
|
16
|
+
STATUS_BAR_OFFSET,
|
|
15
17
|
} from './const';
|
|
16
18
|
import { Device } from './helpers';
|
|
17
19
|
import { resolveVariable } from './services';
|
|
18
20
|
|
|
19
21
|
const window = Dimensions.get('window');
|
|
20
22
|
|
|
21
|
-
const STATUS_BAR_OFFSET =
|
|
22
|
-
Platform.OS === 'android' ? -StatusBar.currentConfig : 0;
|
|
23
|
-
export const NAVIGATION_BAR_HEIGHT = Device.select({
|
|
24
|
-
iPhoneX: NAVIGATION_HEADER_HEIGHT + IPHONE_X_NOTCH_PADDING,
|
|
25
|
-
iPhoneXR: NAVIGATION_HEADER_HEIGHT + IPHONE_XR_NOTCH_PADDING,
|
|
26
|
-
notchedAndroid: NAVIGATION_HEADER_HEIGHT + StatusBar.currentHeight,
|
|
27
|
-
default: NAVIGATION_HEADER_HEIGHT,
|
|
28
|
-
});
|
|
29
|
-
|
|
30
23
|
export const sizeVariants = [
|
|
31
24
|
'',
|
|
32
25
|
'left',
|
|
@@ -54,10 +47,24 @@ export function dimensionRelativeToIphone(
|
|
|
54
47
|
dimension,
|
|
55
48
|
actualRefVal = window.width,
|
|
56
49
|
) {
|
|
50
|
+
// 375 is iPhone width
|
|
51
|
+
// eslint-disable-next-line no-console
|
|
52
|
+
console.warn(
|
|
53
|
+
'dimensionRelativeToIphone is depreacted and will be removed in next major release. Use responsiveWidth instead.',
|
|
54
|
+
);
|
|
55
|
+
return getSizeRelativeToReference(dimension, 375, actualRefVal);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function responsiveWidth(dimension, actualRefVal = window.width) {
|
|
57
59
|
// 375 is iPhone width
|
|
58
60
|
return getSizeRelativeToReference(dimension, 375, actualRefVal);
|
|
59
61
|
}
|
|
60
62
|
|
|
63
|
+
export function responsiveHeight(dimension, actualRefVal = window.height) {
|
|
64
|
+
// 812 is iPhone height
|
|
65
|
+
return getSizeRelativeToReference(dimension, 812, actualRefVal);
|
|
66
|
+
}
|
|
67
|
+
|
|
61
68
|
// 'fontWeight' and 'fontStyle' aren't always supplied for every component, so we're setting default
|
|
62
69
|
// values of 'normal'.
|
|
63
70
|
export function resolveFontFamily(
|
|
@@ -591,65 +598,65 @@ export default () => {
|
|
|
591
598
|
imageSizes: {
|
|
592
599
|
// NOTE: '-avatar' styles do not work with ImageBackground
|
|
593
600
|
'.small-avatar': {
|
|
594
|
-
width:
|
|
595
|
-
height:
|
|
601
|
+
width: responsiveWidth(25),
|
|
602
|
+
height: responsiveWidth(25),
|
|
596
603
|
borderRadius: 12.5,
|
|
597
604
|
borderWidth: 0,
|
|
598
605
|
},
|
|
599
606
|
|
|
600
607
|
'.small': {
|
|
601
|
-
width:
|
|
602
|
-
height:
|
|
608
|
+
width: responsiveWidth(65),
|
|
609
|
+
height: responsiveWidth(65),
|
|
603
610
|
},
|
|
604
611
|
|
|
605
612
|
'.medium-avatar': {
|
|
606
|
-
width:
|
|
607
|
-
height:
|
|
608
|
-
borderRadius:
|
|
613
|
+
width: responsiveWidth(145),
|
|
614
|
+
height: responsiveWidth(145),
|
|
615
|
+
borderRadius: responsiveWidth(72.5),
|
|
609
616
|
borderWidth: 0,
|
|
610
617
|
},
|
|
611
618
|
|
|
612
619
|
'.medium': {
|
|
613
|
-
width:
|
|
614
|
-
height:
|
|
620
|
+
width: responsiveWidth(145),
|
|
621
|
+
height: responsiveWidth(92),
|
|
615
622
|
},
|
|
616
623
|
|
|
617
624
|
'.medium-wide': {
|
|
618
|
-
width:
|
|
619
|
-
height:
|
|
625
|
+
width: responsiveWidth(180),
|
|
626
|
+
height: responsiveWidth(85),
|
|
620
627
|
},
|
|
621
628
|
|
|
622
629
|
'.medium-portrait': {
|
|
623
|
-
width:
|
|
624
|
-
height:
|
|
630
|
+
width: responsiveWidth(209),
|
|
631
|
+
height: responsiveWidth(139),
|
|
625
632
|
},
|
|
626
633
|
|
|
627
634
|
'.medium-square': {
|
|
628
|
-
width:
|
|
629
|
-
height:
|
|
635
|
+
width: responsiveWidth(145),
|
|
636
|
+
height: responsiveWidth(145),
|
|
630
637
|
},
|
|
631
638
|
|
|
632
639
|
// NOTE: Image resizing doesn't work correctly if both
|
|
633
640
|
// dimensions are not explicitly defined, so we can't
|
|
634
641
|
// use flex: 1, or alignSelf: 'stretch' here...
|
|
635
642
|
'.featured': {
|
|
636
|
-
width:
|
|
637
|
-
height:
|
|
643
|
+
width: responsiveWidth(365),
|
|
644
|
+
height: responsiveWidth(345),
|
|
638
645
|
},
|
|
639
646
|
|
|
640
647
|
'.large': {
|
|
641
648
|
width: window.width,
|
|
642
|
-
height:
|
|
649
|
+
height: responsiveWidth(280),
|
|
643
650
|
},
|
|
644
651
|
|
|
645
652
|
'.large-portrait': {
|
|
646
653
|
width: window.width,
|
|
647
|
-
height:
|
|
654
|
+
height: responsiveWidth(518),
|
|
648
655
|
},
|
|
649
656
|
|
|
650
657
|
'.large-banner': {
|
|
651
658
|
width: window.width,
|
|
652
|
-
height:
|
|
659
|
+
height: responsiveWidth(200),
|
|
653
660
|
},
|
|
654
661
|
|
|
655
662
|
'.large-square': {
|
|
@@ -659,12 +666,12 @@ export default () => {
|
|
|
659
666
|
|
|
660
667
|
'.large-wide': {
|
|
661
668
|
width: window.width,
|
|
662
|
-
height:
|
|
669
|
+
height: responsiveWidth(238),
|
|
663
670
|
},
|
|
664
671
|
|
|
665
672
|
'.large-ultra-wide': {
|
|
666
673
|
width: window.width,
|
|
667
|
-
height:
|
|
674
|
+
height: responsiveWidth(130),
|
|
668
675
|
},
|
|
669
676
|
},
|
|
670
677
|
'shoutem.ui.Image': {
|
|
@@ -1130,7 +1137,7 @@ export default () => {
|
|
|
1130
1137
|
backgroundColor: resolveVariable('paperColor'),
|
|
1131
1138
|
},
|
|
1132
1139
|
|
|
1133
|
-
width:
|
|
1140
|
+
width: responsiveWidth(180),
|
|
1134
1141
|
flexDirection: 'column',
|
|
1135
1142
|
justifyContent: 'center',
|
|
1136
1143
|
alignItems: 'flex-start',
|
|
@@ -1144,7 +1151,7 @@ export default () => {
|
|
|
1144
1151
|
'shoutem.ui.View': {
|
|
1145
1152
|
'.pull-left': {
|
|
1146
1153
|
marginVertical: resolveVariable('mediumGutter'),
|
|
1147
|
-
marginLeft: -
|
|
1154
|
+
marginLeft: -responsiveWidth(72),
|
|
1148
1155
|
},
|
|
1149
1156
|
},
|
|
1150
1157
|
|
|
@@ -1347,7 +1354,7 @@ export default () => {
|
|
|
1347
1354
|
fontFamily: 'Rubik-Medium',
|
|
1348
1355
|
},
|
|
1349
1356
|
|
|
1350
|
-
width:
|
|
1357
|
+
width: responsiveWidth(120),
|
|
1351
1358
|
height: 82,
|
|
1352
1359
|
flexDirection: 'column',
|
|
1353
1360
|
},
|
|
@@ -2294,8 +2301,8 @@ export default () => {
|
|
|
2294
2301
|
},
|
|
2295
2302
|
video: {
|
|
2296
2303
|
// 16:9 ratio covers majority of YouTube videos
|
|
2297
|
-
width:
|
|
2298
|
-
height:
|
|
2304
|
+
width: responsiveWidth(345),
|
|
2305
|
+
height: responsiveWidth(194),
|
|
2299
2306
|
paddingBottom: resolveVariable('smallGutter'),
|
|
2300
2307
|
},
|
|
2301
2308
|
fallback: {
|
|
@@ -2572,30 +2579,30 @@ export default () => {
|
|
|
2572
2579
|
'shoutem.ui.InlineGallery': {
|
|
2573
2580
|
'.large-ultra-wide': {
|
|
2574
2581
|
container: {
|
|
2575
|
-
height:
|
|
2582
|
+
height: responsiveWidth(130),
|
|
2576
2583
|
},
|
|
2577
2584
|
},
|
|
2578
2585
|
|
|
2579
2586
|
'.large-banner': {
|
|
2580
2587
|
container: {
|
|
2581
|
-
height:
|
|
2588
|
+
height: responsiveWidth(200),
|
|
2582
2589
|
},
|
|
2583
2590
|
},
|
|
2584
2591
|
|
|
2585
2592
|
'.large-wide': {
|
|
2586
2593
|
container: {
|
|
2587
|
-
height:
|
|
2594
|
+
height: responsiveWidth(238),
|
|
2588
2595
|
},
|
|
2589
2596
|
},
|
|
2590
2597
|
|
|
2591
2598
|
'.large-square': {
|
|
2592
2599
|
container: {
|
|
2593
|
-
height:
|
|
2600
|
+
height: responsiveWidth(375),
|
|
2594
2601
|
},
|
|
2595
2602
|
},
|
|
2596
2603
|
|
|
2597
2604
|
container: {
|
|
2598
|
-
height:
|
|
2605
|
+
height: responsiveWidth(345),
|
|
2599
2606
|
},
|
|
2600
2607
|
|
|
2601
2608
|
imageContainer: {},
|