@widergy/mobile-ui 1.3.3 → 1.4.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,17 @@
1
+ # [1.4.0](https://github.com/widergy/mobile-ui/compare/v1.3.4...v1.4.0) (2024-03-26)
2
+
3
+
4
+ ### Features
5
+
6
+ * added UTProductItem ([#268](https://github.com/widergy/mobile-ui/issues/268)) ([c28b3e8](https://github.com/widergy/mobile-ui/commit/c28b3e83e9f3aea060857778dc15d5537aca7702))
7
+
8
+ ## [1.3.4](https://github.com/widergy/mobile-ui/compare/v1.3.3...v1.3.4) (2024-03-19)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * themed styles and tagline fix ([#270](https://github.com/widergy/mobile-ui/issues/270)) ([6b5b325](https://github.com/widergy/mobile-ui/commit/6b5b32599b39dc1ee07f5af3dc2020fbab9219cf))
14
+
1
15
  ## [1.3.3](https://github.com/widergy/mobile-ui/compare/v1.3.2...v1.3.3) (2024-03-15)
2
16
 
3
17
 
@@ -10,14 +10,16 @@ import propTypes from './propTypes';
10
10
  const IconButton = ({
11
11
  color,
12
12
  disabled,
13
+ effectColor,
14
+ height,
15
+ iconMargin,
16
+ iconStyle,
13
17
  name,
14
18
  onPress,
15
- effectColor,
16
19
  size,
17
20
  style,
18
- iconStyle,
19
21
  type,
20
- iconMargin
22
+ width
21
23
  }) => (
22
24
  <Touchable
23
25
  borderless
@@ -26,15 +28,15 @@ const IconButton = ({
26
28
  effectColor={effectColor}
27
29
  style={[styles.container, getContainerSize(size, iconMargin), style]}
28
30
  >
29
- <Icon style={iconStyle} color={color} name={name} size={size} type={type} />
31
+ <Icon style={iconStyle} {...{ color, height, name, size, type, width }} />
30
32
  </Touchable>
31
33
  );
32
34
 
33
35
  IconButton.propTypes = propTypes;
34
36
 
35
37
  IconButton.defaultProps = {
36
- size: DEFAULT_ICON_SIZE,
37
- iconMargin: ICON_MARGIN
38
+ iconMargin: ICON_MARGIN,
39
+ size: DEFAULT_ICON_SIZE
38
40
  };
39
41
 
40
42
  export default IconButton;
@@ -1,53 +1,58 @@
1
1
  import React from 'react';
2
2
  import { View } from 'react-native';
3
3
  import { string, bool, shape } from 'prop-types';
4
+ import merge from 'lodash/merge';
4
5
 
5
6
  import Label from '../Label';
6
7
  import UTBanner from '../UTBanner';
8
+ import { useTheme } from '../../theming';
7
9
 
8
10
  import ownStyles from './styles';
9
11
 
10
- const UTHeader = ({ tagline, title, subtitle, requiredFieldInfo, helpText, useMarkdown, banner }) => {
12
+ const UTHeader = ({ tagline, title, subtitle, requiredFieldInfo, helpText, useMarkdown, banner, style }) => {
13
+ const theme = useTheme();
14
+ const themedStyles = merge({}, ownStyles, theme?.UTHeader, style);
15
+
11
16
  const renderComponent = (prop, standardComponent) =>
12
17
  React.isValidElement(prop) ? prop : standardComponent;
13
18
 
14
19
  const Tagline = renderComponent(
15
20
  tagline,
16
- <Label disabled bold useMarkdown={useMarkdown} style={ownStyles.child}>
17
- {tagline.toUpperCase()}
21
+ <Label disabled bold useMarkdown={useMarkdown} style={themedStyles.child}>
22
+ {tagline?.toUpperCase?.()}
18
23
  </Label>
19
24
  );
20
25
 
21
26
  const Title = renderComponent(
22
27
  title,
23
- <Label big bold style={ownStyles.title} useMarkdown={useMarkdown}>
28
+ <Label big bold style={themedStyles.title} useMarkdown={useMarkdown}>
24
29
  {title}
25
30
  </Label>
26
31
  );
27
32
 
28
33
  const Subtitle = renderComponent(
29
34
  subtitle,
30
- <Label disabled useMarkdown={useMarkdown} style={ownStyles.child}>
35
+ <Label disabled useMarkdown={useMarkdown} style={themedStyles.child}>
31
36
  {subtitle}
32
37
  </Label>
33
38
  );
34
39
 
35
40
  const RequiredFieldInfo = renderComponent(
36
41
  requiredFieldInfo,
37
- <Label disabled useMarkdown={useMarkdown} style={ownStyles.child}>
42
+ <Label disabled useMarkdown={useMarkdown} style={themedStyles.child}>
38
43
  {requiredFieldInfo}
39
44
  </Label>
40
45
  );
41
46
 
42
47
  const HelpText = renderComponent(
43
48
  helpText,
44
- <Label disabled useMarkdown={useMarkdown} style={ownStyles.child}>
49
+ <Label disabled useMarkdown={useMarkdown} style={themedStyles.child}>
45
50
  {helpText}
46
51
  </Label>
47
52
  );
48
53
 
49
54
  return (
50
- <View style={ownStyles.header}>
55
+ <View style={themedStyles.header}>
51
56
  {!!tagline && Tagline}
52
57
  <View>
53
58
  {Title}
@@ -55,7 +60,9 @@ const UTHeader = ({ tagline, title, subtitle, requiredFieldInfo, helpText, useMa
55
60
  </View>
56
61
  {!!requiredFieldInfo && RequiredFieldInfo}
57
62
  {!!helpText && HelpText}
58
- {banner?.text && <UTBanner text={banner.text} icon={banner.icon} style={{ banner: ownStyles.child }} />}
63
+ {banner?.text && (
64
+ <UTBanner text={banner.text} icon={banner.icon} style={{ banner: themedStyles.child }} />
65
+ )}
59
66
  </View>
60
67
  );
61
68
  };
@@ -0,0 +1,28 @@
1
+ # UTProductItem
2
+
3
+ ### Description
4
+
5
+ This component displays a product with its corresponding image, price and/or discounts. It also provides handlers for adding/removing the amount of products selected.
6
+
7
+ ## Props
8
+
9
+ | Name | Type | Default | Description |
10
+ | ---------------- | -------------- | ------- | ------------------------------------------------------------------------------- |
11
+ | action | actionType | | Renders a button on the rightSection of the component |
12
+ | additionalInfo | string | | Renders a smaller text under the title |
13
+ | amount | number | | Specifies the number to be displayed as a price |
14
+ | counter | counterType | | Renders a chip on the top right corner with a current number and a limit number |
15
+ | discount | number | | Renders a chip above the amount with the given discount as a percentage |
16
+ | imageProps | imagePropsType | | Renders an image at the leftmost part of the component |
17
+ | previousAmount | number | | Renders a text with strikethrough alongside the discount chip |
18
+ | secondaryAction | actionType | | Renders a button alongside the main action |
19
+ | selectedQuantity | number | | Renders a number between the action and the secondary action |
20
+ | title | string | | Renders the main text on the left section of the component |
21
+
22
+ ### Custom Types
23
+
24
+ | Type | Shape |
25
+ | -------------- | ---------------------------------------------------------------------------- |
26
+ | actionType | `{ color: string, name: string, onPress: func, size: number, type: string }` |
27
+ | counterType | `{ current: number, limit: number }` |
28
+ | imagePropsType | `{ image: element \| string, withUri: bool }` |
@@ -0,0 +1,19 @@
1
+ import { ViewPropTypes } from 'deprecated-react-native-prop-types';
2
+ import { bool, string } from 'prop-types';
3
+ import React from 'react';
4
+
5
+ import Label from '../../../Label';
6
+
7
+ const AdditionalInfo = ({ additionalInfo, shouldUseGap, themedStyles }) => (
8
+ <Label small style={[themedStyles.additionalInfo, shouldUseGap ? themedStyles.gap : '']}>
9
+ {additionalInfo}
10
+ </Label>
11
+ );
12
+
13
+ AdditionalInfo.propTypes = {
14
+ additionalInfo: string,
15
+ shouldUseGap: bool,
16
+ themedStyles: ViewPropTypes.style
17
+ };
18
+
19
+ export default AdditionalInfo;
@@ -0,0 +1,17 @@
1
+ import { ViewPropTypes } from 'deprecated-react-native-prop-types';
2
+ import { bool, number } from 'prop-types';
3
+ import React from 'react';
4
+
5
+ import Label from '../../../Label';
6
+
7
+ const Amount = ({ amount, shouldUseGap, themedStyles }) => (
8
+ <Label style={[themedStyles.amount, shouldUseGap ? themedStyles.gap : '']}>{`$ ${amount}`}</Label>
9
+ );
10
+
11
+ Amount.propTypes = {
12
+ amount: number,
13
+ shouldUseGap: bool,
14
+ themedStyles: ViewPropTypes.style
15
+ };
16
+
17
+ export default Amount;
@@ -0,0 +1,28 @@
1
+ import { ViewPropTypes } from 'deprecated-react-native-prop-types';
2
+ import { bool, number } from 'prop-types';
3
+ import React from 'react';
4
+ import { View } from 'react-native';
5
+
6
+ import Label from '../../../Label';
7
+
8
+ const Discount = ({ previousAmount, shouldUseGap, discount, themedStyles }) => (
9
+ <View style={[themedStyles.amountContainer, shouldUseGap ? themedStyles.gap : '']}>
10
+ <View style={themedStyles.discountChip}>
11
+ <Label small style={themedStyles.discount}>
12
+ {discount}
13
+ </Label>
14
+ </View>
15
+ {previousAmount && (
16
+ <Label small color="gray" style={themedStyles.previousAmount}>{`$ ${previousAmount}`}</Label>
17
+ )}
18
+ </View>
19
+ );
20
+
21
+ Discount.propTypes = {
22
+ discount: number,
23
+ previousAmount: number,
24
+ shouldUseGap: bool,
25
+ themedStyles: ViewPropTypes.style
26
+ };
27
+
28
+ export default Discount;
@@ -0,0 +1,59 @@
1
+ import React from 'react';
2
+ import { number } from 'prop-types';
3
+ import { View } from 'react-native';
4
+ import { ViewPropTypes } from 'deprecated-react-native-prop-types';
5
+ import isEmpty from 'lodash/isEmpty';
6
+ import isNil from 'lodash/isNil';
7
+
8
+ import IconButton from '../../../IconButton';
9
+ import Label from '../../../Label';
10
+ import { ActionPropTypes } from '../../propTypes';
11
+ import ImageButton from '../../../ImageButton';
12
+ import { useTheme } from '../../../../theming';
13
+
14
+ const QuantitySelector = ({ action, secondaryAction, selectedQuantity, themedStyles }) => {
15
+ const { UTProductItem } = useTheme();
16
+ const ICON_SIZE = 24;
17
+
18
+ const renderAction = ({ color, image, name, size, type, styles, onPress }) =>
19
+ image ? (
20
+ <ImageButton image={image} size={size || ICON_SIZE} containerStyle={styles.image} onPress={onPress} />
21
+ ) : (
22
+ <IconButton
23
+ color={color || UTProductItem?.actionIconColor || '#091E42'}
24
+ height={size || ICON_SIZE}
25
+ iconMargin={8}
26
+ name={name}
27
+ onPress={onPress}
28
+ size={size || ICON_SIZE}
29
+ style={styles.icon}
30
+ type={type}
31
+ width={size || ICON_SIZE}
32
+ />
33
+ );
34
+
35
+ return (
36
+ <View style={themedStyles.actionsContainer}>
37
+ {!isEmpty(secondaryAction) &&
38
+ renderAction({
39
+ ...secondaryAction,
40
+ styles: { icon: themedStyles.secondaryActionIcon, image: themedStyles.secondaryActionImage }
41
+ })}
42
+ {!isNil(selectedQuantity) && <Label style={themedStyles.selectedQuantity}>{selectedQuantity}</Label>}
43
+ {!isEmpty(action) &&
44
+ renderAction({
45
+ ...action,
46
+ styles: { icon: themedStyles.actionIcon, image: themedStyles.actionImage }
47
+ })}
48
+ </View>
49
+ );
50
+ };
51
+
52
+ QuantitySelector.propTypes = {
53
+ action: ActionPropTypes,
54
+ secondaryAction: ActionPropTypes,
55
+ selectedQuantity: number,
56
+ themedStyles: ViewPropTypes.style
57
+ };
58
+
59
+ export default QuantitySelector;
@@ -0,0 +1,19 @@
1
+ import { ViewPropTypes } from 'deprecated-react-native-prop-types';
2
+ import { bool, string } from 'prop-types';
3
+ import React from 'react';
4
+
5
+ import Label from '../../../Label';
6
+
7
+ const Title = ({ shouldUseGap, themedStyles, title }) => (
8
+ <Label medium style={[themedStyles.title, shouldUseGap ? themedStyles.gap : '']}>
9
+ {title}
10
+ </Label>
11
+ );
12
+
13
+ Title.propTypes = {
14
+ shouldUseGap: bool,
15
+ themedStyles: ViewPropTypes.style,
16
+ title: string
17
+ };
18
+
19
+ export default Title;
@@ -0,0 +1,74 @@
1
+ import React from 'react';
2
+ import { View } from 'react-native';
3
+ import merge from 'lodash/merge';
4
+ import { bool, element, number, oneOf, shape, string } from 'prop-types';
5
+ import isEmpty from 'lodash/isEmpty';
6
+
7
+ import ImageIcon from '../ImageIcon';
8
+ import { useTheme } from '../../theming';
9
+ import Label from '../Label';
10
+
11
+ import { leftSectionComponents } from './utils';
12
+ import QuantitySelector from './components/QuantitySelector';
13
+ import { ActionPropTypes } from './propTypes';
14
+ import { getUTProductItemStyles } from './styles';
15
+
16
+ const UTProductItem = ({
17
+ action,
18
+ additionalInfo,
19
+ amount,
20
+ counter,
21
+ discount,
22
+ imageProps,
23
+ previousAmount,
24
+ secondaryAction,
25
+ selectedQuantity,
26
+ style,
27
+ title
28
+ }) => {
29
+ const theme = useTheme();
30
+ const themedStyles = merge({}, getUTProductItemStyles(theme?.UTProductItem), theme?.UTProductItem, style);
31
+
32
+ const IMAGE_SIZE = 70;
33
+
34
+ return (
35
+ <View style={themedStyles.container}>
36
+ <View style={themedStyles.leftSection}>
37
+ {!isEmpty(imageProps) && <ImageIcon style={themedStyles.image} size={IMAGE_SIZE} {...imageProps} />}
38
+ <View style={themedStyles.mainInfo}>
39
+ {leftSectionComponents({
40
+ additionalInfo,
41
+ amount,
42
+ discount,
43
+ previousAmount,
44
+ themedStyles,
45
+ title
46
+ }).map(({ Component, props }, index, array) => (
47
+ <Component key={Math.random} {...props} shouldUseGap={index !== array.length - 1} />
48
+ ))}
49
+ </View>
50
+ </View>
51
+ <View style={[themedStyles.rightSection, !isEmpty(counter) && themedStyles.spaceBetween]}>
52
+ {!isEmpty(counter) && (
53
+ <Label small style={themedStyles.counter}>{`${counter.current}/${counter.limit}`}</Label>
54
+ )}
55
+ <QuantitySelector {...{ action, secondaryAction, selectedQuantity, themedStyles }} />
56
+ </View>
57
+ </View>
58
+ );
59
+ };
60
+
61
+ UTProductItem.propTypes = {
62
+ action: ActionPropTypes,
63
+ additionalInfo: string,
64
+ amount: number,
65
+ counter: shape({ current: number, limit: number }),
66
+ discount: number,
67
+ imageProps: shape({ image: oneOf([string, element]), withUri: bool }),
68
+ previousAmount: number,
69
+ secondaryAction: ActionPropTypes,
70
+ selectedQuantity: number,
71
+ title: string
72
+ };
73
+
74
+ export default UTProductItem;
@@ -0,0 +1,9 @@
1
+ import { func, number, shape, string } from 'prop-types';
2
+
3
+ export const ActionPropTypes = shape({
4
+ color: string,
5
+ name: string,
6
+ onPress: func,
7
+ size: number,
8
+ type: string
9
+ });
@@ -0,0 +1,80 @@
1
+ import { StyleSheet } from 'react-native';
2
+
3
+ export const getUTProductItemStyles = (theme = {}) =>
4
+ StyleSheet.create({
5
+ actionsContainer: {
6
+ alignItems: 'center',
7
+ backgroundColor: theme.actionsBackground || '#E4E6EA',
8
+ borderRadius: 8,
9
+ display: 'flex',
10
+ flexDirection: 'row'
11
+ },
12
+ additionalInfo: {
13
+ color: theme.additionalInfoColor || 'gray'
14
+ },
15
+ amountContainer: {
16
+ alignItems: 'center',
17
+ display: 'flex',
18
+ flexDirection: 'row'
19
+ },
20
+ container: {
21
+ borderBottomColor: theme.separatorColor || 'gray',
22
+ borderBottomWidth: 1,
23
+ display: 'flex',
24
+ flexDirection: 'row',
25
+ justifyContent: 'space-between',
26
+ paddingVertical: 24
27
+ },
28
+ counter: {
29
+ backgroundColor: theme.counterBackground || '#EBF8FD',
30
+ borderRadius: 4,
31
+ color: theme.counterColor || '#035B83',
32
+ paddingHorizontal: 8,
33
+ paddingVertical: 4
34
+ },
35
+ discount: {
36
+ color: theme.discountColor || 'white'
37
+ },
38
+ discountChip: {
39
+ backgroundColor: theme.discountBackground || '#285AFF',
40
+ borderRadius: 4,
41
+ marginRight: 8,
42
+ paddingHorizontal: 8,
43
+ paddingVertical: 4
44
+ },
45
+ gap: {
46
+ marginBottom: 4
47
+ },
48
+ image: {
49
+ borderRadius: 14,
50
+ marginRight: 16
51
+ },
52
+ leftSection: {
53
+ alignItems: 'center',
54
+ display: 'flex',
55
+ flexDirection: 'row'
56
+ },
57
+ mainInfo: {
58
+ display: 'flex',
59
+ minWidth: 160
60
+ },
61
+ previousAmount: {
62
+ color: theme.previousAmountColor || 'gray',
63
+ textDecorationLine: 'line-through',
64
+ textDecorationStyle: 'solid'
65
+ },
66
+ rightSection: {
67
+ alignItems: 'flex-end',
68
+ display: 'flex',
69
+ justifyContent: 'center'
70
+ },
71
+ secondaryActionImage: {
72
+ marginHorizontal: 4
73
+ },
74
+ selectedQuantity: {
75
+ paddingHorizontal: 8
76
+ },
77
+ spaceBetween: {
78
+ justifyContent: 'space-between'
79
+ }
80
+ });
@@ -0,0 +1,29 @@
1
+ import Title from './components/Title';
2
+ import AdditionalInfo from './components/AdditionalInfo';
3
+ import Discount from './components/Discount';
4
+ import Amount from './components/Amount';
5
+
6
+ export const leftSectionComponents = ({
7
+ additionalInfo,
8
+ amount,
9
+ discount,
10
+ previousAmount,
11
+ themedStyles,
12
+ title
13
+ }) =>
14
+ [
15
+ { Component: Title, key: 'title', props: { themedStyles, title }, show: !!title },
16
+ {
17
+ Component: AdditionalInfo,
18
+ key: 'additionalInfo',
19
+ props: { additionalInfo, themedStyles },
20
+ show: !!additionalInfo
21
+ },
22
+ {
23
+ Component: Discount,
24
+ key: 'discount',
25
+ props: { discount, previousAmount, themedStyles },
26
+ show: !!discount
27
+ },
28
+ { Component: Amount, key: 'amount', props: { amount, themedStyles }, show: !!amount }
29
+ ].filter(elem => elem.show);
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import { string, func, bool } from 'prop-types';
3
3
  import { View } from 'react-native';
4
- import _ from 'lodash';
4
+ import merge from 'lodash/merge';
5
5
 
6
6
  import Button from '../../../../../../../Button';
7
7
  import { useTheme } from '../../../../../../../../theming';
@@ -10,7 +10,7 @@ import ownStyles from './styles';
10
10
 
11
11
  const ActionButton = ({ hidden, disabled, onPress, label, mode, style }) => {
12
12
  const theme = useTheme();
13
- const themedStyles = _.merge({}, ownStyles, theme?.UTWorkflowContainer?.actionButton, style);
13
+ const themedStyles = merge({}, ownStyles, theme?.UTWorkflowContainer?.actionButton, style);
14
14
 
15
15
  return (
16
16
  <View style={themedStyles.actionButton}>
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import { View } from 'react-native';
3
- import _ from 'lodash';
3
+ import merge from 'lodash/merge';
4
4
 
5
5
  import Label from '../../../../../Label';
6
6
  import Button from '../../../../../Button';
@@ -13,31 +13,31 @@ import ActionButtonPropTypes from './components/ActionButton/types';
13
13
  import ownStyles, { ICON_SIZE } from './styles';
14
14
  import { NEXT, RETURN } from './constants';
15
15
 
16
- const BottomActions = ({ nextButton, returnButton, summary, message, theme }) => {
16
+ const BottomActions = ({ nextButton, returnButton, summary, message, style }) => {
17
17
  const messageIcon = message?.icon;
18
18
  const MESSAGE_ICON_SIZE = 16;
19
19
  const checkboxProps = summary?.checkbox;
20
20
 
21
- const themedStyles = _.merge({}, ownStyles, theme?.UTWorkflowContainer);
21
+ const themedStyles = merge({}, ownStyles, style);
22
22
  const nextButtonEnabled = nextButton && !nextButton.hidden;
23
23
  const returnButtonEnabled = returnButton && !returnButton.hidden;
24
24
 
25
25
  return (
26
- <View style={ownStyles.bottomNav}>
26
+ <View style={themedStyles.bottomNav}>
27
27
  {summary && (
28
- <View style={[ownStyles.summary, checkboxProps && ownStyles.summaryCheckbox]}>
28
+ <View style={[themedStyles.summary, checkboxProps && themedStyles.summaryCheckbox]}>
29
29
  {checkboxProps ? (
30
30
  <Checkbox {...checkboxProps} />
31
31
  ) : (
32
- <View style={ownStyles.summaryTitles}>
33
- <Label disabled medium style={ownStyles.summaryTitlesChild}>
32
+ <View style={themedStyles.summaryTitles}>
33
+ <Label disabled medium style={themedStyles.summaryTitlesChild}>
34
34
  {summary.title}
35
35
  </Label>
36
36
  <Label>{summary.mainInfo}</Label>
37
37
  </View>
38
38
  )}
39
39
  {summary.actions && !checkboxProps && (
40
- <View style={ownStyles.summaryActions}>
40
+ <View style={themedStyles.summaryActions}>
41
41
  {summary.actions.map((action, index) => (
42
42
  <Button
43
43
  key={action.name}
@@ -53,10 +53,12 @@ const BottomActions = ({ nextButton, returnButton, summary, message, theme }) =>
53
53
  }
54
54
  title={action.title}
55
55
  labelColor={themedStyles.summaryActions?.labelColor || 'blue'}
56
- containerStyle={ownStyles.summaryActionContainer}
57
- contentStyle={!action.title && ownStyles.summaryActionButton}
56
+ containerStyle={themedStyles.summaryActionContainer}
57
+ contentStyle={!action.title && themedStyles.summaryActionButton}
58
58
  onPress={action.onPress}
59
- outerContainerStyles={index !== summary.actions.length - 1 && ownStyles.summaryActionsChild}
59
+ outerContainerStyles={
60
+ index !== summary.actions.length - 1 && themedStyles.summaryActionsChild
61
+ }
60
62
  />
61
63
  ))}
62
64
  </View>
@@ -70,7 +72,7 @@ const BottomActions = ({ nextButton, returnButton, summary, message, theme }) =>
70
72
  themedStyles[`message${message.variant?.charAt(0).toUpperCase()}${message.variant?.slice(1)}`]
71
73
  ]}
72
74
  >
73
- <Label white style={ownStyles.messageChild}>
75
+ <Label white style={themedStyles.messageChild}>
74
76
  {message.title}
75
77
  </Label>
76
78
  {messageIcon && (
@@ -85,16 +87,31 @@ const BottomActions = ({ nextButton, returnButton, summary, message, theme }) =>
85
87
  )}
86
88
  </View>
87
89
  )}
88
- <View style={ownStyles.actionsContainer}>
90
+ <View style={themedStyles.actionsContainer}>
89
91
  {returnButtonEnabled && (
90
92
  <ActionButton
91
93
  mode="text"
92
94
  label={returnButton.label || RETURN}
93
- style={nextButtonEnabled && { actionButton: ownStyles.actionsChild }}
95
+ style={{
96
+ actionButton: {
97
+ ...themedStyles.returnActionButton,
98
+ ...(nextButtonEnabled ? themedStyles.actionsChild : {})
99
+ },
100
+ buttonContainer: themedStyles.returnButtonContainer
101
+ }}
94
102
  {...returnButton}
95
103
  />
96
104
  )}
97
- {nextButtonEnabled && <ActionButton label={nextButton.label || NEXT} {...nextButton} />}
105
+ {nextButtonEnabled && (
106
+ <ActionButton
107
+ label={nextButton.label || NEXT}
108
+ style={{
109
+ actionButton: themedStyles.nextActionButton,
110
+ buttonContainer: themedStyles.nextButtonContainer
111
+ }}
112
+ {...nextButton}
113
+ />
114
+ )}
98
115
  </View>
99
116
  </View>
100
117
  );
@@ -1,6 +1,7 @@
1
1
  import React, { useEffect } from 'react';
2
2
  import { View, ScrollView } from 'react-native';
3
3
  import { number, func, shape, bool, string, element } from 'prop-types';
4
+ import { merge } from 'lodash';
4
5
 
5
6
  import { useTheme } from '../../../../theming';
6
7
  import UTHeader from '../../../UTHeader';
@@ -26,6 +27,7 @@ const UTWorkflowContainer = ({
26
27
  returnButton,
27
28
  stages,
28
29
  stepsCount,
30
+ style,
29
31
  subtitle,
30
32
  summary,
31
33
  tagline,
@@ -35,17 +37,19 @@ const UTWorkflowContainer = ({
35
37
  }) => {
36
38
  useEffect(() => () => onExit?.(), []);
37
39
  const theme = useTheme();
40
+ const themedStyles = merge({}, ownStyles, theme?.UTWorkflowContainer, style);
38
41
 
39
42
  return (
40
- <View style={ownStyles.container}>
43
+ <View style={themedStyles.container}>
41
44
  {topbar && <UTTopbar {...{ currentStage, currentStep, stages, stepsCount, theme, topbar }} />}
42
- <ScrollView contentContainerStyle={ownStyles.content}>
45
+ <ScrollView contentContainerStyle={themedStyles.content}>
43
46
  {title && (
44
47
  <UTHeader
45
48
  {...{
46
49
  banner,
47
50
  helpText,
48
51
  requiredFieldInfo,
52
+ style: themedStyles,
49
53
  subtitle,
50
54
  tagline,
51
55
  title,
@@ -61,8 +65,8 @@ const UTWorkflowContainer = ({
61
65
  message,
62
66
  nextButton,
63
67
  returnButton,
64
- summary,
65
- theme
68
+ style: themedStyles,
69
+ summary
66
70
  }}
67
71
  />
68
72
  )}
package/lib/index.js CHANGED
@@ -40,6 +40,7 @@ export { default as UTDetailDrawer } from './components/UTDetailDrawer';
40
40
  export { default as UTImage } from './components/UTImage';
41
41
  export { default as UTWorkflowContainer } from './components/UTWorkflowContainer';
42
42
  export { default as UTSelectableCard } from './components/UTSelectableCard';
43
+ export { default as UTProductItem } from './components/UTProductItem';
43
44
  export { default as UTProgressBar } from './components/UTProgressBar';
44
45
  export { default as UTOnBoarding } from './components/UTOnBoarding';
45
46
  export { default as UTRoundView } from './components/UTRoundView';
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.3.3",
5
+ "version": "1.4.0",
6
6
  "repository": "https://github.com/widergy/mobile-ui.git",
7
7
  "main": "lib/index.js",
8
8
  "files": [