@widergy/mobile-ui 1.45.1 → 1.46.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.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ # [1.46.0](https://github.com/widergy/mobile-ui/compare/v1.45.1...v1.46.0) (2025-05-16)
2
+
3
+
4
+ ### Features
5
+
6
+ * [UGEE-273] wizard component ([#431](https://github.com/widergy/mobile-ui/issues/431)) ([3883133](https://github.com/widergy/mobile-ui/commit/38831333979cd365cc0082feac2910f6b3db9651))
7
+
1
8
  ## [1.45.1](https://github.com/widergy/mobile-ui/compare/v1.45.0...v1.45.1) (2025-05-14)
2
9
 
3
10
 
@@ -0,0 +1,48 @@
1
+ # UTWizard
2
+
3
+ Wizard component. Only into the UTWorkflowContainer.
4
+
5
+ ## Props
6
+ Here's a new table for the additional props:
7
+
8
+ | Name | Type | Default | Description |
9
+ |------------|---------|------------|-----------------------------------------------------------|
10
+ | colorTheme | string | `dark` | Defines the color theme for the main component. |
11
+ | variant | string | | From it, the themes of the components are defined. |
12
+ | theme |viewStyle| | Component theme |
13
+ | steps | array | | array of steps |
14
+ | images | array | | Array of images to be displayed within each step. |
15
+ |workflowVersion|string| `V0` | workflow version to know about component bottom. |
16
+
17
+
18
+ ### colorTheme
19
+
20
+ The value of `colorTheme` must be one of the following:
21
+
22
+ - `accent`
23
+ - `negative`
24
+ - `neutral`
25
+ - `dark`
26
+
27
+ ### variant
28
+
29
+ The value of `variant` must be one of the following:
30
+
31
+ - `dark`
32
+ - `information`
33
+ - `light`
34
+
35
+ ### steps
36
+
37
+ `steps` is an array of object, each object have:
38
+
39
+ - `title`: wizard title
40
+ - `subtitle`: wizard subtitle
41
+
42
+ ### images
43
+
44
+ `images` is an array of images with the same order as the steps,
45
+ to place the correct image at the correct step
46
+
47
+ ### workflowVersion
48
+ `workflowVersion` is a string to know the bottom of the component
@@ -0,0 +1,22 @@
1
+ export const VARIANTS = {
2
+ dark: 'dark',
3
+ information: 'information',
4
+ light: 'light'
5
+ };
6
+
7
+ export const DEFAULT_PROPS = {
8
+ variant: 'dark'
9
+ };
10
+
11
+ export const ACTIONS = {
12
+ NEXT: 'next',
13
+ PREVIOUS: 'previous',
14
+ RESET: 'reset'
15
+ };
16
+
17
+ export const COLOR_THEMES = {
18
+ ACCENT: 'accent',
19
+ NEGATIVE: 'negative',
20
+ NEUTRAL: 'neutral',
21
+ DARK: 'dark'
22
+ };
@@ -0,0 +1,136 @@
1
+ import React, { useState, useReducer, useEffect } from 'react';
2
+ import { View } from 'react-native';
3
+ import PropTypes, { string, number, objectOf, arrayOf, shape } from 'prop-types';
4
+
5
+ import UTLabel from '../UTLabel';
6
+ import UTButton from '../UTButton';
7
+ import { withTheme } from '../../theming';
8
+ import UTImage from '../UTImage';
9
+
10
+ import { getLabelTheme, getButtonTheme, getButtonMinimizedTheme } from './utils';
11
+ import { ACTIONS, COLOR_THEMES } from './constants';
12
+ import stylesheet from './styles';
13
+
14
+ const UTWizard = ({
15
+ images,
16
+ steps,
17
+ variant,
18
+ theme,
19
+ colorTheme = COLOR_THEMES.DARK,
20
+ workflowVersion = 'V0'
21
+ }) => {
22
+ const hasSteps = steps.length > 1;
23
+ const [isOpen, setIsOpen] = useState(true);
24
+ const [isClosed, setIsClosed] = useState(false);
25
+
26
+ const [currentSubstep, updateSubstep] = useReducer((state, action) => {
27
+ switch (action) {
28
+ case ACTIONS.RESET:
29
+ return 0;
30
+ case ACTIONS.PREVIOUS:
31
+ return state - 1;
32
+ case ACTIONS.NEXT:
33
+ return state + 1;
34
+ default:
35
+ return state;
36
+ }
37
+ }, 0);
38
+ const { title, description } = steps[currentSubstep] || {};
39
+ useEffect(() => {
40
+ updateSubstep(ACTIONS.RESET);
41
+ }, [isOpen]);
42
+ const styles = stylesheet({ ...theme, workflowVersion });
43
+
44
+ return (
45
+ !isClosed &&
46
+ (isOpen ? (
47
+ <View style={styles.container(colorTheme)}>
48
+ <View style={styles.titleContainer}>
49
+ <UTLabel style={styles.grow} colorTheme={getButtonTheme(variant)} weight="medium" withMarkdown>
50
+ {title}
51
+ </UTLabel>
52
+ <View style={styles.buttons}>
53
+ <UTButton
54
+ colorTheme={getButtonTheme(variant)}
55
+ Icon="IconChevronDown"
56
+ onPress={() => setIsOpen(false)}
57
+ size="small"
58
+ variant="text"
59
+ />
60
+ <UTButton
61
+ colorTheme={getButtonTheme(variant)}
62
+ Icon="IconX"
63
+ onPress={setIsClosed}
64
+ size="small"
65
+ variant="text"
66
+ />
67
+ </View>
68
+ </View>
69
+ <View style={styles.content}>
70
+ <UTLabel variant="small" colorTheme={getLabelTheme(variant)} withMarkdown>
71
+ {description}
72
+ </UTLabel>
73
+ </View>
74
+ <UTImage source={images[currentSubstep]} style={styles.image} />
75
+ {hasSteps && (
76
+ <View style={styles.footer}>
77
+ <View style={styles.page}>
78
+ <UTLabel colorTheme={getLabelTheme(variant)} variant="small" withMarkdown>
79
+ {`${currentSubstep + 1} de ${steps.length}`}
80
+ </UTLabel>
81
+ </View>
82
+ <View style={styles.buttons}>
83
+ {currentSubstep > 0 && (
84
+ <UTButton
85
+ colorTheme={getButtonTheme(variant)}
86
+ onPress={() => updateSubstep(ACTIONS.PREVIOUS)}
87
+ size="small"
88
+ variant="text"
89
+ weight="medium"
90
+ >
91
+ Atras
92
+ </UTButton>
93
+ )}
94
+ {currentSubstep < steps.length - 1 && (
95
+ <UTButton
96
+ colorTheme={getButtonTheme(variant)}
97
+ onPress={() => updateSubstep(ACTIONS.NEXT)}
98
+ size="small"
99
+ variant="filled"
100
+ weight="medium"
101
+ >
102
+ Siguiente
103
+ </UTButton>
104
+ )}
105
+ </View>
106
+ </View>
107
+ )}
108
+ </View>
109
+ ) : (
110
+ <View style={styles.notOpen}>
111
+ <UTButton
112
+ style={styles.button}
113
+ onPress={() => setIsOpen(true)}
114
+ colorTheme={getButtonMinimizedTheme(variant)}
115
+ Icon="IconQuestionMark"
116
+ />
117
+ </View>
118
+ ))
119
+ );
120
+ };
121
+
122
+ UTWizard.propTypes = {
123
+ images: objectOf(number),
124
+ steps: arrayOf(
125
+ shape({
126
+ title: string,
127
+ description: string
128
+ })
129
+ ),
130
+ variant: string,
131
+ theme: PropTypes.object,
132
+ colorTheme: string,
133
+ workflowVersion: string
134
+ };
135
+
136
+ export default withTheme(UTWizard);
@@ -0,0 +1,65 @@
1
+ import { StyleSheet } from 'react-native';
2
+
3
+ import { IS_ANDROID } from '../../utils/platformUtils/constants';
4
+
5
+ import { COLOR_THEMES } from './constants';
6
+
7
+ export default ({ Palette: { accent, neutral, negative, dark }, workflowVersion }) =>
8
+ StyleSheet.create({
9
+ container: colorTheme => ({
10
+ borderRadius: 4,
11
+ backgroundColor: {
12
+ [COLOR_THEMES.ACCENT]: accent['01'],
13
+ [COLOR_THEMES.NEUTRAL]: neutral['01'],
14
+ [COLOR_THEMES.NEGATIVE]: negative['01'],
15
+ [COLOR_THEMES.DARK]: dark['04']
16
+ }[colorTheme],
17
+ bottom: workflowVersion === 'V1' ? (IS_ANDROID ? 72 : 126) : 16,
18
+ display: 'flex',
19
+ width: 296,
20
+ padding: 16,
21
+ position: 'absolute',
22
+ right: 16
23
+ }),
24
+ grow: {
25
+ flexShrink: 1,
26
+ flexGrow: 1,
27
+ marginRight: 8
28
+ },
29
+ titleContainer: {
30
+ flexDirection: 'row',
31
+ justifyContent: 'space-between',
32
+ alignItems: 'flex-start'
33
+ },
34
+ buttons: {
35
+ flexDirection: 'row'
36
+ },
37
+
38
+ content: {
39
+ marginBottom: 8
40
+ },
41
+ image: {
42
+ borderRadius: 4,
43
+ width: 264,
44
+ height: 180
45
+ },
46
+ footer: {
47
+ flexDirection: 'row',
48
+ justifyContent: 'space-between',
49
+ marginTop: 8,
50
+ alignItems: 'flex-end'
51
+ },
52
+ page: {
53
+ alignItems: 'center'
54
+ },
55
+ notOpen: {
56
+ bottom: workflowVersion === 'V1' ? (IS_ANDROID ? 64 : 126) : 16,
57
+ height: 'auto',
58
+ padding: 16,
59
+ position: 'absolute',
60
+ right: 16
61
+ },
62
+ button: {
63
+ borderRadius: 100
64
+ }
65
+ });
@@ -0,0 +1,24 @@
1
+ import { DEFAULT_PROPS, VARIANTS } from './constants';
2
+
3
+ export const getVariant = variant => VARIANTS[variant] || VARIANTS[DEFAULT_PROPS.variant];
4
+
5
+ export const getLabelTheme = variant =>
6
+ ({
7
+ [VARIANTS.dark]: 'light',
8
+ [VARIANTS.information]: 'light',
9
+ [VARIANTS.light]: 'dark'
10
+ })[getVariant(variant)];
11
+
12
+ export const getButtonTheme = variant =>
13
+ ({
14
+ [VARIANTS.dark]: 'negative',
15
+ [VARIANTS.information]: 'negative',
16
+ [VARIANTS.light]: 'dark'
17
+ })[getVariant(variant)];
18
+
19
+ export const getButtonMinimizedTheme = variant =>
20
+ ({
21
+ [VARIANTS.dark]: 'secondary',
22
+ [VARIANTS.information]: 'secondary',
23
+ [VARIANTS.light]: 'negative'
24
+ })[getVariant(variant)];
@@ -1,11 +1,12 @@
1
1
  import React, { useEffect } from 'react';
2
2
  import { ViewPropTypes } from 'deprecated-react-native-prop-types';
3
3
  import { View } from 'react-native';
4
- import { number, func, shape, bool, string, oneOf } from 'prop-types';
4
+ import { number, func, shape, bool, string, oneOf, objectOf } from 'prop-types';
5
5
  import _ from 'lodash';
6
6
 
7
7
  import Label from '../../../Label';
8
8
  import { useTheme } from '../../../../theming';
9
+ import UTWizard from '../../../UTWizard';
9
10
 
10
11
  import ownStyles from './styles';
11
12
  import Header from './components/Header';
@@ -26,7 +27,8 @@ const UTWorkflowContainer = ({
26
27
  stepCounter,
27
28
  bottomHandler,
28
29
  hideHeader = false,
29
- useMarkdown
30
+ useMarkdown,
31
+ wizardConfig
30
32
  }) => {
31
33
  useEffect(() => () => onExit?.(), []);
32
34
  const theme = useTheme();
@@ -87,6 +89,7 @@ const UTWorkflowContainer = ({
87
89
  stepCounter={stepCounter}
88
90
  />
89
91
  )}
92
+ {wizardConfig?.enabled && <UTWizard {...wizardConfig} />}
90
93
  </View>
91
94
  );
92
95
  };
@@ -103,6 +106,16 @@ UTWorkflowContainer.propTypes = {
103
106
  styles: shape(ViewPropTypes?.style),
104
107
  subtitle: string,
105
108
  title: string,
106
- useMarkdown: bool
109
+ useMarkdown: bool,
110
+ wizardConfig: shape({
111
+ variant: string,
112
+ steps: objectOf(
113
+ shape({
114
+ title: string,
115
+ description: string
116
+ })
117
+ ),
118
+ images: objectOf(number)
119
+ })
107
120
  };
108
121
  export default UTWorkflowContainer;
@@ -1,6 +1,6 @@
1
1
  import React, { useEffect, useState } from 'react';
2
2
  import { ScrollView, View, KeyboardAvoidingView, Keyboard } from 'react-native';
3
- import { number, func, shape, bool, string, element, oneOfType, any } from 'prop-types';
3
+ import { number, func, shape, bool, string, element, oneOfType, any, objectOf } from 'prop-types';
4
4
  import { merge } from 'lodash';
5
5
  import { useSafeAreaInsets } from 'react-native-safe-area-context';
6
6
 
@@ -10,6 +10,7 @@ import UTTopbar from '../../../UTTopbar';
10
10
  import { StagesPropTypes } from '../../../UTStepper/types';
11
11
  import { TopbarPropTypes } from '../../../UTTopbar/types';
12
12
  import { IS_IOS } from '../../../../utils/platformUtils/constants';
13
+ import UTWizard from '../../../UTWizard';
13
14
 
14
15
  import ownStyles from './styles';
15
16
  import BottomActions from './components/BottomActions';
@@ -37,7 +38,8 @@ const UTWorkflowContainer = ({
37
38
  tagline,
38
39
  title,
39
40
  topbar,
40
- useMarkdown
41
+ useMarkdown,
42
+ wizardConfig
41
43
  }) => {
42
44
  const { bottom: bottomSafeArea, top: topSafeArea } = useSafeAreaInsets();
43
45
  // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -100,6 +102,7 @@ const UTWorkflowContainer = ({
100
102
  />
101
103
  )}
102
104
  </View>
105
+ {wizardConfig?.enabled && <UTWizard {...wizardConfig} />}
103
106
  </KeyboardAvoidingView>
104
107
  );
105
108
  };
@@ -126,6 +129,16 @@ UTWorkflowContainer.propTypes = {
126
129
  tagline: string,
127
130
  title: oneOfType([string, element]),
128
131
  topbar: TopbarPropTypes,
129
- useMarkdown: bool
132
+ useMarkdown: bool,
133
+ wizardConfig: shape({
134
+ variant: string,
135
+ steps: objectOf(
136
+ shape({
137
+ title: string,
138
+ description: string
139
+ })
140
+ ),
141
+ images: objectOf(number)
142
+ })
130
143
  };
131
144
  export default UTWorkflowContainer;
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@widergy/mobile-ui",
3
3
  "description": "Widergy Mobile Components",
4
4
  "author": "widergy",
5
- "version": "1.45.1",
5
+ "version": "1.46.0",
6
6
  "repository": "https://github.com/widergy/mobile-ui.git",
7
7
  "main": "lib/index.js",
8
8
  "files": [