@shoutem/ui 5.0.1-rc.0 → 5.2.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 +15 -8
- package/components/ActionSheet/ActionSheetOption.js +7 -2
- package/components/Button.js +5 -9
- package/components/CategoryPicker/Category.js +45 -0
- package/components/CategoryPicker/CategoryPicker.js +62 -0
- package/components/CategoryPicker/index.js +1 -0
- package/components/CategoryPicker/shapes.js +7 -0
- package/components/DateTimePicker.js +4 -1
- package/components/DropDownMenu/DropDownMenu.js +20 -23
- package/components/DropDownMenu/DropDownModal.js +56 -54
- package/components/EmptyStateView.js +16 -12
- package/components/FormGroup.js +7 -1
- package/components/GridRow.js +1 -1
- package/components/HorizontalPager/HorizontalPager.js +61 -52
- package/components/HorizontalPager/Page.js +12 -7
- package/components/Icon/Icon.js +1 -1
- package/components/Image.js +4 -4
- package/components/ImageBackground.js +4 -4
- package/components/ImageGallery/ImageGallery.android.js +8 -0
- package/components/ImageGallery/ImageGallery.ios.js +8 -0
- package/components/ImageGallery/ImageGalleryBase.js +65 -48
- package/components/ImageGalleryOverlay.js +12 -7
- package/components/ImagePreview.js +19 -14
- package/components/InlineDropDownMenu/InlineDropDownMenu.js +27 -18
- package/components/InlineDropDownMenu/InlineDropDownMenuItem.js +17 -9
- package/components/InlineGallery.js +42 -35
- package/components/LinearGradient.js +15 -5
- package/components/ListView.js +1 -7
- package/components/LoadingContainer.js +1 -2
- package/components/NavigationBar/NavigationBar.js +18 -13
- package/components/NumberInput.js +32 -24
- package/components/PageIndicators.js +19 -17
- package/components/ScrollView/ScrollDriverProvider.js +20 -10
- package/components/ScrollView/ScrollView.js +15 -13
- package/components/SearchField.js +24 -18
- package/components/ShareButton.js +21 -11
- package/components/Spinner.js +1 -1
- package/components/Switch.js +19 -14
- package/components/TabMenu/TabMenu.js +12 -7
- package/components/TabMenu/TabMenuItem.js +13 -7
- package/components/TextInput.js +3 -1
- package/components/Touchable.js +19 -23
- package/components/TouchableNativeFeedback.js +15 -21
- package/components/TouchableOpacity.js +6 -12
- package/components/Video/Video.js +21 -25
- package/components/View.js +7 -9
- package/components/YearRangePicker/YearRangePicker.js +22 -17
- package/components/YearRangePicker/YearRangePickerButton.js +13 -7
- package/components/YearRangePicker/YearRangePickerModal.js +23 -16
- package/examples/components/NavigationBars.js +4 -0
- package/examples/components/Stage.js +6 -1
- package/html/Html.js +14 -8
- package/html/components/Gallery.js +9 -5
- package/html/components/Image.js +16 -16
- package/html/components/SimpleHtml.js +19 -10
- package/html/elements/A.js +11 -6
- package/html/elements/Inline.js +13 -14
- package/html/elements/Text.js +6 -0
- package/html/elements/Video.js +3 -1
- package/html/elements/list/Li.js +0 -2
- package/html/elements/list/Ol.js +4 -0
- package/html/elements/list/Ul.js +4 -0
- package/html/elements/list/prefix/Bullet.js +4 -0
- package/html/elements/list/prefix/Number.js +6 -1
- package/index.js +47 -52
- package/init.js +7 -1
- package/package.json +1 -1
- package/services/index.js +6 -0
- package/services/variableResolver.js +73 -0
- package/theme.js +2295 -2181
|
@@ -33,14 +33,6 @@ class ActionSheet extends PureComponent {
|
|
|
33
33
|
return null;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
static propTypes = {
|
|
37
|
-
style: PropTypes.any,
|
|
38
|
-
confirmOptions: PropTypes.arrayOf(optionPropType),
|
|
39
|
-
cancelOptions: PropTypes.arrayOf(optionPropType),
|
|
40
|
-
active: PropTypes.bool,
|
|
41
|
-
onDismiss: PropTypes.func,
|
|
42
|
-
};
|
|
43
|
-
|
|
44
36
|
constructor(props) {
|
|
45
37
|
super(props);
|
|
46
38
|
|
|
@@ -187,4 +179,19 @@ class ActionSheet extends PureComponent {
|
|
|
187
179
|
}
|
|
188
180
|
}
|
|
189
181
|
|
|
182
|
+
ActionSheet.propTypes = {
|
|
183
|
+
style: PropTypes.object.isRequired,
|
|
184
|
+
active: PropTypes.bool,
|
|
185
|
+
cancelOptions: PropTypes.arrayOf(optionPropType),
|
|
186
|
+
confirmOptions: PropTypes.arrayOf(optionPropType),
|
|
187
|
+
onDismiss: PropTypes.func,
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
ActionSheet.defaultProps = {
|
|
191
|
+
active: false,
|
|
192
|
+
cancelOptions: undefined,
|
|
193
|
+
confirmOptions: undefined,
|
|
194
|
+
onDismiss: undefined,
|
|
195
|
+
};
|
|
196
|
+
|
|
190
197
|
export default connectStyle('shoutem.ui.ActionSheet')(ActionSheet);
|
|
@@ -26,9 +26,14 @@ function ActionSheetOption({ style, option, cancelOption }) {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
ActionSheetOption.propTypes = {
|
|
29
|
-
style: PropTypes.
|
|
30
|
-
option: optionPropType,
|
|
29
|
+
style: PropTypes.object.isRequired,
|
|
31
30
|
cancelOption: PropTypes.bool,
|
|
31
|
+
option: optionPropType,
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
ActionSheetOption.defaultProps = {
|
|
35
|
+
option: undefined,
|
|
36
|
+
cancelOption: false,
|
|
32
37
|
};
|
|
33
38
|
|
|
34
39
|
export default connectStyle('shoutem.ui.ActionSheetOption')(ActionSheetOption);
|
package/components/Button.js
CHANGED
|
@@ -5,18 +5,14 @@ import { connectStyle } from '@shoutem/theme';
|
|
|
5
5
|
|
|
6
6
|
class Button extends PureComponent {
|
|
7
7
|
render() {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const style = {
|
|
11
|
-
...this.props.style,
|
|
12
|
-
};
|
|
13
|
-
delete style.underlayColor;
|
|
8
|
+
const { style, ...otherProps } = this.props;
|
|
9
|
+
const { underlayColor, ...otherStyle } = style;
|
|
14
10
|
|
|
15
11
|
return (
|
|
16
12
|
<TouchableOpacity
|
|
17
|
-
{...
|
|
18
|
-
style={
|
|
19
|
-
underlayColor={
|
|
13
|
+
{...otherProps}
|
|
14
|
+
style={otherStyle}
|
|
15
|
+
underlayColor={underlayColor}
|
|
20
16
|
/>
|
|
21
17
|
);
|
|
22
18
|
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import React, { useMemo } from 'react';
|
|
2
|
+
import PropTypes from 'prop-types';
|
|
3
|
+
import { connectStyle } from '@shoutem/theme';
|
|
4
|
+
import { Text } from '../Text';
|
|
5
|
+
import { TouchableOpacity } from '../TouchableOpacity';
|
|
6
|
+
import { categoryShape } from './shapes';
|
|
7
|
+
|
|
8
|
+
function Category({ category, style, isSelected, onPress }) {
|
|
9
|
+
const textStyle = useMemo(
|
|
10
|
+
() => [style.category, !isSelected && style.selectedCategory],
|
|
11
|
+
|
|
12
|
+
[isSelected, style.category, style.selectedCategory],
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
function handlePress() {
|
|
16
|
+
if (isSelected) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (onPress) {
|
|
21
|
+
onPress(category);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<TouchableOpacity onPress={handlePress} style={style.container}>
|
|
27
|
+
<Text style={textStyle}>{category.name}</Text>
|
|
28
|
+
</TouchableOpacity>
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
Category.propTypes = {
|
|
33
|
+
category: categoryShape.isRequired,
|
|
34
|
+
isSelected: PropTypes.bool,
|
|
35
|
+
style: PropTypes.object,
|
|
36
|
+
onPress: PropTypes.func,
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
Category.defaultProps = {
|
|
40
|
+
style: {},
|
|
41
|
+
isSelected: false,
|
|
42
|
+
onPress: undefined,
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export default React.memo(connectStyle('shoutem.ui.Category')(Category));
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import React, { useCallback } from 'react';
|
|
2
|
+
import { FlatList } from 'react-native';
|
|
3
|
+
import _ from 'lodash';
|
|
4
|
+
import PropTypes from 'prop-types';
|
|
5
|
+
import { connectStyle } from '@shoutem/theme';
|
|
6
|
+
import { View } from '../View';
|
|
7
|
+
import Category from './Category';
|
|
8
|
+
import { categoryShape } from './shapes';
|
|
9
|
+
|
|
10
|
+
export function CategoryPicker({
|
|
11
|
+
categories,
|
|
12
|
+
onCategorySelected,
|
|
13
|
+
style,
|
|
14
|
+
selectedCategory,
|
|
15
|
+
}) {
|
|
16
|
+
const renderItem = useCallback(
|
|
17
|
+
({ item: category }) => (
|
|
18
|
+
<Category
|
|
19
|
+
category={category}
|
|
20
|
+
key={category.id}
|
|
21
|
+
onPress={onCategorySelected}
|
|
22
|
+
isSelected={selectedCategory.id === category.id}
|
|
23
|
+
/>
|
|
24
|
+
),
|
|
25
|
+
[selectedCategory.id, onCategorySelected],
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
if (_.size(categories) < 2) {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<View style={style.container}>
|
|
34
|
+
<FlatList
|
|
35
|
+
horizontal
|
|
36
|
+
scrollToOverflowEnabled
|
|
37
|
+
contentContainerStyle={style.listContainer}
|
|
38
|
+
showsHorizontalScrollIndicator={false}
|
|
39
|
+
data={categories}
|
|
40
|
+
renderItem={renderItem}
|
|
41
|
+
/>
|
|
42
|
+
</View>
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
CategoryPicker.propTypes = {
|
|
47
|
+
categories: PropTypes.arrayOf(categoryShape),
|
|
48
|
+
selectedCategory: categoryShape,
|
|
49
|
+
style: PropTypes.object,
|
|
50
|
+
onCategorySelected: PropTypes.func,
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
CategoryPicker.defaultProps = {
|
|
54
|
+
categories: [],
|
|
55
|
+
style: {},
|
|
56
|
+
selectedCategory: undefined,
|
|
57
|
+
onCategorySelected: undefined,
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
export default React.memo(
|
|
61
|
+
connectStyle('shoutem.ui.CategoryPicker')(CategoryPicker),
|
|
62
|
+
);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as CategoryPicker } from './CategoryPicker';
|
|
@@ -198,13 +198,14 @@ class DateTimePicker extends PureComponent {
|
|
|
198
198
|
}
|
|
199
199
|
|
|
200
200
|
DateTimePicker.propTypes = {
|
|
201
|
+
style: PropTypes.object.isRequired,
|
|
201
202
|
cancelButtonText: PropTypes.string,
|
|
202
203
|
confirmButtonText: PropTypes.string,
|
|
203
204
|
is24Hour: PropTypes.bool,
|
|
204
205
|
mode: PropTypes.oneOf(Object.values(DATEPICKER_MODES)),
|
|
205
|
-
onValueChanged: PropTypes.func,
|
|
206
206
|
textValue: PropTypes.string,
|
|
207
207
|
value: PropTypes.oneOfType([PropTypes.string, PropTypes.instanceOf(Date)]),
|
|
208
|
+
onValueChanged: PropTypes.func,
|
|
208
209
|
};
|
|
209
210
|
|
|
210
211
|
DateTimePicker.defaultProps = {
|
|
@@ -212,7 +213,9 @@ DateTimePicker.defaultProps = {
|
|
|
212
213
|
confirmButtonText: 'Confirm',
|
|
213
214
|
is24Hour: false,
|
|
214
215
|
mode: 'datetime',
|
|
216
|
+
textValue: undefined,
|
|
215
217
|
value: new Date(),
|
|
218
|
+
onValueChanged: undefined,
|
|
216
219
|
};
|
|
217
220
|
|
|
218
221
|
const StyledDateTimePicker = connectStyle('shoutem.ui.DateTimePicker')(
|
|
@@ -10,31 +10,8 @@ import { View } from '../View';
|
|
|
10
10
|
import { DropDownModal } from './DropDownModal';
|
|
11
11
|
|
|
12
12
|
const modalSpecificProps = ['visible', 'onClose'];
|
|
13
|
-
const dropDownMenuPropTypes = {
|
|
14
|
-
..._.omit(DropDownModal.propTypes, modalSpecificProps),
|
|
15
|
-
};
|
|
16
13
|
|
|
17
14
|
class DropDownMenu extends PureComponent {
|
|
18
|
-
/**
|
|
19
|
-
* @see DropDownModal.propTypes
|
|
20
|
-
*/
|
|
21
|
-
static propTypes = {
|
|
22
|
-
/**
|
|
23
|
-
* Icon displayed on dropdown menu button
|
|
24
|
-
*/
|
|
25
|
-
iconName: PropTypes.string,
|
|
26
|
-
/**
|
|
27
|
-
* Whether the text should be displayed next to dropdown icon or not
|
|
28
|
-
*/
|
|
29
|
-
showSelectedOption: PropTypes.bool,
|
|
30
|
-
...dropDownMenuPropTypes,
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
static defaultProps = {
|
|
34
|
-
iconName: 'drop-down',
|
|
35
|
-
showSelectedOption: true,
|
|
36
|
-
};
|
|
37
|
-
|
|
38
15
|
constructor(props) {
|
|
39
16
|
super(props);
|
|
40
17
|
|
|
@@ -105,6 +82,26 @@ class DropDownMenu extends PureComponent {
|
|
|
105
82
|
}
|
|
106
83
|
}
|
|
107
84
|
|
|
85
|
+
/**
|
|
86
|
+
* @see DropDownModal.propTypes
|
|
87
|
+
*/
|
|
88
|
+
DropDownMenu.propTypes = {
|
|
89
|
+
/**
|
|
90
|
+
* Icon displayed on dropdown menu button
|
|
91
|
+
*/
|
|
92
|
+
iconName: PropTypes.string,
|
|
93
|
+
/**
|
|
94
|
+
* Whether the text should be displayed next to dropdown icon or not
|
|
95
|
+
*/
|
|
96
|
+
showSelectedOption: PropTypes.bool,
|
|
97
|
+
..._.omit(DropDownModal.propTypes, modalSpecificProps),
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
DropDownMenu.defaultProps = {
|
|
101
|
+
iconName: 'drop-down',
|
|
102
|
+
showSelectedOption: true,
|
|
103
|
+
};
|
|
104
|
+
|
|
108
105
|
const StyledDropDownMenu = connectStyle('shoutem.ui.DropDownMenu')(
|
|
109
106
|
DropDownMenu,
|
|
110
107
|
);
|
|
@@ -15,57 +15,6 @@ import { View } from '../View';
|
|
|
15
15
|
const window = Dimensions.get('window');
|
|
16
16
|
|
|
17
17
|
class DropDownModal extends PureComponent {
|
|
18
|
-
static propTypes = {
|
|
19
|
-
/**
|
|
20
|
-
* Callback that is called when dropdown option is selected
|
|
21
|
-
*/
|
|
22
|
-
onOptionSelected: PropTypes.func,
|
|
23
|
-
/**
|
|
24
|
-
* Collection of objects which will be shown as options in DropDownMenu
|
|
25
|
-
*/
|
|
26
|
-
options: PropTypes.array.isRequired,
|
|
27
|
-
/**
|
|
28
|
-
* Selected option that will be shown.
|
|
29
|
-
*/
|
|
30
|
-
selectedOption: PropTypes.any.isRequired,
|
|
31
|
-
/**
|
|
32
|
-
* Key name that represents option's string value,
|
|
33
|
-
* and it will be displayed to the user in the UI
|
|
34
|
-
*/
|
|
35
|
-
titleProperty: PropTypes.string.isRequired,
|
|
36
|
-
/**
|
|
37
|
-
* Key name that represents option's value
|
|
38
|
-
*/
|
|
39
|
-
valueProperty: PropTypes.string.isRequired,
|
|
40
|
-
/**
|
|
41
|
-
* Number of options shown without scroll.
|
|
42
|
-
* Can be set trough DropDown style.visibleOptions.
|
|
43
|
-
* Prop definition overrides style.
|
|
44
|
-
*/
|
|
45
|
-
visibleOptions: PropTypes.number,
|
|
46
|
-
/**
|
|
47
|
-
* Optional render function, for every item in the list.
|
|
48
|
-
* Input parameter should be shaped as one of the items from the
|
|
49
|
-
* options object
|
|
50
|
-
*/
|
|
51
|
-
renderOption: PropTypes.func,
|
|
52
|
-
/**
|
|
53
|
-
* Visibility flag, controling the modal visibility
|
|
54
|
-
*/
|
|
55
|
-
visible: PropTypes.bool,
|
|
56
|
-
/**
|
|
57
|
-
* Callback that is called when modal should be closed
|
|
58
|
-
*/
|
|
59
|
-
onClose: PropTypes.func,
|
|
60
|
-
style: PropTypes.object,
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
static defaultProps = {
|
|
64
|
-
renderOption: (option, titleProperty) => (
|
|
65
|
-
<Text>{option[titleProperty].toUpperCase()}</Text>
|
|
66
|
-
),
|
|
67
|
-
};
|
|
68
|
-
|
|
69
18
|
static DEFAULT_VISIBLE_OPTIONS = 8;
|
|
70
19
|
|
|
71
20
|
constructor(props) {
|
|
@@ -111,14 +60,16 @@ class DropDownModal extends PureComponent {
|
|
|
111
60
|
close() {
|
|
112
61
|
const { onClose } = this.props;
|
|
113
62
|
|
|
114
|
-
if (onClose) {
|
|
63
|
+
if (_.isFunction(onClose)) {
|
|
115
64
|
onClose();
|
|
116
65
|
}
|
|
117
66
|
}
|
|
118
67
|
|
|
119
68
|
emitOnOptionSelectedEvent(option) {
|
|
120
|
-
|
|
121
|
-
|
|
69
|
+
const { onOptionSelected } = this.props;
|
|
70
|
+
|
|
71
|
+
if (_.isFunction(onOptionSelected)) {
|
|
72
|
+
onOptionSelected(option);
|
|
122
73
|
}
|
|
123
74
|
}
|
|
124
75
|
|
|
@@ -299,6 +250,57 @@ class DropDownModal extends PureComponent {
|
|
|
299
250
|
}
|
|
300
251
|
}
|
|
301
252
|
|
|
253
|
+
DropDownModal.propTypes = {
|
|
254
|
+
/**
|
|
255
|
+
* Collection of objects which will be shown as options in DropDownMenu
|
|
256
|
+
*/
|
|
257
|
+
options: PropTypes.array.isRequired,
|
|
258
|
+
/**
|
|
259
|
+
* Selected option that will be shown.
|
|
260
|
+
*/
|
|
261
|
+
selectedOption: PropTypes.any.isRequired,
|
|
262
|
+
style: PropTypes.object.isRequired,
|
|
263
|
+
/**
|
|
264
|
+
* Key name that represents option's string value,
|
|
265
|
+
* and it will be displayed to the user in the UI
|
|
266
|
+
*/
|
|
267
|
+
titleProperty: PropTypes.string.isRequired,
|
|
268
|
+
/**
|
|
269
|
+
* Optional render function, for every item in the list.
|
|
270
|
+
* Input parameter should be shaped as one of the items from the
|
|
271
|
+
* options object
|
|
272
|
+
*/
|
|
273
|
+
renderOption: PropTypes.func,
|
|
274
|
+
/**
|
|
275
|
+
* Visibility flag, controling the modal visibility
|
|
276
|
+
*/
|
|
277
|
+
visible: PropTypes.bool,
|
|
278
|
+
/**
|
|
279
|
+
* Number of options shown without scroll.
|
|
280
|
+
* Can be set trough DropDown style.visibleOptions.
|
|
281
|
+
* Prop definition overrides style.
|
|
282
|
+
*/
|
|
283
|
+
visibleOptions: PropTypes.number,
|
|
284
|
+
/**
|
|
285
|
+
* Callback that is called when modal should be closed
|
|
286
|
+
*/
|
|
287
|
+
onClose: PropTypes.func,
|
|
288
|
+
/**
|
|
289
|
+
* Callback that is called when dropdown option is selected
|
|
290
|
+
*/
|
|
291
|
+
onOptionSelected: PropTypes.func,
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
DropDownModal.defaultProps = {
|
|
295
|
+
renderOption: (option, titleProperty) => (
|
|
296
|
+
<Text>{option[titleProperty].toUpperCase()}</Text>
|
|
297
|
+
),
|
|
298
|
+
visible: false,
|
|
299
|
+
visibleOptions: undefined,
|
|
300
|
+
onClose: undefined,
|
|
301
|
+
onOptionSelected: undefined,
|
|
302
|
+
};
|
|
303
|
+
|
|
302
304
|
const StyledModal = connectStyle('shoutem.ui.DropDownModal')(DropDownModal);
|
|
303
305
|
|
|
304
306
|
export { StyledModal as DropDownModal };
|
|
@@ -8,11 +8,6 @@ import { Subtitle, Text } from './Text';
|
|
|
8
8
|
import { View } from './View';
|
|
9
9
|
|
|
10
10
|
class EmptyStateView extends PureComponent {
|
|
11
|
-
static defaultProps = {
|
|
12
|
-
retryButtonTitle: 'TRY AGAIN',
|
|
13
|
-
icon: 'error',
|
|
14
|
-
};
|
|
15
|
-
|
|
16
11
|
constructor(props) {
|
|
17
12
|
super(props);
|
|
18
13
|
|
|
@@ -20,13 +15,15 @@ class EmptyStateView extends PureComponent {
|
|
|
20
15
|
}
|
|
21
16
|
|
|
22
17
|
onRetry() {
|
|
23
|
-
this.props
|
|
18
|
+
const { onRetry } = this.props;
|
|
19
|
+
|
|
20
|
+
onRetry();
|
|
24
21
|
}
|
|
25
22
|
|
|
26
23
|
renderRetryButton() {
|
|
27
24
|
const { retryButtonTitle } = this.props;
|
|
28
25
|
|
|
29
|
-
// Show retry button at the bottom only if there is an onRetry action passed
|
|
26
|
+
// Show retry button at the bottom only if there is an onRetry action passed
|
|
30
27
|
return (
|
|
31
28
|
<View styleName="horizontal anchor-bottom">
|
|
32
29
|
<Button styleName="full-width" onPress={this.onRetry}>
|
|
@@ -37,10 +34,10 @@ class EmptyStateView extends PureComponent {
|
|
|
37
34
|
}
|
|
38
35
|
|
|
39
36
|
render() {
|
|
40
|
-
const { icon, message, onRetry } = this.props;
|
|
37
|
+
const { icon, message, onRetry, ...otherProps } = this.props;
|
|
41
38
|
|
|
42
39
|
return (
|
|
43
|
-
<View {...
|
|
40
|
+
<View {...otherProps} styleName="vertical flexible h-center v-center">
|
|
44
41
|
<View styleName="icon-placeholder">
|
|
45
42
|
<Icon name={icon} />
|
|
46
43
|
</View>
|
|
@@ -54,10 +51,17 @@ class EmptyStateView extends PureComponent {
|
|
|
54
51
|
}
|
|
55
52
|
|
|
56
53
|
EmptyStateView.propTypes = {
|
|
57
|
-
...EmptyStateView.propTypes,
|
|
58
|
-
onRetry: PropTypes.func,
|
|
59
|
-
message: PropTypes.string,
|
|
60
54
|
icon: PropTypes.string,
|
|
55
|
+
message: PropTypes.string,
|
|
56
|
+
retryButtonTitle: PropTypes.string,
|
|
57
|
+
onRetry: PropTypes.func,
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
EmptyStateView.defaultProps = {
|
|
61
|
+
icon: 'error',
|
|
62
|
+
message: undefined,
|
|
63
|
+
retryButtonTitle: 'TRY AGAIN',
|
|
64
|
+
onRetry: undefined,
|
|
61
65
|
};
|
|
62
66
|
|
|
63
67
|
const StyledView = connectStyle('shoutem.ui.EmptyStateView')(EmptyStateView);
|
package/components/FormGroup.js
CHANGED
|
@@ -5,7 +5,9 @@ import { View } from './View';
|
|
|
5
5
|
|
|
6
6
|
class FormGroup extends PureComponent {
|
|
7
7
|
render() {
|
|
8
|
-
|
|
8
|
+
const { children, ...otherProps } = this.props;
|
|
9
|
+
|
|
10
|
+
return <View {...otherProps}>{children}</View>;
|
|
9
11
|
}
|
|
10
12
|
}
|
|
11
13
|
|
|
@@ -13,6 +15,10 @@ FormGroup.propTypes = {
|
|
|
13
15
|
...View.propTypes,
|
|
14
16
|
};
|
|
15
17
|
|
|
18
|
+
FormGroup.defaultProps = {
|
|
19
|
+
...View.defaultProps,
|
|
20
|
+
};
|
|
21
|
+
|
|
16
22
|
const AnimatedFormGroup = connectAnimation(FormGroup);
|
|
17
23
|
const StyledFormGroup = connectStyle('shoutem.ui.FormGroup')(AnimatedFormGroup);
|
|
18
24
|
|
package/components/GridRow.js
CHANGED
|
@@ -19,61 +19,20 @@ import { Page } from './Page';
|
|
|
19
19
|
*
|
|
20
20
|
*/
|
|
21
21
|
class HorizontalPager extends PureComponent {
|
|
22
|
-
static propTypes = {
|
|
23
|
-
// Prop defining whether the Pager will bounce back
|
|
24
|
-
// when user tries to swipe beyond end of content (iOS only)
|
|
25
|
-
bounces: PropTypes.bool,
|
|
26
|
-
// Array containing objects (pages)
|
|
27
|
-
data: PropTypes.arrayOf(PropTypes.object).isRequired,
|
|
28
|
-
// Callback function called when user swipes between pages (images)
|
|
29
|
-
// Index of new (selected) page is passed to this callback
|
|
30
|
-
onIndexSelected: PropTypes.func,
|
|
31
|
-
// Page margin, margin visible between pages, during swipe gesture.
|
|
32
|
-
pageMargin: PropTypes.number,
|
|
33
|
-
// A function which renders a single page
|
|
34
|
-
// renderPage(pageData, pageIndex)
|
|
35
|
-
renderPage: PropTypes.func,
|
|
36
|
-
// Callback function that can be used to render overlay over pages
|
|
37
|
-
// For example page indicators using `PageIndicators` component
|
|
38
|
-
// renderOverlay(pageData, pageIndex, layout)
|
|
39
|
-
renderOverlay: PropTypes.func,
|
|
40
|
-
// Callback function that can be used to define placeholder
|
|
41
|
-
// that appears when content is loading
|
|
42
|
-
renderPlaceholder: PropTypes.func,
|
|
43
|
-
// Initially selected page in gallery
|
|
44
|
-
selectedIndex: PropTypes.number,
|
|
45
|
-
// Prop that forces enables or disables swiping
|
|
46
|
-
scrollEnabled: PropTypes.bool,
|
|
47
|
-
// Style prop used to override default (theme) styling
|
|
48
|
-
style: PropTypes.object,
|
|
49
|
-
// Prop that reduces page size by pageMargin, allowing 'sneak peak' of next page
|
|
50
|
-
showNextPage: PropTypes.bool,
|
|
51
|
-
// Always render only central (currently loaded) page plus `surroundingPagesToLoad`
|
|
52
|
-
// to the left and to the right. If currently rendered page is out of bounds,
|
|
53
|
-
// empty `View` (with set dimensions for proper scrolling) will be rendered
|
|
54
|
-
// Defaults to 2.
|
|
55
|
-
surroundingPagesToLoad: PropTypes.number,
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
static defaultProps = {
|
|
59
|
-
pageMargin: 0,
|
|
60
|
-
selectedIndex: 0,
|
|
61
|
-
showNextPage: false,
|
|
62
|
-
surroundingPagesToLoad: 2,
|
|
63
|
-
};
|
|
64
|
-
|
|
65
22
|
constructor(props) {
|
|
66
23
|
super(props);
|
|
67
24
|
|
|
68
25
|
autoBindReact(this);
|
|
69
26
|
|
|
27
|
+
const { selectedIndex, pageMargin, showNextPage } = props;
|
|
28
|
+
|
|
70
29
|
this.state = {
|
|
71
30
|
width: 0,
|
|
72
31
|
height: 0,
|
|
73
|
-
selectedIndex
|
|
74
|
-
initialSelectedIndex:
|
|
75
|
-
pageMargin
|
|
76
|
-
showNextPage
|
|
32
|
+
selectedIndex,
|
|
33
|
+
initialSelectedIndex: selectedIndex,
|
|
34
|
+
pageMargin,
|
|
35
|
+
showNextPage,
|
|
77
36
|
shouldRenderContent: false,
|
|
78
37
|
scrolledToInitialIndex: false,
|
|
79
38
|
};
|
|
@@ -98,16 +57,17 @@ class HorizontalPager extends PureComponent {
|
|
|
98
57
|
}
|
|
99
58
|
|
|
100
59
|
onLayoutContainer(event) {
|
|
101
|
-
const { width, height } = event.nativeEvent.layout;
|
|
102
|
-
const { scrolledToInitialIndex } = this.state;
|
|
60
|
+
const { width: newWidth, height: newHeight } = event.nativeEvent.layout;
|
|
61
|
+
const { scrolledToInitialIndex, width, height } = this.state;
|
|
103
62
|
|
|
104
|
-
if (
|
|
63
|
+
if (width === newWidth && height === newHeight) {
|
|
105
64
|
return;
|
|
106
65
|
}
|
|
107
66
|
|
|
108
67
|
this.setState({ width, height }, () => {
|
|
109
|
-
// By checking has the pager scrolled to initial index, we're avoiding
|
|
110
|
-
// where pager would scroll back to initial index after
|
|
68
|
+
// By checking has the pager scrolled to initial index, we're avoiding
|
|
69
|
+
// a weird issue where pager would scroll back to initial index after
|
|
70
|
+
// swiping to other index
|
|
111
71
|
if (!scrolledToInitialIndex) {
|
|
112
72
|
requestAnimationFrame(() => this.scrollToInitialPage());
|
|
113
73
|
}
|
|
@@ -312,6 +272,55 @@ class HorizontalPager extends PureComponent {
|
|
|
312
272
|
}
|
|
313
273
|
}
|
|
314
274
|
|
|
275
|
+
HorizontalPager.propTypes = {
|
|
276
|
+
// Array containing objects (pages)
|
|
277
|
+
data: PropTypes.arrayOf(PropTypes.object).isRequired,
|
|
278
|
+
// Style prop used to override default (theme) styling
|
|
279
|
+
style: PropTypes.object.isRequired,
|
|
280
|
+
// Prop defining whether the Pager will bounce back
|
|
281
|
+
// when user tries to swipe beyond end of content (iOS only)
|
|
282
|
+
bounces: PropTypes.bool,
|
|
283
|
+
// Page margin, margin visible between pages, during swipe gesture.
|
|
284
|
+
pageMargin: PropTypes.number,
|
|
285
|
+
// Callback function that can be used to render overlay over pages
|
|
286
|
+
// For example page indicators using `PageIndicators` component
|
|
287
|
+
// renderOverlay(pageData, pageIndex, layout)
|
|
288
|
+
renderOverlay: PropTypes.func,
|
|
289
|
+
// A function which renders a single page
|
|
290
|
+
// renderPage(pageData, pageIndex)
|
|
291
|
+
renderPage: PropTypes.func,
|
|
292
|
+
// Callback function that can be used to define placeholder
|
|
293
|
+
// that appears when content is loading
|
|
294
|
+
renderPlaceholder: PropTypes.func,
|
|
295
|
+
// Prop that forces enables or disables swiping
|
|
296
|
+
scrollEnabled: PropTypes.bool,
|
|
297
|
+
// Initially selected page in gallery
|
|
298
|
+
selectedIndex: PropTypes.number,
|
|
299
|
+
// Prop that reduces page size by pageMargin, allowing 'sneak peak' of next page
|
|
300
|
+
showNextPage: PropTypes.bool,
|
|
301
|
+
// Always render only central (currently loaded) page plus `surroundingPagesToLoad`
|
|
302
|
+
// to the left and to the right. If currently rendered page is out of bounds,
|
|
303
|
+
// empty `View` (with set dimensions for proper scrolling) will be rendered
|
|
304
|
+
// Defaults to 2.
|
|
305
|
+
surroundingPagesToLoad: PropTypes.number,
|
|
306
|
+
// Callback function called when user swipes between pages (images)
|
|
307
|
+
// Index of new (selected) page is passed to this callback
|
|
308
|
+
onIndexSelected: PropTypes.func,
|
|
309
|
+
};
|
|
310
|
+
|
|
311
|
+
HorizontalPager.defaultProps = {
|
|
312
|
+
bounces: false,
|
|
313
|
+
pageMargin: 0,
|
|
314
|
+
renderOverlay: undefined,
|
|
315
|
+
renderPage: undefined,
|
|
316
|
+
renderPlaceholder: undefined,
|
|
317
|
+
scrollEnabled: false,
|
|
318
|
+
selectedIndex: 0,
|
|
319
|
+
showNextPage: false,
|
|
320
|
+
surroundingPagesToLoad: 2,
|
|
321
|
+
onIndexSelected: undefined,
|
|
322
|
+
};
|
|
323
|
+
|
|
315
324
|
const StyledHorizontalPager = connectStyle('shoutem.ui.HorizontalPager')(
|
|
316
325
|
HorizontalPager,
|
|
317
326
|
);
|
|
@@ -8,13 +8,6 @@ import { View } from '../View';
|
|
|
8
8
|
* rendering of pages that are not currently visible.
|
|
9
9
|
*/
|
|
10
10
|
export class Page extends Component {
|
|
11
|
-
static propTypes = {
|
|
12
|
-
isActive: PropTypes.bool.isRequired,
|
|
13
|
-
width: PropTypes.number.isRequired,
|
|
14
|
-
style: PropTypes.object,
|
|
15
|
-
children: PropTypes.node,
|
|
16
|
-
};
|
|
17
|
-
|
|
18
11
|
shouldComponentUpdate(nextProps) {
|
|
19
12
|
return nextProps.isActive;
|
|
20
13
|
}
|
|
@@ -29,3 +22,15 @@ export class Page extends Component {
|
|
|
29
22
|
);
|
|
30
23
|
}
|
|
31
24
|
}
|
|
25
|
+
|
|
26
|
+
Page.propTypes = {
|
|
27
|
+
isActive: PropTypes.bool.isRequired,
|
|
28
|
+
width: PropTypes.number.isRequired,
|
|
29
|
+
children: PropTypes.node,
|
|
30
|
+
style: PropTypes.object,
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
Page.defaultProps = {
|
|
34
|
+
children: undefined,
|
|
35
|
+
style: {},
|
|
36
|
+
};
|