@widergy/mobile-ui 0.40.1 → 0.42.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.
Files changed (50) hide show
  1. package/lib/components/Button/constants.js +5 -0
  2. package/lib/components/Button/index.js +24 -8
  3. package/lib/components/Button/styles.js +9 -6
  4. package/lib/components/Checkbox/styles.js +3 -3
  5. package/lib/components/Icon/constants.js +1 -0
  6. package/lib/components/Icon/index.js +11 -1
  7. package/lib/components/UTBanner/index.js +42 -0
  8. package/lib/components/UTBanner/styles.js +14 -0
  9. package/lib/components/UTHeader/index.js +56 -0
  10. package/lib/components/UTHeader/styles.js +16 -0
  11. package/lib/components/UTRoundView/index.js +14 -7
  12. package/lib/components/UTRoundView/propTypes.js +5 -3
  13. package/lib/components/UTRoundView/styles.js +11 -3
  14. package/lib/components/UTRoundView/utils.js +14 -0
  15. package/lib/components/UTStepper/components/Connectors/index.js +33 -0
  16. package/lib/components/UTStepper/components/Connectors/styles.js +26 -0
  17. package/lib/components/UTStepper/components/Step/index.js +50 -0
  18. package/lib/components/UTStepper/components/Step/styles.js +47 -0
  19. package/lib/components/UTStepper/index.js +34 -0
  20. package/lib/components/UTStepper/styles.js +12 -0
  21. package/lib/components/UTStepper/types.js +3 -0
  22. package/lib/components/UTTopbar/index.js +64 -0
  23. package/lib/components/UTTopbar/styles.js +16 -0
  24. package/lib/components/UTTopbar/types.js +8 -0
  25. package/lib/components/UTWorkflowContainer/index.js +10 -102
  26. package/lib/components/UTWorkflowContainer/{components → versions/V0/components}/BottomStepHandler/index.js +4 -4
  27. package/lib/components/UTWorkflowContainer/{components → versions/V0/components}/BottomStepHandler/styles.js +3 -3
  28. package/lib/components/UTWorkflowContainer/{components → versions/V0/components}/Header/index.js +9 -9
  29. package/lib/components/UTWorkflowContainer/{components → versions/V0/components}/Header/styles.js +3 -3
  30. package/lib/components/UTWorkflowContainer/{components → versions/V0/components}/StepsHandler/components/ActionButton/index.js +2 -2
  31. package/lib/components/UTWorkflowContainer/{components → versions/V0/components}/StepsHandler/components/ActionButton/styles.js +12 -12
  32. package/lib/components/UTWorkflowContainer/{components → versions/V0/components}/StepsHandler/components/ActionButton/types.js +9 -9
  33. package/lib/components/UTWorkflowContainer/{components → versions/V0/components}/StepsHandler/index.js +6 -6
  34. package/lib/components/UTWorkflowContainer/{components → versions/V0/components}/StepsHandler/styles.js +3 -3
  35. package/lib/components/UTWorkflowContainer/versions/V0/index.js +108 -0
  36. package/lib/components/UTWorkflowContainer/{styles.js → versions/V0/styles.js} +4 -4
  37. package/lib/components/UTWorkflowContainer/versions/V1/components/BottomActions/components/ActionButton/index.js +35 -0
  38. package/lib/components/UTWorkflowContainer/versions/V1/components/BottomActions/components/ActionButton/styles.js +13 -0
  39. package/lib/components/UTWorkflowContainer/versions/V1/components/BottomActions/components/ActionButton/types.js +9 -0
  40. package/lib/components/UTWorkflowContainer/versions/V1/components/BottomActions/constants.js +2 -0
  41. package/lib/components/UTWorkflowContainer/versions/V1/components/BottomActions/index.js +110 -0
  42. package/lib/components/UTWorkflowContainer/versions/V1/components/BottomActions/styles.js +75 -0
  43. package/lib/components/UTWorkflowContainer/versions/V1/index.js +94 -0
  44. package/lib/components/UTWorkflowContainer/versions/V1/styles.js +14 -0
  45. package/lib/components/UTWorkflowContainer/versions/V1/types.js +24 -0
  46. package/package.json +3 -2
  47. /package/lib/components/UTWorkflowContainer/{README.md → versions/V0/README.md} +0 -0
  48. /package/lib/components/UTWorkflowContainer/{components → versions/V0/components}/Header/utils.js +0 -0
  49. /package/lib/components/UTWorkflowContainer/{components → versions/V0/components}/StepsHandler/constants.js +0 -0
  50. /package/lib/components/UTWorkflowContainer/{components → versions/V0/components}/StepsHandler/utils.js +0 -0
@@ -4,3 +4,8 @@ export const CONTAINED_ELEVATION = 2;
4
4
  export const CONTAINED = 'contained';
5
5
  export const OUTLINED = 'outlined';
6
6
  export const TEXT = 'text';
7
+
8
+ export const ICON_PLACEMENTS = {
9
+ left: 'left',
10
+ right: 'right',
11
+ };
@@ -9,7 +9,7 @@ import { withTheme } from '../../theming';
9
9
 
10
10
  import propTypes, { buttonDefaultProps } from './propTypes';
11
11
  import styles, { getThemeStyles, getButtonModeStyles, getEffectColor } from './styles';
12
- import { NO_ELEVATION, OUTLINED, TEXT } from './constants';
12
+ import { ICON_PLACEMENTS, NO_ELEVATION, OUTLINED, TEXT } from './constants';
13
13
 
14
14
  const Button = ({
15
15
  color,
@@ -20,6 +20,7 @@ const Button = ({
20
20
  elevation,
21
21
  icon,
22
22
  iconStyle,
23
+ iconPlacement,
23
24
  labelColor,
24
25
  testID,
25
26
  labelProps,
@@ -41,8 +42,8 @@ const Button = ({
41
42
  disabled || mode === TEXT
42
43
  ? NO_ELEVATION
43
44
  : mode === OUTLINED
44
- ? NO_ELEVATION
45
- : elevation || themeStyles.buttonElevation
45
+ ? NO_ELEVATION
46
+ : elevation || themeStyles.buttonElevation
46
47
  }
47
48
  style={[
48
49
  styles.container,
@@ -59,18 +60,33 @@ const Button = ({
59
60
  effectColor={getEffectColor(textColor, theme, effectColor)}
60
61
  >
61
62
  <View style={[styles.button, contentStyle]}>
62
- {icon && (
63
+ {icon && iconPlacement !== ICON_PLACEMENTS.right && (
64
+ <Icon
65
+ color={textColor}
66
+ name={icon.name}
67
+ type={icon.type}
68
+ style={[title && styles.leftIcon, iconStyle]}
69
+ size={icon.size || themeStyles.fontSize}
70
+ width={icon.width}
71
+ height={icon.height}
72
+ />
73
+ )}
74
+ {title && (
75
+ <Label base color={textColor} {...labelProps}>
76
+ {lowerCase ? title : title.toUpperCase()}
77
+ </Label>
78
+ )}
79
+ {icon && iconPlacement === ICON_PLACEMENTS.right && (
63
80
  <Icon
64
81
  color={textColor}
65
82
  name={icon.name}
66
83
  type={icon.type}
67
- style={[styles.leftIcon, iconStyle]}
84
+ style={[title && styles.rightIcon, iconStyle]}
68
85
  size={icon.size || themeStyles.fontSize}
86
+ width={icon.width}
87
+ height={icon.height}
69
88
  />
70
89
  )}
71
- <Label base color={textColor} {...labelProps}>
72
- {lowerCase ? title : title.toUpperCase()}
73
- </Label>
74
90
  </View>
75
91
  </Touchable>
76
92
  </Surface>
@@ -8,12 +8,12 @@ import { OUTLINED, TEXT, CONTAINED } from './constants';
8
8
  export const getThemeStyles = theme => {
9
9
  const { colors, fonts, button } = theme;
10
10
  return {
11
- primaryColor: colors.primary,
12
- secondaryColor: colors.secondary,
13
- disabledColor: colors.disabled,
14
- buttonOutlineWidth: button.borderWidth,
15
11
  buttonElevation: button.elevation,
16
- fontSize: fonts.fontSizes.base
12
+ buttonOutlineWidth: button.borderWidth,
13
+ disabledColor: colors.disabled,
14
+ fontSize: fonts.fontSizes.base,
15
+ primaryColor: colors.primary,
16
+ secondaryColor: colors.secondary
17
17
  };
18
18
  };
19
19
 
@@ -82,11 +82,14 @@ export default StyleSheet.create({
82
82
  overflow: 'hidden'
83
83
  },
84
84
  leftIcon: {
85
- paddingRight: portraitHorizontalScale(8)
85
+ marginRight: portraitHorizontalScale(8)
86
86
  },
87
87
  outerContainer: {
88
88
  alignItems: 'center'
89
89
  },
90
+ rightIcon: {
91
+ marginLeft: portraitHorizontalScale(8)
92
+ },
90
93
  touchable: {
91
94
  alignItems: 'center',
92
95
  justifyContent: 'center'
@@ -17,10 +17,10 @@ export default StyleSheet.create({
17
17
  containerReversed: {
18
18
  flexDirection: 'row-reverse',
19
19
  justifyContent: 'space-between',
20
- width: '100%',
21
- paddingHorizontal: moderateHorizontalScale(10)
20
+ paddingHorizontal: moderateHorizontalScale(10),
21
+ width: '100%'
22
22
  },
23
23
  icon: {
24
- paddingRight: moderateHorizontalScale(10)
24
+ marginRight: moderateHorizontalScale(10)
25
25
  }
26
26
  });
@@ -10,6 +10,7 @@ import FontAwesomeIcon from 'react-native-vector-icons/FontAwesome';
10
10
  import SimpleLineIcon from 'react-native-vector-icons/SimpleLineIcons';
11
11
  import FeatherIcon from 'react-native-vector-icons/Feather';
12
12
  import AntIcon from 'react-native-vector-icons/AntDesign';
13
+
13
14
  import VisibilityOff from './assets/eye-off.svg';
14
15
  import Visibility from './assets/eye.svg';
15
16
 
@@ -5,7 +5,17 @@ import { getIconComponent, DEFAULT_ICON_TYPE, DEFAULT_ICON_SIZE } from './consta
5
5
 
6
6
  const Icon = ({ color, height, name, size, style, type, width }) => {
7
7
  const IconComponent = getIconComponent(type);
8
- return <IconComponent color={color} height={height} name={name} size={size} style={style} type={type} width={width}/>;
8
+ return (
9
+ <IconComponent
10
+ color={color}
11
+ height={height}
12
+ name={name}
13
+ size={size}
14
+ style={style}
15
+ type={type}
16
+ width={width}
17
+ />
18
+ );
9
19
  };
10
20
 
11
21
  Icon.propTypes = propTypes;
@@ -0,0 +1,42 @@
1
+ import React from 'react';
2
+ import { View } from 'react-native';
3
+ import { shape, string } from 'prop-types';
4
+ import _ from 'lodash';
5
+
6
+ import Icon from '../Icon';
7
+ import Label from '../Label';
8
+ import { useTheme } from '../../theming';
9
+
10
+ import ownStyles from './styles';
11
+
12
+ const UTBanner = ({ text, icon, style }) => {
13
+ const theme = useTheme();
14
+
15
+ const ICON_SIZE = 24;
16
+
17
+ const themedStyles = _.merge({}, ownStyles, theme?.UTBanner, style);
18
+
19
+ return (
20
+ <View style={themedStyles.banner}>
21
+ {icon && (
22
+ <Icon
23
+ name={icon.name}
24
+ type={icon.type}
25
+ size={ICON_SIZE}
26
+ height={ICON_SIZE}
27
+ width={ICON_SIZE}
28
+ color={theme.UTBanner?.iconColor}
29
+ style={ownStyles.icon}
30
+ />
31
+ )}
32
+ <Label>{text}</Label>
33
+ </View>
34
+ );
35
+ };
36
+
37
+ UTBanner.propTypes = {
38
+ icon: shape({ name: string, type: string }),
39
+ text: string
40
+ };
41
+
42
+ export default UTBanner;
@@ -0,0 +1,14 @@
1
+ import { StyleSheet } from 'react-native';
2
+
3
+ export default StyleSheet.create({
4
+ banner: {
5
+ backgroundColor: '#F4F5F7',
6
+ borderRadius: 8,
7
+ display: 'flex',
8
+ flexDirection: 'row',
9
+ padding: 16
10
+ },
11
+ icon: {
12
+ marginRight: 16
13
+ }
14
+ });
@@ -0,0 +1,56 @@
1
+ import React from 'react';
2
+ import { View } from 'react-native';
3
+ import { string, bool, shape, element } from 'prop-types';
4
+
5
+ import Label from '../Label';
6
+ import UTBanner from '../UTBanner';
7
+
8
+ import ownStyles from './styles';
9
+
10
+ const Header = ({ tagline, title, subtitle, requiredFieldInfo, helpText, useMarkdown, banner }) => {
11
+ return (
12
+ <View style={ownStyles.header}>
13
+ {tagline && (
14
+ <Label disabled bold useMarkdown={useMarkdown} style={ownStyles.child}>
15
+ {tagline.toUpperCase()}
16
+ </Label>
17
+ )}
18
+ <View>
19
+ <Label big bold style={ownStyles.title} useMarkdown={useMarkdown}>
20
+ {title}
21
+ </Label>
22
+ {subtitle && (
23
+ <Label disabled useMarkdown={useMarkdown} style={ownStyles.child}>
24
+ {subtitle}
25
+ </Label>
26
+ )}
27
+ </View>
28
+ {requiredFieldInfo && (
29
+ <Label disabled useMarkdown={useMarkdown} style={ownStyles.child}>
30
+ {requiredFieldInfo}
31
+ </Label>
32
+ )}
33
+ {helpText && (
34
+ <Label disabled useMarkdown={useMarkdown} style={ownStyles.child}>
35
+ {helpText}
36
+ </Label>
37
+ )}
38
+ {banner?.text && <UTBanner text={banner.text} icon={banner.icon} style={{ banner: ownStyles.child }} />}
39
+ </View>
40
+ );
41
+ };
42
+
43
+ Header.propTypes = {
44
+ banner: shape({
45
+ Icon: element,
46
+ text: string
47
+ }),
48
+ helpText: string,
49
+ requiredFieldInfo: string,
50
+ subtitle: string,
51
+ tagline: string,
52
+ title: string,
53
+ useMarkdown: bool
54
+ };
55
+
56
+ export default Header;
@@ -0,0 +1,16 @@
1
+ import { StyleSheet } from 'react-native';
2
+
3
+ export default StyleSheet.create({
4
+ child: {
5
+ marginBottom: 16
6
+ },
7
+ header: {
8
+ display: 'flex',
9
+ flexDirection: 'column',
10
+ paddingBottom: 16,
11
+ paddingTop: 24
12
+ },
13
+ title: {
14
+ marginBottom: 12
15
+ }
16
+ });
@@ -1,20 +1,27 @@
1
- import React from 'react';
1
+ import React, { Fragment } from 'react';
2
2
  import { View, Animated } from 'react-native';
3
- import _ from 'lodash';
3
+ import merge from 'lodash/merge';
4
4
 
5
5
  import { useTheme } from '../../theming';
6
6
 
7
7
  import propTypes from './propTypes';
8
8
  import ownStyles from './styles';
9
+ import { generateBackgroundGradient } from './utils';
9
10
 
10
- const UTRoundView = ({ children, styles }) => {
11
+ const UTRoundView = ({ children, styles, startColor, endColor }) => {
11
12
  const theme = useTheme();
12
- const themedStyles = _.merge({}, theme?.roundView, styles);
13
+ const themedStyles = merge({}, theme?.roundView, styles);
14
+ const withBackgroundGradient = !!startColor && !!endColor;
13
15
 
14
16
  return (
15
- <Animated.View style={[ownStyles.container, themedStyles?.outerContainer]}>
16
- <View style={[ownStyles.innerContainer, themedStyles?.innerContainer]}>{children}</View>
17
- </Animated.View>
17
+ <Fragment>
18
+ {withBackgroundGradient && (
19
+ <View style={ownStyles.backgroundGradient}>{generateBackgroundGradient(startColor, endColor)}</View>
20
+ )}
21
+ <Animated.View style={[ownStyles.container, themedStyles?.outerContainer, withBackgroundGradient && ownStyles?.outerWithBackground]}>
22
+ <View style={[ownStyles.innerContainer, themedStyles?.innerContainer]}>{children}</View>
23
+ </Animated.View>
24
+ </Fragment>
18
25
  );
19
26
  };
20
27
 
@@ -1,9 +1,11 @@
1
1
  import { ViewPropTypes } from 'deprecated-react-native-prop-types';
2
- import { shape } from 'prop-types';
2
+ import { shape, string } from 'prop-types';
3
3
 
4
4
  export default {
5
5
  styles: shape({
6
6
  outerContainer: ViewPropTypes.style,
7
- innerContainer: ViewPropTypes.style
8
- })
7
+ innerContainer: ViewPropTypes.style,
8
+ }),
9
+ startColor: string,
10
+ endColor: string,
9
11
  };
@@ -3,8 +3,13 @@ import { StyleSheet } from 'react-native';
3
3
  export const ROUND_VIEW_BORDER_RADIUS = 25;
4
4
 
5
5
  const styles = StyleSheet.create({
6
+ backgroundGradient: {
7
+ height: '100%',
8
+ position: 'absolute',
9
+ width: '100%',
10
+ },
6
11
  container: {
7
- flex: 1
12
+ flex: 1,
8
13
  },
9
14
  innerContainer: {
10
15
  height: '100%',
@@ -12,8 +17,11 @@ const styles = StyleSheet.create({
12
17
  backgroundColor: 'white',
13
18
  borderTopLeftRadius: ROUND_VIEW_BORDER_RADIUS,
14
19
  borderTopRightRadius: ROUND_VIEW_BORDER_RADIUS,
15
- paddingTop: ROUND_VIEW_BORDER_RADIUS
16
- }
20
+ paddingTop: ROUND_VIEW_BORDER_RADIUS,
21
+ },
22
+ outerWithBackground: {
23
+ backgroundColor: 'transparent',
24
+ },
17
25
  });
18
26
 
19
27
  export default styles;
@@ -0,0 +1,14 @@
1
+ import React from 'react';
2
+ import Svg, { Rect, LinearGradient, Defs, Stop } from 'react-native-svg';
3
+
4
+ export const generateBackgroundGradient = (startColor, endColor) => (
5
+ <Svg height="100%" width="100%">
6
+ <Defs>
7
+ <LinearGradient id="gradient1" x1="0%" y1="0%" x2="100%" y2="0%">
8
+ <Stop offset="0%" stopColor={startColor} stopOpacity="1" />
9
+ <Stop offset="100%" stopColor={endColor} stopOpacity="1" />
10
+ </LinearGradient>
11
+ </Defs>
12
+ <Rect x="0" y="0" width="100%" height="100%" fill="url(#gradient1)" />
13
+ </Svg>
14
+ );
@@ -0,0 +1,33 @@
1
+ import React from 'react';
2
+ import { View } from 'react-native';
3
+ import { func, number } from 'prop-types';
4
+
5
+ import ownStyles from './styles';
6
+
7
+ const Connectors = ({ isCompleted, numberOfStages, theme = {} }) => {
8
+ const connectors = Array.from(Array(numberOfStages - 1), (_, index) => ({ key: index })).map(
9
+ ({ key }, index) => (
10
+ <View
11
+ key={key}
12
+ style={[
13
+ ownStyles.connector,
14
+ theme.connector,
15
+ isCompleted(index + 1) && [ownStyles.coloredProgress, theme.coloredProgress]
16
+ ]}
17
+ />
18
+ )
19
+ );
20
+
21
+ return (
22
+ <View style={ownStyles.wrapper}>
23
+ <View style={ownStyles.container}>{connectors}</View>
24
+ </View>
25
+ );
26
+ };
27
+
28
+ Connectors.propTypes = {
29
+ isCompleted: func,
30
+ numberOfStages: number
31
+ };
32
+
33
+ export default Connectors;
@@ -0,0 +1,26 @@
1
+ import { StyleSheet } from 'react-native';
2
+
3
+ import { OVAL_SIZE } from '../../styles';
4
+
5
+ export default StyleSheet.create({
6
+ coloredProgress: {
7
+ backgroundColor: 'blue'
8
+ },
9
+ connector: {
10
+ backgroundColor: 'gray',
11
+ flexGrow: 1,
12
+ height: 2
13
+ },
14
+ container: {
15
+ display: 'flex',
16
+ flexDirection: 'row',
17
+ justifyContent: 'space-around'
18
+ },
19
+ wrapper: {
20
+ left: 0,
21
+ paddingHorizontal: OVAL_SIZE,
22
+ paddingTop: OVAL_SIZE,
23
+ position: 'absolute',
24
+ width: '100%'
25
+ }
26
+ });
@@ -0,0 +1,50 @@
1
+ import React from 'react';
2
+ import { func, number, shape } from 'prop-types';
3
+ import { View } from 'react-native';
4
+
5
+ import Icon from '../../../Icon';
6
+ import { OVAL_SIZE } from '../../styles';
7
+
8
+ import ownStyles, { ICON_OFFSET } from './styles';
9
+
10
+ const Step = ({ isCompleted, isActive, stage, theme = {} }) => {
11
+ const stageCompleted = isCompleted(stage.id);
12
+ const stageActive = isActive(stage.id);
13
+
14
+ return (
15
+ <View
16
+ style={[
17
+ [ownStyles.stepContainer, theme.stepContainer],
18
+ stageCompleted && [ownStyles.completedContainer, theme.completeStepContainer],
19
+ stageActive && [ownStyles.activeContainer, theme.activeStepContainer]
20
+ ]}
21
+ >
22
+ <View style={ownStyles.checkContainer}>
23
+ <View
24
+ style={[
25
+ [ownStyles.stepInnerContainer, theme.stepInnerContainer],
26
+ stageCompleted && [ownStyles.completedInnerContainer, theme.completeStepInnerContainer],
27
+ stageActive && [ownStyles.activeInnerContainer, theme.activeStepInnerContainer]
28
+ ]}
29
+ />
30
+ {stageCompleted && (
31
+ <Icon
32
+ name="check"
33
+ type="feather"
34
+ size={OVAL_SIZE - ICON_OFFSET}
35
+ color="white"
36
+ style={ownStyles.checkIcon}
37
+ />
38
+ )}
39
+ </View>
40
+ </View>
41
+ );
42
+ };
43
+
44
+ Step.propTypes = {
45
+ isActive: func,
46
+ isCompleted: func,
47
+ stage: shape({ id: number })
48
+ };
49
+
50
+ export default Step;
@@ -0,0 +1,47 @@
1
+ import { StyleSheet } from 'react-native';
2
+
3
+ import { OVAL_SIZE } from '../../styles';
4
+
5
+ export const ICON_OFFSET = OVAL_SIZE / 4;
6
+
7
+ export default StyleSheet.create({
8
+ checkContainer: {
9
+ alignItems: 'center',
10
+ display: 'flex',
11
+ justifyContent: 'center'
12
+ },
13
+ checkIcon: {
14
+ left: ICON_OFFSET / 2,
15
+ position: 'absolute',
16
+ top: ICON_OFFSET / 2
17
+ },
18
+
19
+ activeContainer: {
20
+ backgroundColor: 'blue'
21
+ },
22
+ completedContainer: {
23
+ backgroundColor: 'blue'
24
+ },
25
+ stepContainer: {
26
+ backgroundColor: 'white',
27
+ borderRadius: OVAL_SIZE / 2,
28
+ height: OVAL_SIZE,
29
+ margin: OVAL_SIZE / 2,
30
+ width: OVAL_SIZE
31
+ },
32
+
33
+ activeInnerContainer: {
34
+ backgroundColor: 'white'
35
+ },
36
+ completedInnerContainer: {
37
+ backgroundColor: 'blue'
38
+ },
39
+ stepInnerContainer: {
40
+ backgroundColor: 'gray',
41
+ borderRadius: OVAL_SIZE / 2,
42
+ height: OVAL_SIZE / 2,
43
+ position: 'absolute',
44
+ top: OVAL_SIZE / 4,
45
+ width: OVAL_SIZE / 2
46
+ }
47
+ });
@@ -0,0 +1,34 @@
1
+ import { number } from 'prop-types';
2
+ import React from 'react';
3
+ import { View } from 'react-native';
4
+
5
+ import { useTheme } from '../../theming';
6
+
7
+ import ownStyles from './styles';
8
+ import Step from './components/Step';
9
+ import Connectors from './components/Connectors';
10
+ import { StagesPropTypes } from './types';
11
+
12
+ const UTStepper = ({ currentStage, stages }) => {
13
+ const isCompleted = stageNumber => stageNumber < currentStage;
14
+ const isActive = stageNumber => stageNumber === currentStage;
15
+ const numberOfStages = stages.length;
16
+
17
+ const theme = useTheme().UTStepper;
18
+
19
+ return (
20
+ <View style={ownStyles.container}>
21
+ <Connectors {...{ isCompleted, numberOfStages, theme }} />
22
+ {stages.map(stage => (
23
+ <Step key={stage.id} {...{ isActive, isCompleted, stage, theme }} />
24
+ ))}
25
+ </View>
26
+ );
27
+ };
28
+
29
+ UTStepper.propTypes = {
30
+ currentStage: number,
31
+ stages: StagesPropTypes
32
+ };
33
+
34
+ export default UTStepper;
@@ -0,0 +1,12 @@
1
+ import { StyleSheet } from 'react-native';
2
+
3
+ export const OVAL_SIZE = 16;
4
+
5
+ export default StyleSheet.create({
6
+ container: {
7
+ display: 'flex',
8
+ flexDirection: 'row',
9
+ flexGrow: 1,
10
+ justifyContent: 'space-between'
11
+ }
12
+ });
@@ -0,0 +1,3 @@
1
+ import { arrayOf, number, shape } from 'prop-types';
2
+
3
+ export const StagesPropTypes = arrayOf(shape({ id: number }));
@@ -0,0 +1,64 @@
1
+ import React from 'react';
2
+ import { View } from 'react-native';
3
+ import { number } from 'prop-types';
4
+
5
+ import IconButton from '../IconButton';
6
+ import Label from '../Label';
7
+ import UTStepper from '../UTStepper';
8
+ import UTProgressBar from '../UTProgressBar';
9
+ import { StagesPropTypes } from '../UTStepper/types';
10
+
11
+ import ownStyles, { BAR_HEIGHT } from './styles';
12
+ import { TopbarPropTypes } from './types';
13
+
14
+ const UTTopbar = ({
15
+ currentStage,
16
+ currentStep,
17
+ stages,
18
+ stepsCount,
19
+ theme,
20
+ topbar: { colorTheme = 'light', goBack, title, variant = 'secondary', icon } = {}
21
+ }) => {
22
+ const size = { big: variant === 'primary' };
23
+
24
+ const ownTheme = theme.UTWorkflowContainer?.topbar?.[colorTheme];
25
+
26
+ return (
27
+ <View>
28
+ <View style={[ownStyles.container, ownTheme?.container]}>
29
+ <IconButton
30
+ color={ownTheme?.icon || 'black'}
31
+ name={icon?.name || 'arrow-left'}
32
+ size={24}
33
+ style={ownStyles.child}
34
+ type={icon?.type || 'material-community'}
35
+ onPress={goBack}
36
+ />
37
+ <Label color={ownTheme?.text || 'black'} {...size} bold style={ownStyles.child}>
38
+ {title}
39
+ </Label>
40
+ {stages && <UTStepper {...{ currentStage, stages }} />}
41
+ </View>
42
+ {currentStep && stepsCount && (
43
+ <UTProgressBar
44
+ value={currentStep / stepsCount}
45
+ styles={{
46
+ barContainer: {
47
+ height: BAR_HEIGHT
48
+ }
49
+ }}
50
+ />
51
+ )}
52
+ </View>
53
+ );
54
+ };
55
+
56
+ UTTopbar.propTypes = {
57
+ currentStage: number,
58
+ currentStep: number,
59
+ stages: StagesPropTypes,
60
+ stepsCount: number,
61
+ topbar: TopbarPropTypes
62
+ };
63
+
64
+ export default UTTopbar;
@@ -0,0 +1,16 @@
1
+ import { StyleSheet } from 'react-native';
2
+
3
+ export const BAR_HEIGHT = 8;
4
+
5
+ export default StyleSheet.create({
6
+ child: {
7
+ marginRight: 16
8
+ },
9
+ container: {
10
+ alignItems: 'center',
11
+ display: 'flex',
12
+ flexDirection: 'row',
13
+ justifyContent: 'flex-start',
14
+ padding: 16
15
+ }
16
+ });