@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.
- package/components/ActionSheet/ActionSheet.js +6 -1
- package/components/ActionSheet/ActionSheetOption.js +13 -2
- package/components/EmptyListImage.js +20 -3
- package/components/Icon/Icon.web.js +38 -0
- package/components/Icon/assets/index.js +4 -0
- package/components/Icon/assets/queue.svg +1 -0
- package/components/Icon/assets/wheelchair.svg +4 -0
- package/components/Switch.js +21 -11
- package/components/TextInput.js +3 -3
- package/components/ToastMessage/components/ToastProgressBar.js +7 -7
- package/html/components/SimpleHtml.js +0 -2
- package/package.json +3 -3
- package/services/index.js +1 -0
- package/services/platform.js +5 -0
- package/theme.js +15 -12
|
@@ -43,7 +43,11 @@ const ActionSheet = ({
|
|
|
43
43
|
{hasConfirmOptions && (
|
|
44
44
|
<View style={style.segmentContainer}>
|
|
45
45
|
{_.map(confirmOptions, option => (
|
|
46
|
-
<ActionSheetOption
|
|
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
|
|
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={
|
|
43
|
-
<Title styleName="title" style={
|
|
58
|
+
<EmptyStateImage style={resolvedImageStyle} />
|
|
59
|
+
<Title styleName="title" style={resolvedTitleStyle}>
|
|
44
60
|
{title}
|
|
45
61
|
</Title>
|
|
46
|
-
<Text styleName="description" style={
|
|
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>
|
package/components/Switch.js
CHANGED
|
@@ -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
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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,
|
package/components/TextInput.js
CHANGED
|
@@ -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
|
|
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 ===
|
|
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
|
|
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
|
|
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
|
|
18
|
+
"@shoutem/animation": "0.17.0",
|
|
19
19
|
"@shoutem/eslint-config-react": "~1.0.6",
|
|
20
|
-
"@shoutem/theme": "~0.
|
|
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
package/theme.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Dimensions,
|
|
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 (
|
|
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 (
|
|
107
|
-
return
|
|
106
|
+
if (!isIos) {
|
|
107
|
+
return 'normal';
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
-
return
|
|
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 (
|
|
118
|
-
return
|
|
117
|
+
if (!isIos) {
|
|
118
|
+
return 'normal';
|
|
119
119
|
}
|
|
120
120
|
|
|
121
|
-
return
|
|
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:
|
|
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:
|
|
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: {
|