@shoutem/ui 7.1.0-beta.8 → 7.1.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.
@@ -43,7 +43,11 @@ const ActionSheet = ({
43
43
  {hasConfirmOptions && (
44
44
  <View style={style.segmentContainer}>
45
45
  {_.map(confirmOptions, option => (
46
- <ActionSheetOption key={option.title} option={option} />
46
+ <ActionSheetOption
47
+ key={option.title}
48
+ option={option}
49
+ style={style.option}
50
+ />
47
51
  ))}
48
52
  </View>
49
53
  )}
@@ -55,6 +59,7 @@ const ActionSheet = ({
55
59
  key={option.title}
56
60
  cancelOption
57
61
  option={option}
62
+ style={style.option}
58
63
  />
59
64
  ))}
60
65
  </View>
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
  import PropTypes from 'prop-types';
3
3
  import { connectStyle } from '@shoutem/theme';
4
+ import { isIos } from '../../services';
4
5
  import { Text } from '../Text';
5
6
  import { TouchableOpacity } from '../TouchableOpacity';
6
7
 
@@ -9,16 +10,24 @@ export const optionPropType = PropTypes.shape({
9
10
  onPress: PropTypes.func,
10
11
  });
11
12
 
12
- function ActionSheetOption({ style, option, cancelOption }) {
13
+ function ActionSheetOption({ style, option, cancelOption, nativeStyle }) {
13
14
  const { title, onPress } = option;
14
15
 
16
+ const useIosTextColor = nativeStyle && isIos;
17
+
15
18
  return (
16
19
  <TouchableOpacity
17
20
  onPress={onPress}
18
21
  style={style.container}
19
22
  styleName="horizontal"
20
23
  >
21
- <Text style={[style.text, cancelOption && style.cancelText]}>
24
+ <Text
25
+ style={[
26
+ style.text,
27
+ cancelOption && style.cancelText,
28
+ useIosTextColor && style.iosBlueTextColor,
29
+ ]}
30
+ >
22
31
  {title}
23
32
  </Text>
24
33
  </TouchableOpacity>
@@ -28,12 +37,14 @@ function ActionSheetOption({ style, option, cancelOption }) {
28
37
  ActionSheetOption.propTypes = {
29
38
  style: PropTypes.object.isRequired,
30
39
  cancelOption: PropTypes.bool,
40
+ nativeStyle: PropTypes.bool,
31
41
  option: optionPropType,
32
42
  };
33
43
 
34
44
  ActionSheetOption.defaultProps = {
35
45
  option: undefined,
36
46
  cancelOption: false,
47
+ nativeStyle: false,
37
48
  };
38
49
 
39
50
  export default connectStyle('shoutem.ui.ActionSheetOption')(ActionSheetOption);
@@ -37,13 +37,29 @@ class EmptyListImage extends PureComponent {
37
37
  } = this.props;
38
38
  const EmptyStateImage = this.resolveImage();
39
39
 
40
+ // SVG cannot receive array of style elements on Web
41
+ const resolvedImageStyle = {
42
+ ...style.image,
43
+ ...imageStyle,
44
+ };
45
+
46
+ const resolvedTitleStyle = {
47
+ ...style.title,
48
+ ...titleStyle,
49
+ };
50
+
51
+ const resolvedTextStyle = {
52
+ ...style.message,
53
+ ...messageStyle,
54
+ };
55
+
40
56
  return (
41
57
  <View styleName="vertical h-center ">
42
- <EmptyStateImage style={[style.image, imageStyle]} />
43
- <Title styleName="title" style={[style.title, titleStyle]}>
58
+ <EmptyStateImage style={resolvedImageStyle} />
59
+ <Title styleName="title" style={resolvedTitleStyle}>
44
60
  {title}
45
61
  </Title>
46
- <Text styleName="description" style={[style.message, messageStyle]}>
62
+ <Text styleName="description" style={resolvedTextStyle}>
47
63
  {message}
48
64
  </Text>
49
65
  </View>
@@ -52,6 +68,7 @@ class EmptyListImage extends PureComponent {
52
68
  }
53
69
 
54
70
  EmptyListImage.propTypes = {
71
+ style: PropTypes.object.isRequired,
55
72
  image: PropTypes.func,
56
73
  imageStyle: PropTypes.object,
57
74
  message: PropTypes.string,
@@ -0,0 +1,38 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { connectStyle } from '@shoutem/theme';
4
+ import { View } from '../View';
5
+ import { getIcon } from './services';
6
+
7
+ function Icon({ name, style, ...otherProps }) {
8
+ const { color, width, height, ...otherStyle } = style;
9
+
10
+ const NamedIcon = getIcon(name);
11
+
12
+ if (!NamedIcon) {
13
+ // eslint-disable-next-line no-console
14
+ console.warn(`Icon with name '${name}' not found within the provided set`);
15
+
16
+ return null;
17
+ }
18
+
19
+ return (
20
+ // Sometimes, in web, svg icons are not resized as expected, unless svg is wrapped inside View.
21
+ <View>
22
+ <NamedIcon
23
+ fill={color}
24
+ width={width}
25
+ height={height}
26
+ style={{ ...otherStyle }}
27
+ {...otherProps}
28
+ />
29
+ </View>
30
+ );
31
+ }
32
+
33
+ Icon.propTypes = {
34
+ name: PropTypes.string.isRequired,
35
+ style: PropTypes.object.isRequired,
36
+ };
37
+
38
+ export default connectStyle('shoutem.ui.Icon')(Icon);
@@ -83,6 +83,7 @@ import playlistPlay from './playlist-play.svg';
83
83
  import plusButton from './plus-button.svg';
84
84
  import podcasts from './podcasts.svg';
85
85
  import products from './products.svg';
86
+ import queue from './queue.svg';
86
87
  import radio from './radio.svg';
87
88
  import radiobuttonOff from './radiobutton-off.svg';
88
89
  import radiobuttonOn from './radiobutton-on.svg';
@@ -123,6 +124,7 @@ import videoCam from './video-cam.svg';
123
124
  import videoCamOff from './video-cam-off.svg';
124
125
  import videoChat from './video-chat.svg';
125
126
  import web from './web.svg';
127
+ import wheelchair from './wheelchair.svg';
126
128
 
127
129
  export const defaultConfig = [
128
130
  { name: 'about', icon: about },
@@ -210,6 +212,7 @@ export const defaultConfig = [
210
212
  { name: 'plus-button', icon: plusButton },
211
213
  { name: 'podcasts', icon: podcasts },
212
214
  { name: 'products', icon: products },
215
+ { name: 'queue', icon: queue },
213
216
  { name: 'radio', icon: radio },
214
217
  { name: 'radiobutton-off', icon: radiobuttonOff },
215
218
  { name: 'radiobutton-on', icon: radiobuttonOn },
@@ -250,4 +253,5 @@ export const defaultConfig = [
250
253
  { name: 'video-cam-off', icon: videoCamOff },
251
254
  { name: 'video-chat', icon: videoChat },
252
255
  { name: 'web', icon: web },
256
+ { name: 'wheelchair', icon: wheelchair },
253
257
  ];
@@ -0,0 +1 @@
1
+ <?xml version="1.0" ?><svg viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M0 2h20v4H0V2zm0 8h20v2H0v-2zm0 6h20v2H0v-2z"/></svg>
@@ -0,0 +1,4 @@
1
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 22 24">
2
+ <title>wheelchair</title>
3
+ <path d="M13.701 15.897l1.366 2.732c-1.031 3.188-4.004 5.371-7.353 5.371-4.246 0-7.714-3.469-7.714-7.714 0-3.241 2.036-6.134 5.076-7.246l0.228 1.754c-2.183 0.964-3.589 3.107-3.589 5.491 0 3.308 2.692 6 6 6 3.442 0 6.228-2.946 5.987-6.388zM21.040 17.237l0.777 1.527-3.429 1.714c-0.121 0.067-0.254 0.094-0.388 0.094-0.321 0-0.629-0.188-0.763-0.469l-3.201-6.388h-6.321c-0.429 0-0.804-0.335-0.857-0.763l-1.286-10.433c-0.013-0.134 0.040-0.429 0.080-0.563 0.254-0.924 1.112-1.527 2.063-1.527 1.179 0 2.143 0.964 2.143 2.143 0 1.219-1.071 2.263-2.304 2.129l0.496 3.871h5.665v1.714h-5.451l0.214 1.714h6.094c0.321 0 0.629 0.188 0.763 0.469l3.054 6.094z"></path>
4
+ </svg>
@@ -2,19 +2,29 @@ import React from 'react';
2
2
  import { Switch as RNSwitch } from 'react-native';
3
3
  import PropTypes from 'prop-types';
4
4
  import { connectStyle } from '@shoutem/theme';
5
+ import { isWeb } from '../services/platform';
5
6
  import { View } from './View';
6
7
 
7
- const Switch = ({ value, onValueChange, style }) => (
8
- <View style={style.container}>
9
- <RNSwitch
10
- trackColor={style.track}
11
- thumbColor={style.thumb}
12
- ios_backgroundColor={style.track?.false}
13
- onValueChange={onValueChange}
14
- value={value}
15
- />
16
- </View>
17
- );
8
+ const Switch = ({ value, onValueChange, style }) => {
9
+ const webColors = {
10
+ trackColor: style.track?.false,
11
+ activeThumbColor: style.thumb,
12
+ activeTrackColor: style.track.true,
13
+ };
14
+
15
+ return (
16
+ <View style={style.container}>
17
+ <RNSwitch
18
+ trackColor={isWeb ? style.track?.false : style.track}
19
+ thumbColor={style.thumb}
20
+ ios_backgroundColor={style.track?.false}
21
+ onValueChange={onValueChange}
22
+ value={value}
23
+ {...(isWeb && webColors)}
24
+ />
25
+ </View>
26
+ );
27
+ };
18
28
 
19
29
  Switch.propTypes = {
20
30
  onValueChange: PropTypes.func.isRequired,
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable react/no-multi-comp */
2
2
  import React, { forwardRef, PureComponent } from 'react';
3
- import { TextInput as RNTextInput, Platform } from 'react-native';
3
+ import { Platform, TextInput as RNTextInput } from 'react-native';
4
4
  import autoBindReact from 'auto-bind/react';
5
5
  import { TextInputPropTypes } from 'deprecated-react-native-prop-types';
6
6
  import PropTypes from 'prop-types';
@@ -64,7 +64,7 @@ class TextInput extends PureComponent {
64
64
  ...otherStyle
65
65
  } = style;
66
66
 
67
- const containerStyle = Platform.OS === "web" ? { height } : undefined;
67
+ const containerStyle = Platform.OS === 'web' ? { height } : undefined;
68
68
  const hasBorder = (isFocused && highlightOnFocus) || !!errorMessage;
69
69
  const startErrorAnimation = animate && !!errorMessage;
70
70
 
@@ -82,7 +82,7 @@ class TextInput extends PureComponent {
82
82
  ...(hasBorder ? withBorder : withoutBorder),
83
83
  ...(errorMessage ? errorBorderColor : {}),
84
84
  ...otherStyle,
85
- height: 50,
85
+ height,
86
86
  }}
87
87
  ref={forwardedRef}
88
88
  />
@@ -12,6 +12,13 @@ function ToastProgressBar({
12
12
  }) {
13
13
  const progressValue = useRef(new Animated.Value(0)).current;
14
14
 
15
+ const handleAnimationEnd = useCallback(() => {
16
+ progressValue.setValue(0);
17
+ if (onProgressComplete) {
18
+ onProgressComplete();
19
+ }
20
+ }, [onProgressComplete, progressValue]);
21
+
15
22
  useEffect(() => {
16
23
  if (!visible) {
17
24
  progressValue.setValue(0);
@@ -25,13 +32,6 @@ function ToastProgressBar({
25
32
  }).start(handleAnimationEnd);
26
33
  }, [visible, duration, handleAnimationEnd]);
27
34
 
28
- const handleAnimationEnd = useCallback(() => {
29
- progressValue.setValue(0);
30
- if (onProgressComplete) {
31
- onProgressComplete();
32
- }
33
- }, [onProgressComplete, progressValue]);
34
-
35
35
  return (
36
36
  <View style={style.container}>
37
37
  <Animated.View
@@ -6,7 +6,6 @@ import { iframeModel } from '@native-html/iframe-plugin';
6
6
  import table, {
7
7
  cssRulesFromSpecs,
8
8
  defaultTableStylesSpecs,
9
- IGNORED_TAGS,
10
9
  tableModel,
11
10
  } from '@native-html/table-plugin';
12
11
  import autoBindReact from 'auto-bind/react';
@@ -119,7 +118,6 @@ class SimpleHtml extends PureComponent {
119
118
  ...customHtmlElementModels,
120
119
  },
121
120
  WebView,
122
- ignoredTags: IGNORED_TAGS,
123
121
  domVisitors: { onElement, ...customDomVisitors },
124
122
  };
125
123
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shoutem/ui",
3
- "version": "7.1.0-beta.8",
3
+ "version": "7.1.0",
4
4
  "description": "Styleable set of components for React Native applications",
5
5
  "scripts": {
6
6
  "lint": "eslint .",
@@ -15,9 +15,9 @@
15
15
  "@native-html/table-plugin": "5.3.1",
16
16
  "@openspacelabs/react-native-zoomable-view": "2.0.4",
17
17
  "@react-native-community/datetimepicker": "6.2.0",
18
- "@shoutem/animation": "0.17.0-beta.0",
18
+ "@shoutem/animation": "0.17.0",
19
19
  "@shoutem/eslint-config-react": "~1.0.6",
20
- "@shoutem/theme": "~0.13.2",
20
+ "@shoutem/theme": "~0.14.0",
21
21
  "auto-bind": "4.0.0",
22
22
  "babel-plugin-transform-decorators-legacy": "1.3.5",
23
23
  "buffer": "5.6.0",
package/services/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ export { isAndroid, isIos, isWeb } from './platform';
1
2
  export { unavailableInWeb } from './unavailableInWeb';
2
3
  export {
3
4
  createScopedResolver,
@@ -0,0 +1,5 @@
1
+ import { Platform } from 'react-native';
2
+
3
+ export const isAndroid = Platform.OS === 'android';
4
+ export const isIos = Platform.OS === 'ios';
5
+ export const isWeb = Platform.OS === 'web';
package/theme.js CHANGED
@@ -1,4 +1,4 @@
1
- import { Dimensions, Platform, StyleSheet } from 'react-native';
1
+ import { Dimensions, StyleSheet } from 'react-native';
2
2
  import {
3
3
  changeColorAlpha,
4
4
  createSharedStyle,
@@ -16,7 +16,7 @@ import {
16
16
  STATUS_BAR_OFFSET,
17
17
  } from './const';
18
18
  import { Device } from './helpers';
19
- import { resolveVariable } from './services';
19
+ import { isAndroid, isIos, resolveVariable } from './services';
20
20
 
21
21
  const window = Dimensions.get('window');
22
22
 
@@ -72,7 +72,7 @@ export function resolveFontFamily(
72
72
  fontWeight = 'normal',
73
73
  fontStyle = 'normal',
74
74
  ) {
75
- if (Platform.OS === 'ios') {
75
+ if (isIos) {
76
76
  return fontName;
77
77
  }
78
78
 
@@ -103,22 +103,22 @@ export function resolveFontFamily(
103
103
  // being provided to fontWeight will cause the default system font to be used, so we conditionally
104
104
  // resolve it.
105
105
  export function resolveFontWeight(fontWeight) {
106
- if (Platform.OS === 'ios') {
107
- return fontWeight;
106
+ if (!isIos) {
107
+ return 'normal';
108
108
  }
109
109
 
110
- return 'normal';
110
+ return fontWeight;
111
111
  }
112
112
 
113
113
  // Currently, resolveFontFamily will provide fontStyle styling, but any value other than 'normal'
114
114
  // being provided to fontStyle will cause the default system font to be used, so we conditionally
115
115
  // resolve it.
116
116
  export function resolveFontStyle(fontStyle) {
117
- if (Platform.OS === 'ios') {
118
- return fontStyle;
117
+ if (!isIos) {
118
+ return 'normal';
119
119
  }
120
120
 
121
- return 'normal';
121
+ return fontStyle;
122
122
  }
123
123
 
124
124
  // This function is deprecated and replaced with calculateLineHeight.
@@ -1819,7 +1819,7 @@ export default () => {
1819
1819
  top: Device.select({
1820
1820
  iPhoneX: 6,
1821
1821
  iPhoneXR: 8,
1822
- default: Platform.OS === 'android' ? 0 : -4,
1822
+ default: isAndroid ? 0 : -4,
1823
1823
  }),
1824
1824
  left: 0,
1825
1825
  right: 0,
@@ -2427,7 +2427,7 @@ export default () => {
2427
2427
  number: {
2428
2428
  // Font should be monospace so that item content has same offset
2429
2429
  // Can not apply width to the Text for some reason
2430
- fontFamily: Platform.OS === 'ios' ? 'Menlo-Regular' : 'monospace',
2430
+ fontFamily: isIos ? 'Menlo-Regular' : 'monospace',
2431
2431
  fontSize: 12,
2432
2432
  },
2433
2433
  bullet: {},
@@ -2733,6 +2733,7 @@ export default () => {
2733
2733
  paddingVertical: 16,
2734
2734
  borderBottomWidth: 1,
2735
2735
  borderColor: 'rgba(130, 130, 130, 0.1)',
2736
+ alignItems: 'center',
2736
2737
  },
2737
2738
  text: {
2738
2739
  fontSize: 15,
@@ -2745,6 +2746,9 @@ export default () => {
2745
2746
  textAlign: 'center',
2746
2747
  fontWeight: resolveFontWeight('700'),
2747
2748
  },
2749
+ iosBlueTextColor: {
2750
+ color: '#007AFF',
2751
+ },
2748
2752
  },
2749
2753
 
2750
2754
  //
@@ -3126,7 +3130,6 @@ export default () => {
3126
3130
  },
3127
3131
  textContainer: {
3128
3132
  flex: 1,
3129
- height: responsiveHeight(48),
3130
3133
  justifyContent: 'space-between',
3131
3134
  },
3132
3135
  title: {