@widergy/mobile-ui 1.47.0 → 1.48.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 (80) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/lib/components/CaptionLabel/README.md +30 -8
  3. package/lib/components/CaptionLabel/index.js +2 -1
  4. package/lib/components/CaptionLabel/propTypes.js +1 -0
  5. package/lib/components/Checkbox/README.md +93 -25
  6. package/lib/components/Checkbox/index.js +14 -1
  7. package/lib/components/Checkbox/propTypes.js +1 -0
  8. package/lib/components/Label/index.js +2 -1
  9. package/lib/components/Label/propTypes.js +1 -0
  10. package/lib/components/RadioGroup/components/RadioButton/index.js +29 -18
  11. package/lib/components/RadioGroup/index.js +19 -5
  12. package/lib/components/Touchable/index.js +3 -1
  13. package/lib/components/Touchable/propTypes.js +1 -0
  14. package/lib/components/UTBadge/index.js +3 -1
  15. package/lib/components/UTBaseInputField/README.md +41 -19
  16. package/lib/components/UTBaseInputField/components/ActionAdornment/index.js +10 -3
  17. package/lib/components/UTBaseInputField/components/BadgeAdornment/index.js +6 -1
  18. package/lib/components/UTBaseInputField/components/IconAdornment/index.js +8 -1
  19. package/lib/components/UTBaseInputField/components/PrefixAdornment/index.js +8 -2
  20. package/lib/components/UTBaseInputField/components/SuffixAdornment/index.js +6 -1
  21. package/lib/components/UTBaseInputField/components/TooltipAdornment/index.js +16 -3
  22. package/lib/components/UTBaseInputField/index.js +15 -4
  23. package/lib/components/UTBottomSheet/README.md +94 -23
  24. package/lib/components/UTBottomSheet/index.js +27 -4
  25. package/lib/components/UTButton/index.js +18 -4
  26. package/lib/components/UTButton/proptypes.js +1 -0
  27. package/lib/components/UTCheckBox/README.md +47 -0
  28. package/lib/components/UTCheckBox/index.js +24 -3
  29. package/lib/components/UTCheckBox/proptypes.js +1 -0
  30. package/lib/components/UTCheckList/README.MD +63 -0
  31. package/lib/components/UTCheckList/index.js +25 -2
  32. package/lib/components/UTCheckList/proptypes.js +1 -0
  33. package/lib/components/UTDetailDrawer/README.md +60 -10
  34. package/lib/components/UTDetailDrawer/index.js +11 -1
  35. package/lib/components/UTDetailDrawer/propTypes.js +1 -0
  36. package/lib/components/UTFieldLabel/README.md +99 -0
  37. package/lib/components/UTFieldLabel/index.js +19 -2
  38. package/lib/components/UTIcon/README.md +25 -2
  39. package/lib/components/UTIcon/index.js +3 -1
  40. package/lib/components/UTLabel/README.md +26 -0
  41. package/lib/components/UTLabel/index.js +2 -0
  42. package/lib/components/UTLabel/proptypes.js +1 -0
  43. package/lib/components/UTMenu/README.md +275 -0
  44. package/lib/components/UTMenu/components/ListView/index.js +5 -3
  45. package/lib/components/UTMenu/components/ListView/proptypes.js +2 -1
  46. package/lib/components/UTMenu/components/MenuOption/index.js +5 -3
  47. package/lib/components/UTMenu/index.js +18 -3
  48. package/lib/components/UTMenu/proptypes.js +2 -1
  49. package/lib/components/UTModal/README.md +193 -0
  50. package/lib/components/UTModal/index.js +22 -2
  51. package/lib/components/UTModal/proptypes.js +1 -0
  52. package/lib/components/UTPhoneInput/index.js +25 -2
  53. package/lib/components/UTRoundView/README.md +158 -0
  54. package/lib/components/UTRoundView/index.js +12 -1
  55. package/lib/components/UTRoundView/propTypes.js +4 -2
  56. package/lib/components/UTSearchField/README.md +64 -14
  57. package/lib/components/UTSearchField/index.js +3 -1
  58. package/lib/components/UTSearchField/proptypes.js +2 -1
  59. package/lib/components/UTSelect/versions/V0/README.md +216 -0
  60. package/lib/components/UTSelect/versions/V0/componentes/MultipleItem/index.js +4 -2
  61. package/lib/components/UTSelect/versions/V0/index.js +5 -2
  62. package/lib/components/UTSelect/versions/V0/proptypes.js +2 -1
  63. package/lib/components/UTSelect/versions/V1/README.md +94 -0
  64. package/lib/components/UTSelect/versions/V1/index.js +28 -6
  65. package/lib/components/UTSelect/versions/V1/proptypes.js +1 -0
  66. package/lib/components/UTSelectableCard/README.md +85 -0
  67. package/lib/components/UTSelectableCard/index.js +52 -4
  68. package/lib/components/UTTextInput/versions/V0/components/BaseInput/index.js +5 -1
  69. package/lib/components/UTTextInput/versions/V0/components/InputLabel/index.js +4 -1
  70. package/lib/components/UTTextInput/versions/V0/flavors/FilledInput/index.js +9 -1
  71. package/lib/components/UTTextInput/versions/V0/flavors/OutlinedInput/index.js +9 -1
  72. package/lib/components/UTTextInput/versions/V0/flavors/StandardInput/index.js +9 -1
  73. package/lib/components/UTTextInput/versions/V1/components/TextInputField/index.js +3 -0
  74. package/lib/components/UTTextInput/versions/V1/index.js +20 -3
  75. package/lib/components/UTTooltip/README.md +99 -0
  76. package/lib/components/UTTooltip/index.js +2 -0
  77. package/lib/components/UTTooltip/proptypes.js +2 -1
  78. package/lib/components/UTValidation/index.js +26 -4
  79. package/lib/constants/testIds.js +44 -0
  80. package/package.json +1 -1
@@ -10,17 +10,31 @@ import { useTheme } from '../../theming';
10
10
  import UTIcon from '../UTIcon';
11
11
  import UTLabel from '../UTLabel';
12
12
  import { mergeMultipleStyles } from '../../utils/styleUtils';
13
+ import { TEST_ID_CONSTANTS } from '../../constants/testIds';
13
14
 
14
15
  import { getColorTheme, ownStyles, ICON_SIZE, getAppearanceStyles, ownSizeStyles } from './styles';
15
16
 
17
+ const {
18
+ icon,
19
+ titleText: titleTextTestId,
20
+ tooltip: tooltipTestId,
21
+ content,
22
+ description: descriptionTestId,
23
+ additionalInfo: additionalInfoTestId,
24
+ title: titleTestId,
25
+ checkIcon: checkIconTestId
26
+ } = TEST_ID_CONSTANTS;
27
+
16
28
  const UTSelectableCard = ({
17
29
  additionalInfo = {},
18
30
  appearance = 'white',
19
31
  checkIcon = true,
20
32
  children,
33
+ dataTestId,
21
34
  description,
22
35
  disabled = false,
23
36
  Icon,
37
+ iconDataTestId,
24
38
  numberOfLines,
25
39
  onPress,
26
40
  selected = false,
@@ -43,6 +57,7 @@ const UTSelectableCard = ({
43
57
  return (
44
58
  <Surface style={themedStyles.outerContainer}>
45
59
  <Touchable
60
+ dataTestId={dataTestId}
46
61
  disabled={disabled}
47
62
  onPress={() => onPress?.()}
48
63
  style={[
@@ -56,6 +71,7 @@ const UTSelectableCard = ({
56
71
  {hasIcon &&
57
72
  (Icon.url ? (
58
73
  <Image
74
+ testID={dataTestId ? `${dataTestId}.${icon}` : undefined}
59
75
  source={{ uri: Icon.url }}
60
76
  width={Icon.size || ICON_SIZE}
61
77
  height={Icon.size || ICON_SIZE}
@@ -63,6 +79,7 @@ const UTSelectableCard = ({
63
79
  />
64
80
  ) : Icon.name ? (
65
81
  <UTIcon
82
+ dataTestId={dataTestId ? `${dataTestId}.${icon}` : undefined}
66
83
  name={Icon.name}
67
84
  colorTheme={colorTheme}
68
85
  shade={Icon.shade}
@@ -70,12 +87,16 @@ const UTSelectableCard = ({
70
87
  style={themedStyles.icon}
71
88
  />
72
89
  ) : (
73
- <Icon.Component style={themedStyles.icon} />
90
+ <Icon.Component
91
+ testID={iconDataTestId || (dataTestId ? `${dataTestId}.${icon}` : undefined)}
92
+ style={themedStyles.icon}
93
+ />
74
94
  ))}
75
95
  <View style={themedStyles.textContainer}>
76
96
  <View style={[themedStyles.column, themedStyles.leftColumn]}>
77
97
  <View style={[themedStyles.titleAndTooltip, selected && themedStyles.selectedTitleAndTooltip]}>
78
98
  <UTLabel
99
+ dataTestId={dataTestId ? `${dataTestId}.${titleTextTestId}` : undefined}
79
100
  colorTheme={colorTheme}
80
101
  numberOfLines={numberOfLines}
81
102
  style={tooltip && themedStyles.titleMargin}
@@ -85,13 +106,24 @@ const UTSelectableCard = ({
85
106
  {titleText}
86
107
  </UTLabel>
87
108
  {tooltip && (
88
- <UTTooltip content={<UTLabel>{tooltip}</UTLabel>} position="top">
109
+ <UTTooltip
110
+ dataTestId={dataTestId ? `${dataTestId}.${tooltipTestId}` : undefined}
111
+ content={
112
+ <UTLabel
113
+ dataTestId={dataTestId ? `${dataTestId}.${tooltipTestId}.${content}` : undefined}
114
+ >
115
+ {tooltip}
116
+ </UTLabel>
117
+ }
118
+ position="top"
119
+ >
89
120
  <UTIcon colorTheme={colorTheme} name="IconHelp" />
90
121
  </UTTooltip>
91
122
  )}
92
123
  </View>
93
124
  {description && (
94
125
  <UTLabel
126
+ dataTestId={dataTestId ? `${dataTestId}.${descriptionTestId}` : undefined}
95
127
  numberOfLines={numberOfLines}
96
128
  colorTheme={selected ? 'accent' : 'gray'}
97
129
  style={themedStyles.description}
@@ -103,12 +135,21 @@ const UTSelectableCard = ({
103
135
  {!isEmpty(additionalInfo) && (
104
136
  <View style={themedStyles.column}>
105
137
  {!!additionalInfo.title && (
106
- <UTLabel colorTheme={colorTheme} style={themedStyles.additionalInfo}>
138
+ <UTLabel
139
+ dataTestId={
140
+ dataTestId ? `${dataTestId}.${additionalInfoTestId}.${titleTestId}` : undefined
141
+ }
142
+ colorTheme={colorTheme}
143
+ style={themedStyles.additionalInfo}
144
+ >
107
145
  {additionalInfo.title}
108
146
  </UTLabel>
109
147
  )}
110
148
  {!!additionalInfo.description && (
111
149
  <UTLabel
150
+ dataTestId={
151
+ dataTestId ? `${dataTestId}.${additionalInfoTestId}.${descriptionTestId}` : undefined
152
+ }
112
153
  colorTheme={colorTheme}
113
154
  style={[themedStyles.description, themedStyles.additionalInfo]}
114
155
  >
@@ -120,7 +161,12 @@ const UTSelectableCard = ({
120
161
  </View>
121
162
  {children}
122
163
  {checkIcon && selected && (
123
- <UTIcon colorTheme="accent" name="IconCheck" style={themedStyles.checkIcon} />
164
+ <UTIcon
165
+ dataTestId={dataTestId ? `${dataTestId}.${checkIconTestId}` : undefined}
166
+ colorTheme="accent"
167
+ name="IconCheck"
168
+ style={themedStyles.checkIcon}
169
+ />
124
170
  )}
125
171
  </View>
126
172
  </Touchable>
@@ -132,9 +178,11 @@ UTSelectableCard.propTypes = {
132
178
  additionalInfo: shape({ description: string, title: string }),
133
179
  appearance: string,
134
180
  checkIcon: bool,
181
+ dataTestId: string,
135
182
  description: string,
136
183
  disabled: bool,
137
184
  Icon: shape({ name: string, shade: string, size: number }),
185
+ iconDataTestId: string,
138
186
  numberOfLines: number,
139
187
  onPress: func,
140
188
  selected: bool,
@@ -23,6 +23,7 @@ const BaseInput = forwardRef(
23
23
  (
24
24
  {
25
25
  onBlur,
26
+ dataTestId,
26
27
  onFocus,
27
28
  onLayout,
28
29
  label,
@@ -80,6 +81,7 @@ const BaseInput = forwardRef(
80
81
  return (
81
82
  <Fragment>
82
83
  <TextInput
84
+ testID={dataTestId}
83
85
  autoCorrect={false}
84
86
  ref={textInputRef}
85
87
  onLayout={onLayout}
@@ -100,6 +102,7 @@ const BaseInput = forwardRef(
100
102
  {(RightIcon || hiddenInput) && (
101
103
  <Touchable
102
104
  borderless
105
+ dataTestId={dataTestId ? `${dataTestId}.icon` : undefined}
103
106
  onPress={hiddenInput ? toggleShowInput : onRightIconPress}
104
107
  style={[
105
108
  styles.iconContainer,
@@ -141,7 +144,8 @@ BaseInput.propTypes = {
141
144
  outlined: bool,
142
145
  InputRef: func,
143
146
  variantStyle: ViewPropTypes.style,
144
- standard: bool
147
+ standard: bool,
148
+ dataTestId: string
145
149
  };
146
150
 
147
151
  export default withTheme(BaseInput);
@@ -10,6 +10,7 @@ const AnimatedView = Animated.View;
10
10
  const AnimatedText = Animated.Text;
11
11
 
12
12
  const InputLabel = ({
13
+ dataTestId,
13
14
  focused,
14
15
  error,
15
16
  value,
@@ -109,6 +110,7 @@ const InputLabel = ({
109
110
  ]}
110
111
  >
111
112
  <AnimatedText
113
+ testID={dataTestId}
112
114
  onLayout={handleLayout}
113
115
  ellipsizeMode={overflowControl?.ellipsizeMode}
114
116
  numberOfLines={overflowControl?.numberOfLines}
@@ -167,7 +169,8 @@ InputLabel.propTypes = {
167
169
  initX: number,
168
170
  initY: number
169
171
  }),
170
- labelBackgroundColor: string
172
+ labelBackgroundColor: string,
173
+ dataTestId: string
171
174
  };
172
175
 
173
176
  export default withTheme(InputLabel);
@@ -97,6 +97,7 @@ const FilledInput = ({
97
97
  />
98
98
  {!!label && (
99
99
  <InputLabel
100
+ dataTestId={props.dataTestId ? `${props.dataTestId}.inputLabel` : undefined}
100
101
  focused={focused}
101
102
  error={error}
102
103
  value={value}
@@ -127,8 +128,14 @@ const FilledInput = ({
127
128
  </View>
128
129
  {!!tooltip && (
129
130
  <View style={[ownStyles.tooltipContainer, multiline && { height: initialHeight }]}>
130
- <UTTooltip content={tooltip} position="left" {...tooltipProps}>
131
+ <UTTooltip
132
+ dataTestId={props.dataTestId ? `${props.dataTestId}.tooltip` : undefined}
133
+ content={tooltip}
134
+ position="left"
135
+ {...tooltipProps}
136
+ >
131
137
  <Icon
138
+ testID={props.dataTestId ? `${props.dataTestId}.tooltip.icon` : undefined}
132
139
  name="questioncircleo"
133
140
  type="antdesign"
134
141
  color={themeStyles?.tooltip?.color}
@@ -140,6 +147,7 @@ const FilledInput = ({
140
147
  )}
141
148
  </View>
142
149
  <CaptionLabel
150
+ dataTestId={props.dataTestId ? `${props.dataTestId}.captionLabel` : undefined}
143
151
  error={error}
144
152
  color={theme.colors.primary}
145
153
  errorColor={theme.colors.error}
@@ -125,6 +125,7 @@ const OutlinedInput = ({
125
125
  />
126
126
  {!!label && (
127
127
  <InputLabel
128
+ dataTestId={props.dataTestId ? `${props.dataTestId}.inputLabel` : undefined}
128
129
  focused={focused}
129
130
  error={error}
130
131
  value={value}
@@ -152,8 +153,14 @@ const OutlinedInput = ({
152
153
  </View>
153
154
  {!!tooltip && (
154
155
  <View style={[ownStyles.tooltipContainer, multiline && { height: initialHeight }]}>
155
- <UTTooltip content={<UTLabel>{tooltip}</UTLabel>} position="left" {...tooltipProps}>
156
+ <UTTooltip
157
+ dataTestId={props.dataTestId ? `${props.dataTestId}.tooltip` : undefined}
158
+ content={<UTLabel>{tooltip}</UTLabel>}
159
+ position="left"
160
+ {...tooltipProps}
161
+ >
156
162
  <Icon
163
+ testID={props.dataTestId ? `${props.dataTestId}.tooltip.icon` : undefined}
157
164
  name="questioncircleo"
158
165
  type="antdesign"
159
166
  color={themeStyles?.tooltip?.color}
@@ -165,6 +172,7 @@ const OutlinedInput = ({
165
172
  )}
166
173
  </View>
167
174
  <CaptionLabel
175
+ dataTestId={props.dataTestId ? `${props.dataTestId}.captionLabel` : undefined}
168
176
  error={error}
169
177
  color={theme.colors.primary}
170
178
  errorColor={theme.colors.error}
@@ -84,6 +84,7 @@ const StandardInput = ({
84
84
  />
85
85
  {!!label && (
86
86
  <InputLabel
87
+ dataTestId={props.dataTestId ? `${props.dataTestId}.inputLabel` : undefined}
87
88
  focused={focused}
88
89
  error={error}
89
90
  value={value}
@@ -115,8 +116,14 @@ const StandardInput = ({
115
116
  </View>
116
117
  {!!tooltip && (
117
118
  <View style={ownStyles.tooltipContainer}>
118
- <UTTooltip content={tooltip} position="left" {...tooltipProps}>
119
+ <UTTooltip
120
+ dataTestId={props.dataTestId ? `${props.dataTestId}.tooltip` : undefined}
121
+ content={tooltip}
122
+ position="left"
123
+ {...tooltipProps}
124
+ >
119
125
  <Icon
126
+ testID={props.dataTestId ? `${props.dataTestId}.tooltip.icon` : undefined}
120
127
  name="questioncircleo"
121
128
  type="antdesign"
122
129
  color={themeStyles?.tooltip?.color}
@@ -128,6 +135,7 @@ const StandardInput = ({
128
135
  )}
129
136
  </View>
130
137
  <CaptionLabel
138
+ dataTestId={props.dataTestId ? `${props.dataTestId}.captionLabel` : undefined}
131
139
  error={error}
132
140
  color={theme.colors.primary}
133
141
  errorColor={theme.colors.error}
@@ -9,6 +9,7 @@ const TextInputField = ({
9
9
  autoCapitalize,
10
10
  alwaysShowPlaceholder,
11
11
  blurOnSubmit,
12
+ dataTestId,
12
13
  disabled,
13
14
  error,
14
15
  id,
@@ -51,6 +52,7 @@ const TextInputField = ({
51
52
  alwaysShowPlaceholder={alwaysShowPlaceholder}
52
53
  autoCapitalize={autoCapitalize}
53
54
  blurOnSubmit={blurOnSubmit}
55
+ dataTestId={dataTestId}
54
56
  disabled={disabled && !readOnly}
55
57
  error={error}
56
58
  id={id}
@@ -82,6 +84,7 @@ TextInputField.propTypes = {
82
84
  alwaysShowPlaceholder: bool,
83
85
  autoCapitalize: string,
84
86
  blurOnSubmit: bool,
87
+ dataTestId: string,
85
88
  disabled: bool,
86
89
  error: string,
87
90
  id: oneOfType([number, string]),
@@ -16,6 +16,7 @@ const UTTextInput = ({
16
16
  alwaysShowPlaceholder,
17
17
  autoCapitalize,
18
18
  blurOnSubmit,
19
+ dataTestId,
19
20
  disabled,
20
21
  error,
21
22
  helpText,
@@ -56,7 +57,12 @@ const UTTextInput = ({
56
57
  return (
57
58
  <View style={[styles.container, style.root]}>
58
59
  {title && (
59
- <UTFieldLabel colorTheme={titleColorTheme} required={required} variant={TITLE_VARIANTS[titleVariant]}>
60
+ <UTFieldLabel
61
+ colorTheme={titleColorTheme}
62
+ dataTestId={dataTestId ? `${dataTestId}.title` : undefined}
63
+ required={required}
64
+ variant={TITLE_VARIANTS[titleVariant]}
65
+ >
60
66
  {title}
61
67
  </UTFieldLabel>
62
68
  )}
@@ -65,6 +71,7 @@ const UTTextInput = ({
65
71
  alwaysShowPlaceholder={alwaysShowPlaceholder}
66
72
  autoCapitalize={autoCapitalize}
67
73
  blurOnSubmit={blurOnSubmit}
74
+ dataTestId={dataTestId}
68
75
  disabled={disabled}
69
76
  error={error}
70
77
  id={id}
@@ -91,11 +98,20 @@ const UTTextInput = ({
91
98
  value={value}
92
99
  />
93
100
  {helpText && (
94
- <UTLabel colorTheme="gray" variant="small">
101
+ <UTLabel
102
+ colorTheme="gray"
103
+ dataTestId={dataTestId ? `${dataTestId}.helpText` : undefined}
104
+ variant="small"
105
+ >
95
106
  {helpText}
96
107
  </UTLabel>
97
108
  )}
98
- {validationData && <UTValidation validationData={validationData} />}
109
+ {validationData && (
110
+ <UTValidation
111
+ dataTestId={dataTestId ? `${dataTestId}.validation` : undefined}
112
+ validationData={validationData}
113
+ />
114
+ )}
99
115
  </View>
100
116
  );
101
117
  };
@@ -110,6 +126,7 @@ export const propTypes = {
110
126
  alwaysShowPlaceholder: bool,
111
127
  autoCapitalize: string,
112
128
  blurOnSubmit: bool,
129
+ dataTestId: string,
113
130
  disabled: bool,
114
131
  error: string,
115
132
  helpText: string,
@@ -0,0 +1,99 @@
1
+ # UTTooltip
2
+
3
+ ## Description
4
+
5
+ > ⚠️ **AI-GENERATED DOCUMENTATION**
6
+ > This documentation was entirely generated by an AI assistant and has NOT been reviewed by human developers. The test ID implementation details, patterns, examples, and usage instructions should be thoroughly verified before use in production. Please validate all functionality and testing approaches with your development team.
7
+
8
+ `UTTooltip` is a tooltip component that displays contextual information when triggered. It provides a flexible way to show additional details or help text for UI elements.
9
+
10
+ ## Props
11
+
12
+ | Name | Type | Default | Description |
13
+ | ---------- | ------ | ------- | -------------------------------------------------------------------- |
14
+ | children | node | | The trigger element that will show the tooltip when interacted with. |
15
+ | dataTestId | string | | Test ID for automated testing. |
16
+ | tooltip | string | | The text content to display in the tooltip. |
17
+ | style | object | | Custom styles to apply to the tooltip container. |
18
+
19
+ ## Test IDs
20
+
21
+ When `dataTestId` is provided, the component applies the test ID to its element:
22
+
23
+ | Element | Test ID | Condition |
24
+ | ------- | --------------- | --------------------------------- |
25
+ | Tooltip | `${dataTestId}` | Always when `dataTestId` provided |
26
+
27
+ ### Test ID Details
28
+
29
+ - **Tooltip**: The main tooltip container element
30
+
31
+ The UTTooltip component applies the test ID directly to its root tooltip element, making it easy to identify and interact with in automated tests.
32
+
33
+ ## Usage
34
+
35
+ ### Basic Example
36
+
37
+ ```jsx
38
+ import React from 'react';
39
+ import { Text, View } from 'react-native';
40
+ import UTTooltip from '@widergy/mobile-ui';
41
+
42
+ const BasicExample = () => {
43
+ return (
44
+ <UTTooltip tooltip="This is helpful information">
45
+ <View style={{ padding: 10, backgroundColor: '#f0f0f0' }}>
46
+ <Text>Hover or press for tooltip</Text>
47
+ </View>
48
+ </UTTooltip>
49
+ );
50
+ };
51
+
52
+ export default BasicExample;
53
+ ```
54
+
55
+ ### Example with Test IDs
56
+
57
+ ```jsx
58
+ import React from 'react';
59
+ import { Text, View } from 'react-native';
60
+ import UTTooltip from '@widergy/mobile-ui';
61
+
62
+ const TestableExample = () => {
63
+ return (
64
+ <UTTooltip dataTestId="helpTooltip" tooltip="Click here to get help with this feature">
65
+ <View style={{ padding: 10, backgroundColor: '#e3f2fd' }}>
66
+ <Text>Help</Text>
67
+ </View>
68
+ </UTTooltip>
69
+ );
70
+ };
71
+
72
+ // Generated test IDs:
73
+ // helpTooltip (tooltip container)
74
+
75
+ export default TestableExample;
76
+ ```
77
+
78
+ ### Custom Styled Example
79
+
80
+ ```jsx
81
+ import React from 'react';
82
+ import { Text, View } from 'react-native';
83
+ import UTTooltip from '@widergy/mobile-ui';
84
+
85
+ const StyledExample = () => {
86
+ return (
87
+ <UTTooltip
88
+ tooltip="Custom styled tooltip with longer text content"
89
+ style={{ backgroundColor: '#333', borderRadius: 8 }}
90
+ >
91
+ <View style={{ padding: 12, backgroundColor: '#4caf50' }}>
92
+ <Text style={{ color: 'white' }}>Custom Trigger</Text>
93
+ </View>
94
+ </UTTooltip>
95
+ );
96
+ };
97
+
98
+ export default StyledExample;
99
+ ```
@@ -10,6 +10,7 @@ const UTTooltip = ({
10
10
  content,
11
11
  onClose,
12
12
  children,
13
+ dataTestId,
13
14
  onOpen,
14
15
  offset = 5,
15
16
  disabled,
@@ -107,6 +108,7 @@ const UTTooltip = ({
107
108
  <View style={styles.overlay} />
108
109
  </TouchableOpacity>
109
110
  <View
111
+ testID={dataTestId}
110
112
  style={[styles.tooltip, tooltipPosition, propStyles?.tooltip]}
111
113
  ref={contentRef}
112
114
  onLayout={handleTooltipLayout}
@@ -1,9 +1,10 @@
1
- import { bool, func, number, node, oneOf } from 'prop-types';
1
+ import { bool, func, number, node, oneOf, string } from 'prop-types';
2
2
 
3
3
  import { BOTTOM, LEFT, RIGHT, TOP } from './constants';
4
4
 
5
5
  export default {
6
6
  content: node,
7
+ dataTestId: string,
7
8
  onClose: func,
8
9
  onOpen: func,
9
10
  fullWidth: bool,
@@ -6,13 +6,16 @@ import { View } from 'react-native';
6
6
  import { useTheme } from '../../theming';
7
7
  import UTIcon from '../UTIcon';
8
8
  import UTLabel from '../UTLabel';
9
+ import { TEST_ID_CONSTANTS } from '../../constants/testIds';
9
10
 
10
11
  import { ICON_MAPPER, ICON_SIZE, STATUS_COLOR_MAPPER, STATUSES_WITH_ICON, STATUSES } from './constants';
11
12
  import { retrieveStyle } from './theme';
12
13
  import styles from './styles';
13
14
  import { generateItemKey, generateKey } from './utils';
14
15
 
15
- const UTValidation = ({ style, validationData = [] }) => {
16
+ const { title: titleTestId, icon, text: textTestId } = TEST_ID_CONSTANTS;
17
+
18
+ const UTValidation = ({ dataTestId, style, validationData = [] }) => {
16
19
  const theme = useTheme();
17
20
 
18
21
  if (isEmpty(validationData)) return null;
@@ -26,7 +29,11 @@ const UTValidation = ({ style, validationData = [] }) => {
26
29
  {validationData.map(({ items, status = STATUSES.default, title }, index) => (
27
30
  <View key={generateKey({ items, status, title }, index)} style={styles.validationContainer}>
28
31
  {title && (
29
- <UTLabel colorTheme={STATUS_COLOR_MAPPER[status]} variant="small">
32
+ <UTLabel
33
+ dataTestId={dataTestId ? `${dataTestId}.group_${index}.${titleTestId}` : undefined}
34
+ colorTheme={STATUS_COLOR_MAPPER[status]}
35
+ variant="small"
36
+ >
30
37
  {title}
31
38
  </UTLabel>
32
39
  )}
@@ -39,11 +46,25 @@ const UTValidation = ({ style, validationData = [] }) => {
39
46
  {withIcon && (
40
47
  <View style={[styles.iconContainer, themeStyles.icon[itemStatus]]}>
41
48
  {showIcon(itemStatus) && (
42
- <UTIcon colorTheme={itemStatus} name={ICON_MAPPER[itemStatus]} size={ICON_SIZE} />
49
+ <UTIcon
50
+ dataTestId={
51
+ dataTestId ? `${dataTestId}.group_${index}.item_${itemIndex}.${icon}` : undefined
52
+ }
53
+ colorTheme={itemStatus}
54
+ name={ICON_MAPPER[itemStatus]}
55
+ size={ICON_SIZE}
56
+ />
43
57
  )}
44
58
  </View>
45
59
  )}
46
- <UTLabel colorTheme={STATUS_COLOR_MAPPER[itemStatus]} variant="small" style={styles.itemText}>
60
+ <UTLabel
61
+ dataTestId={
62
+ dataTestId ? `${dataTestId}.group_${index}.item_${itemIndex}.${textTestId}` : undefined
63
+ }
64
+ colorTheme={STATUS_COLOR_MAPPER[itemStatus]}
65
+ variant="small"
66
+ style={styles.itemText}
67
+ >
47
68
  {text}
48
69
  </UTLabel>
49
70
  </View>
@@ -70,6 +91,7 @@ export const validationDataProptypes = arrayOf(
70
91
  );
71
92
 
72
93
  UTValidation.propTypes = {
94
+ dataTestId: string,
73
95
  style: object,
74
96
  validationData: validationDataProptypes
75
97
  };
@@ -0,0 +1,44 @@
1
+ export const TEST_IDS = {
2
+ modal: 'modal',
3
+ roundView: 'roundView'
4
+ };
5
+
6
+ export const TEST_ID_CONSTANTS = {
7
+ acceptButton: 'acceptButton',
8
+ additionalInfo: 'additionalInfo',
9
+ anchor: 'anchor',
10
+ areaCode: 'areaCode',
11
+ attribution: 'attribution',
12
+ badge: 'badge',
13
+ cancelButton: 'cancelButton',
14
+ characterCount: 'characterCount',
15
+ checkIcon: 'checkIcon',
16
+ close: 'close',
17
+ closeButton: 'closeButton',
18
+ content: 'content',
19
+ description: 'description',
20
+ error: 'error',
21
+ helpText: 'helpText',
22
+ icon: 'icon',
23
+ label: 'label',
24
+ left: 'left',
25
+ list: 'list',
26
+ logo: 'logo',
27
+ modal: 'modal',
28
+ option: 'option',
29
+ phoneNumber: 'phoneNumber',
30
+ primaryAction: 'primaryAction',
31
+ required: 'required',
32
+ right: 'right',
33
+ searchInput: 'searchInput',
34
+ secondaryAction: 'secondaryAction',
35
+ selectAll: 'selectAll',
36
+ subLabel: 'subLabel',
37
+ subtitle: 'subtitle',
38
+ tertiaryAction: 'tertiaryAction',
39
+ text: 'text',
40
+ title: 'title',
41
+ titleText: 'titleText',
42
+ tooltip: 'tooltip',
43
+ validation: 'validation'
44
+ };
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.47.0",
5
+ "version": "1.48.0",
6
6
  "repository": "https://github.com/widergy/mobile-ui.git",
7
7
  "main": "lib/index.js",
8
8
  "files": [