@momo-kits/step 0.0.49-beta → 0.0.49-beta.2

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,434 @@
1
+ import React, { Component } from 'react';
2
+ import { View, StyleSheet, Image, Dimensions, ScrollView } from 'react-native';
3
+
4
+ import PropTypes from 'prop-types';
5
+ import Colors from '../../core/colors';
6
+ import Text from '../../core/components/typography';
7
+ import { Icons as IconSource } from '../../core/icons';
8
+
9
+ const CIRCLE_SIZE = 24;
10
+ const SCREEN_WIDTH = Dimensions.get('window').width;
11
+
12
+ const styles = StyleSheet.create({
13
+ circle: {
14
+ width: CIRCLE_SIZE,
15
+ height: CIRCLE_SIZE,
16
+ borderRadius: CIRCLE_SIZE / 2,
17
+ borderWidth: 2,
18
+ padding: 4,
19
+ },
20
+ iconImage: {
21
+ width: 16,
22
+ height: 16,
23
+ position: 'absolute',
24
+ top: 2,
25
+ left: 2,
26
+ },
27
+ titleDefault: {
28
+ fontSize: 14,
29
+ color: Colors.black_12,
30
+ fontWeight: 'normal',
31
+ },
32
+ titleActive: {
33
+ fontSize: 14,
34
+ color: Colors.black_17,
35
+ fontWeight: 'bold',
36
+ },
37
+ description: {
38
+ fontSize: 12,
39
+ color: Colors.black_12,
40
+ marginBottom: 16,
41
+ paddingTop: 4,
42
+ paddingLeft: 11,
43
+ },
44
+ date: {
45
+ fontSize: 10,
46
+ color: Colors.black_12,
47
+ },
48
+ number: {
49
+ fontSize: 12,
50
+ color: 'white',
51
+ textAlign: 'center',
52
+ lineHeight: 13,
53
+ },
54
+ lineHorizontal: {
55
+ height: 2,
56
+ width: '100%',
57
+ },
58
+ minHeight: {
59
+ minHeight: 12,
60
+ marginBottom: 4,
61
+ },
62
+ });
63
+
64
+ export default class HorizontalStep extends Component {
65
+ constructor(props) {
66
+ super(props);
67
+ this.state = {
68
+ width: 0,
69
+ height: 0,
70
+ };
71
+ }
72
+
73
+ onLayout = (e) => {
74
+ this.setState({
75
+ width: e.nativeEvent.layout.width,
76
+ height: e.nativeEvent.layout.height,
77
+ });
78
+ };
79
+
80
+ _renderCircleImage = ({
81
+ icon = '',
82
+ circleColor = '',
83
+ circleBorderColor = '',
84
+ }) => {
85
+ return (
86
+ <View>
87
+ <View
88
+ style={[
89
+ styles.circle,
90
+ {
91
+ backgroundColor: circleColor,
92
+ borderColor: circleBorderColor,
93
+ },
94
+ ]}>
95
+ <Image
96
+ source={icon}
97
+ style={[styles.iconImage, { tintColor: '#ffffff' }]}
98
+ />
99
+ </View>
100
+ </View>
101
+ );
102
+ };
103
+
104
+ _renderCircleText = ({
105
+ circleColor = '',
106
+ circleBorderColor = '',
107
+ index = 0,
108
+ }) => {
109
+ return (
110
+ <View>
111
+ <View
112
+ style={[
113
+ styles.circle,
114
+ {
115
+ backgroundColor: circleColor,
116
+ borderColor: circleBorderColor,
117
+ },
118
+ ]}>
119
+ <Text style={styles.number}>{index + 1}</Text>
120
+ </View>
121
+ </View>
122
+ );
123
+ };
124
+
125
+ _renderDateOrValue = ({
126
+ date = '',
127
+ isActiveState = false,
128
+ circleChecked = false,
129
+ minHeight = 0,
130
+ dateStyle = {},
131
+ index = 0,
132
+ }) => {
133
+ // Init states in render function
134
+ let resultComponent = <></>;
135
+ if (!date) {
136
+ return resultComponent;
137
+ }
138
+ if (isActiveState || circleChecked) {
139
+ resultComponent = (
140
+ <Text
141
+ style={[
142
+ styles.date,
143
+ dateStyle,
144
+ { minHeight: 12, marginBottom: 4 },
145
+ ]}>
146
+ {date[index]}
147
+ </Text>
148
+ );
149
+ } else {
150
+ resultComponent = <View style={minHeight}></View>;
151
+ }
152
+ return resultComponent;
153
+ };
154
+
155
+ _renderCircle = ({
156
+ circleColor = '',
157
+ circleBorderColor = '',
158
+ isActiveState = false,
159
+ circleUnchecked = false,
160
+ iconActive = {},
161
+ iconUnchecked = {},
162
+ icon = {},
163
+ index = 0,
164
+ }) => {
165
+ let resultComponent = <></>;
166
+ if (!isActiveState) {
167
+ if (circleUnchecked) {
168
+ if (Object.keys(iconUnchecked).length === 0) {
169
+ resultComponent = this._renderCircleImage({
170
+ icon,
171
+ circleColor,
172
+ circleBorderColor,
173
+ });
174
+ } else {
175
+ resultComponent = this._renderCircleText({
176
+ circleColor,
177
+ circleBorderColor,
178
+ index,
179
+ });
180
+ }
181
+ } else {
182
+ resultComponent = this._renderCircleImage({
183
+ icon,
184
+ circleColor,
185
+ circleBorderColor,
186
+ });
187
+ }
188
+ } else {
189
+ // This is active case
190
+ // If icon diff "" & regex http or https url so will render image component
191
+ if (Object.keys(iconActive).length === 0) {
192
+ resultComponent = this._renderCircleImage({
193
+ icon,
194
+ circleColor,
195
+ circleBorderColor,
196
+ });
197
+ } else {
198
+ // Otherwise render index number in text component
199
+ resultComponent = resultComponent = this._renderCircleText({
200
+ circleColor,
201
+ circleBorderColor,
202
+ index,
203
+ });
204
+ }
205
+ }
206
+ return resultComponent;
207
+ };
208
+
209
+ _renderTitle = ({ textFontStyle = {}, titleStyle = {}, value = {} }) => {
210
+ let resultComponent = (
211
+ <View>
212
+ <Text.Caption
213
+ style={[{ marginTop: 4 }, textFontStyle, titleStyle]}>
214
+ {value}
215
+ </Text.Caption>
216
+ </View>
217
+ );
218
+ return resultComponent;
219
+ };
220
+
221
+ _renderDescription = ({ items = {}, descriptionStyle = {}, index = 0 }) => {
222
+ let resultComponent = <></>;
223
+
224
+ if (items) {
225
+ resultComponent = (
226
+ <View>
227
+ <Text style={[{ fontSize: 10 }, descriptionStyle]}>
228
+ {items[index]}
229
+ </Text>
230
+ </View>
231
+ );
232
+ }
233
+ return resultComponent;
234
+ };
235
+
236
+ _renderLine = ({
237
+ titles = {},
238
+ index = 0,
239
+ lineRight = 0,
240
+ lineWidth = 0,
241
+ lineActive = '',
242
+ date = {},
243
+ }) => {
244
+ let resultComponent = <></>;
245
+
246
+ if (titles?.length - 1 !== index) {
247
+ resultComponent = (
248
+ <View
249
+ style={{
250
+ position: 'absolute',
251
+ right: lineRight,
252
+ width: lineWidth,
253
+ zIndex: -1,
254
+ }}>
255
+ <View
256
+ style={[
257
+ styles.lineHorizontal,
258
+ {
259
+ backgroundColor: lineActive,
260
+ },
261
+ date ? { marginTop: 27 } : { marginTop: 27 - 16 },
262
+ /* subtracting spacing from date */
263
+ ]}
264
+ />
265
+ </View>
266
+ );
267
+ }
268
+ return resultComponent;
269
+ };
270
+
271
+ circleColumn = (value, index) => {
272
+ const {
273
+ currentStep,
274
+ titles,
275
+ iconActive,
276
+ iconChecked,
277
+ iconUnchecked,
278
+ circleColorActive,
279
+ circleColorChecked,
280
+ circleColorUnchecked,
281
+ circleBorderColorActive,
282
+ circleBorderColorChecked,
283
+ circleBorderColorUnchecked,
284
+ lineColorActive,
285
+ lineColorInActive,
286
+ items,
287
+ date,
288
+ isVertical,
289
+ titleStyle,
290
+ descriptionStyle,
291
+ dateStyle,
292
+ } = this.props;
293
+
294
+ // Three circle states
295
+ const isActiveState = currentStep == index + 1;
296
+ const circleChecked = currentStep > index + 1;
297
+ const circleUnchecked = currentStep < index + 1;
298
+
299
+ // Default properties is inactive state
300
+ let icon = {};
301
+ let circleColor = circleColorUnchecked || Colors.black_06;
302
+ let circleBorderColor = circleBorderColorUnchecked || Colors.black_04;
303
+ let textFontStyle = styles.titleDefault;
304
+ let lineActive = lineColorInActive || Colors.black_04;
305
+ let minHeight = !isVertical && styles.minHeight;
306
+
307
+ let tintColor = '#ffd6e7';
308
+
309
+ // This is all properties in active state
310
+ if (isActiveState) {
311
+ icon = iconActive || index + 1;
312
+ circleColor = circleColorActive || '#d82d8b';
313
+ circleBorderColor = circleBorderColorActive || Colors.pink_09;
314
+ textFontStyle = styles.titleActive;
315
+ }
316
+
317
+ if (circleChecked) {
318
+ icon = iconChecked || IconSource.ic_check_24;
319
+ lineActive = lineColorActive || tintColor;
320
+ circleColor = circleColorChecked || '#ffadd2';
321
+ circleBorderColor = circleBorderColorChecked || Colors.pink_09;
322
+ }
323
+
324
+ if (circleUnchecked) {
325
+ icon = iconUnchecked || index + 1;
326
+ }
327
+
328
+ const lineWidth = Math.round(
329
+ (SCREEN_WIDTH - 10 - CIRCLE_SIZE - 4) / titles.length,
330
+ );
331
+ const lineRight = parseInt(`-${lineWidth / 2}`);
332
+
333
+ return (
334
+ <View
335
+ key={index}
336
+ style={{
337
+ flexDirection: 'row',
338
+ flex: 1,
339
+ justifyContent: 'center',
340
+ }}>
341
+ <View
342
+ style={{
343
+ flexDirection: 'column',
344
+ alignItems: 'center',
345
+ }}>
346
+ {this._renderDateOrValue({
347
+ date,
348
+ isActiveState,
349
+ circleChecked,
350
+ minHeight,
351
+ dateStyle,
352
+ index,
353
+ })}
354
+ {this._renderCircle({
355
+ circleColor,
356
+ circleBorderColor,
357
+ isActiveState,
358
+ circleUnchecked,
359
+ iconActive,
360
+ iconUnchecked,
361
+ icon,
362
+ index,
363
+ })}
364
+ {this._renderTitle({
365
+ textFontStyle,
366
+ titleStyle,
367
+ value,
368
+ })}
369
+ {this._renderDescription({
370
+ items,
371
+ descriptionStyle,
372
+ index,
373
+ })}
374
+ </View>
375
+ {this._renderLine({
376
+ titles,
377
+ index,
378
+ lineRight,
379
+ lineWidth,
380
+ lineActive,
381
+ date,
382
+ })}
383
+ </View>
384
+ );
385
+ };
386
+
387
+ renderCircle = () => {
388
+ const { titles = [[]] } = this.props;
389
+ return titles.map(this.circleColumn);
390
+ };
391
+
392
+ render() {
393
+ const { style = {} } = this.props;
394
+ return (
395
+ <ScrollView>
396
+ <View style={[style]} onLayout={this.onLayout}>
397
+ <View
398
+ style={{
399
+ flexDirection: 'row',
400
+ }}>
401
+ {this.renderCircle()}
402
+ </View>
403
+ </View>
404
+ </ScrollView>
405
+ );
406
+ }
407
+ }
408
+
409
+ HorizontalStep.propTypes = {
410
+ titles: PropTypes.array,
411
+ currentStep: PropTypes.number,
412
+ style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
413
+ items: PropTypes.array,
414
+ isVertical: PropTypes.bool,
415
+ iconActive: PropTypes.any,
416
+ iconChecked: PropTypes.any,
417
+ iconUnchecked: PropTypes.any,
418
+ circleColorActive: PropTypes.string,
419
+ circleColorChecked: PropTypes.string,
420
+ circleColorUnchecked: PropTypes.string,
421
+ circleBorderColorActive: PropTypes.string,
422
+ circleBorderColorChecked: PropTypes.string,
423
+ circleBorderColorUnchecked: PropTypes.string,
424
+ lineColorActive: PropTypes.string,
425
+ lineColorInActive: PropTypes.string,
426
+ titleStyle: PropTypes.object,
427
+ descriptionStyle: PropTypes.object,
428
+ dateStyle: PropTypes.object,
429
+ };
430
+
431
+ HorizontalStep.defaultProps = {
432
+ titles: [],
433
+ currentStep: 0,
434
+ };
package/Step.js CHANGED
@@ -1,171 +1,56 @@
1
1
  import React, { Component } from 'react';
2
- import { View, StyleSheet } from 'react-native';
3
-
4
2
  import PropTypes from 'prop-types';
5
- import {
6
- Colors, Text, IconSource, Image
7
- } from '@momo-kits/core';
8
-
9
- const CIRCLE_SIZE = 18;
10
-
11
- const styles = StyleSheet.create({
12
- circle: {
13
- width: CIRCLE_SIZE,
14
- height: CIRCLE_SIZE,
15
- borderWidth: 1,
16
- borderColor: Colors.sepia_05,
17
- borderRadius: 9,
18
- backgroundColor: 'white'
19
- },
20
- line: {
21
- height: 1,
22
- backgroundColor: 'white',
23
- borderWidth: 1,
24
- borderRadius: 1,
25
- borderStyle: 'dashed',
26
- zIndex: 0,
27
- marginTop: 9
28
- },
29
- topRight: {
30
- position: 'absolute',
31
- right: -1,
32
- top: -1,
33
- width: 1,
34
- height: '100%',
35
- backgroundColor: 'white',
36
- zIndex: 1
37
- },
38
- topLeft: {
39
- position: 'absolute',
40
- left: -1,
41
- top: -1,
42
- width: '100%',
43
- height: 1,
44
- backgroundColor: 'white',
45
- zIndex: 1
46
- },
47
- topLeftWidth: {
48
- position: 'absolute',
49
- left: -1,
50
- top: -1,
51
- width: 1,
52
- height: '100%',
53
- backgroundColor: 'white',
54
- zIndex: 1
55
- },
56
- circleRow: {
57
- position: 'absolute',
58
- justifyContent: 'space-between',
59
- flexDirection: 'row',
60
- },
61
- titleDefault: {
62
- color: Colors.black_12
63
- },
64
- titleActive: {
65
- color: Colors.black_17,
66
- fontWeight: 'bold'
67
- },
68
- containerStyle: {
69
- minHeight: CIRCLE_SIZE + 20 + CIRCLE_SIZE
70
- }
71
- });
3
+ import HorizontalStep from './Step.horizontal';
4
+ import VerticalStep from './Step.vertical';
72
5
 
6
+ import { Colors, IconSource } from '@momo-kits/core';
73
7
  export default class Step extends Component {
74
8
  constructor(props) {
75
9
  super(props);
76
- this.state = {
77
- width: 0
78
- };
79
- }
80
-
81
- onLayout = (e) => {
82
- this.setState({ width: e.nativeEvent.layout.width });
83
- }
84
-
85
- renderLine = () => {
86
- const { lineColor } = this.props;
87
- return (
88
- <View style={[styles.line, { borderColor: lineColor }]}>
89
- <View style={styles.topLeft} />
90
- <View style={styles.topLeftWidth} />
91
- <View style={styles.topRight} />
92
- </View>
93
- );
94
- }
95
-
96
- circle = (value, index) => {
97
- const { currentStep, tintColor, data } = this.props;
98
- const { width } = this.state;
99
- const icon = currentStep >= (index + 1) ? IconSource.ic_step_active : IconSource.ic_step_coming;
100
- const textFontStyle = currentStep >= (index + 1) ? styles.titleActive : styles.titleDefault;
101
- const itemWidth = (width - CIRCLE_SIZE) / data?.length;
102
- let left = 0;
103
- let textAlignStyle = { textAlign: 'center' };
104
- /**
105
- * item lefr
106
- */
107
- if (index === 0) {
108
- left = 0;
109
- textAlignStyle = { textAlign: 'left' };
110
-
111
- /**
112
- * item right
113
- */
114
- } else if (index === data?.length - 1) {
115
- left = -itemWidth + CIRCLE_SIZE;
116
- textAlignStyle = { textAlign: 'right' };
117
- /**
118
- * center item
119
- */
120
- } else { left = -itemWidth / 2 + CIRCLE_SIZE / 2; }
121
- const textStyle = [textAlignStyle, textFontStyle];
122
- return (
123
- <View>
124
- <Image source={icon} style={[styles.circle, { tintColor }]} />
125
- <View style={{
126
- position: 'absolute',
127
- width: itemWidth,
128
- left,
129
- top: CIRCLE_SIZE + CIRCLE_SIZE / 2
130
- }}
131
- >
132
- <Text.Title style={textStyle}>{value}</Text.Title>
133
- </View>
134
- </View>
135
- );
136
- }
137
-
138
- renderCircle = () => {
139
- const { data = [] } = this.props;
140
- const views = data.map(this.circle);
141
- return views;
142
10
  }
143
11
 
144
12
  render() {
145
- const { width } = this.state;
146
- const { style } = this.props;
147
- return (
148
- <View style={[styles.containerStyle, style]} onLayout={this.onLayout}>
149
- {this.renderLine()}
150
- <View style={[styles.circleRow, { width }]}>
151
- {this.renderCircle()}
152
- </View>
153
- </View>
154
- );
13
+ const { isVertical } = this.props;
14
+ let DefaultComponent = HorizontalStep;
15
+ if (isVertical) {
16
+ DefaultComponent = VerticalStep;
17
+ }
18
+ return <DefaultComponent {...this.props} />;
155
19
  }
156
20
  }
157
21
 
158
22
  Step.propTypes = {
159
- lineColor: PropTypes.string,
160
- data: PropTypes.arrayOf(PropTypes.string),
23
+ titles: PropTypes.array,
161
24
  currentStep: PropTypes.number,
162
- tintColor: PropTypes.string,
163
25
  style: PropTypes.oneOfType([PropTypes.object, PropTypes.array]),
26
+ items: PropTypes.array,
27
+ isVertical: PropTypes.bool,
28
+ iconActive: PropTypes.any,
29
+ iconChecked: PropTypes.any,
30
+ iconUnchecked: PropTypes.any,
31
+ circleColorActive: PropTypes.string,
32
+ circleColorChecked: PropTypes.string,
33
+ circleColorUnchecked: PropTypes.string,
34
+ circleBorderColorActive: PropTypes.string,
35
+ circleBorderColorChecked: PropTypes.string,
36
+ circleBorderColorUnchecked: PropTypes.string,
37
+ lineColorActive: PropTypes.string,
38
+ lineColorInActive: PropTypes.string,
39
+ titleStyle: PropTypes.object,
40
+ descriptionStyle: PropTypes.object,
41
+ dateStyle: PropTypes.object,
164
42
  };
165
43
 
166
44
  Step.defaultProps = {
167
- data: [],
168
- lineColor: Colors.sepia_05,
45
+ titles: [],
169
46
  currentStep: 0,
170
- tintColor: Colors.sepia_05
47
+ isVertical: false,
48
+ circleColorActive: '#d82d8b',
49
+ circleColorChecked: '#ffadd2',
50
+ circleColorUnchecked: Colors.black_06,
51
+ circleBorderColorActive: Colors.pink_09,
52
+ circleBorderColorChecked: Colors.pink_09,
53
+ circleBorderColorUnchecked: Colors.black_04,
54
+ lineColorActive: '#ffd6e7',
55
+ lineColorInActive: Colors.black_04,
171
56
  };