@hero-design/rn 8.103.5 → 8.103.6

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 (33) hide show
  1. package/.turbo/turbo-build.log +4 -4
  2. package/CHANGELOG.md +10 -0
  3. package/es/index.js +51 -17
  4. package/lib/index.js +51 -17
  5. package/package.json +1 -1
  6. package/src/components/DatePicker/__tests__/__snapshots__/DatePicker.spec.tsx.snap +3 -0
  7. package/src/components/DatePicker/__tests__/__snapshots__/DatePickerAndroid.spec.tsx.snap +1 -0
  8. package/src/components/DatePicker/__tests__/__snapshots__/DatePickerCalendar.spec.tsx.snap +1 -0
  9. package/src/components/DatePicker/__tests__/__snapshots__/DatePickerIOS.spec.tsx.snap +2 -0
  10. package/src/components/RichTextEditor/RichTextEditor.tsx +6 -2
  11. package/src/components/RichTextEditor/StyledRichTextEditor.ts +1 -4
  12. package/src/components/RichTextEditor/__tests__/RichTextEditor.spec.tsx +4 -2
  13. package/src/components/RichTextEditor/__tests__/__snapshots__/RichTextEditor.spec.tsx.snap +8 -5
  14. package/src/components/Select/MultiSelect/__tests__/__snapshots__/index.spec.tsx.snap +7 -0
  15. package/src/components/Select/MultiSelect/__tests__/index.spec.tsx +53 -0
  16. package/src/components/Select/MultiSelect/index.tsx +18 -8
  17. package/src/components/Select/SingleSelect/__tests__/__snapshots__/index.spec.tsx.snap +6 -0
  18. package/src/components/Select/SingleSelect/__tests__/index.spec.tsx +50 -0
  19. package/src/components/Select/SingleSelect/index.tsx +19 -8
  20. package/src/components/Select/StyledSelect.tsx +25 -2
  21. package/src/components/Select/index.tsx +8 -2
  22. package/src/components/TextInput/__tests__/__snapshots__/index.spec.tsx.snap +14 -0
  23. package/src/components/TextInput/index.tsx +6 -1
  24. package/src/components/TimePicker/__tests__/__snapshots__/TimePickerAndroid.spec.tsx.snap +2 -0
  25. package/src/components/TimePicker/__tests__/__snapshots__/TimePickerIOS.spec.tsx.snap +2 -0
  26. package/stats/8.103.5/rn-stats.html +0 -2
  27. package/stats/8.103.6/rn-stats.html +4844 -0
  28. package/types/components/RichTextEditor/StyledRichTextEditor.d.ts +0 -2
  29. package/types/components/Select/MultiSelect/index.d.ts +2 -1
  30. package/types/components/Select/SingleSelect/index.d.ts +2 -1
  31. package/types/components/Select/StyledSelect.d.ts +8 -1
  32. package/types/components/Select/index.d.ts +2 -2
  33. package/types/components/Select/index.internal.d.ts +1 -1
@@ -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', () => {
@@ -1,16 +1,16 @@
1
- import React, { useRef, useState } from 'react';
1
+ import React, { useCallback, useRef, useState } from 'react';
2
2
  import type {
3
- SectionList,
4
3
  TextInputProps as NativeTextInputProps,
4
+ SectionList,
5
5
  } from 'react-native';
6
- import { TouchableOpacity, View } from 'react-native';
6
+ import { View } from 'react-native';
7
+ import { deepCompareValue, useKeyboard } from '../../../utils/helpers';
7
8
  import BottomSheet from '../../BottomSheet';
8
9
  import TextInput, { TextInputProps } from '../../TextInput';
9
10
  import { getScrollParams, toFlatOptions, toSections } from '../helpers';
10
- import { StyledSearchBar } from '../StyledSelect';
11
- import type { SelectOptionType, SectionType, SelectProps } from '../types';
11
+ import { StyledSearchBar, StyledTouchableOpacity } from '../StyledSelect';
12
+ import type { SectionType, SelectOptionType, SelectProps } from '../types';
12
13
  import OptionList from './OptionList';
13
- import { deepCompareValue, useKeyboard } from '../../../utils/helpers';
14
14
 
15
15
  export interface SingleSelectProps<
16
16
  V,
@@ -43,6 +43,7 @@ export interface InternalSingleSelectProps<
43
43
  T extends SelectOptionType<V> = SelectOptionType<V>
44
44
  > extends SingleSelectProps<V, T> {
45
45
  TextInputComponent?: React.ComponentType<TextInputProps>;
46
+ groupStyleEnabled?: boolean;
46
47
  }
47
48
 
48
49
  const SingleSelect = <V, T extends SelectOptionType<V>>({
@@ -66,6 +67,7 @@ const SingleSelect = <V, T extends SelectOptionType<V>>({
66
67
  value,
67
68
  supportedOrientations = ['portrait'],
68
69
  bottomSheetConfig = {},
70
+ groupStyleEnabled = false,
69
71
  ...rest
70
72
  }: InternalSingleSelectProps<V, T>) => {
71
73
  const { isKeyboardVisible, keyboardHeight } = useKeyboard();
@@ -83,6 +85,10 @@ const SingleSelect = <V, T extends SelectOptionType<V>>({
83
85
 
84
86
  const TextInputComponent = rest.TextInputComponent || TextInput;
85
87
 
88
+ const onPress = useCallback(() => {
89
+ setOpen(true);
90
+ }, []);
91
+
86
92
  return (
87
93
  <>
88
94
  <View
@@ -90,7 +96,12 @@ const SingleSelect = <V, T extends SelectOptionType<V>>({
90
96
  !editable || disabled || inputProps?.loading ? 'none' : 'auto'
91
97
  }
92
98
  >
93
- <TouchableOpacity onPress={() => setOpen(true)}>
99
+ <StyledTouchableOpacity
100
+ onPress={onPress}
101
+ themeGroupStyleEnabled={groupStyleEnabled}
102
+ themeHasError={!!error}
103
+ testID="single-select-touchable-opacity"
104
+ >
94
105
  {
95
106
  // prevent users from focusing TextInput
96
107
  }
@@ -115,7 +126,7 @@ const SingleSelect = <V, T extends SelectOptionType<V>>({
115
126
  }
116
127
  />
117
128
  </View>
118
- </TouchableOpacity>
129
+ </StyledTouchableOpacity>
119
130
  </View>
120
131
  <BottomSheet
121
132
  variant={bottomSheetVariant || 'fixed'}
@@ -1,4 +1,4 @@
1
- import { SectionList, View } from 'react-native';
1
+ import { SectionList, TouchableOpacity, View } from 'react-native';
2
2
  import styled from '@emotion/native';
3
3
 
4
4
  const SectionSpacer = styled(View)(({ theme }) => ({
@@ -19,4 +19,27 @@ const StyledSectionList = styled(SectionList)(({ theme }) => ({
19
19
  paddingHorizontal: theme.__hd__.select.space.optionListHorizontalPadding,
20
20
  })) as unknown as typeof SectionList;
21
21
 
22
- export { SectionSpacer, OptionSpacer, StyledSearchBar, StyledSectionList };
22
+ const getZIndexByState = ({ themeHasError }: { themeHasError: boolean }) => {
23
+ if (themeHasError) {
24
+ return 1;
25
+ }
26
+
27
+ return 0;
28
+ };
29
+
30
+ const StyledTouchableOpacity = styled(TouchableOpacity)<{
31
+ themeGroupStyleEnabled: boolean;
32
+ themeHasError: boolean;
33
+ }>(({ themeGroupStyleEnabled, themeHasError }) => ({
34
+ ...(themeGroupStyleEnabled && {
35
+ zIndex: getZIndexByState({ themeHasError }),
36
+ }),
37
+ }));
38
+
39
+ export {
40
+ SectionSpacer,
41
+ OptionSpacer,
42
+ StyledSearchBar,
43
+ StyledSectionList,
44
+ StyledTouchableOpacity,
45
+ };
@@ -10,11 +10,17 @@ type SingleSelectType = <
10
10
  V,
11
11
  T extends SelectOptionType<V> = SelectOptionType<V>
12
12
  >(
13
- props: Omit<SingleSelectProps<V, T>, 'TextInputComponent'>
13
+ props: Omit<
14
+ SingleSelectProps<V, T>,
15
+ 'TextInputComponent' | 'groupStyleEnabled'
16
+ >
14
17
  ) => React.ReactElement;
15
18
 
16
19
  type MultiSelectType = <V, T extends SelectOptionType<V> = SelectOptionType<V>>(
17
- props: Omit<MultiSelectProps<V, T>, 'TextInputComponent'>
20
+ props: Omit<
21
+ MultiSelectProps<V, T>,
22
+ 'TextInputComponent' | 'groupStyleEnabled'
23
+ >
18
24
  ) => React.ReactElement;
19
25
 
20
26
  export default Object.assign(SingleSelect as SingleSelectType, {
@@ -199,6 +199,7 @@ exports[`TextInput backgroundColor renders correctly 1`] = `
199
199
  defaultValue="1000"
200
200
  editable={true}
201
201
  maxLength={255}
202
+ numberOfLines={1}
202
203
  onBlur={[Function]}
203
204
  onChangeText={[Function]}
204
205
  onFocus={[Function]}
@@ -527,6 +528,7 @@ exports[`TextInput defaultValue TextInput is idle renders correctly 1`] = `
527
528
  defaultValue="1000"
528
529
  editable={true}
529
530
  maxLength={255}
531
+ numberOfLines={1}
530
532
  onBlur={[Function]}
531
533
  onChangeText={[Function]}
532
534
  onFocus={[Function]}
@@ -854,6 +856,7 @@ exports[`TextInput defaultValue default Value and Value renders correctly with 2
854
856
  defaultValue="1000"
855
857
  editable={true}
856
858
  maxLength={255}
859
+ numberOfLines={1}
857
860
  onBlur={[Function]}
858
861
  onChangeText={[Function]}
859
862
  onFocus={[Function]}
@@ -1165,6 +1168,7 @@ exports[`TextInput disabled renders correctly 1`] = `
1165
1168
  }
1166
1169
  allowFontScaling={false}
1167
1170
  editable={true}
1171
+ numberOfLines={1}
1168
1172
  onBlur={[Function]}
1169
1173
  onChangeText={[Function]}
1170
1174
  onFocus={[Function]}
@@ -1441,6 +1445,7 @@ exports[`TextInput error renders correctly 1`] = `
1441
1445
  }
1442
1446
  allowFontScaling={false}
1443
1447
  editable={true}
1448
+ numberOfLines={1}
1444
1449
  onBlur={[Function]}
1445
1450
  onChangeText={[Function]}
1446
1451
  onFocus={[Function]}
@@ -1744,6 +1749,7 @@ exports[`TextInput filled renders correctly 1`] = `
1744
1749
  }
1745
1750
  allowFontScaling={false}
1746
1751
  editable={true}
1752
+ numberOfLines={1}
1747
1753
  onBlur={[Function]}
1748
1754
  onChangeText={[Function]}
1749
1755
  onFocus={[Function]}
@@ -2035,6 +2041,7 @@ exports[`TextInput helper text renders correctly 1`] = `
2035
2041
  }
2036
2042
  allowFontScaling={false}
2037
2043
  editable={true}
2044
+ numberOfLines={1}
2038
2045
  onBlur={[Function]}
2039
2046
  onChangeText={[Function]}
2040
2047
  onFocus={[Function]}
@@ -2304,6 +2311,7 @@ exports[`TextInput idle renders correctly 1`] = `
2304
2311
  }
2305
2312
  allowFontScaling={false}
2306
2313
  editable={true}
2314
+ numberOfLines={1}
2307
2315
  onBlur={[Function]}
2308
2316
  onChangeText={[Function]}
2309
2317
  onFocus={[Function]}
@@ -2594,6 +2602,7 @@ exports[`TextInput idle with suffix and prefix are React Element renders correct
2594
2602
  }
2595
2603
  allowFontScaling={false}
2596
2604
  editable={true}
2605
+ numberOfLines={1}
2597
2606
  onBlur={[Function]}
2598
2607
  onChangeText={[Function]}
2599
2608
  onFocus={[Function]}
@@ -2796,6 +2805,7 @@ exports[`TextInput loading renders correctly 1`] = `
2796
2805
  }
2797
2806
  allowFontScaling={false}
2798
2807
  editable={true}
2808
+ numberOfLines={1}
2799
2809
  onBlur={[Function]}
2800
2810
  onChangeText={[Function]}
2801
2811
  onFocus={[Function]}
@@ -3766,6 +3776,7 @@ exports[`TextInput placeholder TextInput is idle renders correctly 1`] = `
3766
3776
  }
3767
3777
  allowFontScaling={false}
3768
3778
  editable={true}
3779
+ numberOfLines={1}
3769
3780
  onBlur={[Function]}
3770
3781
  onChangeText={[Function]}
3771
3782
  onFocus={[Function]}
@@ -4061,6 +4072,7 @@ exports[`TextInput readonly renders correctly 1`] = `
4061
4072
  }
4062
4073
  allowFontScaling={false}
4063
4074
  editable={false}
4075
+ numberOfLines={1}
4064
4076
  onBlur={[Function]}
4065
4077
  onChangeText={[Function]}
4066
4078
  onFocus={[Function]}
@@ -4307,6 +4319,7 @@ exports[`TextInput ref ref methods work correctly 1`] = `
4307
4319
  }
4308
4320
  allowFontScaling={false}
4309
4321
  editable={true}
4322
+ numberOfLines={1}
4310
4323
  onBlur={[Function]}
4311
4324
  onChangeText={[Function]}
4312
4325
  onFocus={[Function]}
@@ -4583,6 +4596,7 @@ exports[`TextInput required renders correctly 1`] = `
4583
4596
  }
4584
4597
  allowFontScaling={false}
4585
4598
  editable={true}
4599
+ numberOfLines={1}
4586
4600
  onBlur={[Function]}
4587
4601
  onChangeText={[Function]}
4588
4602
  onFocus={[Function]}
@@ -226,13 +226,18 @@ export const renderInput = ({
226
226
  ref?: React.Ref<RNTextInput>;
227
227
  theme: Theme;
228
228
  }) => {
229
+ const multiline = variant === 'textarea' || nativeInputProps.multiline;
230
+ // `numberOfLines` must be `1` for single-line inputs to render properly on Android.
231
+ const numberOfLines = multiline ? nativeInputProps.numberOfLines : 1;
232
+
229
233
  return renderInputValue ? (
230
234
  renderInputValue(nativeInputProps, ref)
231
235
  ) : (
232
236
  <StyledTextInput
233
237
  {...nativeInputProps}
234
238
  themeVariant={variant}
235
- multiline={variant === 'textarea' || nativeInputProps.multiline}
239
+ multiline={multiline}
240
+ numberOfLines={numberOfLines}
236
241
  ref={ref}
237
242
  placeholderTextColor={theme.__hd__.textInput.colors.placeholder}
238
243
  />
@@ -190,6 +190,7 @@ exports[`TimePickerAndroid renders correct with hide suffix 1`] = `
190
190
  }
191
191
  allowFontScaling={false}
192
192
  editable={true}
193
+ numberOfLines={1}
193
194
  onBlur={[Function]}
194
195
  onChangeText={[Function]}
195
196
  onFocus={[Function]}
@@ -481,6 +482,7 @@ exports[`TimePickerAndroid renders correctly 1`] = `
481
482
  }
482
483
  allowFontScaling={false}
483
484
  editable={true}
485
+ numberOfLines={1}
484
486
  onBlur={[Function]}
485
487
  onChangeText={[Function]}
486
488
  onFocus={[Function]}
@@ -190,6 +190,7 @@ exports[`TimePickerIOS renders correct with hide suffix 1`] = `
190
190
  }
191
191
  allowFontScaling={false}
192
192
  editable={true}
193
+ numberOfLines={1}
193
194
  onBlur={[Function]}
194
195
  onChangeText={[Function]}
195
196
  onFocus={[Function]}
@@ -481,6 +482,7 @@ exports[`TimePickerIOS renders correctly 1`] = `
481
482
  }
482
483
  allowFontScaling={false}
483
484
  editable={true}
485
+ numberOfLines={1}
484
486
  onBlur={[Function]}
485
487
  onChangeText={[Function]}
486
488
  onFocus={[Function]}
@@ -4840,5 +4840,3 @@ var drawChart = (function (exports) {
4840
4840
  </body>
4841
4841
  </html>
4842
4842
 
4843
- ml>
4844
-