@momo-kits/step 0.0.59-beta.9 → 0.0.60-alpha.3

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