@widergy/mobile-ui 1.41.0 → 1.43.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.43.0](https://github.com/widergy/mobile-ui/compare/v1.42.0...v1.43.0) (2025-05-05)
2
+
3
+
4
+ ### Features
5
+
6
+ * [UGENSA-1749] hide amount in rate chart ([#426](https://github.com/widergy/mobile-ui/issues/426)) ([53bf273](https://github.com/widergy/mobile-ui/commit/53bf273e688d4c06849381e854a93908d2f9fcdf))
7
+
8
+ # [1.42.0](https://github.com/widergy/mobile-ui/compare/v1.41.0...v1.42.0) (2025-04-30)
9
+
10
+
11
+ ### Features
12
+
13
+ * [UGC-1420] UTStatus and support in UTProductItem ([#429](https://github.com/widergy/mobile-ui/issues/429)) ([3e2b309](https://github.com/widergy/mobile-ui/commit/3e2b309479ff062f4949b0cbedcb781eab8aa5fc))
14
+
1
15
  # [1.41.0](https://github.com/widergy/mobile-ui/compare/v1.40.4...v1.41.0) (2025-04-29)
2
16
 
3
17
 
@@ -1,11 +1,12 @@
1
1
  import React from 'react';
2
2
  import { arrayOf, bool, object, string } from 'prop-types';
3
3
  import { Linking, View } from 'react-native';
4
+ import { isEmpty } from 'lodash';
4
5
 
5
6
  import UTButton from '../../../UTButton';
6
7
 
7
8
  const CategoryButton = ({ category, texts, showCategory, categoryButtonUrl = '' }) => {
8
- const handleOpenUrl = () => Linking.openURL(categoryButtonUrl);
9
+ const handleOpenUrl = () => (!isEmpty(categoryButtonUrl) ? Linking.openURL(categoryButtonUrl) : {});
9
10
 
10
11
  return (
11
12
  <View>
@@ -1,5 +1,5 @@
1
1
  import React, { Fragment, useState } from 'react';
2
- import { number, string, arrayOf, shape, any } from 'prop-types';
2
+ import { number, string, arrayOf, shape, any, bool } from 'prop-types';
3
3
  import { View } from 'react-native';
4
4
 
5
5
  import Magnitude from '../../../Magnitude';
@@ -10,13 +10,14 @@ import styles, { ICON_SIZE } from './styles';
10
10
  import { getIndicatorPosition, getTextPosition, getTotalRange } from './utils';
11
11
 
12
12
  const Indicator = ({
13
- consumptionValue,
14
- consumptionUnit,
15
- amountValue,
16
13
  amountUnit,
14
+ amountValue,
15
+ consumptionLimit,
16
+ consumptionUnit,
17
+ consumptionValue,
17
18
  rateStages,
18
19
  texts,
19
- consumptionLimit
20
+ withoutAmountValue
20
21
  }) => {
21
22
  const { indicatorLabel } = texts || {};
22
23
  const [surfaceWidth, setSurfaceWidth] = useState(0);
@@ -63,7 +64,7 @@ const Indicator = ({
63
64
  unity={consumptionUnit}
64
65
  iconProps={{ height: ICON_SIZE, width: ICON_SIZE }}
65
66
  />
66
- {consumptionValue > 0 && (
67
+ {!withoutAmountValue && consumptionValue > 0 && (
67
68
  <Magnitude
68
69
  semibold
69
70
  value={amountValue}
@@ -102,13 +103,14 @@ const Indicator = ({
102
103
  };
103
104
 
104
105
  Indicator.propTypes = {
105
- consumptionValue: number,
106
- consumptionUnit: string,
107
- amountValue: string,
108
106
  amountUnit: number,
107
+ amountValue: string,
108
+ consumptionLimit: number,
109
+ consumptionUnit: string,
110
+ consumptionValue: number,
109
111
  rateStages: arrayOf(shape(any)),
110
112
  texts: arrayOf(shape(any)),
111
- consumptionLimit: number
113
+ withoutAmountValue: bool
112
114
  };
113
115
 
114
116
  export default Indicator;
@@ -9,14 +9,15 @@ import styles from './styles';
9
9
  import Indicator from './components/Indicator';
10
10
 
11
11
  const RateStagesGraph = ({
12
- consumptionValue,
13
- consumptionUnit,
14
- amountValue,
15
12
  amountUnit,
13
+ amountValue,
14
+ consumptionLimit,
15
+ consumptionUnit,
16
+ consumptionValue,
16
17
  rateStages,
17
18
  texts,
18
- withoutStages,
19
- consumptionLimit
19
+ withoutAmountValue,
20
+ withoutStages
20
21
  }) => (
21
22
  <View style={styles.container}>
22
23
  <Bars rateStages={rateStages} withoutStages={withoutStages} />
@@ -28,18 +29,20 @@ const RateStagesGraph = ({
28
29
  amountUnit={amountUnit}
29
30
  rateStages={rateStages}
30
31
  texts={texts}
32
+ withoutAmountValue={withoutAmountValue}
31
33
  />
32
34
  </View>
33
35
  );
34
36
 
35
37
  RateStagesGraph.propTypes = {
36
- consumptionValue: number,
38
+ amountUnit: string,
39
+ amountValue: number,
37
40
  consumptionLimit: number,
38
41
  consumptionUnit: string,
39
- amountValue: number,
40
- amountUnit: string,
42
+ consumptionValue: number,
41
43
  rateStages: rateStagesTypes,
42
44
  texts: arrayOf(shape(any)),
45
+ withoutAmountValue: bool,
43
46
  withoutStages: bool
44
47
  };
45
48
 
@@ -7,19 +7,20 @@ import RateStagesGraph from './components/RateStagesGraph';
7
7
  import styles from './styles';
8
8
 
9
9
  const RateChart = ({
10
- consumptionValue,
11
- consumptionUnit,
12
- amountValue,
13
10
  amountUnit,
11
+ amountValue,
14
12
  category,
13
+ categoryButtonUrl,
14
+ consumptionLimit,
15
+ consumptionUnit,
16
+ consumptionValue,
15
17
  rate,
16
18
  rateStages,
17
- texts,
18
- withoutStages,
19
19
  showCategory,
20
20
  showCategoryButton,
21
- categoryButtonUrl,
22
- consumptionLimit
21
+ texts,
22
+ withoutAmountValue = false,
23
+ withoutStages
23
24
  }) => {
24
25
  const consumptionValueCorrected = consumptionValue && Math.round(consumptionValue);
25
26
 
@@ -45,6 +46,7 @@ const RateChart = ({
45
46
  rateStages={rateStages}
46
47
  texts={texts}
47
48
  withoutStages={withoutStages}
49
+ withoutAmountValue={withoutAmountValue}
48
50
  />
49
51
  )}
50
52
  </View>
@@ -53,19 +55,20 @@ const RateChart = ({
53
55
  };
54
56
 
55
57
  RateChart.propTypes = {
56
- consumptionValue: number,
57
- consumptionUnit: string,
58
- amountValue: number,
59
58
  amountUnit: string,
59
+ amountValue: number,
60
60
  category: string,
61
- rate: string,
61
+ categoryButtonUrl: string,
62
62
  consumptionLimit: number,
63
+ consumptionUnit: string,
64
+ consumptionValue: number,
65
+ rate: string,
63
66
  rateStages: arrayOf(shape(any)),
64
- texts: arrayOf(shape(any)),
65
- withoutStages: bool,
66
67
  showCategory: bool,
67
68
  showCategoryButton: bool,
68
- categoryButtonUrl: string
69
+ texts: arrayOf(shape(any)),
70
+ withoutAmountValue: bool,
71
+ withoutStages: bool
69
72
  };
70
73
 
71
74
  export default RateChart;
@@ -0,0 +1,33 @@
1
+ import React from 'react';
2
+ import { ViewPropTypes } from 'deprecated-react-native-prop-types';
3
+ import { bool, object, shape, string } from 'prop-types';
4
+
5
+ import UTStatus from '../../../UTStatus';
6
+
7
+ const Status = ({ shouldUseGap, statusProps, themedStyles }) => {
8
+ const { Icon, label, labelProps, type, variant, withoutIcon } = statusProps;
9
+
10
+ return (
11
+ <UTStatus
12
+ Icon={Icon}
13
+ labelProps={labelProps}
14
+ style={{ container: [shouldUseGap ? themedStyles.gap : '', themedStyles.status] }}
15
+ type={type}
16
+ variant={variant}
17
+ withoutIcon={withoutIcon}
18
+ >
19
+ {label}
20
+ </UTStatus>
21
+ );
22
+ };
23
+
24
+ Status.propTypes = {
25
+ shouldUseGap: bool,
26
+ statusProps: shape({
27
+ label: string,
28
+ labelProps: object
29
+ }),
30
+ themedStyles: ViewPropTypes.style
31
+ };
32
+
33
+ export default Status;
@@ -29,6 +29,7 @@ const UTProductItem = ({
29
29
  secondaryAction,
30
30
  selectedQuantity,
31
31
  style,
32
+ statusProps = {},
32
33
  title
33
34
  }) => {
34
35
  const theme = useTheme();
@@ -47,7 +48,8 @@ const UTProductItem = ({
47
48
  discount,
48
49
  previousAmount,
49
50
  themedStyles,
50
- title
51
+ title,
52
+ statusProps
51
53
  }).map(({ Component, props }, index, array) => (
52
54
  <Component key={Math.random} {...props} shouldUseGap={index !== array.length - 1} />
53
55
  ))}
@@ -90,7 +92,8 @@ UTProductItem.propTypes = {
90
92
  quantityLabelProps: object,
91
93
  secondaryAction: ActionPropTypes,
92
94
  selectedQuantity: number,
93
- title: string
95
+ title: string,
96
+ statusProps: object
94
97
  };
95
98
 
96
99
  export default UTProductItem;
@@ -83,5 +83,8 @@ export const getUTProductItemStyles = (theme = {}) =>
83
83
  },
84
84
  spaceBetween: {
85
85
  justifyContent: 'space-between'
86
+ },
87
+ status: {
88
+ alignSelf: 'flex-start'
86
89
  }
87
90
  });
@@ -1,7 +1,10 @@
1
+ import isEmpty from 'lodash/isEmpty';
2
+
1
3
  import Title from './components/Title';
2
4
  import AdditionalInfo from './components/AdditionalInfo';
3
5
  import Discount from './components/Discount';
4
6
  import Amount from './components/Amount';
7
+ import Status from './components/Status';
5
8
 
6
9
  export const leftSectionComponents = ({
7
10
  additionalInfo,
@@ -9,7 +12,8 @@ export const leftSectionComponents = ({
9
12
  discount,
10
13
  previousAmount,
11
14
  themedStyles,
12
- title
15
+ title,
16
+ statusProps
13
17
  }) =>
14
18
  [
15
19
  { Component: Title, key: 'title', props: { themedStyles, title }, show: !!title },
@@ -19,6 +23,12 @@ export const leftSectionComponents = ({
19
23
  props: { additionalInfo, themedStyles },
20
24
  show: additionalInfo
21
25
  },
26
+ {
27
+ Component: Status,
28
+ key: 'status',
29
+ props: { themedStyles, statusProps },
30
+ show: !isEmpty(statusProps)
31
+ },
22
32
  {
23
33
  Component: Discount,
24
34
  key: 'discount',
@@ -0,0 +1,24 @@
1
+ # UTStatus
2
+
3
+ ## Description
4
+
5
+ `UTStatus` is a simple status indicator that combines an icon and a label. It's fully theme-aware and supports multiple variants and types. It is designed to be flexible and themeable to fit different UI requirements.
6
+
7
+ ## Props
8
+
9
+ | Name | Type | Default | Description |
10
+ | ----------- | ------ | --------- | ----------------------------------------------------------------------------------------------------------------------------------- |
11
+ | Icon | string | - | Allows display for a custom icon. If omitted, a default Icon for the variant will be used. |
12
+ | labelProps | object | {} | Props to pass down to the internal UTLabel component. |
13
+ | style | object | - | Custom styles to apply to the component. |
14
+ | type | string | 'dark' | Color theme to apply for both the icon and label text. |
15
+ | variant | string | 'success' | The variant will defined the default icon that the component will render, as well as the background color for the status container. |
16
+ | withoutIcon | bool | false | if `true`, no icon will be rendered. |
17
+
18
+ ## Example
19
+
20
+ ```jsx
21
+ <UTStatus variant="error" type="negative" labelProps={{ withMarkdown: true }}>
22
+ Error con Markdown
23
+ </UTStatus>
24
+ ```
@@ -0,0 +1,14 @@
1
+ export const VARIANTS = {
2
+ accent: 'accent',
3
+ error: 'error',
4
+ gray: 'gray',
5
+ information: 'information',
6
+ success: 'success',
7
+ warning: 'warning'
8
+ };
9
+
10
+ export const TYPES = {
11
+ accent: 'accent',
12
+ dark: 'dark',
13
+ negative: 'negative'
14
+ };
@@ -0,0 +1,48 @@
1
+ import { View } from 'react-native';
2
+ import React from 'react';
3
+ import { bool, object, string } from 'prop-types';
4
+
5
+ import UTLabel from '../UTLabel';
6
+ import UTIcon from '../UTIcon';
7
+ import { mergeMultipleStyles } from '../../utils/styleUtils';
8
+ import { useTheme } from '../../theming';
9
+
10
+ import { defaultIconMapper, ownStyles, getVariantStyles } from './theme';
11
+ import { TYPES, VARIANTS } from './constants';
12
+
13
+ const UTStatus = ({
14
+ children,
15
+ Icon,
16
+ labelProps = {},
17
+ style,
18
+ type = TYPES.dark,
19
+ variant = VARIANTS.success,
20
+ withoutIcon
21
+ }) => {
22
+ const theme = useTheme();
23
+ const themedStyles = mergeMultipleStyles(
24
+ ownStyles,
25
+ getVariantStyles(theme)({ variant, type }),
26
+ theme?.UTStatus,
27
+ style
28
+ );
29
+ const StatusIcon = Icon ?? defaultIconMapper(variant);
30
+ return (
31
+ <View style={themedStyles.container}>
32
+ {withoutIcon ? null : <UTIcon colorTheme={type} name={StatusIcon} />}
33
+ <UTLabel colorTheme={type} {...labelProps}>
34
+ {children}
35
+ </UTLabel>
36
+ </View>
37
+ );
38
+ };
39
+
40
+ UTStatus.propTypes = {
41
+ Icon: string,
42
+ labelProps: object,
43
+ type: string,
44
+ variant: string,
45
+ withoutIcon: bool
46
+ };
47
+
48
+ export default UTStatus;
@@ -0,0 +1,30 @@
1
+ import { TYPES, VARIANTS } from './constants';
2
+
3
+ export const defaultIconMapper = variant =>
4
+ ({
5
+ [VARIANTS.accent]: 'IconInfoCircle',
6
+ [VARIANTS.error]: 'IconX',
7
+ [VARIANTS.information]: 'IconInfoCircle',
8
+ [VARIANTS.success]: 'IconCheck',
9
+ [VARIANTS.gray]: 'IconArchive',
10
+ [VARIANTS.warning]: 'IconAlertTriangle'
11
+ })[variant];
12
+
13
+ export const ownStyles = {
14
+ container: {
15
+ flexDirection: 'row',
16
+ gap: 8,
17
+ borderRadius: 4,
18
+ paddingHorizontal: 8,
19
+ paddingVertical: 4,
20
+ alignItems: 'center'
21
+ }
22
+ };
23
+
24
+ export const getVariantStyles =
25
+ theme =>
26
+ ({ variant, type }) => ({
27
+ container: {
28
+ backgroundColor: theme.Palette[variant]?.[type === TYPES.negative ? '04' : '01']
29
+ }
30
+ });
package/lib/index.js CHANGED
@@ -64,6 +64,7 @@ export { default as UTRoundView } from './components/UTRoundView';
64
64
  export { default as UTSearchField } from './components/UTSearchField';
65
65
  export { default as UTSelect } from './components/UTSelect';
66
66
  export { default as UTSelectableCard } from './components/UTSelectableCard';
67
+ export { default as UTStatus } from './components/UTStatus';
67
68
  export { default as UTStatusMessage } from './components/UTStatusMessage';
68
69
  export { default as UTStepFeedback } from './components/UTStepFeedback';
69
70
  export { default as UTSwitch } from './components/UTSwitch';
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.41.0",
5
+ "version": "1.43.0",
6
6
  "repository": "https://github.com/widergy/mobile-ui.git",
7
7
  "main": "lib/index.js",
8
8
  "files": [