@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.
@@ -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
+ `;
@@ -5,12 +5,12 @@ import { connectStyle } from '@shoutem/theme';
5
5
 
6
6
  class Button extends PureComponent {
7
7
  render() {
8
- const { style, ...otherProps } = this.props;
8
+ const { style } = this.props;
9
9
  const { underlayColor, ...otherStyle } = style;
10
10
 
11
11
  return (
12
12
  <TouchableOpacity
13
- {...otherProps}
13
+ {...this.props}
14
14
  style={otherStyle}
15
15
  underlayColor={underlayColor}
16
16
  />
@@ -52,7 +52,6 @@ class EmptyListImage extends PureComponent {
52
52
  }
53
53
 
54
54
  EmptyListImage.propTypes = {
55
- ...EmptyListImage.propTypes,
56
55
  image: PropTypes.func,
57
56
  imageStyle: PropTypes.object,
58
57
  message: PropTypes.string,
@@ -1,5 +1,5 @@
1
1
  import React, { Children, PureComponent } from 'react';
2
- import { View as RNView, ViewPropTypes } from 'react-native';
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
- ...ViewPropTypes,
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 },
@@ -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
- ...RNImage.propTypes,
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.
@@ -1,4 +1,4 @@
1
- import { default as Lightbox } from 'react-native-lightbox';
1
+ import Lightbox from 'react-native-lightbox';
2
2
  import { connectAnimation } from '@shoutem/animation';
3
3
  import { connectStyle } from '@shoutem/theme';
4
4
 
@@ -64,16 +64,18 @@ class ScrollView extends PureComponent {
64
64
  }
65
65
 
66
66
  addIphoneXPadding(style) {
67
- if (typeof style.paddingBottom !== 'number') {
68
- style.paddingBottom = 0;
67
+ const resolvedStyle = { ...style };
68
+
69
+ if (typeof resolvedStyle.paddingBottom !== 'number') {
70
+ resolvedStyle.paddingBottom = 0;
69
71
  }
70
72
 
71
- style.paddingBottom = Device.select({
72
- iPhoneX: style.paddingBottom + IPHONE_X_HOME_INDICATOR_PADDING,
73
- default: style.paddingBottom,
73
+ resolvedStyle.paddingBottom = Device.select({
74
+ iPhoneX: resolvedStyle.paddingBottom + IPHONE_X_HOME_INDICATOR_PADDING,
75
+ default: resolvedStyle.paddingBottom,
74
76
  });
75
77
 
76
- return style;
78
+ return resolvedStyle;
77
79
  }
78
80
 
79
81
  render() {
@@ -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
- ...RNText.propTypes,
14
+ ...TextPropTypes,
14
15
  };
15
16
 
16
17
  const AnimatedText = connectAnimation(Text);
@@ -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}>{errorMessage}</Caption>
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
- ...RNTextInput.propTypes,
95
+ ...TextInputPropTypes,
93
96
  style: PropTypes.object.isRequired,
94
97
  animate: PropTypes.bool,
95
98
  errorMessage: PropTypes.string,
@@ -13,13 +13,13 @@ import { View } from './View';
13
13
  */
14
14
  class Touchable extends PureComponent {
15
15
  render() {
16
- const { children, style, styleName, ...otherProps } = this.props;
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
- {...otherProps}
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
- {...otherProps}
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, ...otherProps } = this.props;
8
+ const { children, style } = this.props;
9
9
  const { background, useForeground, ...otherStyle } = style;
10
10
 
11
11
  return (
12
12
  <RNTouchableNativeFeedback
13
- {...otherProps}
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, ...otherProps } = this.props;
7
+ const { children, style } = this.props;
8
8
  const { activeOpacity, ...otherStyle } = style;
9
9
 
10
10
  return (
11
11
  <RNTouchableOpacity
12
- {...otherProps}
12
+ {...this.props}
13
13
  style={otherStyle}
14
14
  activeOpacity={activeOpacity}
15
15
  >
@@ -1,5 +1,6 @@
1
1
  import React, { PureComponent } from 'react';
2
- import { View as RNView, ViewPropTypes } from 'react-native';
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, ...otherProps } = this.props;
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 {...otherProps} style={viewStyle}>
22
+ <RNView {...this.props} style={viewStyle}>
25
23
  {gradient}
26
24
  {children}
27
25
  </RNView>
package/const.js CHANGED
@@ -1,22 +1,30 @@
1
- const IPHONE_X_HOME_INDICATOR_PADDING = 34;
2
- const IPHONE_X_LONG_SIDE = 812;
3
- const IPHONE_X_NOTCH_PADDING = 30;
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
- import { Device } from './device-selector';
2
- import Keyboard from './keyboard';
3
-
4
- export { Device, Keyboard };
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';
@@ -1,5 +1,5 @@
1
1
  import { Platform, StatusBar } from 'react-native';
2
- import { NAVIGATION_BAR_HEIGHT } from '../theme';
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
- export { Device, Keyboard } from './helpers';
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.2.2",
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": "mocha '_tests_/*.js' --require react-native-mock-render/mock --require @babel/register"
9
+ "test": "jest"
10
10
  },
11
11
  "dependencies": {
12
- "@react-native-community/datetimepicker": "3.5.2",
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-react-native": "5.0.1",
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": "8.4.8",
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.5.6",
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#e7f0003",
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.1.1",
35
- "react-native-svg-transformer": "0.14.3",
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.3",
38
- "react-native-youtube-iframe": "2.1.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": "^16.9.0",
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-addons-test-utils": "15.6.2",
66
- "react-dom": "16.14.0",
67
- "react-native-mock-render": "0.1.9"
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: dimensionRelativeToIphone(25),
595
- height: dimensionRelativeToIphone(25),
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: dimensionRelativeToIphone(65),
602
- height: dimensionRelativeToIphone(65),
608
+ width: responsiveWidth(65),
609
+ height: responsiveWidth(65),
603
610
  },
604
611
 
605
612
  '.medium-avatar': {
606
- width: dimensionRelativeToIphone(145),
607
- height: dimensionRelativeToIphone(145),
608
- borderRadius: dimensionRelativeToIphone(72.5),
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: dimensionRelativeToIphone(145),
614
- height: dimensionRelativeToIphone(92),
620
+ width: responsiveWidth(145),
621
+ height: responsiveWidth(92),
615
622
  },
616
623
 
617
624
  '.medium-wide': {
618
- width: dimensionRelativeToIphone(180),
619
- height: dimensionRelativeToIphone(85),
625
+ width: responsiveWidth(180),
626
+ height: responsiveWidth(85),
620
627
  },
621
628
 
622
629
  '.medium-portrait': {
623
- width: dimensionRelativeToIphone(209),
624
- height: dimensionRelativeToIphone(139),
630
+ width: responsiveWidth(209),
631
+ height: responsiveWidth(139),
625
632
  },
626
633
 
627
634
  '.medium-square': {
628
- width: dimensionRelativeToIphone(145),
629
- height: dimensionRelativeToIphone(145),
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: dimensionRelativeToIphone(365),
637
- height: dimensionRelativeToIphone(345),
643
+ width: responsiveWidth(365),
644
+ height: responsiveWidth(345),
638
645
  },
639
646
 
640
647
  '.large': {
641
648
  width: window.width,
642
- height: dimensionRelativeToIphone(280),
649
+ height: responsiveWidth(280),
643
650
  },
644
651
 
645
652
  '.large-portrait': {
646
653
  width: window.width,
647
- height: dimensionRelativeToIphone(518),
654
+ height: responsiveWidth(518),
648
655
  },
649
656
 
650
657
  '.large-banner': {
651
658
  width: window.width,
652
- height: dimensionRelativeToIphone(200),
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: dimensionRelativeToIphone(238),
669
+ height: responsiveWidth(238),
663
670
  },
664
671
 
665
672
  '.large-ultra-wide': {
666
673
  width: window.width,
667
- height: dimensionRelativeToIphone(130),
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: dimensionRelativeToIphone(180),
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: -dimensionRelativeToIphone(72),
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: dimensionRelativeToIphone(120),
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: dimensionRelativeToIphone(345),
2298
- height: dimensionRelativeToIphone(194),
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: dimensionRelativeToIphone(130),
2582
+ height: responsiveWidth(130),
2576
2583
  },
2577
2584
  },
2578
2585
 
2579
2586
  '.large-banner': {
2580
2587
  container: {
2581
- height: dimensionRelativeToIphone(200),
2588
+ height: responsiveWidth(200),
2582
2589
  },
2583
2590
  },
2584
2591
 
2585
2592
  '.large-wide': {
2586
2593
  container: {
2587
- height: dimensionRelativeToIphone(238),
2594
+ height: responsiveWidth(238),
2588
2595
  },
2589
2596
  },
2590
2597
 
2591
2598
  '.large-square': {
2592
2599
  container: {
2593
- height: dimensionRelativeToIphone(375),
2600
+ height: responsiveWidth(375),
2594
2601
  },
2595
2602
  },
2596
2603
 
2597
2604
  container: {
2598
- height: dimensionRelativeToIphone(345),
2605
+ height: responsiveWidth(345),
2599
2606
  },
2600
2607
 
2601
2608
  imageContainer: {},