@momo-kits/step 0.0.61-rc.1 → 0.0.62-alpha.13

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