@widergy/mobile-ui 1.46.1 → 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 (83) hide show
  1. package/CHANGELOG.md +14 -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/UTTabs/README.md +27 -11
  69. package/lib/components/UTTabs/index.js +139 -24
  70. package/lib/components/UTTabs/styles.js +104 -58
  71. package/lib/components/UTTextInput/versions/V0/components/BaseInput/index.js +5 -1
  72. package/lib/components/UTTextInput/versions/V0/components/InputLabel/index.js +4 -1
  73. package/lib/components/UTTextInput/versions/V0/flavors/FilledInput/index.js +9 -1
  74. package/lib/components/UTTextInput/versions/V0/flavors/OutlinedInput/index.js +9 -1
  75. package/lib/components/UTTextInput/versions/V0/flavors/StandardInput/index.js +9 -1
  76. package/lib/components/UTTextInput/versions/V1/components/TextInputField/index.js +3 -0
  77. package/lib/components/UTTextInput/versions/V1/index.js +20 -3
  78. package/lib/components/UTTooltip/README.md +99 -0
  79. package/lib/components/UTTooltip/index.js +2 -0
  80. package/lib/components/UTTooltip/proptypes.js +2 -1
  81. package/lib/components/UTValidation/index.js +26 -4
  82. package/lib/constants/testIds.js +44 -0
  83. package/package.json +1 -1
@@ -15,10 +15,20 @@ import UTLoading from '../UTLoading';
15
15
  import SeparatorBar from '../SeparatorBar';
16
16
  import UTButton from '../UTButton';
17
17
  import { IS_IOS } from '../../utils/platformUtils/constants';
18
+ import { TEST_IDS, TEST_ID_CONSTANTS } from '../../constants/testIds';
18
19
 
19
20
  import ModalTypes from './proptypes';
20
21
  import ownStyles from './styles';
21
22
 
23
+ const { modal } = TEST_IDS;
24
+ const {
25
+ closeButton,
26
+ title: titleTestId,
27
+ subtitle: subtitleTestId,
28
+ cancelButton: cancelButtonTestId,
29
+ acceptButton: acceptButtonTestId
30
+ } = TEST_ID_CONSTANTS;
31
+
22
32
  const UTModal = ({
23
33
  acceptButton,
24
34
  backgroundImg,
@@ -26,6 +36,7 @@ const UTModal = ({
26
36
  cancelButton,
27
37
  children,
28
38
  closeButtonColorTheme,
39
+ dataTestId = modal,
29
40
  disableTouchable,
30
41
  hideCloseButton,
31
42
  hideSeparatorBar,
@@ -53,6 +64,7 @@ const UTModal = ({
53
64
  transparent
54
65
  visible={visible}
55
66
  onRequestClose={loading ? () => {} : onRequestClose}
67
+ testID={dataTestId}
56
68
  >
57
69
  <KeyboardAvoidingView behavior={IS_IOS ? 'padding' : 'height'} style={styles.keyboardAvoidingView}>
58
70
  <ParentView onPress={() => Keyboard.dismiss()} style={[disableTouchable && styles.viewContainer]}>
@@ -81,6 +93,7 @@ const UTModal = ({
81
93
  onPress={onRequestClose || cancelButton.onPress}
82
94
  style={{ root: styles.closeButton }}
83
95
  variant="text"
96
+ dataTestId={`${dataTestId}.${closeButton}`}
84
97
  />
85
98
  )}
86
99
  <View style={styles.imageContainer}>{imageComponent}</View>
@@ -89,7 +102,7 @@ const UTModal = ({
89
102
  <View style={styles.content}>
90
103
  <View style={[styles.headerContainer, !!title && styles.closeButtonContainer]}>
91
104
  {!!title && (
92
- <UTLabel variant="title3" weight="medium">
105
+ <UTLabel variant="title3" weight="medium" dataTestId={`${dataTestId}.${titleTestId}`}>
93
106
  {title}
94
107
  </UTLabel>
95
108
  )}
@@ -100,11 +113,16 @@ const UTModal = ({
100
113
  onPress={onRequestClose}
101
114
  style={{ root: styles.closeButton }}
102
115
  variant="text"
116
+ dataTestId={`${dataTestId}.${closeButton}`}
103
117
  />
104
118
  )}
105
119
  </View>
106
120
  {!!subtitle && (
107
- <UTLabel colorTheme="gray" {...subtitleProps}>
121
+ <UTLabel
122
+ colorTheme="gray"
123
+ {...subtitleProps}
124
+ dataTestId={`${dataTestId}.${subtitleTestId}`}
125
+ >
108
126
  {subtitle}
109
127
  </UTLabel>
110
128
  )}
@@ -119,6 +137,7 @@ const UTModal = ({
119
137
  disabled={cancelButton.disabled || loading}
120
138
  onPress={cancelButton.onPress}
121
139
  variant="text"
140
+ dataTestId={`${dataTestId}.${cancelButtonTestId}`}
122
141
  >
123
142
  {cancelButton.text || 'Cancelar'}
124
143
  </UTButton>
@@ -128,6 +147,7 @@ const UTModal = ({
128
147
  colorTheme={acceptButton.colorTheme || 'primary'}
129
148
  disabled={acceptButton.disabled || loading}
130
149
  onPress={acceptButton.onPress}
150
+ dataTestId={`${dataTestId}.${acceptButtonTestId}`}
131
151
  >
132
152
  {acceptButton.text || 'Aceptar'}
133
153
  </UTButton>
@@ -19,6 +19,7 @@ export default {
19
19
  backgroundStyles: ViewPropTypes.style,
20
20
  cancelButton: buttonPropType,
21
21
  closeButtonColorTheme: string,
22
+ dataTestId: string,
22
23
  disableTouchable: bool,
23
24
  fill: string,
24
25
  hideCloseButton: bool,
@@ -9,10 +9,19 @@ import UTBaseInputField from '../UTBaseInputField';
9
9
  import UTFieldLabel from '../UTFieldLabel';
10
10
  import UTLabel from '../UTLabel';
11
11
  import UTValidation, { validationDataProptypes } from '../UTValidation';
12
+ import { TEST_ID_CONSTANTS } from '../../constants/testIds';
12
13
 
13
14
  import { AREA_CODES } from './constants';
14
15
  import styles from './styles';
15
16
 
17
+ const {
18
+ title: titleTestId,
19
+ areaCode: areaCodeTestId,
20
+ phoneNumber: phoneNumberTestId,
21
+ helpText: helpTextTestId,
22
+ validation: validationTestId
23
+ } = TEST_ID_CONSTANTS;
24
+
16
25
  class UTPhoneInput extends PureComponent {
17
26
  constructor(props) {
18
27
  super(props);
@@ -156,6 +165,7 @@ class UTPhoneInput extends PureComponent {
156
165
  const {
157
166
  areaCodePlaceholder,
158
167
  countryCode,
168
+ dataTestId,
159
169
  disabled,
160
170
  error,
161
171
  helpText,
@@ -189,6 +199,7 @@ class UTPhoneInput extends PureComponent {
189
199
  colorTheme={titleColorTheme}
190
200
  required={required}
191
201
  variant={TITLE_VARIANTS[titleVariant]}
202
+ dataTestId={dataTestId ? `${dataTestId}.${titleTestId}` : undefined}
192
203
  >
193
204
  {title}
194
205
  </UTFieldLabel>
@@ -215,6 +226,7 @@ class UTPhoneInput extends PureComponent {
215
226
  style={{ container: styles.areaCode }}
216
227
  type="number"
217
228
  value={areaCode}
229
+ dataTestId={dataTestId ? `${dataTestId}.${areaCodeTestId}` : undefined}
218
230
  />
219
231
  ) : null}
220
232
  <View style={styles.phoneNumber}>
@@ -240,15 +252,25 @@ class UTPhoneInput extends PureComponent {
240
252
  ]}
241
253
  type="number"
242
254
  value={phoneNumber}
255
+ dataTestId={dataTestId ? `${dataTestId}.${phoneNumberTestId}` : undefined}
243
256
  />
244
257
  </View>
245
258
  </View>
246
259
  {helpText && (
247
- <UTLabel colorTheme="gray" variant="small">
260
+ <UTLabel
261
+ colorTheme="gray"
262
+ variant="small"
263
+ dataTestId={dataTestId ? `${dataTestId}.${helpTextTestId}` : undefined}
264
+ >
248
265
  {helpText}
249
266
  </UTLabel>
250
267
  )}
251
- {validationData && <UTValidation validationData={validationData} />}
268
+ {validationData && (
269
+ <UTValidation
270
+ validationData={validationData}
271
+ dataTestId={dataTestId ? `${dataTestId}.${validationTestId}` : undefined}
272
+ />
273
+ )}
252
274
  </View>
253
275
  );
254
276
  }
@@ -267,6 +289,7 @@ UTPhoneInput.defaultProps = {
267
289
  UTPhoneInput.propTypes = {
268
290
  areaCodePlaceholder: string,
269
291
  countryCode: string,
292
+ dataTestId: string,
270
293
  disabled: bool,
271
294
  error: string,
272
295
  helpText: string,
@@ -0,0 +1,158 @@
1
+ # UTRoundView
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
+ `UTRoundView` is a container component that provides a rounded view with optional gradient background and shadow effects. It's designed to wrap content in a visually appealing rounded container with customizable styling options.
9
+
10
+ ## Props
11
+
12
+ | Name | Type | Default | Description |
13
+ | ---------- | ------ | ----------- | --------------------------------------------------------------------- |
14
+ | children | node | | Content to display inside the rounded view. |
15
+ | dataTestId | string | 'roundView' | Test ID for automated testing. |
16
+ | styles | object | | Custom styles object with `outerContainer` and `innerContainer` keys. |
17
+ | withShadow | bool | false | If true, applies shadow effects to the container. |
18
+ | startColor | string | | Starting color for gradient background (requires endColor). |
19
+ | endColor | string | | Ending color for gradient background (requires startColor). |
20
+
21
+ ## Test IDs
22
+
23
+ When `dataTestId` is provided (defaults to 'roundView'), the component applies the test ID to its element:
24
+
25
+ | Element | Test ID | Condition |
26
+ | --------- | --------------- | -------------------------------- |
27
+ | Container | `${dataTestId}` | Always (defaults to 'roundView') |
28
+
29
+ ### Test ID Details
30
+
31
+ - **Container**: The main outer Animated.View container that provides the rounded styling and background
32
+
33
+ Children components are responsible for their own test ID implementation. The UTRoundView only provides a test ID for its main container element.
34
+
35
+ **Default Test ID**: Since only one UTRoundView should be used per view, the `dataTestId` prop defaults to 'roundView'. This ensures that every UTRoundView instance has a consistent, predictable test ID available, while still allowing for custom test IDs when multiple round view types need to be distinguished.
36
+
37
+ ### Styles Object
38
+
39
+ The `styles` prop accepts an object with the following keys:
40
+
41
+ | Key | Type | Description |
42
+ | -------------- | ------ | ------------------------------------- |
43
+ | outerContainer | object | Styles applied to the outer container |
44
+ | innerContainer | object | Styles applied to the inner container |
45
+
46
+ ## Usage
47
+
48
+ ### Basic Example
49
+
50
+ ```jsx
51
+ import React from 'react';
52
+ import { UTRoundView, UTLabel } from '@widergy/mobile-ui';
53
+
54
+ const Example = () => {
55
+ return (
56
+ <UTRoundView>
57
+ <UTLabel>Content inside the rounded view</UTLabel>
58
+ </UTRoundView>
59
+ );
60
+ };
61
+
62
+ export default Example;
63
+ ```
64
+
65
+ ### With Custom Styles
66
+
67
+ ```jsx
68
+ import React from 'react';
69
+ import { UTRoundView, UTLabel } from '@widergy/mobile-ui';
70
+
71
+ const StyledExample = () => {
72
+ return (
73
+ <UTRoundView
74
+ styles={{
75
+ outerContainer: { margin: 20 },
76
+ innerContainer: { padding: 16, backgroundColor: '#f0f0f0' }
77
+ }}
78
+ >
79
+ <UTLabel>Styled rounded view content</UTLabel>
80
+ </UTRoundView>
81
+ );
82
+ };
83
+
84
+ export default StyledExample;
85
+ ```
86
+
87
+ ### With Gradient Background
88
+
89
+ ```jsx
90
+ import React from 'react';
91
+ import { UTRoundView, UTLabel } from '@widergy/mobile-ui';
92
+
93
+ const GradientExample = () => {
94
+ return (
95
+ <UTRoundView
96
+ startColor="#ff6b6b"
97
+ endColor="#4ecdc4"
98
+ styles={{
99
+ innerContainer: { padding: 20 }
100
+ }}
101
+ >
102
+ <UTLabel colorTheme="light">Gradient background content</UTLabel>
103
+ </UTRoundView>
104
+ );
105
+ };
106
+
107
+ export default GradientExample;
108
+ ```
109
+
110
+ ### With Shadow and Test IDs
111
+
112
+ ```jsx
113
+ import React from 'react';
114
+ import { UTRoundView, UTLabel } from '@widergy/mobile-ui';
115
+
116
+ const TestableExample = () => {
117
+ return (
118
+ <UTRoundView
119
+ dataTestId="profileCard"
120
+ withShadow
121
+ styles={{
122
+ outerContainer: { margin: 16 },
123
+ innerContainer: { padding: 20 }
124
+ }}
125
+ >
126
+ <UTLabel>Profile information card</UTLabel>
127
+ </UTRoundView>
128
+ );
129
+ };
130
+
131
+ // Generated test IDs:
132
+ // profileCard (main container)
133
+
134
+ export default TestableExample;
135
+ ```
136
+
137
+ ### With Test IDs
138
+
139
+ ```jsx
140
+ import React from 'react';
141
+ import { UTRoundView, UTLabel } from '@widergy/mobile-ui';
142
+
143
+ const TestableExample = () => {
144
+ return (
145
+ <UTRoundView dataTestId="infoCard" startColor="#667eea" endColor="#764ba2" withShadow>
146
+ <UTLabel dataTestId="infoCard.message" colorTheme="light">
147
+ Important information
148
+ </UTLabel>
149
+ </UTRoundView>
150
+ );
151
+ };
152
+
153
+ // Generated test IDs:
154
+ // infoCard (main container)
155
+ // infoCard.message (child UTLabel - handled by UTLabel component)
156
+
157
+ export default TestableExample;
158
+ ```
@@ -4,12 +4,22 @@ import merge from 'lodash/merge';
4
4
 
5
5
  import { useTheme } from '../../theming';
6
6
  import Surface from '../Surface';
7
+ import { TEST_IDS } from '../../constants/testIds';
7
8
 
8
9
  import propTypes from './propTypes';
9
10
  import ownStyles from './styles';
10
11
  import { generateBackgroundGradient } from './utils';
11
12
 
12
- const UTRoundView = ({ children, styles, withShadow = false, startColor, endColor }) => {
13
+ const { roundView } = TEST_IDS;
14
+
15
+ const UTRoundView = ({
16
+ children,
17
+ dataTestId = roundView,
18
+ styles,
19
+ withShadow = false,
20
+ startColor,
21
+ endColor
22
+ }) => {
13
23
  const theme = useTheme();
14
24
  const themedStyles = merge({}, theme?.roundView, styles);
15
25
  const withBackgroundGradient = !!startColor && !!endColor;
@@ -27,6 +37,7 @@ const UTRoundView = ({ children, styles, withShadow = false, startColor, endColo
27
37
  themedStyles?.outerContainer,
28
38
  withBackgroundGradient && ownStyles?.outerWithBackground
29
39
  ]}
40
+ testID={dataTestId}
30
41
  >
31
42
  <ChildrenContainer position="top" style={[ownStyles.innerContainer, themedStyles?.innerContainer]}>
32
43
  {children}
@@ -1,11 +1,13 @@
1
1
  import { ViewPropTypes } from 'deprecated-react-native-prop-types';
2
- import { shape, string } from 'prop-types';
2
+ import { shape, string, bool } from 'prop-types';
3
3
 
4
4
  export default {
5
+ dataTestId: string,
5
6
  styles: shape({
6
7
  outerContainer: ViewPropTypes.style,
7
8
  innerContainer: ViewPropTypes.style
8
9
  }),
9
10
  startColor: string,
10
- endColor: string
11
+ endColor: string,
12
+ withShadow: bool
11
13
  };
@@ -6,23 +6,44 @@
6
6
 
7
7
  ## Props
8
8
 
9
- | Name | Type | Default | Description |
10
- | --------------- | ------ | ------- | ------------------------------------------------------------ |
11
- | inputRef | func | | Reference to the input field. |
12
- | onBlur | func | | Function to call when the input field loses focus. |
13
- | onChange | func | | Function to call when the input field value changes. |
14
- | onFocus | func | | Function to call when the input field gains focus. |
15
- | onSubmitEditing | func | | Function to call when the input field is submitted. |
16
- | placeholder | string | | Placeholder text for the input field. |
17
- | returnKeyType | string | | Determines the return key type on the keyboard. |
18
- | size | string | medium | Size of the input field. One of: `small`, `medium`, `large`. |
19
- | style | object | | Style object to customize the input field. |
20
- | type | string | | Type of input (e.g., 'text', 'password', 'email'). |
21
- | value | string | '' | The value of the input field. |
22
- | variant | string | white | Variant of the input field. One of: `white`, `gray`. |
9
+ | Name | Type | Default | Description |
10
+ | ----------------- | ------ | ------- | ---------------------------------------------------------------------- |
11
+ | `dataTestId` | string | | Test ID for automated testing. Enables hierarchical test ID structure. |
12
+ | `inputRef` | func | | Reference to the input field. |
13
+ | `onBlur` | func | | Function to call when the input field loses focus. |
14
+ | `onChange` | func | | Function to call when the input field value changes. |
15
+ | `onFocus` | func | | Function to call when the input field gains focus. |
16
+ | `onSubmitEditing` | func | | Function to call when the input field is submitted. |
17
+ | `placeholder` | string | | Placeholder text for the input field. |
18
+ | `returnKeyType` | string | | Determines the return key type on the keyboard. |
19
+ | `size` | string | medium | Size of the input field. One of: `small`, `medium`, `large`. |
20
+ | `style` | object | | Style object to customize the input field. |
21
+ | `type` | string | | Type of input (e.g., 'text', 'password', 'email'). |
22
+ | `value` | string | '' | The value of the input field. |
23
+ | `variant` | string | white | Variant of the input field. One of: `white`, `gray`. |
24
+
25
+ ## Test IDs
26
+
27
+ When `dataTestId` is provided, the component creates a hierarchical test ID structure:
28
+
29
+ | Element | Test ID | Condition |
30
+ | ------------ | --------------------- | --------------------------------- |
31
+ | Text input | `${dataTestId}` | Always when `dataTestId` provided |
32
+ | Search icon | `${dataTestId}.left` | Always when `dataTestId` provided |
33
+ | Clear button | `${dataTestId}.right` | When `value` is not empty |
34
+
35
+ ### Test ID Structure Details
36
+
37
+ UTSearchField uses `UTBaseInputField` internally with predefined adornments:
38
+
39
+ - **Search Icon**: Always present on the left side as an `IconAdornment`
40
+ - **Clear Button**: Appears on the right side as an `ActionAdornment` when text is entered
41
+ - **Input Field**: The main TextInput element gets the base `dataTestId`
23
42
 
24
43
  ## Example
25
44
 
45
+ ### Basic Usage
46
+
26
47
  ```jsx
27
48
  import React, { useState } from 'react';
28
49
  import { View, Text } from 'react-native';
@@ -41,3 +62,32 @@ const UTSearchFieldExample = () => {
41
62
 
42
63
  export default UTSearchFieldExample;
43
64
  ```
65
+
66
+ ### With Test IDs
67
+
68
+ ```jsx
69
+ import React, { useState } from 'react';
70
+ import { View, Text } from 'react-native';
71
+ import UTSearchField from './UTSearchField';
72
+
73
+ const TestableSearchExample = () => {
74
+ const [searchValue, setSearchValue] = useState('');
75
+
76
+ return (
77
+ <View style={{ padding: 20 }}>
78
+ <UTSearchField
79
+ dataTestId="productSearch"
80
+ placeholder="Search products..."
81
+ value={searchValue}
82
+ onChange={setSearchValue}
83
+ />
84
+ <Text>Search Value: {searchValue}</Text>
85
+ </View>
86
+ );
87
+ };
88
+
89
+ // Generated test IDs:
90
+ // productSearch (input field)
91
+ // productSearch.left (search icon)
92
+ // productSearch.right (clear button, when value is not empty)
93
+ ```
@@ -20,7 +20,8 @@ const UTSearchField = ({
20
20
  style,
21
21
  type,
22
22
  value,
23
- variant
23
+ variant,
24
+ dataTestId
24
25
  }) => {
25
26
  const theme = useTheme();
26
27
  const { input } = useMemo(() => retrieveStyle({ theme }), [theme]);
@@ -54,6 +55,7 @@ const UTSearchField = ({
54
55
  type={type}
55
56
  value={value}
56
57
  variant={variant}
58
+ dataTestId={dataTestId}
57
59
  />
58
60
  );
59
61
  };
@@ -20,5 +20,6 @@ export const propTypes = {
20
20
  style: object,
21
21
  type: string,
22
22
  value: string,
23
- variant: oneOf(Object.values(VARIANT))
23
+ variant: oneOf(Object.values(VARIANT)),
24
+ dataTestId: string
24
25
  };