@widergy/mobile-ui 2.8.1 → 2.9.1
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 +14 -0
- package/lib/components/UTBanner/constants.js +5 -0
- package/lib/components/UTBanner/index.js +48 -15
- package/lib/components/UTBanner/proptypes.js +24 -0
- package/lib/components/UTBanner/theme.js +102 -0
- package/lib/components/UTCheckBox/index.js +1 -1
- package/lib/components/UTWorkflowContainer/versions/V1/components/BottomActions/index.js +21 -7
- package/lib/components/UTWorkflowContainer/versions/V1/components/BottomActions/styles.js +10 -3
- package/lib/components/UTWorkflowContainer/versions/V1/index.js +3 -0
- package/package.json +1 -1
- package/lib/components/UTBanner/styles.js +0 -14
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
## [2.9.1](https://github.com/widergy/mobile-ui/compare/v2.9.0...v2.9.1) (2026-03-16)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* [UGGC-78] standardize utbanner and stacked actions utworkflowcontainer ([#488](https://github.com/widergy/mobile-ui/issues/488)) ([ed0772c](https://github.com/widergy/mobile-ui/commit/ed0772c64aaf8818bc3650a284f8f253cd6e33bf))
|
|
7
|
+
|
|
8
|
+
# [2.9.0](https://github.com/widergy/mobile-ui/compare/v2.8.1...v2.9.0) (2026-03-11)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
* add test id ([#487](https://github.com/widergy/mobile-ui/issues/487)) ([c9ea05b](https://github.com/widergy/mobile-ui/commit/c9ea05b22d834c666ad3746f0075657f223c8b78))
|
|
14
|
+
|
|
1
15
|
## [2.8.1](https://github.com/widergy/mobile-ui/compare/v2.8.0...v2.8.1) (2026-02-19)
|
|
2
16
|
|
|
3
17
|
|
|
@@ -1,33 +1,66 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { View } from 'react-native';
|
|
3
|
-
import { bool, shape, string } from 'prop-types';
|
|
4
3
|
|
|
5
4
|
import UTIcon from '../UTIcon';
|
|
6
5
|
import UTLabel from '../UTLabel';
|
|
7
6
|
import { useTheme } from '../../theming';
|
|
8
|
-
import {
|
|
7
|
+
import { TEST_ID_CONSTANTS } from '../../constants/testIds';
|
|
9
8
|
|
|
10
|
-
import
|
|
9
|
+
import { defaultProps, propTypes } from './proptypes';
|
|
10
|
+
import { retrieveStyle } from './theme';
|
|
11
11
|
|
|
12
|
-
const
|
|
12
|
+
const { icon: iconTestId, label: labelTestId } = TEST_ID_CONSTANTS;
|
|
13
|
+
|
|
14
|
+
const UTBanner = ({ text, title, description, icon, size, style, withMarkdown, dataTestId }) => {
|
|
13
15
|
const theme = useTheme();
|
|
14
16
|
|
|
15
|
-
const
|
|
17
|
+
const displayTitle = title || text; // Backwards compatibility
|
|
18
|
+
|
|
19
|
+
const { bannerStyles, iconStyles, titleStyles, descriptionStyles, textContainerStyles } = retrieveStyle({
|
|
20
|
+
style,
|
|
21
|
+
size,
|
|
22
|
+
theme
|
|
23
|
+
});
|
|
16
24
|
|
|
17
25
|
return (
|
|
18
|
-
<View style={
|
|
19
|
-
{icon &&
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
26
|
+
<View style={bannerStyles} testID={dataTestId}>
|
|
27
|
+
{icon && (
|
|
28
|
+
<UTIcon
|
|
29
|
+
name={icon.name}
|
|
30
|
+
colorTheme={icon.colorTheme}
|
|
31
|
+
size={iconStyles.size}
|
|
32
|
+
dataTestId={dataTestId ? `${dataTestId}.${iconTestId}` : undefined}
|
|
33
|
+
/>
|
|
34
|
+
)}
|
|
35
|
+
<View style={textContainerStyles}>
|
|
36
|
+
{displayTitle && (
|
|
37
|
+
<UTLabel
|
|
38
|
+
withMarkdown={withMarkdown}
|
|
39
|
+
variant={titleStyles.variant}
|
|
40
|
+
weight={titleStyles.weight}
|
|
41
|
+
style={titleStyles.style}
|
|
42
|
+
dataTestId={dataTestId ? `${dataTestId}.title.${labelTestId}` : undefined}
|
|
43
|
+
>
|
|
44
|
+
{displayTitle}
|
|
45
|
+
</UTLabel>
|
|
46
|
+
)}
|
|
47
|
+
{description && (
|
|
48
|
+
<UTLabel
|
|
49
|
+
withMarkdown={withMarkdown}
|
|
50
|
+
variant={descriptionStyles.variant}
|
|
51
|
+
weight={descriptionStyles.weight}
|
|
52
|
+
style={descriptionStyles.style}
|
|
53
|
+
dataTestId={dataTestId ? `${dataTestId}.description.${labelTestId}` : undefined}
|
|
54
|
+
>
|
|
55
|
+
{description}
|
|
56
|
+
</UTLabel>
|
|
57
|
+
)}
|
|
58
|
+
</View>
|
|
23
59
|
</View>
|
|
24
60
|
);
|
|
25
61
|
};
|
|
26
62
|
|
|
27
|
-
UTBanner.
|
|
28
|
-
|
|
29
|
-
text: string,
|
|
30
|
-
withMarkdown: bool
|
|
31
|
-
};
|
|
63
|
+
UTBanner.defaultProps = defaultProps;
|
|
64
|
+
UTBanner.propTypes = propTypes;
|
|
32
65
|
|
|
33
66
|
export default UTBanner;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { bool, object, shape, string } from 'prop-types';
|
|
2
|
+
|
|
3
|
+
import { SIZES } from './constants';
|
|
4
|
+
|
|
5
|
+
export const defaultProps = {
|
|
6
|
+
size: SIZES.MEDIUM
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const propTypes = {
|
|
10
|
+
/** @deprecated Use `title` instead. Will be removed in next major version. */
|
|
11
|
+
text: string,
|
|
12
|
+
title: string,
|
|
13
|
+
description: string,
|
|
14
|
+
icon: shape({ name: string, colorTheme: string }),
|
|
15
|
+
size: string,
|
|
16
|
+
withMarkdown: bool,
|
|
17
|
+
dataTestId: string,
|
|
18
|
+
style: shape({
|
|
19
|
+
root: object,
|
|
20
|
+
icon: object,
|
|
21
|
+
title: object,
|
|
22
|
+
description: object
|
|
23
|
+
})
|
|
24
|
+
};
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { defaultProps } from './proptypes';
|
|
2
|
+
|
|
3
|
+
const baseBannerTheme = theme => ({
|
|
4
|
+
banner: {
|
|
5
|
+
backgroundColor: theme.Palette.light['03'],
|
|
6
|
+
borderRadius: 8,
|
|
7
|
+
flexDirection: 'row',
|
|
8
|
+
padding: 16,
|
|
9
|
+
gap: 16
|
|
10
|
+
},
|
|
11
|
+
textContainer: {
|
|
12
|
+
flex: 1,
|
|
13
|
+
gap: 8
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
const sizeBannerTheme = size => {
|
|
18
|
+
const definition = {
|
|
19
|
+
large: {
|
|
20
|
+
banner: {
|
|
21
|
+
padding: 24,
|
|
22
|
+
gap: 24
|
|
23
|
+
},
|
|
24
|
+
icon: {
|
|
25
|
+
size: 32
|
|
26
|
+
},
|
|
27
|
+
title: {
|
|
28
|
+
variant: 'title3',
|
|
29
|
+
weight: 'medium'
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
medium: {
|
|
33
|
+
banner: {
|
|
34
|
+
padding: 16,
|
|
35
|
+
gap: 16
|
|
36
|
+
},
|
|
37
|
+
icon: {
|
|
38
|
+
size: 24
|
|
39
|
+
},
|
|
40
|
+
title: {
|
|
41
|
+
variant: 'title3',
|
|
42
|
+
weight: 'medium'
|
|
43
|
+
},
|
|
44
|
+
description: {
|
|
45
|
+
variant: 'small'
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
small: {
|
|
49
|
+
banner: {
|
|
50
|
+
paddingHorizontal: 12,
|
|
51
|
+
paddingVertical: 8,
|
|
52
|
+
gap: 8
|
|
53
|
+
},
|
|
54
|
+
icon: {
|
|
55
|
+
size: 24
|
|
56
|
+
},
|
|
57
|
+
title: {
|
|
58
|
+
variant: 'title3',
|
|
59
|
+
weight: 'medium'
|
|
60
|
+
},
|
|
61
|
+
description: {
|
|
62
|
+
variant: 'small'
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
return definition[size] || definition[defaultProps.size];
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export const retrieveStyle = ({ style = {}, size, theme }) => {
|
|
71
|
+
const baseTheme = baseBannerTheme(theme);
|
|
72
|
+
const sizeTheme = sizeBannerTheme(size);
|
|
73
|
+
|
|
74
|
+
const bannerStyles = {
|
|
75
|
+
...baseTheme.banner,
|
|
76
|
+
...sizeTheme.banner,
|
|
77
|
+
...style.banner
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const iconStyles = {
|
|
81
|
+
size: sizeTheme.icon?.size
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const titleStyles = {
|
|
85
|
+
variant: sizeTheme.title?.variant,
|
|
86
|
+
weight: sizeTheme.title?.weight,
|
|
87
|
+
style: style.title
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
const descriptionStyles = {
|
|
91
|
+
variant: sizeTheme.description?.variant,
|
|
92
|
+
weight: sizeTheme.description?.weight,
|
|
93
|
+
style: style.description
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
const textContainerStyles = {
|
|
97
|
+
...baseTheme.textContainer,
|
|
98
|
+
...sizeTheme.textContainer
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
return { bannerStyles, iconStyles, titleStyles, descriptionStyles, textContainerStyles };
|
|
102
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { View } from 'react-native';
|
|
3
3
|
import merge from 'lodash/merge';
|
|
4
|
-
import { number } from 'prop-types';
|
|
4
|
+
import { bool, number } from 'prop-types';
|
|
5
5
|
|
|
6
6
|
import { TEST_IDS } from '../../../../../../constants/testIds';
|
|
7
7
|
import UTLabel from '../../../../../UTLabel';
|
|
@@ -19,7 +19,15 @@ import { NEXT, RETURN } from './constants';
|
|
|
19
19
|
|
|
20
20
|
const { workflowContainer } = TEST_IDS;
|
|
21
21
|
|
|
22
|
-
const BottomActions = ({
|
|
22
|
+
const BottomActions = ({
|
|
23
|
+
bottomSafeArea,
|
|
24
|
+
message,
|
|
25
|
+
nextButton,
|
|
26
|
+
returnButton,
|
|
27
|
+
stackedBottomActions,
|
|
28
|
+
summary,
|
|
29
|
+
style
|
|
30
|
+
}) => {
|
|
23
31
|
const messageIcon = message?.Icon;
|
|
24
32
|
const MESSAGE_ICON_SIZE = 16;
|
|
25
33
|
const checkboxProps = summary?.checkbox;
|
|
@@ -28,6 +36,12 @@ const BottomActions = ({ bottomSafeArea, message, nextButton, returnButton, summ
|
|
|
28
36
|
const nextButtonEnabled = nextButton && !nextButton.hidden;
|
|
29
37
|
const returnButtonEnabled = returnButton && !returnButton.hidden;
|
|
30
38
|
|
|
39
|
+
const actionButtonStyle = {
|
|
40
|
+
...themedStyles.returnActionButton,
|
|
41
|
+
...(nextButtonEnabled &&
|
|
42
|
+
(stackedBottomActions ? themedStyles.actionsChildStacked : themedStyles.actionsChild))
|
|
43
|
+
};
|
|
44
|
+
|
|
31
45
|
return (
|
|
32
46
|
<Surface position="top" style={[themedStyles.bottomNav, themedStyles.bottomSafeArea(bottomSafeArea)]}>
|
|
33
47
|
{summary && (
|
|
@@ -92,17 +106,16 @@ const BottomActions = ({ bottomSafeArea, message, nextButton, returnButton, summ
|
|
|
92
106
|
{messageIcon && <UTIcon colorTheme="negative" name={messageIcon} size={MESSAGE_ICON_SIZE} />}
|
|
93
107
|
</View>
|
|
94
108
|
)}
|
|
95
|
-
<View
|
|
109
|
+
<View
|
|
110
|
+
style={[themedStyles.actionsContainer, stackedBottomActions && themedStyles.actionsContainerStacked]}
|
|
111
|
+
>
|
|
96
112
|
{returnButtonEnabled && (
|
|
97
113
|
<ActionButton
|
|
98
114
|
dataTestId={workflowContainer.bottomActions.returnButton}
|
|
99
115
|
label={returnButton.label || RETURN}
|
|
100
116
|
variant="text"
|
|
101
117
|
style={{
|
|
102
|
-
actionButton:
|
|
103
|
-
...themedStyles.returnActionButton,
|
|
104
|
-
...(nextButtonEnabled ? themedStyles.actionsChild : {})
|
|
105
|
-
},
|
|
118
|
+
actionButton: actionButtonStyle,
|
|
106
119
|
buttonContainer: themedStyles.returnButtonContainer
|
|
107
120
|
}}
|
|
108
121
|
{...returnButton}
|
|
@@ -129,6 +142,7 @@ BottomActions.propTypes = {
|
|
|
129
142
|
message: MessagePropTypes,
|
|
130
143
|
nextButton: ActionButtonPropTypes,
|
|
131
144
|
returnButton: ActionButtonPropTypes,
|
|
145
|
+
stackedBottomActions: bool,
|
|
132
146
|
summary: SummaryPropTypes
|
|
133
147
|
};
|
|
134
148
|
|
|
@@ -4,6 +4,9 @@ export default StyleSheet.create({
|
|
|
4
4
|
actionsChild: {
|
|
5
5
|
marginRight: 16
|
|
6
6
|
},
|
|
7
|
+
actionsChildStacked: {
|
|
8
|
+
marginTop: 8
|
|
9
|
+
},
|
|
7
10
|
actionsContainer: {
|
|
8
11
|
alignItems: 'center',
|
|
9
12
|
flexDirection: 'row',
|
|
@@ -12,12 +15,16 @@ export default StyleSheet.create({
|
|
|
12
15
|
padding: 16,
|
|
13
16
|
width: '100%'
|
|
14
17
|
},
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
+
actionsContainerStacked: {
|
|
19
|
+
alignItems: 'stretch',
|
|
20
|
+
flexDirection: 'column-reverse'
|
|
21
|
+
},
|
|
18
22
|
bottomNav: {
|
|
19
23
|
backgroundColor: 'white'
|
|
20
24
|
},
|
|
25
|
+
bottomSafeArea: safeArea => ({
|
|
26
|
+
paddingBottom: safeArea
|
|
27
|
+
}),
|
|
21
28
|
message: {
|
|
22
29
|
alignItems: 'center',
|
|
23
30
|
backgroundColor: 'blue',
|
|
@@ -39,6 +39,7 @@ const UTWorkflowContainer = ({
|
|
|
39
39
|
scrollable = true,
|
|
40
40
|
scrollViewRef,
|
|
41
41
|
stages,
|
|
42
|
+
stackedBottomActions = false,
|
|
42
43
|
stepsCount,
|
|
43
44
|
style,
|
|
44
45
|
subtitle,
|
|
@@ -109,6 +110,7 @@ const UTWorkflowContainer = ({
|
|
|
109
110
|
message,
|
|
110
111
|
nextButton,
|
|
111
112
|
returnButton,
|
|
113
|
+
stackedBottomActions,
|
|
112
114
|
style: themedStyles,
|
|
113
115
|
bottomSafeArea: isKeyboardVisible ? 0 : bottomSafeArea,
|
|
114
116
|
summary
|
|
@@ -136,6 +138,7 @@ UTWorkflowContainer.propTypes = {
|
|
|
136
138
|
scrollable: bool,
|
|
137
139
|
scrollViewRef: shape({ current: any }),
|
|
138
140
|
stages: StagesPropTypes,
|
|
141
|
+
stackedBottomActions: bool,
|
|
139
142
|
stepsCount: number.isRequired,
|
|
140
143
|
subtitle: oneOfType([string, element]),
|
|
141
144
|
summary: SummaryPropTypes,
|
package/package.json
CHANGED