@hero-design/rn 8.103.5 → 8.103.7

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 (54) hide show
  1. package/.turbo/turbo-build.log +4 -4
  2. package/CHANGELOG.md +16 -0
  3. package/es/index.js +174 -73
  4. package/lib/index.js +174 -73
  5. package/package.json +1 -1
  6. package/src/components/DatePicker/DatePickerAndroid.tsx +18 -4
  7. package/src/components/DatePicker/DatePickerCalendar.tsx +18 -4
  8. package/src/components/DatePicker/DatePickerIOS.tsx +18 -4
  9. package/src/components/DatePicker/StyledDatePicker.tsx +19 -2
  10. package/src/components/DatePicker/__tests__/DatePicker.spec.tsx +102 -1
  11. package/src/components/DatePicker/__tests__/__snapshots__/DatePicker.spec.tsx.snap +6 -0
  12. package/src/components/DatePicker/__tests__/__snapshots__/DatePickerAndroid.spec.tsx.snap +2 -0
  13. package/src/components/DatePicker/__tests__/__snapshots__/DatePickerCalendar.spec.tsx.snap +2 -0
  14. package/src/components/DatePicker/__tests__/__snapshots__/DatePickerIOS.spec.tsx.snap +4 -0
  15. package/src/components/DatePicker/types.ts +11 -0
  16. package/src/components/RichTextEditor/RichTextEditor.tsx +6 -2
  17. package/src/components/RichTextEditor/StyledRichTextEditor.ts +1 -4
  18. package/src/components/RichTextEditor/__tests__/RichTextEditor.spec.tsx +4 -2
  19. package/src/components/RichTextEditor/__tests__/__snapshots__/RichTextEditor.spec.tsx.snap +8 -5
  20. package/src/components/Select/MultiSelect/__tests__/__snapshots__/index.spec.tsx.snap +7 -0
  21. package/src/components/Select/MultiSelect/__tests__/index.spec.tsx +53 -0
  22. package/src/components/Select/MultiSelect/index.tsx +18 -8
  23. package/src/components/Select/SingleSelect/__tests__/__snapshots__/index.spec.tsx.snap +6 -0
  24. package/src/components/Select/SingleSelect/__tests__/index.spec.tsx +50 -0
  25. package/src/components/Select/SingleSelect/index.tsx +19 -8
  26. package/src/components/Select/StyledSelect.tsx +25 -2
  27. package/src/components/Select/index.tsx +8 -2
  28. package/src/components/TextInput/__tests__/__snapshots__/index.spec.tsx.snap +14 -0
  29. package/src/components/TextInput/index.tsx +6 -1
  30. package/src/components/TimePicker/StyledTimePicker.tsx +19 -2
  31. package/src/components/TimePicker/TimePickerAndroid.tsx +18 -4
  32. package/src/components/TimePicker/TimePickerIOS.tsx +21 -5
  33. package/src/components/TimePicker/__tests__/TimePicker.spec.tsx +72 -1
  34. package/src/components/TimePicker/__tests__/__snapshots__/TimePickerAndroid.spec.tsx.snap +4 -0
  35. package/src/components/TimePicker/__tests__/__snapshots__/TimePickerIOS.spec.tsx.snap +4 -0
  36. package/src/components/TimePicker/types.ts +11 -0
  37. package/stats/8.103.5/rn-stats.html +0 -2
  38. package/stats/8.103.6/rn-stats.html +4842 -0
  39. package/stats/8.103.7/rn-stats.html +4844 -0
  40. package/types/components/DatePicker/DatePickerAndroid.d.ts +1 -1
  41. package/types/components/DatePicker/DatePickerCalendar.d.ts +1 -1
  42. package/types/components/DatePicker/DatePickerIOS.d.ts +1 -1
  43. package/types/components/DatePicker/StyledDatePicker.d.ts +8 -1
  44. package/types/components/DatePicker/types.d.ts +11 -0
  45. package/types/components/RichTextEditor/StyledRichTextEditor.d.ts +0 -2
  46. package/types/components/Select/MultiSelect/index.d.ts +2 -1
  47. package/types/components/Select/SingleSelect/index.d.ts +2 -1
  48. package/types/components/Select/StyledSelect.d.ts +8 -1
  49. package/types/components/Select/index.d.ts +2 -2
  50. package/types/components/Select/index.internal.d.ts +1 -1
  51. package/types/components/TimePicker/StyledTimePicker.d.ts +8 -1
  52. package/types/components/TimePicker/TimePickerAndroid.d.ts +1 -1
  53. package/types/components/TimePicker/TimePickerIOS.d.ts +1 -1
  54. package/types/components/TimePicker/types.d.ts +11 -0
@@ -1,5 +1,5 @@
1
1
  import styled from '@emotion/native';
2
- import { View } from 'react-native';
2
+ import { View, TouchableOpacity } from 'react-native';
3
3
  import type { ViewProps } from 'react-native';
4
4
 
5
5
  const StyledPickerWrapper = styled(View)<ViewProps>(({ theme }) => ({
@@ -7,4 +7,21 @@ const StyledPickerWrapper = styled(View)<ViewProps>(({ theme }) => ({
7
7
  alignItems: 'center',
8
8
  }));
9
9
 
10
- export { StyledPickerWrapper };
10
+ const getZIndexByState = ({ themeHasError }: { themeHasError: boolean }) => {
11
+ if (themeHasError) {
12
+ return 1;
13
+ }
14
+
15
+ return 0;
16
+ };
17
+
18
+ const StyledTouchableOpacity = styled(TouchableOpacity)<{
19
+ themeGroupStyleEnabled: boolean;
20
+ themeHasError: boolean;
21
+ }>(({ themeGroupStyleEnabled, themeHasError }) => ({
22
+ ...(themeGroupStyleEnabled && {
23
+ zIndex: getZIndexByState({ themeHasError }),
24
+ }),
25
+ }));
26
+
27
+ export { StyledPickerWrapper, StyledTouchableOpacity };
@@ -1,7 +1,8 @@
1
1
  import React from 'react';
2
2
  import { Platform } from 'react-native';
3
3
  import { fireEvent } from '@testing-library/react-native';
4
- import DatePicker from '..';
4
+ // Use internal import for full prop support
5
+ import DatePicker from '../index.internal';
5
6
  import renderWithTheme from '../../../testHelpers/renderWithTheme';
6
7
  import { Button, Typography } from '../../..';
7
8
 
@@ -57,6 +58,106 @@ describe('DatePicker', () => {
57
58
  expect(getByTestId('datePickerCalendar')).toBeDefined();
58
59
  });
59
60
 
61
+ it('renders correctly when inputProps loading is true', () => {
62
+ Platform.OS = 'ios';
63
+ const { getByTestId } = renderWithTheme(
64
+ <DatePicker
65
+ label="Start date"
66
+ value={new Date('1995-12-17T00:00:00.000Z')}
67
+ minDate={new Date('1994-12-17T00:00:00.000Z')}
68
+ maxDate={new Date('1996-12-17T00:00:00.000Z')}
69
+ confirmLabel="Confirm"
70
+ inputProps={{ loading: true }}
71
+ onChange={jest.fn()}
72
+ />
73
+ );
74
+
75
+ expect(getByTestId('input-suffix')).toHaveProp('name', 'loading');
76
+ });
77
+
78
+ it('renders correctly when groupStyleEnabled is true and no error', () => {
79
+ Platform.OS = 'ios';
80
+ const { getByTestId } = renderWithTheme(
81
+ <DatePicker
82
+ label="Start date"
83
+ value={new Date('1995-12-17T00:00:00.000Z')}
84
+ minDate={new Date('1994-12-17T00:00:00.000Z')}
85
+ maxDate={new Date('1996-12-17T00:00:00.000Z')}
86
+ confirmLabel="Confirm"
87
+ groupStyleEnabled
88
+ onChange={jest.fn()}
89
+ />
90
+ );
91
+
92
+ const touchableOpacity = getByTestId('date-picker-ios-touchable-opacity');
93
+ expect(touchableOpacity).toBeTruthy();
94
+ expect(touchableOpacity.props.style).toHaveProperty('zIndex', 0);
95
+ });
96
+
97
+ it('renders correctly when groupStyleEnabled is true and has error', () => {
98
+ Platform.OS = 'ios';
99
+ const { getByTestId } = renderWithTheme(
100
+ <DatePicker
101
+ label="Start date"
102
+ value={new Date('1995-12-17T00:00:00.000Z')}
103
+ minDate={new Date('1994-12-17T00:00:00.000Z')}
104
+ maxDate={new Date('1996-12-17T00:00:00.000Z')}
105
+ confirmLabel="Confirm"
106
+ groupStyleEnabled
107
+ error="This field is required"
108
+ onChange={jest.fn()}
109
+ />
110
+ );
111
+
112
+ const touchableOpacity = getByTestId('date-picker-ios-touchable-opacity');
113
+ expect(touchableOpacity).toBeTruthy();
114
+ expect(touchableOpacity.props.style).toHaveProperty('zIndex', 1);
115
+ });
116
+
117
+ it('renders correctly when groupStyleEnabled is true and has error for Android', () => {
118
+ Platform.OS = 'android';
119
+ const { getByTestId } = renderWithTheme(
120
+ <DatePicker
121
+ label="Start date"
122
+ value={new Date('1995-12-17T00:00:00.000Z')}
123
+ minDate={new Date('1994-12-17T00:00:00.000Z')}
124
+ maxDate={new Date('1996-12-17T00:00:00.000Z')}
125
+ confirmLabel="Confirm"
126
+ groupStyleEnabled
127
+ error="This field is required"
128
+ onChange={jest.fn()}
129
+ />
130
+ );
131
+
132
+ const touchableOpacity = getByTestId(
133
+ 'date-picker-android-touchable-opacity'
134
+ );
135
+ expect(touchableOpacity).toBeTruthy();
136
+ expect(touchableOpacity.props.style).toHaveProperty('zIndex', 1);
137
+ });
138
+
139
+ it('renders correctly when groupStyleEnabled is true and has error for Calendar variant', () => {
140
+ const { getByTestId } = renderWithTheme(
141
+ <DatePicker
142
+ label="Start date"
143
+ value={new Date('1995-12-17T00:00:00.000Z')}
144
+ minDate={new Date('1994-12-17T00:00:00.000Z')}
145
+ maxDate={new Date('1996-12-17T00:00:00.000Z')}
146
+ confirmLabel="Confirm"
147
+ variant="calendar"
148
+ groupStyleEnabled
149
+ error="This field is required"
150
+ onChange={jest.fn()}
151
+ />
152
+ );
153
+
154
+ const touchableOpacity = getByTestId(
155
+ 'date-picker-calendar-touchable-opacity'
156
+ );
157
+ expect(touchableOpacity).toBeTruthy();
158
+ expect(touchableOpacity.props.style).toHaveProperty('zIndex', 1);
159
+ });
160
+
60
161
  it.each`
61
162
  OS | variant
62
163
  ${'ios'} | ${'calendar'}
@@ -41,6 +41,7 @@ exports[`DatePicker renders DatePickerAndroid when OS is android 1`] = `
41
41
  "opacity": 1,
42
42
  }
43
43
  }
44
+ testID="date-picker-android-touchable-opacity"
44
45
  >
45
46
  <View
46
47
  pointerEvents="none"
@@ -190,6 +191,7 @@ exports[`DatePicker renders DatePickerAndroid when OS is android 1`] = `
190
191
  }
191
192
  allowFontScaling={false}
192
193
  editable={true}
194
+ numberOfLines={1}
193
195
  onBlur={[Function]}
194
196
  onChangeText={[Function]}
195
197
  onFocus={[Function]}
@@ -327,6 +329,7 @@ exports[`DatePicker renders DatePickerIOS when OS is iOS 1`] = `
327
329
  "opacity": 1,
328
330
  }
329
331
  }
332
+ testID="date-picker-ios-touchable-opacity"
330
333
  >
331
334
  <View
332
335
  pointerEvents="none"
@@ -476,6 +479,7 @@ exports[`DatePicker renders DatePickerIOS when OS is iOS 1`] = `
476
479
  }
477
480
  allowFontScaling={false}
478
481
  editable={true}
482
+ numberOfLines={1}
479
483
  onBlur={[Function]}
480
484
  onChangeText={[Function]}
481
485
  onFocus={[Function]}
@@ -613,6 +617,7 @@ exports[`DatePicker renders variant Calendar 1`] = `
613
617
  "opacity": 1,
614
618
  }
615
619
  }
620
+ testID="date-picker-calendar-touchable-opacity"
616
621
  >
617
622
  <View
618
623
  pointerEvents="none"
@@ -762,6 +767,7 @@ exports[`DatePicker renders variant Calendar 1`] = `
762
767
  }
763
768
  allowFontScaling={false}
764
769
  editable={true}
770
+ numberOfLines={1}
765
771
  onBlur={[Function]}
766
772
  onChangeText={[Function]}
767
773
  onFocus={[Function]}
@@ -41,6 +41,7 @@ exports[`DatePickerAndroid renders correctly 1`] = `
41
41
  "opacity": 1,
42
42
  }
43
43
  }
44
+ testID="date-picker-android-touchable-opacity"
44
45
  >
45
46
  <View
46
47
  pointerEvents="none"
@@ -190,6 +191,7 @@ exports[`DatePickerAndroid renders correctly 1`] = `
190
191
  }
191
192
  allowFontScaling={false}
192
193
  editable={true}
194
+ numberOfLines={1}
193
195
  onBlur={[Function]}
194
196
  onChangeText={[Function]}
195
197
  onFocus={[Function]}
@@ -41,6 +41,7 @@ exports[`DatePickerCalendar renders correctly 1`] = `
41
41
  "opacity": 1,
42
42
  }
43
43
  }
44
+ testID="date-picker-calendar-touchable-opacity"
44
45
  >
45
46
  <View
46
47
  pointerEvents="none"
@@ -190,6 +191,7 @@ exports[`DatePickerCalendar renders correctly 1`] = `
190
191
  }
191
192
  allowFontScaling={false}
192
193
  editable={true}
194
+ numberOfLines={1}
193
195
  onBlur={[Function]}
194
196
  onChangeText={[Function]}
195
197
  onFocus={[Function]}
@@ -41,6 +41,7 @@ exports[`DatePickerIOS renders correctly 1`] = `
41
41
  "opacity": 1,
42
42
  }
43
43
  }
44
+ testID="date-picker-ios-touchable-opacity"
44
45
  >
45
46
  <View
46
47
  pointerEvents="none"
@@ -190,6 +191,7 @@ exports[`DatePickerIOS renders correctly 1`] = `
190
191
  }
191
192
  allowFontScaling={false}
192
193
  editable={true}
194
+ numberOfLines={1}
193
195
  onBlur={[Function]}
194
196
  onChangeText={[Function]}
195
197
  onFocus={[Function]}
@@ -710,6 +712,7 @@ exports[`DatePickerIOS renders correctly with custom locale 1`] = `
710
712
  "opacity": 1,
711
713
  }
712
714
  }
715
+ testID="date-picker-ios-touchable-opacity"
713
716
  >
714
717
  <View
715
718
  pointerEvents="none"
@@ -859,6 +862,7 @@ exports[`DatePickerIOS renders correctly with custom locale 1`] = `
859
862
  }
860
863
  allowFontScaling={false}
861
864
  editable={true}
865
+ numberOfLines={1}
862
866
  onBlur={[Function]}
863
867
  onChangeText={[Function]}
864
868
  onFocus={[Function]}
@@ -104,5 +104,16 @@ export interface DatePickerProps {
104
104
 
105
105
  // Add an internal prop type for TextInputComponent, not exported
106
106
  export interface InternalDatePickerProps extends DatePickerProps {
107
+ /**
108
+ * Props that are passed to TextInput.
109
+ */
110
+ inputProps?: Pick<TextInputProps, 'loading' | 'numberOfLines'>;
111
+ /**
112
+ * Whether the component is used within a FormGroup for styling purposes.
113
+ */
114
+ groupStyleEnabled?: boolean;
115
+ /**
116
+ * Input component to use instead of the default TextInput.
117
+ */
107
118
  TextInputComponent?: React.ComponentType<TextInputProps>;
108
119
  }
@@ -408,7 +408,12 @@ const RichTextEditor: ComponentType<RichTextEditorProps> = ({
408
408
  <StyledTextInputContainer onLayout={onLayout}>
409
409
  <StyledBorderBackDrop themeState={state} themeFocused={isFocused} />
410
410
 
411
- <StyledTextInputAndLabelContainer>
411
+ <StyledTextInputAndLabelContainer
412
+ style={{
413
+ height: webviewHeight,
414
+ }}
415
+ testID="webViewWrapper"
416
+ >
412
417
  <TouchableWithoutFeedback onPress={(e) => e.stopPropagation()}>
413
418
  <StyledWebView
414
419
  ref={webview}
@@ -420,7 +425,6 @@ const RichTextEditor: ComponentType<RichTextEditorProps> = ({
420
425
  scrollEnabled={false}
421
426
  hideKeyboardAccessoryView
422
427
  keyboardDisplayRequiresUserAction={false}
423
- height={webviewHeight}
424
428
  />
425
429
  </TouchableWithoutFeedback>
426
430
  </StyledTextInputAndLabelContainer>
@@ -6,10 +6,7 @@ export const StyledWrapper = styled(View)(({ theme }) => ({
6
6
  marginBottom: theme.__hd__.richTextEditor.space.wrapperMarginBottom,
7
7
  }));
8
8
 
9
- export const StyledWebView = styled(WebView)<{
10
- height: number | undefined;
11
- }>(({ height, theme }) => ({
12
- height,
9
+ export const StyledWebView = styled(WebView)(({ theme }) => ({
13
10
  minHeight: theme.__hd__.richTextEditor.sizes.editorMinHeight,
14
11
  backgroundColor: 'transparent',
15
12
  textAlignVertical: 'center',
@@ -58,7 +58,7 @@ jest.mock('../utils/rnWebView', () => {
58
58
  /* eslint-disable */
59
59
  /// @ts-ignore
60
60
  import { postMessageMock } from '../utils/rnWebView';
61
- import { RichTextEditorRef } from "../../../../types";
61
+ import { RichTextEditorRef } from '../../../../types';
62
62
  /* eslint-enable */
63
63
 
64
64
  describe('RichTextEditor', () => {
@@ -201,7 +201,9 @@ describe('RichTextEditor', () => {
201
201
  );
202
202
 
203
203
  expect(wrapper.toJSON()).toMatchSnapshot();
204
- expect(wrapper.getByTestId('webview')).toHaveStyle({ height: 480 });
204
+ expect(wrapper.getByTestId('webViewWrapper')).toHaveStyle({
205
+ height: 480,
206
+ });
205
207
  });
206
208
  });
207
209
  });
@@ -132,9 +132,12 @@ exports[`RichTextEditor onMessage recevied event editor-layout should update hei
132
132
  "flexGrow": 2,
133
133
  "flexShrink": 1,
134
134
  },
135
- undefined,
135
+ {
136
+ "height": 480,
137
+ },
136
138
  ]
137
139
  }
140
+ testID="webViewWrapper"
138
141
  >
139
142
  <WebView
140
143
  accessibilityState={
@@ -148,7 +151,6 @@ exports[`RichTextEditor onMessage recevied event editor-layout should update hei
148
151
  }
149
152
  accessible={true}
150
153
  focusable={true}
151
- height={480}
152
154
  hideKeyboardAccessoryView={true}
153
155
  keyboardDisplayRequiresUserAction={false}
154
156
  onClick={[Function]}
@@ -204,7 +206,6 @@ exports[`RichTextEditor onMessage recevied event editor-layout should update hei
204
206
  {
205
207
  "backgroundColor": "transparent",
206
208
  "fontSize": 16,
207
- "height": 480,
208
209
  "marginHorizontal": 8,
209
210
  "minHeight": 24,
210
211
  "textAlignVertical": "center",
@@ -456,9 +457,12 @@ exports[`RichTextEditor should render correctly 1`] = `
456
457
  "flexGrow": 2,
457
458
  "flexShrink": 1,
458
459
  },
459
- undefined,
460
+ {
461
+ "height": undefined,
462
+ },
460
463
  ]
461
464
  }
465
+ testID="webViewWrapper"
462
466
  >
463
467
  <WebView
464
468
  accessibilityState={
@@ -527,7 +531,6 @@ exports[`RichTextEditor should render correctly 1`] = `
527
531
  {
528
532
  "backgroundColor": "transparent",
529
533
  "fontSize": 16,
530
- "height": undefined,
531
534
  "marginHorizontal": 8,
532
535
  "minHeight": 24,
533
536
  "textAlignVertical": "center",
@@ -44,6 +44,7 @@ exports[`rendering allows custom renderer 1`] = `
44
44
  "opacity": 1,
45
45
  }
46
46
  }
47
+ testID="multi-select-touchable-opacity"
47
48
  >
48
49
  <View
49
50
  pointerEvents="none"
@@ -1573,6 +1574,7 @@ exports[`rendering renders correct floating bottom sheet variant 1`] = `
1573
1574
  "opacity": 1,
1574
1575
  }
1575
1576
  }
1577
+ testID="multi-select-touchable-opacity"
1576
1578
  >
1577
1579
  <View
1578
1580
  pointerEvents="none"
@@ -3288,6 +3290,7 @@ exports[`rendering renders correctly when bottom sheet is NOT visible 1`] = `
3288
3290
  "opacity": 1,
3289
3291
  }
3290
3292
  }
3293
+ testID="multi-select-touchable-opacity"
3291
3294
  >
3292
3295
  <View
3293
3296
  pointerEvents="none"
@@ -3579,6 +3582,7 @@ exports[`rendering renders correctly when bottom sheet is visible 1`] = `
3579
3582
  "opacity": 1,
3580
3583
  }
3581
3584
  }
3585
+ testID="multi-select-touchable-opacity"
3582
3586
  >
3583
3587
  <View
3584
3588
  pointerEvents="none"
@@ -5308,6 +5312,7 @@ exports[`rendering renders correctly when input is loading 1`] = `
5308
5312
  "opacity": 1,
5309
5313
  }
5310
5314
  }
5315
+ testID="multi-select-touchable-opacity"
5311
5316
  >
5312
5317
  <View
5313
5318
  pointerEvents="none"
@@ -5612,6 +5617,7 @@ exports[`rendering renders correctly when receives sections 1`] = `
5612
5617
  "opacity": 1,
5613
5618
  }
5614
5619
  }
5620
+ testID="multi-select-touchable-opacity"
5615
5621
  >
5616
5622
  <View
5617
5623
  pointerEvents="none"
@@ -6929,6 +6935,7 @@ exports[`rendering renders correctly when receives sections 2`] = `
6929
6935
  "opacity": 1,
6930
6936
  }
6931
6937
  }
6938
+ testID="multi-select-touchable-opacity"
6932
6939
  >
6933
6940
  <View
6934
6941
  pointerEvents="none"
@@ -362,6 +362,59 @@ describe('rendering', () => {
362
362
  expect(getByText('Monday')).toBeVisible();
363
363
  expect(getByText('Tuesday')).toBeVisible();
364
364
  });
365
+
366
+ it('renders correctly when groupStyleEnabled is true and no error', () => {
367
+ const { getByTestId } = renderWithTheme(
368
+ <MultiSelect
369
+ label="Allow notifications"
370
+ footerLabel="Confirm"
371
+ options={options}
372
+ value={['mon', 'tue']}
373
+ onConfirm={jest.fn()}
374
+ groupStyleEnabled
375
+ />
376
+ );
377
+
378
+ const touchableOpacity = getByTestId('multi-select-touchable-opacity');
379
+ expect(touchableOpacity).toBeTruthy();
380
+ expect(touchableOpacity.props.style).toHaveProperty('zIndex', 0);
381
+ });
382
+
383
+ it('renders correctly when groupStyleEnabled is true and has error', () => {
384
+ const { getByTestId } = renderWithTheme(
385
+ <MultiSelect
386
+ label="Allow notifications"
387
+ footerLabel="Confirm"
388
+ options={options}
389
+ value={['mon', 'tue']}
390
+ onConfirm={jest.fn()}
391
+ groupStyleEnabled
392
+ error="This field is required"
393
+ />
394
+ );
395
+
396
+ const touchableOpacity = getByTestId('multi-select-touchable-opacity');
397
+ expect(touchableOpacity).toBeTruthy();
398
+ expect(touchableOpacity.props.style).toHaveProperty('zIndex', 1);
399
+ });
400
+
401
+ it('renders correctly when groupStyleEnabled is false', () => {
402
+ const { getByTestId } = renderWithTheme(
403
+ <MultiSelect
404
+ label="Allow notifications"
405
+ footerLabel="Confirm"
406
+ options={options}
407
+ value={['mon', 'tue']}
408
+ onConfirm={jest.fn()}
409
+ groupStyleEnabled={false}
410
+ error="This field is required"
411
+ />
412
+ );
413
+
414
+ const touchableOpacity = getByTestId('multi-select-touchable-opacity');
415
+ expect(touchableOpacity).toBeTruthy();
416
+ expect(touchableOpacity.props.style).not.toHaveProperty('zIndex');
417
+ });
365
418
  });
366
419
 
367
420
  describe('behavior', () => {
@@ -1,19 +1,19 @@
1
- import React, { useEffect, useRef, useState } from 'react';
1
+ import React, { useCallback, useEffect, useRef, useState } from 'react';
2
2
  import type {
3
3
  TextInputProps as NativeTextInputProps,
4
4
  SectionList,
5
5
  } from 'react-native';
6
- import { TouchableOpacity, View } from 'react-native';
6
+ import { View } from 'react-native';
7
+ import { useKeyboard } from '../../../utils/helpers';
7
8
  import BottomSheet from '../../BottomSheet';
8
9
  import Box from '../../Box';
9
10
  import TextInput, { TextInputProps } from '../../TextInput';
10
11
  import Footer from '../Footer';
11
12
  import { getScrollParams, toFlatOptions, toSections } from '../helpers';
12
- import { StyledSearchBar } from '../StyledSelect';
13
- import type { SelectOptionType, SectionType, SelectProps } from '../types';
13
+ import { StyledSearchBar, StyledTouchableOpacity } from '../StyledSelect';
14
+ import type { SectionType, SelectOptionType, SelectProps } from '../types';
14
15
  import OptionList from './OptionList';
15
16
  import { isOptionSelected } from './utils';
16
- import { useKeyboard } from '../../../utils/helpers';
17
17
 
18
18
  export interface MultiSelectProps<
19
19
  V,
@@ -58,6 +58,7 @@ export interface InternalMultiSelectProps<
58
58
  T extends SelectOptionType<V> = SelectOptionType<V>
59
59
  > extends MultiSelectProps<V, T> {
60
60
  TextInputComponent?: React.ComponentType<TextInputProps>;
61
+ groupStyleEnabled?: boolean;
61
62
  }
62
63
 
63
64
  function MultiSelect<V, T extends SelectOptionType<V>>({
@@ -82,6 +83,7 @@ function MultiSelect<V, T extends SelectOptionType<V>>({
82
83
  value,
83
84
  supportedOrientations = ['portrait'],
84
85
  bottomSheetConfig = {},
86
+ groupStyleEnabled = false,
85
87
  ...rest
86
88
  }: InternalMultiSelectProps<V, T>) {
87
89
  const { isKeyboardVisible, keyboardHeight } = useKeyboard();
@@ -100,10 +102,13 @@ function MultiSelect<V, T extends SelectOptionType<V>>({
100
102
 
101
103
  const TextInputComponent = rest.TextInputComponent || TextInput;
102
104
 
105
+ const onPress = useCallback(() => {
106
+ setOpen(true);
107
+ }, []);
108
+
103
109
  useEffect(() => {
104
110
  setSelectingValue(value);
105
111
  }, [open, value]);
106
-
107
112
  return (
108
113
  <>
109
114
  <View
@@ -111,7 +116,12 @@ function MultiSelect<V, T extends SelectOptionType<V>>({
111
116
  !editable || disabled || inputProps?.loading ? 'none' : 'auto'
112
117
  }
113
118
  >
114
- <TouchableOpacity onPress={() => setOpen(true)}>
119
+ <StyledTouchableOpacity
120
+ onPress={onPress}
121
+ themeGroupStyleEnabled={groupStyleEnabled}
122
+ themeHasError={!!error}
123
+ testID="multi-select-touchable-opacity"
124
+ >
115
125
  {
116
126
  // prevent users from focusing TextInput
117
127
  }
@@ -136,7 +146,7 @@ function MultiSelect<V, T extends SelectOptionType<V>>({
136
146
  }
137
147
  />
138
148
  </View>
139
- </TouchableOpacity>
149
+ </StyledTouchableOpacity>
140
150
  </View>
141
151
  <BottomSheet
142
152
  variant={bottomSheetVariant || 'fixed'}
@@ -44,6 +44,7 @@ exports[`rendering allows custom renderer 1`] = `
44
44
  "opacity": 1,
45
45
  }
46
46
  }
47
+ testID="single-select-touchable-opacity"
47
48
  >
48
49
  <View
49
50
  pointerEvents="none"
@@ -1485,6 +1486,7 @@ exports[`rendering renders correct floating bottom sheet variant 1`] = `
1485
1486
  "opacity": 1,
1486
1487
  }
1487
1488
  }
1489
+ testID="single-select-touchable-opacity"
1488
1490
  >
1489
1491
  <View
1490
1492
  pointerEvents="none"
@@ -3085,6 +3087,7 @@ exports[`rendering renders correctly when bottom sheet is NOT visible 1`] = `
3085
3087
  "opacity": 1,
3086
3088
  }
3087
3089
  }
3090
+ testID="single-select-touchable-opacity"
3088
3091
  >
3089
3092
  <View
3090
3093
  pointerEvents="none"
@@ -3376,6 +3379,7 @@ exports[`rendering renders correctly when bottom sheet is visible 1`] = `
3376
3379
  "opacity": 1,
3377
3380
  }
3378
3381
  }
3382
+ testID="single-select-touchable-opacity"
3379
3383
  >
3380
3384
  <View
3381
3385
  pointerEvents="none"
@@ -4962,6 +4966,7 @@ exports[`rendering renders correctly when input is loading 1`] = `
4962
4966
  "opacity": 1,
4963
4967
  }
4964
4968
  }
4969
+ testID="single-select-touchable-opacity"
4965
4970
  >
4966
4971
  <View
4967
4972
  pointerEvents="none"
@@ -5266,6 +5271,7 @@ exports[`rendering renders correctly when receives sections 1`] = `
5266
5271
  "opacity": 1,
5267
5272
  }
5268
5273
  }
5274
+ testID="single-select-touchable-opacity"
5269
5275
  >
5270
5276
  <View
5271
5277
  pointerEvents="none"
@@ -293,6 +293,56 @@ describe('rendering', () => {
293
293
  expect(getByText('Option with object value 1')).toBeVisible();
294
294
  expect(getByText('Option with object value 2')).toBeVisible();
295
295
  });
296
+
297
+ it('renders correctly when groupStyleEnabled is true and no error', () => {
298
+ const { getByTestId } = renderWithTheme(
299
+ <SingleSelect
300
+ label="Allow notifications"
301
+ options={options}
302
+ value="mon"
303
+ onConfirm={jest.fn()}
304
+ groupStyleEnabled
305
+ />
306
+ );
307
+
308
+ const touchableOpacity = getByTestId('single-select-touchable-opacity');
309
+ expect(touchableOpacity).toBeTruthy();
310
+ expect(touchableOpacity.props.style).toHaveProperty('zIndex', 0);
311
+ });
312
+
313
+ it('renders correctly when groupStyleEnabled is true and has error', () => {
314
+ const { getByTestId } = renderWithTheme(
315
+ <SingleSelect
316
+ label="Allow notifications"
317
+ options={options}
318
+ value="mon"
319
+ onConfirm={jest.fn()}
320
+ groupStyleEnabled
321
+ error="This field is required"
322
+ />
323
+ );
324
+
325
+ const touchableOpacity = getByTestId('single-select-touchable-opacity');
326
+ expect(touchableOpacity).toBeTruthy();
327
+ expect(touchableOpacity.props.style).toHaveProperty('zIndex', 1);
328
+ });
329
+
330
+ it('renders correctly when groupStyleEnabled is false', () => {
331
+ const { getByTestId } = renderWithTheme(
332
+ <SingleSelect
333
+ label="Allow notifications"
334
+ options={options}
335
+ value="mon"
336
+ onConfirm={jest.fn()}
337
+ groupStyleEnabled={false}
338
+ error="This field is required"
339
+ />
340
+ );
341
+
342
+ const touchableOpacity = getByTestId('single-select-touchable-opacity');
343
+ expect(touchableOpacity).toBeTruthy();
344
+ expect(touchableOpacity.props.style).not.toHaveProperty('zIndex');
345
+ });
296
346
  });
297
347
 
298
348
  describe('behavior', () => {