@shoutem/ui 5.5.0 → 5.6.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.
@@ -12,26 +12,91 @@ class TabMenu extends PureComponent {
12
12
  super(props);
13
13
 
14
14
  autoBindReact(this);
15
+
16
+ this.state = {
17
+ itemWidths: {},
18
+ scrollOffset: 0,
19
+ };
15
20
  }
16
21
 
17
- handleOptionSelected(option) {
22
+ handleOptionSelected(key, option) {
18
23
  const { onOptionSelected } = this.props;
24
+ const { scrollOffset, itemWidths, viewportHorizontal } = this.state;
25
+
26
+ let itemStart = 0;
27
+
28
+ _.forEach(itemWidths, (itemWidth, index) => {
29
+ if (index < key) {
30
+ itemStart += itemWidth;
31
+ }
32
+ });
33
+
34
+ const itemEnd = itemStart + itemWidths[key];
19
35
 
20
36
  LayoutAnimation.easeInEaseOut();
21
37
  onOptionSelected(option);
38
+
39
+ if (itemEnd > _.last(viewportHorizontal)) {
40
+ const extraScroll = itemEnd - _.last(viewportHorizontal);
41
+
42
+ this.scroll.scrollTo({
43
+ x: extraScroll + scrollOffset,
44
+ y: 0,
45
+ animated: true,
46
+ });
47
+ }
48
+
49
+ if (itemStart < _.head(viewportHorizontal)) {
50
+ const extraScroll = _.head(viewportHorizontal) - itemStart;
51
+
52
+ this.scroll.scrollTo({
53
+ x: scrollOffset - extraScroll,
54
+ y: 0,
55
+ animated: true,
56
+ });
57
+ }
58
+ }
59
+
60
+ handleItemLayout(key, width) {
61
+ const { itemWidths } = this.state;
62
+
63
+ this.setState({
64
+ itemWidths: {
65
+ ...itemWidths,
66
+ [key]: width,
67
+ },
68
+ });
69
+ }
70
+
71
+ handleScroll({
72
+ nativeEvent: {
73
+ contentOffset: { x },
74
+ layoutMeasurement: { width },
75
+ },
76
+ }) {
77
+ this.setState({ scrollOffset: x, viewportHorizontal: [x, x + width] });
78
+ }
79
+
80
+ handleScrollLayout({
81
+ nativeEvent: {
82
+ layout: { width },
83
+ },
84
+ }) {
85
+ this.setState({ viewportHorizontal: [0, width] });
22
86
  }
23
87
 
24
- renderOption(option) {
88
+ renderOption(option, key) {
25
89
  const { selectedOption } = this.props;
26
90
 
27
91
  const isSelected = selectedOption && option.title === selectedOption.title;
28
92
 
29
93
  return (
30
94
  <TabMenuItem
31
- key={option.title}
95
+ key={key}
32
96
  isSelected={isSelected}
33
97
  item={option}
34
- onItemPressed={this.handleOptionSelected}
98
+ onItemPressed={option => this.handleOptionSelected(key, option)}
99
+ onLayoutMeasured={width => this.handleItemLayout(key, width)}
35
100
  />
36
101
  );
37
102
  }
@@ -43,6 +108,11 @@ class TabMenu extends PureComponent {
43
108
  <ScrollView
44
109
  horizontal
45
110
  contentContainerStyle={style.container}
111
+ onScroll={this.handleScroll}
112
+ onLayout={this.handleScrollLayout}
113
+ ref={ref => {
114
+ this.scroll = ref;
115
+ }}
46
116
  showsHorizontalScrollIndicator={false}
47
117
  style={style.list}
48
118
  >
@@ -1,7 +1,6 @@
1
1
  import React, { PureComponent } from 'react';
2
2
  import { LayoutAnimation } from 'react-native';
3
3
  import autoBindReact from 'auto-bind/react';
4
- import _ from 'lodash';
5
4
  import PropTypes from 'prop-types';
6
5
  import { connectStyle } from '@shoutem/theme';
7
6
  import { Text } from '../Text';
@@ -26,7 +25,7 @@ class TabMenuItem extends PureComponent {
26
25
  onItemPressed(item);
27
26
  }
28
27
 
29
- handleLayout({
28
+ handleTextLayout({
30
29
  nativeEvent: {
31
30
  layout: { width },
32
31
  },
@@ -35,6 +34,16 @@ class TabMenuItem extends PureComponent {
35
34
  this.setState({ baseWidth: width });
36
35
  }
37
36
 
37
+ handleContainerLayout({
38
+ nativeEvent: {
39
+ layout: { width },
40
+ },
41
+ }) {
42
+ const { onLayoutMeasured } = this.props;
43
+
44
+ onLayoutMeasured(width);
45
+ }
46
+
38
47
  render() {
39
48
  const { style, isSelected, item } = this.props;
40
49
  const { baseWidth } = this.state;
@@ -42,11 +51,12 @@ class TabMenuItem extends PureComponent {
42
51
  return (
43
52
  <TouchableOpacity
44
53
  onPress={this.handleItemPressed}
54
+ onLayout={this.handleContainerLayout}
45
55
  styleName="vertical h-center"
46
56
  >
47
57
  <Text
48
58
  style={[style.text, isSelected && style.selectedText]}
49
- onLayout={this.handleLayout}
59
+ onLayout={this.handleTextLayout}
50
60
  >
51
61
  {item.title}
52
62
  </Text>
@@ -58,6 +68,7 @@ class TabMenuItem extends PureComponent {
58
68
 
59
69
  TabMenuItem.propTypes = {
60
70
  style: PropTypes.object.isRequired,
71
+ onLayoutMeasured: PropTypes.func.isRequired,
61
72
  isSelected: PropTypes.bool,
62
73
  item: optionShape,
63
74
  onItemPressed: PropTypes.func,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shoutem/ui",
3
- "version": "5.5.0",
3
+ "version": "5.6.0",
4
4
  "description": "Styleable set of components for React Native applications",
5
5
  "scripts": {
6
6
  "lint": "eslint .",
package/theme.js CHANGED
@@ -1,4 +1,4 @@
1
- import { Dimensions, Platform, StatusBar, StyleSheet } from 'react-native';
1
+ import { Dimensions, Platform, StyleSheet } from 'react-native';
2
2
  import {
3
3
  changeColorAlpha,
4
4
  createSharedStyle,
@@ -2899,7 +2899,6 @@ export default () => {
2899
2899
  borderRadius: 1,
2900
2900
  flexDirection: 'row',
2901
2901
  marginBottom: 8,
2902
- marginLeft: 8,
2903
2902
  },
2904
2903
  text: {
2905
2904
  marginTop: 12,